pax_global_header00006660000000000000000000000064147622666160014532gustar00rootroot0000000000000052 comment=b4b4d780bb4d1c2ecf571cd10aba7c5639bb6dc3 qt5integration-5.7.12/000077500000000000000000000000001476226661600146035ustar00rootroot00000000000000qt5integration-5.7.12/.clog.toml000066400000000000000000000002261476226661600165020ustar00rootroot00000000000000[clog] repository = "https://github.com/linuxdeepin/qt5integration" from-latest-tag = true changelog = "CHANGELOG.md" [sections] Others = ["chore"] qt5integration-5.7.12/.github/000077500000000000000000000000001476226661600161435ustar00rootroot00000000000000qt5integration-5.7.12/.github/ISSUE_TEMPLATE/000077500000000000000000000000001476226661600203265ustar00rootroot00000000000000qt5integration-5.7.12/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000023651476226661600223240ustar00rootroot00000000000000blank_issues_enabled: false contact_links: - name: BUG Report | 缺陷报告 url: https://github.com/linuxdeepin/dtk/issues/new?assignees=&labels=&template=bug-report.yml about: Please create bug reports to the issue board in our dtk repo. - name: docs-update | 文档补充 url: https://github.com/linuxdeepin/dtk/issues/new?assignees=&labels=&template=docs-update.yml about: Please create docs-update to the issue board in our dtk repo. - name: unit-test-report | 单元测试报告 url: https://github.com/linuxdeepin/dtk/issues/new?assignees=&labels=&template=unit-test-report.yml about: Please create unit-test-report to the issue board in our dtk repo. - name: Feature Request | 特性请求 url: https://github.com/linuxdeepin/developer-center/discussions/new?category=features-request-ideas-%E7%89%B9%E6%80%A7%E8%AF%B7%E6%B1%82-%E5%A4%B4%E8%84%91%E9%A3%8E%E6%9A%B4 about: Please create feature requests to the discussion board in our developer-center repo. - name: General Discussion & Questions | 常规讨论与问答 url: https://github.com/linuxdeepin/developer-center/discussions/categories/q-a-%E9%97%AE%E7%AD%94%E6%9D%BF%E5%9D%97 about: Please use the discussion board in our developer-center repo. qt5integration-5.7.12/.github/workflows/000077500000000000000000000000001476226661600202005ustar00rootroot00000000000000qt5integration-5.7.12/.github/workflows/backup-to-gitlab.yml000066400000000000000000000005371476226661600240550ustar00rootroot00000000000000name: backup to gitlab on: [push] concurrency: group: ${{ github.workflow }} cancel-in-progress: true jobs: backup-to-gitlabwh: uses: linuxdeepin/.github/.github/workflows/backup-to-gitlabwh.yml@master secrets: inherit backup-to-gitee: uses: linuxdeepin/.github/.github/workflows/backup-to-gitee.yml@master secrets: inherit qt5integration-5.7.12/.github/workflows/call-auto-tag.yml000066400000000000000000000005171476226661600233600ustar00rootroot00000000000000name: auto tag on: pull_request_target: types: [opened, synchronize, closed] paths: - "debian/changelog" concurrency: group: ${{ github.workflow }}-pull/${{ github.event.number }} cancel-in-progress: true jobs: auto_tag: uses: linuxdeepin/.github/.github/workflows/auto-tag.yml@master secrets: inherit qt5integration-5.7.12/.github/workflows/call-build-distribution.yml000066400000000000000000000004321476226661600254470ustar00rootroot00000000000000name: Call build-distribution on: push: paths-ignore: - ".github/workflows/**" pull_request_target: paths-ignore: - ".github/workflows/**" jobs: check_job: uses: linuxdeepin/.github/.github/workflows/build-distribution.yml@master secrets: inherit qt5integration-5.7.12/.github/workflows/call-chatOps.yml000066400000000000000000000002421476226661600232330ustar00rootroot00000000000000name: chatOps on: issue_comment: types: [created] jobs: chatopt: uses: linuxdeepin/.github/.github/workflows/chatOps.yml@master secrets: inherit qt5integration-5.7.12/.github/workflows/call-clacheck.yml000066400000000000000000000005251476226661600233730ustar00rootroot00000000000000name: Call CLA check on: issue_comment: types: [created] pull_request_target: types: [opened, closed, synchronize] concurrency: group: ${{ github.workflow }}-pull/${{ github.event.number }} cancel-in-progress: true jobs: clacheck: uses: linuxdeepin/.github/.github/workflows/cla-check.yml@master secrets: inherit qt5integration-5.7.12/.github/workflows/call-commitlint.yml000066400000000000000000000003641476226661600240160ustar00rootroot00000000000000name: Call commitlint on: pull_request_target: concurrency: group: ${{ github.workflow }}-pull/${{ github.event.number }} cancel-in-progress: true jobs: check_job: uses: linuxdeepin/.github/.github/workflows/commitlint.yml@master qt5integration-5.7.12/.github/workflows/call-license-check.yml000066400000000000000000000005521476226661600243330ustar00rootroot00000000000000name: Call License and README Check on: pull_request_target: types: [opened, synchronize, reopened] permissions: pull-requests: write contents: read concurrency: group: ${{ github.workflow }}-pull/${{ github.event.number }} cancel-in-progress: true jobs: license-check: uses: linuxdeepin/.github/.github/workflows/license-check.yml@master qt5integration-5.7.12/.github/workflows/call-synchronize-to-dtk6.yml000066400000000000000000000010371476226661600254760ustar00rootroot00000000000000name: Call synchronize to dtk6 on: pull_request_target: paths-ignore: - "debian/**" - "archlinux/**" - "rpm/**" - ".obs/**" - ".github/**" jobs: call-synchronize: uses: linuxdeepin/dtk/.github/workflows/synchronize-to-dtk6.yml@master secrets: inherit with: dest_repo: linuxdeepin/qt6integration source_repo: ${{ github.event.pull_request.head.repo.full_name }} source_ref: ${{ github.event.pull_request.head.ref }} pull_number: ${{ github.event.pull_request.number }} qt5integration-5.7.12/.github/workflows/cppcheck.yml000066400000000000000000000012651476226661600225070ustar00rootroot00000000000000name: cppcheck on: pull_request_target: paths-ignore: - ".github/workflows/**" concurrency: group: ${{ github.workflow }}-pull/${{ github.event.number }} cancel-in-progress: true jobs: cppchceck: name: cppcheck runs-on: ubuntu-latest steps: - run: export - uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false - uses: linuxdeepin/action-cppcheck@main with: github_token: ${{ secrets.GITHUB_TOKEN }} repository: ${{ github.repository }} pull_request_id: ${{ github.event.pull_request.number }} allow_approve: false qt5integration-5.7.12/.gitignore000066400000000000000000000005761476226661600166030ustar00rootroot00000000000000*.pro.user* build*/ bin/ # C++ objects and libs *.slo *.lo *.o *.a *.la *.lai *.so *.dll *.dylib # Qt-es /.qmake.cache .qmake.stash *.pro.user *.pro.user.* *.qbs.user *.qbs.user.* *.moc moc_*.cpp qrc_*.cpp ui_*.h Makefile* *build-* # QtCreator *.autosave # QtCtreator Qml *.qmlproject.user *.qmlproject.user.* # QtCtreator CMake CMakeLists.txt.user platformthemeplugin/NUL qt5integration-5.7.12/.gitlab-ci.yml000066400000000000000000000002271476226661600172400ustar00rootroot00000000000000include: - remote: 'https://gitlab.deepin.io/dev-tools/letmeci/raw/master/gitlab-ci/dde.yml' variables: CPPCHECK: "true" CODESPELL: "true" qt5integration-5.7.12/.obs/000077500000000000000000000000001476226661600154445ustar00rootroot00000000000000qt5integration-5.7.12/.obs/workflows.yml000066400000000000000000000022231476226661600202230ustar00rootroot00000000000000test_build: steps: - link_package: source_project: deepin:Develop:dde source_package: %{SCM_REPOSITORY_NAME} target_project: deepin:CI - configure_repositories: project: deepin:CI repositories: - name: deepin_develop paths: - target_project: deepin:CI target_repository: deepin_develop architectures: - x86_64 - aarch64 - name: debian paths: - target_project: deepin:CI target_repository: debian_sid architectures: - x86_64 - name: archlinux paths: - target_project: deepin:CI target_repository: archlinux architectures: - x86_64 filters: event: pull_request tag_build: steps: - trigger_services: project: deepin:Unstable:dde package: %{SCM_REPOSITORY_NAME} filters: event: tag_push commit_build: steps: - trigger_services: project: deepin:Develop:dde package: %{SCM_REPOSITORY_NAME} filters: event: push qt5integration-5.7.12/.packit.yaml000066400000000000000000000010231476226661600170140ustar00rootroot00000000000000# See the documentation for more information: # https://packit.dev/docs/configuration/ specfile_path: rpm/deepin-qt5integration.spec # add or remove files that should be synced synced_files: - rpm/deepin-qt5integration.spec - .packit.yaml upstream_package_name: qt5integration # downstream (Fedora) RPM package name downstream_package_name: deepin-qt5integration actions: fix-spec-file: | bash -c "sed -i -r \"0,/Version:/ s/Version:(\s*)\S*/Version:\1${PACKIT_PROJECT_VERSION}/\" rpm/deepin-qt5integration.spec" qt5integration-5.7.12/.reuse/000077500000000000000000000000001476226661600160045ustar00rootroot00000000000000qt5integration-5.7.12/.reuse/dep5000066400000000000000000000023611476226661600165660ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: qt5integration Upstream-Contact: UnionTech Software Technology Co., Ltd. <> Source: https://github.com/linuxdeepin/qt5integration # README Files: *.md CHANGELOG.md Copyright: None License: CC0-1.0 # Project file Files: *.pro *.prf *.pri Copyright: None License: CC0-1.0 # css Files: *.css Copyright: None License: CC0-1.0 # qrc Files: *.qrc Copyright: None License: CC0-1.0 # png svg dci Files: platformthemeplugin/icons/* styleplugins/chameleon/*.svg styles/images/*.png tests/*/icons/*/*.svg tests/*/*.svg tests/*/icons/*/*.dci tests/imageformats/dci/*.dci tests/platformtheme/qt-theme.ini Copyright: None License: CC0-1.0 # sh Files: tests/test-recoverage-qmake.sh Copyright: None License: CC0-1.0 # ignore git Files: .git* .syncexclude Copyright: None License: CC0-1.0 # xml toml json conf yaml Files: *.xml *.toml *.json *.conf *.yaml Copyright: None License: CC0-1.0 # rpm Files: rpm/* Copyright: None License: CC0-1.0 # debian Files: debian/* Copyright: None License: CC0-1.0 # Arch Files: archlinux/* Copyright: None License: CC0-1.0 # OBS Files: .obs/* Copyright: None License: CC0-1.0 Files: toolGenerate/**/* Copyright: None License: CC0-1.0 qt5integration-5.7.12/.syncexclude000066400000000000000000000003651476226661600171360ustar00rootroot00000000000000# Paths that will be exclude from synchronize workflow # Please use relative path which use project directory as root # Notice that # * .git # * debian # * archlinux # * .obs # * .github # are always ignored linglong.yaml conanfile.py qt5integration-5.7.12/3rdparty/000077500000000000000000000000001476226661600163535ustar00rootroot00000000000000qt5integration-5.7.12/3rdparty/qdbusmenuconnection.cpp000066400000000000000000000102461476226661600231450ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #ifndef QT_NO_SYSTEMTRAYICON #include "qdbustrayicon_p.h" #endif #include "qdbusmenuconnection_p.h" #include #include #include #include #include #include #include namespace thirdparty { #ifndef QT_DEBUG Q_LOGGING_CATEGORY(dLcMenu, "dtk.qpa.Menu"); #else Q_LOGGING_CATEGORY(dLcMenu, "dtk.qpa.Menu", QtInfoMsg); #endif const QString StatusNotifierWatcherService = QLatin1String("org.kde.StatusNotifierWatcher"); const QString StatusNotifierWatcherPath = QLatin1String("/StatusNotifierWatcher"); const QString StatusNotifierItemPath = QLatin1String("/StatusNotifierItem"); const QString MenuBarPath = QLatin1String("/MenuBar"); /*! \class QDBusMenuConnection \internal A D-Bus connection which is used for both menu and tray icon services. Connects to the session bus and registers with the respective watcher services. */ QDBusMenuConnection::QDBusMenuConnection(QObject *parent, const QString &serviceName) : QObject(parent) , m_connection(serviceName.isNull() ? QDBusConnection::sessionBus() : QDBusConnection::connectToBus(QDBusConnection::SessionBus, serviceName)) , m_dbusWatcher(new QDBusServiceWatcher(StatusNotifierWatcherService, m_connection, QDBusServiceWatcher::WatchForRegistration, this)) , m_statusNotifierHostRegistered(false) { #ifndef QT_NO_SYSTEMTRAYICON QDBusInterface systrayHost(StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, m_connection); if (systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool()) m_statusNotifierHostRegistered = true; else qCDebug(dLcMenu) << "StatusNotifierHost is not registered"; #endif } void QDBusMenuConnection::dbusError(const QDBusError &error) { qWarning() << "QDBusTrayIcon encountered a D-Bus error:" << error; } #ifndef QT_NO_SYSTEMTRAYICON bool QDBusMenuConnection::registerTrayIconMenu(QDBusTrayIcon *item) { bool success = connection().registerObject(MenuBarPath, item->menu()); if (!success) // success == false is normal, because the object may be already registered qCDebug(dLcMenu) << "failed to register" << item->instanceId() << MenuBarPath; return success; } void QDBusMenuConnection::unregisterTrayIconMenu(QDBusTrayIcon *item) { if (item->menu()) connection().unregisterObject(MenuBarPath); } bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) { bool success = connection().registerService(item->instanceId()); if (!success) { qWarning() << "failed to register service" << item->instanceId(); return false; } success = connection().registerObject(StatusNotifierItemPath, item); if (!success) { unregisterTrayIcon(item); qWarning() << "failed to register" << item->instanceId() << StatusNotifierItemPath; return false; } if (item->menu()) registerTrayIconMenu(item); return registerTrayIconWithWatcher(item); } bool QDBusMenuConnection::registerTrayIconWithWatcher(QDBusTrayIcon *item) { QDBusMessage registerMethod = QDBusMessage::createMethodCall( StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, QLatin1String("RegisterStatusNotifierItem")); registerMethod.setArguments(QVariantList() << item->instanceId()); return m_connection.callWithCallback(registerMethod, this, SIGNAL(trayIconRegistered()), SLOT(dbusError(QDBusError))); } bool QDBusMenuConnection::unregisterTrayIcon(QDBusTrayIcon *item) { unregisterTrayIconMenu(item); connection().unregisterObject(StatusNotifierItemPath); bool success = connection().unregisterService(item->instanceId()); if (!success) qWarning() << "failed to unregister service" << item->instanceId(); return success; } #endif // QT_NO_SYSTEMTRAYICON } // namespace thirdparty qt5integration-5.7.12/3rdparty/qdbusmenuconnection_p.h000066400000000000000000000033701476226661600231310ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef DBUSCONNECTION_H #define DBUSCONNECTION_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include class QDBusServiceWatcher; namespace thirdparty { #ifndef QT_NO_SYSTEMTRAYICON Q_DECLARE_LOGGING_CATEGORY(dLcMenu); class QDBusTrayIcon; #endif // QT_NO_SYSTEMTRAYICON class QDBusMenuConnection : public QObject { Q_OBJECT public: QDBusMenuConnection(QObject *parent = 0, const QString &serviceName = QString()); QDBusConnection connection() const { return m_connection; } QDBusServiceWatcher *dbusWatcher() const { return m_dbusWatcher; } bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; } #ifndef QT_NO_SYSTEMTRAYICON bool registerTrayIconMenu(QDBusTrayIcon *item); void unregisterTrayIconMenu(QDBusTrayIcon *item); bool registerTrayIcon(QDBusTrayIcon *item); bool registerTrayIconWithWatcher(QDBusTrayIcon *item); bool unregisterTrayIcon(QDBusTrayIcon *item); #endif // QT_NO_SYSTEMTRAYICON Q_SIGNALS: #ifndef QT_NO_SYSTEMTRAYICON void trayIconRegistered(); #endif // QT_NO_SYSTEMTRAYICON private Q_SLOTS: void dbusError(const QDBusError &error); private: QDBusConnection m_connection; QDBusServiceWatcher *m_dbusWatcher; bool m_statusNotifierHostRegistered; }; } // namespace thirdparty #endif // DBUSCONNECTION_H qt5integration-5.7.12/3rdparty/qdbustrayicon.cpp000066400000000000000000000265471476226661600217640ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qdbustrayicon_p.h" #ifndef QT_NO_SYSTEMTRAYICON #include "qdbusmenuconnection_p.h" #include "qstatusnotifieritemadaptor_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #include // Defined in Windows headers which get included by qlockfile_p.h #undef interface namespace thirdparty { #ifndef QT_DEBUG Q_LOGGING_CATEGORY(dLcTray, "dtk.qpa.tray"); #else Q_LOGGING_CATEGORY(dLcTray, "dtk.qpa.tray", QtInfoMsg); #endif static QString iconTempPath() { QString tempPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); if (!tempPath.isEmpty()) return tempPath; tempPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); if (!tempPath.isEmpty()) { QDir tempDir(tempPath); if (tempDir.exists()) return tempPath; if (tempDir.mkpath(QStringLiteral("."))) { const QFile::Permissions permissions = QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; if (QFile(tempPath).setPermissions(permissions)) return tempPath; } } return QDir::tempPath(); } // delay to access dbus. static QString KDEItemFormat() { static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2") .arg(QDBusConnection::sessionBus().baseService().replace( QRegularExpression(QStringLiteral("[\\.:]")), QStringLiteral("_"))); return KDEItemFormat; } static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher"); static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications"); static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications"); static const QString DefaultAction = QStringLiteral("default"); static int instanceCount = 0; static inline QString tempFileTemplate() { static const QString TempFileTemplate = iconTempPath() + QLatin1String("/qt-trayicon-XXXXXX.png"); return TempFileTemplate; } /*! \class QDBusTrayIcon \internal */ QDBusTrayIcon::QDBusTrayIcon() : m_dbusConnection(nullptr) , m_adaptor(new QStatusNotifierItemAdaptor(this)) , m_menuAdaptor(nullptr) , m_menu(nullptr) , m_notifier(nullptr) , m_instanceId(KDEItemFormat().arg(instanceCount)) , m_category(QStringLiteral("ApplicationStatus")) , m_defaultStatus(QStringLiteral("Active")) // be visible all the time. QSystemTrayIcon has no API to control this. , m_status(m_defaultStatus) , m_tempIcon(nullptr) , m_tempAttentionIcon(nullptr) , m_registered(false) { qCDebug(dLcTray); ++instanceCount; if (instanceCount == 1) { QDBusMenuItem::registerDBusTypes(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); } connect(this, SIGNAL(statusChanged(QString)), m_adaptor, SIGNAL(NewStatus(QString))); connect(this, SIGNAL(tooltipChanged()), m_adaptor, SIGNAL(NewToolTip())); connect(this, SIGNAL(iconChanged()), m_adaptor, SIGNAL(NewIcon())); connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewAttentionIcon())); connect(this, SIGNAL(menuChanged()), m_adaptor, SIGNAL(NewMenu())); connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewTitle())); connect(&m_attentionTimer, SIGNAL(timeout()), this, SLOT(attentionTimerExpired())); m_attentionTimer.setSingleShot(true); } QDBusTrayIcon::~QDBusTrayIcon() { } void QDBusTrayIcon::init() { qCDebug(dLcTray) << "registering" << m_instanceId; m_registered = dBusConnection()->registerTrayIcon(this); QObject::connect(dBusConnection()->dbusWatcher(), &QDBusServiceWatcher::serviceRegistered, this, &QDBusTrayIcon::watcherServiceRegistered); } void QDBusTrayIcon::cleanup() { qCDebug(dLcTray) << "unregistering" << m_instanceId; if (m_registered) dBusConnection()->unregisterTrayIcon(this); delete m_dbusConnection; m_dbusConnection = nullptr; delete m_notifier; m_notifier = nullptr; m_registered = false; } void QDBusTrayIcon::watcherServiceRegistered(const QString &serviceName) { Q_UNUSED(serviceName); // We have the icon registered, but the watcher has restarted or // changed, so we need to tell it about our icon again if (m_registered) dBusConnection()->registerTrayIconWithWatcher(this); } void QDBusTrayIcon::attentionTimerExpired() { m_messageTitle = QString(); m_message = QString(); m_attentionIcon = QIcon(); emit attention(); emit tooltipChanged(); setStatus(m_defaultStatus); } void QDBusTrayIcon::setStatus(const QString &status) { qCDebug(dLcTray) << status; if (m_status == status) return; m_status = status; emit statusChanged(m_status); } QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) { // Hack for indicator-application, which doesn't handle icons sent across D-Bus: // save the icon to a temp file and set the icon name to that filename. static bool necessity_checked = false; static bool necessary = false; if (!necessity_checked) { QDBusConnection session = QDBusConnection::sessionBus(); uint pid = session.interface()->servicePid(KDEWatcherService).value(); QString processName = QLockFilePrivate::processNameByPid(pid); necessary = processName.endsWith(QLatin1String("indicator-application-service")); if (!necessary && QGuiApplication::desktopSettingsAware()) { // Accessing to process name might be not allowed if the application // is confined, thus we can just rely on the current desktop in use const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); necessary = services->desktopEnvironment().split(':').contains("UNITY"); } necessity_checked = true; } if (!necessary) return nullptr; qreal dpr = qGuiApp->devicePixelRatio(); QTemporaryFile *ret = new QTemporaryFile(tempFileTemplate(), this); ret->open(); icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret); ret->close(); return ret; } QDBusMenuConnection * QDBusTrayIcon::dBusConnection() { if (!m_dbusConnection) { m_dbusConnection = new QDBusMenuConnection(this, m_instanceId); m_notifier = new QXdgNotificationInterface(XdgNotificationService, XdgNotificationPath, m_dbusConnection->connection(), this); connect(m_notifier, SIGNAL(NotificationClosed(uint,uint)), this, SLOT(notificationClosed(uint,uint))); connect(m_notifier, SIGNAL(ActionInvoked(uint,QString)), this, SLOT(actionInvoked(uint,QString))); } return m_dbusConnection; } void QDBusTrayIcon::updateIcon(const QIcon &icon) { m_iconName = icon.name(); m_icon = icon; if (m_iconName.isEmpty()) { if (m_tempIcon) delete m_tempIcon; m_tempIcon = tempIcon(icon); if (m_tempIcon) m_iconName = m_tempIcon->fileName(); } qCDebug(dLcTray) << m_iconName << icon.availableSizes(); emit iconChanged(); } void QDBusTrayIcon::updateToolTip(const QString &tooltip) { qCDebug(dLcTray) << tooltip; m_tooltip = tooltip; emit tooltipChanged(); } QPlatformMenu *QDBusTrayIcon::createMenu() const { return new QDBusPlatformMenu(); } void QDBusTrayIcon::updateMenu(QPlatformMenu * menu) { qCDebug(dLcTray) << menu; QDBusPlatformMenu *newMenu = qobject_cast(menu); if (m_menu != newMenu) { if (m_menu) { dBusConnection()->unregisterTrayIconMenu(this); delete m_menuAdaptor; } m_menu = newMenu; m_menuAdaptor = new QDBusMenuAdaptor(m_menu); // TODO connect(m_menu, , m_menuAdaptor, SIGNAL(ItemActivationRequested(int,uint))); connect(m_menu, SIGNAL(propertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)), m_menuAdaptor, SIGNAL(ItemsPropertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList))); connect(m_menu, SIGNAL(updated(uint,int)), m_menuAdaptor, SIGNAL(LayoutUpdated(uint,int))); dBusConnection()->registerTrayIconMenu(this); emit menuChanged(); } } void QDBusTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon, QPlatformSystemTrayIcon::MessageIcon iconType, int msecs) { m_messageTitle = title; m_message = msg; m_attentionIcon = icon; QStringList notificationActions; switch (iconType) { case Information: m_attentionIconName = QStringLiteral("dialog-information"); break; case Warning: m_attentionIconName = QStringLiteral("dialog-warning"); break; case Critical: m_attentionIconName = QStringLiteral("dialog-error"); // If there are actions, the desktop notification may appear as a message dialog // with button(s), which will interrupt the user and require a response. // That is an optional feature in implementations of org.freedesktop.Notifications notificationActions << DefaultAction << tr("OK"); break; default: m_attentionIconName.clear(); break; } if (m_attentionIconName.isEmpty()) { if (m_tempAttentionIcon) delete m_tempAttentionIcon; m_tempAttentionIcon = tempIcon(icon); if (m_tempAttentionIcon) m_attentionIconName = m_tempAttentionIcon->fileName(); } qCDebug(dLcTray) << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs; setStatus(QStringLiteral("NeedsAttention")); m_attentionTimer.start(msecs); emit tooltipChanged(); emit attention(); // Desktop notification QVariantMap hints; // urgency levels according to https://developer.gnome.org/notification-spec/#urgency-levels // 0 low, 1 normal, 2 critical int urgency = static_cast(iconType) - 1; if (urgency < 0) // no icon urgency = 0; hints.insert(QLatin1String("urgency"), QVariant(urgency)); m_notifier->notify(QCoreApplication::applicationName(), 0, m_attentionIconName, title, msg, notificationActions, hints, msecs); } void QDBusTrayIcon::actionInvoked(uint id, const QString &action) { qCDebug(dLcTray) << id << action; emit messageClicked(); } void QDBusTrayIcon::notificationClosed(uint id, uint reason) { qCDebug(dLcTray) << id << reason; } bool QDBusTrayIcon::isSystemTrayAvailable() const { QDBusMenuConnection * conn = const_cast(this)->dBusConnection(); qCDebug(dLcTray) << conn->isStatusNotifierHostRegistered(); return conn->isStatusNotifierHostRegistered(); } #endif //QT_NO_SYSTEMTRAYICON } // namespace thirdparty qt5integration-5.7.12/3rdparty/qdbustrayicon_p.h000066400000000000000000000102701476226661600217320ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QDBUSTRAYICON_H #define QDBUSTRAYICON_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qdbusmenuconnection_p.h" #include "qstatusnotifieritemadaptor_p.h" #include #include QT_REQUIRE_CONFIG(systemtrayicon); #include #include #include #include #include class QXdgNotificationInterface; namespace thirdparty { Q_DECLARE_LOGGING_CATEGORY(dLcTray); class QStatusNotifierItemAdaptor; class QDBusTrayIcon: public QPlatformSystemTrayIcon { Q_OBJECT Q_PROPERTY(QString category READ category NOTIFY categoryChanged) Q_PROPERTY(QString status READ status NOTIFY statusChanged) Q_PROPERTY(QString tooltip READ tooltip NOTIFY tooltipChanged) Q_PROPERTY(QString iconName READ iconName NOTIFY iconChanged) Q_PROPERTY(QIcon icon READ icon NOTIFY iconChanged) Q_PROPERTY(bool isRequestingAttention READ isRequestingAttention NOTIFY attention) Q_PROPERTY(QString attentionTitle READ attentionTitle NOTIFY attention) Q_PROPERTY(QString attentionMessage READ attentionMessage NOTIFY attention) Q_PROPERTY(QString attentionIconName READ attentionIconName NOTIFY attention) Q_PROPERTY(QIcon attentionIcon READ attentionIcon NOTIFY attention) Q_PROPERTY(QDBusPlatformMenu *menu READ menu NOTIFY menuChanged) public: QDBusTrayIcon(); virtual ~QDBusTrayIcon(); QDBusMenuConnection * dBusConnection(); void init() override; void cleanup() override; void updateIcon(const QIcon &icon) override; void updateToolTip(const QString &tooltip) override; void updateMenu(QPlatformMenu *menu) override; QPlatformMenu *createMenu() const override; void showMessage(const QString &title, const QString &msg, const QIcon &icon, MessageIcon iconType, int msecs) override; bool isSystemTrayAvailable() const override; bool supportsMessages() const override { return true; } QRect geometry() const override { return QRect(); } QString category() const { return m_category; } QString status() const { return m_status; } QString tooltip() const { return m_tooltip; } QString iconName() const { return m_iconName; } const QIcon & icon() const { return m_icon; } bool isRequestingAttention() const { return m_attentionTimer.isActive(); } QString attentionTitle() const { return m_messageTitle; } QString attentionMessage() const { return m_message; } QString attentionIconName() const { return m_attentionIconName; } const QIcon & attentionIcon() const { return m_attentionIcon; } QString instanceId() const { return m_instanceId; } QDBusPlatformMenu *menu() { return m_menu; } signals: void categoryChanged(); void statusChanged(QString arg); void tooltipChanged(); void iconChanged(); void attention(); void menuChanged(); private Q_SLOTS: void attentionTimerExpired(); void actionInvoked(uint id, const QString &action); void notificationClosed(uint id, uint reason); void watcherServiceRegistered(const QString &serviceName); private: void setStatus(const QString &status); QTemporaryFile *tempIcon(const QIcon &icon); private: QDBusMenuConnection* m_dbusConnection; QStatusNotifierItemAdaptor *m_adaptor; QDBusMenuAdaptor *m_menuAdaptor; QDBusPlatformMenu *m_menu; QXdgNotificationInterface *m_notifier; QString m_instanceId; QString m_category; QString m_defaultStatus; QString m_status; QString m_tooltip; QString m_messageTitle; QString m_message; QIcon m_icon; QTemporaryFile *m_tempIcon; QString m_iconName; QIcon m_attentionIcon; QTemporaryFile *m_tempAttentionIcon; QString m_attentionIconName; QTimer m_attentionTimer; bool m_registered; }; }// namespace thirdparty #endif // QBUSTRAYICON_H qt5integration-5.7.12/3rdparty/qstatusnotifieritemadaptor.cpp000066400000000000000000000100131476226661600245500ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only /* This file was originally created by qdbusxml2cpp version 0.8 Command line was: qdbusxml2cpp -a statusnotifieritem ../../3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml However it is maintained manually, because this adapter needs to do significant interface adaptation, and can do it more efficiently using the QDBusTrayIcon API directly rather than via QObject::property() and QMetaObject::invokeMethod(). */ #include "qstatusnotifieritemadaptor_p.h" #ifndef QT_NO_SYSTEMTRAYICON #include "qdbustrayicon_p.h" namespace thirdparty{ QStatusNotifierItemAdaptor::QStatusNotifierItemAdaptor(QDBusTrayIcon *parent) : QDBusAbstractAdaptor(parent), m_trayIcon(parent) { setAutoRelaySignals(true); } QStatusNotifierItemAdaptor::~QStatusNotifierItemAdaptor() { } QString QStatusNotifierItemAdaptor::attentionIconName() const { return m_trayIcon->attentionIconName(); } QXdgDBusImageVector QStatusNotifierItemAdaptor::attentionIconPixmap() const { return iconToQXdgDBusImageVector(m_trayIcon->attentionIcon()); } QString QStatusNotifierItemAdaptor::attentionMovieName() const { return QString(); } QString QStatusNotifierItemAdaptor::category() const { return m_trayIcon->category(); } QString QStatusNotifierItemAdaptor::iconName() const { return m_trayIcon->iconName(); } QXdgDBusImageVector QStatusNotifierItemAdaptor::iconPixmap() const { return iconToQXdgDBusImageVector(m_trayIcon->icon()); } QString QStatusNotifierItemAdaptor::id() const { // from the API docs: "a name that should be unique for this application and // consistent between sessions, such as the application name itself" return QCoreApplication::applicationName(); } bool QStatusNotifierItemAdaptor::itemIsMenu() const { // From KDE docs: if this is true, the item only supports the context menu, // so the visualization should prefer sending ContextMenu() instead of Activate(). // But QSystemTrayIcon doesn't have such a setting: it will emit activated() // and the application is free to use it or ignore it; we don't know whether it will. return false; } QDBusObjectPath QStatusNotifierItemAdaptor::menu() const { return QDBusObjectPath(m_trayIcon->menu() ? "/MenuBar" : "/NO_DBUSMENU"); } QString QStatusNotifierItemAdaptor::overlayIconName() const { return QString(); } QXdgDBusImageVector QStatusNotifierItemAdaptor::overlayIconPixmap() const { QXdgDBusImageVector ret; // empty vector return ret; } QString QStatusNotifierItemAdaptor::status() const { return m_trayIcon->status(); } QString QStatusNotifierItemAdaptor::title() const { // Shown e.g. when the icon is hidden, in the popup showing all hidden items. // Since QSystemTrayIcon doesn't have this property, the application name // is the best information we have available. return QCoreApplication::applicationName(); } QXdgDBusToolTipStruct QStatusNotifierItemAdaptor::toolTip() const { QXdgDBusToolTipStruct ret; if (m_trayIcon->isRequestingAttention()) { ret.title = m_trayIcon->attentionTitle(); ret.subTitle = m_trayIcon->attentionMessage(); ret.icon = m_trayIcon->attentionIconName(); } else { ret.title = m_trayIcon->tooltip(); } return ret; } void QStatusNotifierItemAdaptor::Activate(int x, int y) { qCDebug(dLcTray) << x << y; emit m_trayIcon->activated(QPlatformSystemTrayIcon::Trigger); } void QStatusNotifierItemAdaptor::ContextMenu(int x, int y) { qCDebug(dLcTray) << x << y; emit m_trayIcon->activated(QPlatformSystemTrayIcon::Context); } void QStatusNotifierItemAdaptor::Scroll(int w, const QString &s) { qCDebug(dLcTray) << w << s; // unsupported } void QStatusNotifierItemAdaptor::SecondaryActivate(int x, int y) { qCDebug(dLcTray) << x << y; emit m_trayIcon->activated(QPlatformSystemTrayIcon::MiddleClick); } } // namespace thirdparty #endif // QT_NO_SYSTEMTRAYICON qt5integration-5.7.12/3rdparty/qstatusnotifieritemadaptor_p.h000066400000000000000000000136271476226661600245520ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only /* This file was originally created by qdbusxml2cpp version 0.8 Command line was: qdbusxml2cpp -a statusnotifieritem ../../3rdparty/dbus-ifaces/org.kde.StatusNotifierItem.xml However it is maintained manually. It is also not part of the public API. This header file may change from version to version without notice, or even be removed. */ #ifndef QSTATUSNOTIFIERITEMADAPTER_P_H #define QSTATUSNOTIFIERITEMADAPTER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include QT_REQUIRE_CONFIG(systemtrayicon); namespace thirdparty { class QDBusTrayIcon; /* Adaptor class for interface org.kde.StatusNotifierItem see http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/ (also http://www.notmart.org/misc/statusnotifieritem/) */ class QStatusNotifierItemAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.StatusNotifierItem") Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: QStatusNotifierItemAdaptor(QDBusTrayIcon *parent); virtual ~QStatusNotifierItemAdaptor(); public: // PROPERTIES Q_PROPERTY(QString AttentionIconName READ attentionIconName) QString attentionIconName() const; Q_PROPERTY(QXdgDBusImageVector AttentionIconPixmap READ attentionIconPixmap) QXdgDBusImageVector attentionIconPixmap() const; Q_PROPERTY(QString AttentionMovieName READ attentionMovieName) QString attentionMovieName() const; Q_PROPERTY(QString Category READ category) QString category() const; Q_PROPERTY(QString IconName READ iconName) QString iconName() const; Q_PROPERTY(QXdgDBusImageVector IconPixmap READ iconPixmap) QXdgDBusImageVector iconPixmap() const; Q_PROPERTY(QString Id READ id) QString id() const; Q_PROPERTY(bool ItemIsMenu READ itemIsMenu) bool itemIsMenu() const; Q_PROPERTY(QDBusObjectPath Menu READ menu) QDBusObjectPath menu() const; Q_PROPERTY(QString OverlayIconName READ overlayIconName) QString overlayIconName() const; Q_PROPERTY(QXdgDBusImageVector OverlayIconPixmap READ overlayIconPixmap) QXdgDBusImageVector overlayIconPixmap() const; Q_PROPERTY(QString Status READ status) QString status() const; Q_PROPERTY(QString Title READ title) QString title() const; Q_PROPERTY(QXdgDBusToolTipStruct ToolTip READ toolTip) QXdgDBusToolTipStruct toolTip() const; public Q_SLOTS: // METHODS void Activate(int x, int y); void ContextMenu(int x, int y); void Scroll(int delta, const QString &orientation); void SecondaryActivate(int x, int y); Q_SIGNALS: // SIGNALS void NewAttentionIcon(); void NewIcon(); void NewOverlayIcon(); void NewMenu(); void NewStatus(const QString &status); void NewTitle(); void NewToolTip(); private: QDBusTrayIcon *m_trayIcon; }; } // namespace thirdparty #endif // QSTATUSNOTIFIERITEMADAPTER_P_H qt5integration-5.7.12/CHANGELOG.md000066400000000000000000000311701476226661600164160ustar00rootroot00000000000000 ## 0.3.11 (2019-04-17) #### Bug Fixes * ScreenScaleFactors cannot be applied to all screens when only one value is specified ([24a73d6b](https://github.com/linuxdeepin/qt5integration/commit/24a73d6b2243602781dd7c56071efadb5387142c)) * font pixel changed when connect a screen ([fcca6b5e](https://github.com/linuxdeepin/qt5integration/commit/fcca6b5e64863741a48600bdc22b18d2c3eac3d6)) * enable real-time scale for window only on enable screenScaleFactors ([520f00eb](https://github.com/linuxdeepin/qt5integration/commit/520f00eb47e57883838040372fa4bc377cf8be78)) #### Features * support auto update the window geometry by new device pixel ratio ([6902fc8a](https://github.com/linuxdeepin/qt5integration/commit/6902fc8ad8923f1579b115561f4aa0a361ac0f64)) ## 0.3.10 (2019-04-04) ## 0.3.9 (2019-04-03) #### Bug Fixes * build failed on Qt 5.7.x ([9159a9fa](https://github.com/linuxdeepin/qt5integration/commit/9159a9fadf70c0190c698769b7f0d576bf380567)) #### Features * screen scale support takes effect in real time ([1e9c855b](https://github.com/linuxdeepin/qt5integration/commit/1e9c855b7409fdaa04eb938ddab42b5a38d51790)) ## 0.3.8 (2019-03-27) ## 0.3.7.2 (2019-01-10) #### Bug Fixes * QComboBox show icon ([9ac0b0bc](https://github.com/linuxdeepin/qt5integration/commit/9ac0b0bc54add64fa249cf78d1960a270e8f5af1)) * adjust QComboBox height ([4778931f](https://github.com/linuxdeepin/qt5integration/commit/4778931f7605a04ff5ec3c6166d89bb9166c9b4e)) #### Features * add property "touchFlickBeginMoveDelay" for DThemeSettings ([2ab1fab0](https://github.com/linuxdeepin/qt5integration/commit/2ab1fab0b65f6d4f41d3f2c06a61816346fda153)) ## 0.3.7.1 (2018-12-14) #### Bug Fixes * QPushButton icon color follow theme ([e1f6d379](https://github.com/linuxdeepin/qt5integration/commit/e1f6d379ebf05a96689ddcfa01e02126df42c540)) ## 0.3.7 (2018-11-30) #### Bug Fixes * can not read image file on the second time ([668540cf](https://github.com/linuxdeepin/qt5integration/commit/668540cfc655ae9e9953b90b70411f8f6f7a732a)) * set the QMenu Qt::WA_TranslucentBackground does not take effect ([6814e028](https://github.com/linuxdeepin/qt5integration/commit/6814e028a90e3b82e4db91e8b62ee76cc86a5489)) * **Menu:** check icon when select state ([8fe47513](https://github.com/linuxdeepin/qt5integration/commit/8fe475130f7d7aacef438b258acfaeae0560c598)) ## 0.3.6 (2018-10-25) #### Features * **menu:** add check label ([f7d4530b](https://github.com/linuxdeepin/qt5integration/commit/f7d4530bb396e79a45e6b62e0cdb0b1c14b431e9)) ## 0.3.5 (2018-08-28) #### Bug Fixes * **iconengine:** use the original one if cast failed ([50286e1d](https://github.com/linuxdeepin/qt5integration/commit/50286e1d2d4a31c86bc556f3cc8433ac2e2803bb)) ## 0.3.4 (2018-08-13) #### Bug Fixes * build failed on libqt5xdg2 ([da972cac](https://github.com/linuxdeepin/qt5integration/commit/da972cac239240ae4f2ed08e505c75a2bd7aaae9)) * return a null pixmap in QIcon::pixmap ([8d923ea9](https://github.com/linuxdeepin/qt5integration/commit/8d923ea94f49eee3ad6cda201a04b1125031ebe7)) ## 0.3.3 (2018-08-06) #### Features * anyway try to enable dxcb for QMenu and QTipLabel ([689e440b](https://github.com/linuxdeepin/qt5integration/commit/689e440bf160a0ed094f03eca9d307e1d1d0f63c)) #### Bug Fixes * the dde-desktop UI is blocked ([c75ffad8](https://github.com/linuxdeepin/qt5integration/commit/c75ffad83ff353f10840dac2e38a2daa3b8e3187)) ## 0.3.2 (2018-07-31) #### Bug Fixes * not update the xdg system icon theme when the icon theme is changed ([cc738c11](https://github.com/linuxdeepin/qt5integration/commit/cc738c114853ed9a9be46f2ebe711e2db98a41e1)) * remove gtk2 depend ([6b2d1f7d](https://github.com/linuxdeepin/qt5integration/commit/6b2d1f7dfae7d17591f3f1d98a67da933505b9f6)) #### Features * support custom the color scheme of get icon from theme ([0daec72b](https://github.com/linuxdeepin/qt5integration/commit/0daec72b6467a29bcbc126b9bfefe5a7e22c1123)) ## 0.3.1 (2018-07-19) #### Bug Fixes * can not build if the "Qt5Xdg" package version is not 2.0.0 ([444f3a47](https://github.com/linuxdeepin/qt5integration/commit/444f3a47cec873010c254c726249b476dd29c8fc)) #### Features * **DIconEngine:** bypass some path which contains '/' ([0c6a7496](https://github.com/linuxdeepin/qt5integration/commit/0c6a7496ec64348fde628866c5d42b493aa7cdd7)) ### 0.3.0 (2018-05-24) #### Features * **style:** use QPalette active text brush on DTabBar tab widget ([d8ee34e6](https://github.com/linuxdeepin/qt5integration/commit/d8ee34e6efeda4faa3a953849d2b5e5a6a183985)) #### Bug Fixes * crash on paint QTabBar ([8d74156e](https://github.com/linuxdeepin/qt5integration/commit/8d74156e4fc07eecc86bf992a9a2a05370f2756d)) * the line edit widget border color on focus state ([4718470d](https://github.com/linuxdeepin/qt5integration/commit/4718470d0b31b28d67b71c1a77d05a0443fcaa21)) * **QLineEdit:** not refresh close button after theme changed ([7aca7279](https://github.com/linuxdeepin/qt5integration/commit/7aca72794235f9345c916102f5ed9a2666c3e61f)) * **combox:** don't render text when edit state ([2f558376](https://github.com/linuxdeepin/qt5integration/commit/2f558376d7788cadf27e280eed01c174435d1262)) * **style:** DTabBar close button cannot visible ([399ad32d](https://github.com/linuxdeepin/qt5integration/commit/399ad32d4facfc73574d4a56551309f3f7c28e6b)) ### 0.2.10 (2018-03-14) #### Bug Fixes * the line edit widget border color on focus state ([4718470d](https://github.com/linuxdeepin/qt5integration/commit/4718470d0b31b28d67b71c1a77d05a0443fcaa21)) ## 0.2.9 (2018-03-08) #### Bug Fixes * set the progress bar widget radius to 4 ([3cc29bbf](https://github.com/linuxdeepin/qt5integration/commit/3cc29bbf49d93d48ec3027a35721f4ccfa6af1cb)) * progress bar border color ([7da33a5d](https://github.com/linuxdeepin/qt5integration/commit/7da33a5d5882debae5448a24fc01200b4a390e56)) * button border color in pressed state ([578948d4](https://github.com/linuxdeepin/qt5integration/commit/578948d4d1a22521f8c39d2f89914761af4a0c20)) * Style::fullBrush filled icon is not the right size ([fb785a3f](https://github.com/linuxdeepin/qt5integration/commit/fb785a3fa6fabc82117846eeca64a3ee479077f8)) * drawProgressBarContentsControl crash if widget is nullptr ([1494cff6](https://github.com/linuxdeepin/qt5integration/commit/1494cff6247968025c3c0750f30cb4f186acafcd)) * crash at drawPushButtonLabel ([795e9fb6](https://github.com/linuxdeepin/qt5integration/commit/795e9fb65f7fb88fc414fb33b230396db7e4ffb4)) * crash at drawStandardIcon/isTabBarToolButton ([45a305fd](https://github.com/linuxdeepin/qt5integration/commit/45a305fd5919525b8dc6cc9dc0234f242cf00874)) * tab of QTabBar close button visible position is wrong on after tabs move ([6049831b](https://github.com/linuxdeepin/qt5integration/commit/6049831bc14a0a39aa15d3189b1ab35155e20d0f)) * not visible close button on tab when QTabBar style is QStyleSheetStyle ([0ca51e06](https://github.com/linuxdeepin/qt5integration/commit/0ca51e0651972ebbf26d14cbbeb0528cf2e2df79)) * **dstyle:** button border corner offset ([2c74e56e](https://github.com/linuxdeepin/qt5integration/commit/2c74e56e9d75adab5b4a8853043af596abdf2710)) * **style:** * set the scroll bar padding to 2px ([8cf9a91a](https://github.com/linuxdeepin/qt5integration/commit/8cf9a91ad77c90684e2da9412810b37dbcc6be64)) * scroll bar border color on dark style ([0b3472b0](https://github.com/linuxdeepin/qt5integration/commit/0b3472b048cc20803b8c468c60662de477d3a2c5)) #### Features * support add custom widgets to deepin file chooser dialog ([63caf8ff](https://github.com/linuxdeepin/qt5integration/commit/63caf8ff553c3951ff91af12792f3c40be1eba61)) * add split line for DTabBar add button ([31730a0b](https://github.com/linuxdeepin/qt5integration/commit/31730a0b2285504cbb3d803655ad55adae545187)) * add dark style for QTabBar/DTabBar ([7c811b44](https://github.com/linuxdeepin/qt5integration/commit/7c811b440b6fafa1233261690b03abc81645011d)) * draw QTabBar widget ([9da78b60](https://github.com/linuxdeepin/qt5integration/commit/9da78b6088596da68e800a048a47d6264642ee01)) * **dstyle:** * hide menu icon with DApplication and QLineEdit ([291c7292](https://github.com/linuxdeepin/qt5integration/commit/291c7292ff6f49349e3591835962bb1c715e8972)) * support SuggestButtonColor ([a644e697](https://github.com/linuxdeepin/qt5integration/commit/a644e697d47573ee8d5dc907c9d21411d925fd99)) * **style:** * draw alert border on DLineEdit ([810ebeda](https://github.com/linuxdeepin/qt5integration/commit/810ebedad0c50610aee6edd8507858931bfc954d)) * the tab bar tab text below the close button increases the transparency gradient ([83bdc592](https://github.com/linuxdeepin/qt5integration/commit/83bdc59210366ac53a41f7397dbc32c22d364d65)) * lineedit left padding to 3px ([e56ae93c](https://github.com/linuxdeepin/qt5integration/commit/e56ae93c32f3020d528e7cd780d544c63fea3ab5)) ## 0.2.8.3 (2017-12-06) #### Bug Fixes * **style:** visable bottom lines on QMenu when hover item ([c8eb56b7](https://github.com/linuxdeepin/qt5integration/commit/c8eb56b7cadb8f7a3d95207bf6ff7a7048a89706)) ## 0.2.8.2 (2017-12-06) #### Features * **theme:** set window flags for native dialog ([3ec67bf0](https://github.com/linuxdeepin/qt5integration/commit/3ec67bf01fead41dbac5a4b096622f7ca50d685c)) #### Bug Fixes * is dxcb platform if the "_d_isDxcb" property is true of QCoreApplication ([714b5f78](https://github.com/linuxdeepin/qt5integration/commit/714b5f78b98f7e63757db15ab84a8eb653c36b31)) * **style:** * visable left/top lines on draw rubber band control ([9c06e770](https://github.com/linuxdeepin/qt5integration/commit/9c06e7709b99958e6ebb98714fbbfa2a61d7a0a5)) * bottom/right visible lines on draw rubber band rect for QListView ([1177381a](https://github.com/linuxdeepin/qt5integration/commit/1177381ae5914188ca4236e993475367071d66bd)) * slider icons ([dae8caa6](https://github.com/linuxdeepin/qt5integration/commit/dae8caa6ec73b95b3781ebe6ecd6da0b359a189f)) ## 0.2.8.1 (2017-11-02) #### Bug Fixes * remove libqt5dxcb-dev for "Conflicts" and "Provides" ([4d38dbca](https://github.com/linuxdeepin/qt5integration/commit/4d38dbcac71375f96469cfdda2b4bad0124c7b16)) ## 0.2.8 (2017-11-02) #### Features * keep the window border is 1px for hiDPI ([da8040c4](https://github.com/linuxdeepin/qt5integration/commit/da8040c42df0cbde97e21693f472a288ef46a9d8)) * **theme plugin:** read settings from config file ([aacc2995](https://github.com/linuxdeepin/qt5integration/commit/aacc299512f4006ff174c5700d471d344d7155d0)) * **theme style:** auto update the widgets font when theme config file changed ([d478074e](https://github.com/linuxdeepin/qt5integration/commit/d478074e73d8e22e2d70080ad1430c565261d9af)) #### Bug Fixes * add build-depend: libegl1-mesa-dev ([2d265267](https://github.com/linuxdeepin/qt5integration/commit/2d265267ad1f6f113a74c931a67fe938b85a5af0)) * build failed(add build-depend: libmtdev-dev) ([babdc356](https://github.com/linuxdeepin/qt5integration/commit/babdc3561ab22d85ab83e4b6e385a4daa1387516)) * set cursor is invaild ([a2e235be](https://github.com/linuxdeepin/qt5integration/commit/a2e235bed7873d35030be380e8cd73acc0192e89)) * **dxcb:** * crash when screen changed ([7e1627c2](https://github.com/linuxdeepin/qt5integration/commit/7e1627c20fd92d7b4c1d7a69c55b4de5869cf6b6)) * the window border size is wrong ([83d6ac50](https://github.com/linuxdeepin/qt5integration/commit/83d6ac500b7e070f5c97ff220da16736229fd060)) * draw shadow area ([284cae9d](https://github.com/linuxdeepin/qt5integration/commit/284cae9dd90e9b9d7af92480e3a0e217a7c5f478)) * the DFrameWindow shadow area ([6e9c8274](https://github.com/linuxdeepin/qt5integration/commit/6e9c8274ef871fe3fa48a60a0861a96b6880dbf0)) * **style:** * update all widgets on font changed ([0e28f244](https://github.com/linuxdeepin/qt5integration/commit/0e28f244217f57d454424cc7dfba488ee6be93e3)) * update all widgets on font changed ([d4a65deb](https://github.com/linuxdeepin/qt5integration/commit/d4a65deb9e21e18390447c8b26eb429843333be4)) * **theme:** * "DFileSystemWatcherPrivate::addPaths: inotify_add_watch failed" ([a0322a68](https://github.com/linuxdeepin/qt5integration/commit/a0322a68447b7d918af49fbba23ebe1d5f53da25)) * set ini codec to "utf8" for QSettings ([3a4f7d76](https://github.com/linuxdeepin/qt5integration/commit/3a4f7d7651f6c433ef9735426d936289ac04d6c9)) qt5integration-5.7.12/CMakeLists.txt000066400000000000000000000112251476226661600173440ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later cmake_minimum_required(VERSION 3.13) set(DTK_VERSION 5.6.12 CACHE STRING "Project version" ) project( qtintegration VERSION ${DTK_VERSION} DESCRIPTION "Qt platform integration for DTK" HOMEPAGE_URL "https://github.com/linuxdeepin/qt5integration" LANGUAGES CXX C ) option(ENABLE_COV "Enable code coverage" OFF) if(PROJECT_VERSION_MAJOR EQUAL 6) set(VERSION_SUFFIX 6) find_package(QT NAMES Qt6 REQUIRED COMPONENTS Core) else() set(VERSION_SUFFIX) find_package(QT NAMES Qt5 REQUIRED COMPONENTS Core) endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX /usr) endif() include(GNUInstallDirs) include(CMakeParseArguments) include(CMakeDependentOption) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) if(CMAKE_BUILD_TYPE_LOWER STREQUAL release) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") elseif(CMAKE_BUILD_TYPE_LOWER STREQUAL debug) set(BUILD_TESTING ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g") endif() if(ENABLE_COV) find_package(DtkBuildHelper REQUIRED) endif() # Some util functions function(dtk_add_plugin) set(options) set(oneValueArgs NAME OUTPUT_NAME OUTPUT_DIR INSTALL_DIR) set(multiValueArgs SOURCES HEADERS RESOURCES DEPENDENCIES DEFINITIONS OPTIONS INCLUDE_DIRS) cmake_parse_arguments(TARGET "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(RAW_SOURCES ${TARGET_SOURCES} ${TARGET_RESOURCES}) foreach(HEADER ${TARGET_HEADERS}) get_filename_component(HEADER_ABS_PATH ${HEADER} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) list(APPEND ABS_PATH_SOURCES ${SOURCE_ABS_PATH}) get_filename_component(HEADER_DIR ${HEADER_ABS_PATH} DIRECTORY) list(APPEND TARGET_INTERFACE_INCLUDE_DIRS ${HEADER_DIR}) endforeach() list(REMOVE_DUPLICATES TARGET_INTERFACE_INCLUDE_DIRS) foreach(SOURCE ${RAW_SOURCES}) get_filename_component(SOURCE_ABS_PATH ${SOURCE} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) list(APPEND ABS_PATH_SOURCES ${SOURCE_ABS_PATH}) endforeach() add_library(${TARGET_NAME} SHARED ${TARGET_HEADERS} ${TARGET_SOURCES} ${TARGET_RESOURCES}) target_compile_definitions(${TARGET_NAME} PRIVATE ${TARGET_DEFINITIONS}) target_compile_options(${TARGET_NAME} PRIVATE ${TARGET_OPTIONS}) target_link_libraries(${TARGET_NAME} PRIVATE ${TARGET_DEPENDENCIES}) foreach(dependency ${TARGET_DEPENDENCIES}) target_link_libraries(${TARGET_NAME} INTERFACE $) endforeach() target_include_directories(${TARGET_NAME} PRIVATE ${TARGET_INCLUDE_DIRS}) foreach(include_dir ${TARGET_INCLUDE_DIRS}) target_include_directories(${TARGET_NAME} INTERFACE $) endforeach() if(TARGET_OUTPUT_NAME) set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${OUTPUT_NAME}) endif() if(TARGET_OUTPUT_DIR) set_target_properties(${TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${TARGET_OUTPUT_DIR}) endif() if(TARGET_INSTALL_DIR) install(TARGETS ${TARGET_NAME} DESTINATION ${TARGET_INSTALL_DIR}) endif() if(ENABLE_COV) dtk_setup_code_coverage(${TARGET_NAME}) endif() endfunction() find_package(Dtk${VERSION_SUFFIX} REQUIRED COMPONENTS Widget) option(ENABLE_QT_XDG_ICON_LOADER "Enable QtXdgIconLoader" ON) find_package(Qt${QT_VERSION_MAJOR}Xdg) if (NOT Qt${QT_VERSION_MAJOR}Xdg_FOUND) message(WARNING " Qt${QT_VERSION_MAJOR}XdgIconLoader Not Found, DISABLE QtXdgIconLoader !") set (ENABLE_QT_XDG_ICON_LOADER OFF) endif() if(ENABLE_QT_XDG_ICON_LOADER) set(QT_XDG_ICON_DEPS Qt${QT_VERSION_MAJOR}XdgIconLoader Qt${QT_VERSION_MAJOR}Xdg) if("${QT_VERSION_MAJOR}" STREQUAL "5") set(XDG_ICON_VERSION_MAJOR ${Qt5XdgIconLoader_VERSION_MAJOR}) elseif("${QT_VERSION_MAJOR}" STREQUAL "6") set(XDG_ICON_VERSION_MAJOR ${Qt6XdgIconLoader_VERSION_MAJOR}) endif() endif() set(PLUGIN_OUTPUT_BASE_DIR ${CMAKE_BINARY_DIR}/plugins CACHE STRING "Plugin output base path") set(PLUGIN_INSTALL_BASE_DIR ${CMAKE_INSTALL_LIBDIR}/qt${QT_VERSION_MAJOR}/plugins CACHE STRING "Plugin install base path") add_subdirectory(iconengineplugins) add_subdirectory(imageformatplugins) add_subdirectory(platformthemeplugin) add_subdirectory(styleplugins) if(CMAKE_BUILD_TYPE_LOWER STREQUAL debug) add_subdirectory(styles) endif() if(BUILD_TESTING) add_subdirectory(tests) endif() qt5integration-5.7.12/LICENSE000066400000000000000000001221631476226661600156150ustar00rootroot00000000000000GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License. “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . qt5integration-5.7.12/LICENSES/000077500000000000000000000000001476226661600160105ustar00rootroot00000000000000qt5integration-5.7.12/LICENSES/CC0-1.0.txt000066400000000000000000000156101476226661600174150ustar00rootroot00000000000000Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. qt5integration-5.7.12/LICENSES/GPL-2.0-only.txt000066400000000000000000000416711476226661600204600ustar00rootroot00000000000000GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice qt5integration-5.7.12/LICENSES/GPL-3.0-only.txt000066400000000000000000001035561476226661600204620ustar00rootroot00000000000000GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License. “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . qt5integration-5.7.12/LICENSES/LGPL-3.0-only.txt000066400000000000000000001221621476226661600205700ustar00rootroot00000000000000GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License. “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . qt5integration-5.7.12/LICENSES/LGPL-3.0-or-later.txt000066400000000000000000001221621476226661600213340ustar00rootroot00000000000000GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. “This License” refers to version 3 of the GNU General Public License. “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. A “covered work” means either the unmodified Program or a work based on the Program. To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. Copyright (C) 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 . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . qt5integration-5.7.12/LICENSES/LicenseRef-Qt-Commercial.txt000066400000000000000000000007161476226661600232270ustar00rootroot00000000000000Licensees holding valid commercial Qt licenses may use this software in accordance with the the terms contained in a written agreement between you and The Qt Company. Alternatively, the terms and conditions that were accepted by the licensee when buying and/or downloading the software do apply. For the latest licensing terms and conditions, see https://www.qt.io/terms-conditions. For further information use the contact form at https://www.qt.io/contact-us. qt5integration-5.7.12/README.md000066400000000000000000000027611476226661600160700ustar00rootroot00000000000000# qt5integration qt5integration is the Qt platform theme integration plugins for Deepin Desktop Environment. It includes multiple Qt5 plugins to make make DDE more Qt5 Apps friendly. ## Dependencies ### Build dependencies * gtk+-2.0 * mtdev * [dtk](https://github.com/linuxdeepin/deepin-tool-kit) * [libqtxdg](https://github.com/lxde/libqtxdg) * Qt5 (>= 5.6) * Qt5-Core * Qt5-Gui * Qt5-Widgets * Qt5-DBus * Qt5-Multimedia * Qt5-MultimediaWidgets * Qt5-Svg * Qt5-OpenGL * Qt5-X11extras * Qt5-Core-Private * Qt5-Widgets-Private ### Runtime dependencies * DDE File Manager (suggestion, to make Qt5 file dialogs more elegant) ## Installation ### Build from source code 1. Make sure you have installed all dependencies. 2. Build: ``` $ cd qt5integration $ mkdir build $ cd build $ qmake .. $ make ``` 3. Install: ``` $ sudo make install ``` ## Usage To be done. ## Getting help You may also find these channels useful if you encounter any other issues: * [Telegram group](https://t.me/deepin) * [Matrix](https://matrix.to/#/#deepin-community:matrix.org) * [IRC (libera.chat)](https://web.libera.chat/#deepin-community) * [Official Forum](https://bbs.deepin.org/) * [Wiki](http://wiki.deepin.org/) ## Getting involved We encourage you to report issues and contribute changes * [Contribution guide for developers](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers-en). ## License qt5integration is licensed under [LGPL-3.0-or-later](LICENSE). qt5integration-5.7.12/README.zh_CN.md000066400000000000000000000025401476226661600170630ustar00rootroot00000000000000## qt5integration qt5integration 是用于深度桌面环境的Qt平台主题集成插件。它包括多个Qt5插件使DDE对Qt5应用程序更加友好。 ## 依赖 ### 编译依赖 * gtk+-2.0 * mtdev * [dtk](https://github.com/linuxdeepin/deepin-tool-kit) * [libqtxdg](https://github.com/lxde/libqtxdg) * Qt5 (>= 5.6) * Qt5-Core * Qt5-Gui * Qt5-Widgets * Qt5-DBus * Qt5-Multimedia * Qt5-MultimediaWidgets * Qt5-Svg * Qt5-OpenGL * Qt5-X11extras * Qt5-Core-Private * Qt5-Widgets-Private ### Runtime dependencies * DDE文件管理器(建议使Qt5文件对话框更优雅) ## 安装 ### 从源代码构建 1. 确保已经安装了所有的编译依赖. 2. 构建: ```bash mkdir build cd build qmake .. make ``` 3. 安装: ```bash sudo make install ``` ## 使用 待补充. ## 帮助 任何使用问题都可以通过以下方式寻求帮助: * [Telegram 群组](https://t.me/deepin) * [Matrix](https://matrix.to/#/#deepin-community:matrix.org) * [IRC (libera.chat)](https://web.libera.chat/#deepin-community) * [Forum](https://bbs.deepin.org) * [WiKi](https://wiki.deepin.org/) ## 参与贡献 我们鼓励您报告问题并作出更改 * [开发者代码贡献指南](https://github.com/linuxdeepin/developer-center/wiki/Contribution-Guidelines-for-Developers) ## 协议 qt5integration遵循协议 [LGPL-3.0-or-later](LICENSE). qt5integration-5.7.12/archlinux/000077500000000000000000000000001476226661600166005ustar00rootroot00000000000000qt5integration-5.7.12/archlinux/PKGBUILD000066400000000000000000000015511476226661600177260ustar00rootroot00000000000000# Maintainer: justforlxz pkgname=deepin-qt5integration-git pkgver=5.1.12.r54.g732a237 pkgrel=1 sourcename=qt5integration sourcetars=("$sourcename"_"$pkgver".tar.xz) sourcedir="$sourcename" pkgdesc='Qt platform theme integration plugins for DDE' arch=('x86_64' 'aarch64') url="https://github.com/linuxdeepin/qt5integration" license=('GPL3') depends=('dtkwidget-git' 'libqt5xdg' 'deepin-qt5platform-plugins-git') makedepends=('git' 'qt5-tools' 'xcb-util-renderutil' 'gtest' 'gmock' 'cmake' 'ninja') conflicts=('deepin-qt5integration') provides=('deepin-qt5integration') groups=('deepin-git') source=("${sourcetars[@]}") sha512sums=('SKIP') build() { cd $sourcedir cmake . -GNinja \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_BUILD_TYPE=Release ninja } package() { cd $sourcedir DESTDIR="$pkgdir" ninja install } qt5integration-5.7.12/clog.toml000066400000000000000000000001661476226661600164270ustar00rootroot00000000000000[clog] repository = "https://github.com/linuxdeepin/qt5integration" from-latest-tag = true changelog = "CHANGELOG.md" qt5integration-5.7.12/debian/000077500000000000000000000000001476226661600160255ustar00rootroot00000000000000qt5integration-5.7.12/debian/changelog000066400000000000000000000206121476226661600177000ustar00rootroot00000000000000qt5integration (5.7.12) unstable; urgency=medium * feat: Add files generated by qdbusXML2cpp and DCONG2cpp -- YeShanShan Thu, 06 Mar 2025 17:30:04 +0800 qt5integration (5.7.11) unstable; urgency=medium * Release 5.7.11 -- YeShanShan Thu, 27 Feb 2025 20:48:12 +0800 qt5integration (5.7.10) unstable; urgency=medium * Release 5.7.10 -- YeShanShan Thu, 13 Feb 2025 17:18:50 +0800 qt5integration (5.7.9) unstable; urgency=medium * chore: disable ut by default -- Deepin Packages Builder Thu, 23 Jan 2025 09:07:08 +0000 qt5integration (5.7.8) unstable; urgency=medium * chore: delay to access dbus for trayicon -- Deepin Packages Builder Tue, 14 Jan 2025 11:17:31 +0000 qt5integration (5.7.7) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Thu, 09 Jan 2025 09:28:38 +0000 qt5integration (5.7.6) unstable; urgency=medium * fix: missing antialiased for menuItem -- Deepin Packages Builder Thu, 02 Jan 2025 05:43:53 +0000 qt5integration (5.7.5) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Thu, 12 Dec 2024 03:03:54 +0000 qt5integration (5.7.4) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Tue, 03 Dec 2024 02:00:45 +0000 qt5integration (5.7.3) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Wed, 20 Nov 2024 02:19:06 +0000 qt5integration (5.7.2) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Wed, 13 Nov 2024 01:53:26 +0000 qt5integration (5.7.1) unstable; urgency=medium * fix: loongarch64 disable compile unit test binaries * menu item and slider style tweak (#242) Thanks to Whale107(Bug: 254295)(Task: 362001)(Influence: 调整滑动条横条和刻度颜色) * merge dev/animation to master (#243) Thanks to Whale107 -- Deepin Packages Builder Wed, 16 Oct 2024 03:30:44 +0000 qt5integration (5.6.34) unstable; urgency=medium * fix(build): failed when qt6xdg not found -- Deepin Packages Builder Tue, 20 Aug 2024 05:03:51 +0000 qt5integration (5.6.32) unstable; urgency=medium * fix: can't set transparent for Menu's background * chore: adapt to qt6xdg -- Deepin Packages Builder Mon, 08 Jul 2024 02:29:21 +0000 qt5integration (5.6.31) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Thu, 27 Jun 2024 09:11:34 +0000 qt5integration (5.6.30) unstable; urgency=medium * fix: qapitrace open file crash * fix: close action in lineedit is narrowed(Issue: https://github.com/linuxdeepin/developer-center/issues/8423) -- Deepin Packages Builder Thu, 30 May 2024 02:46:31 +0000 qt5integration (5.6.29) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Mon, 13 May 2024 03:02:54 +0000 qt5integration (5.6.28) unstable; urgency=medium [ root ] * UNRELEASED -- Deepin Packages Builder Mon, 29 Apr 2024 08:23:39 +0000 qt5integration (5.6.27) unstable; urgency=medium * fix: The month button arrow in DCalendarWidget is out of range(Issue: https://github.com/linuxdeepin/developer-center/issues/7402) -- Deepin Packages Builder Fri, 19 Apr 2024 08:55:34 +0000 qt5integration (5.6.26) unstable; urgency=medium * fix: icon size of the selected item in context menu(Issue: https://github.com/linuxdeepin/developer-center/issues/7446) * chore: scrollerbar tweak(Task: 331783) -- Deepin Packages Builder Tue, 26 Mar 2024 05:47:34 +0000 qt5integration (5.6.25) unstable; urgency=medium * fix: Button can't reponse Return/Enter key(Issue: https://github.com/linuxdeepin/developer-center/issues/5852) * chore: ButtonPressKeys is only supported in Qt6 * fix: wrong style for ComboBox in RightToLeft layout(Issue: https://github.com/linuxdeepin/developer-center/issues/1765) * fix: Need link x11 Thanks to Hillwood Yang * chore: check platformtheme is valid when set menu windowradius -- Deepin Packages Builder Mon, 11 Mar 2024 01:16:27 +0000 qt5integration (5.6.20) unstable; urgency=medium * release 5.6.20 -- Deepin Packages Builder Wed, 29 Nov 2023 09:56:07 +0800 qt5integration (5.6.17) unstable; urgency=medium * release 5.6.17 * feat: scrollbar show policy tweak * fix: some apps failed to create system tray -- Deepin Packages Builder Wed, 30 Aug 2023 13:42:26 +0800 qt5integration (5.6.16) unstable; urgency=medium * chore: Sync by https://github.com/linuxdeepin/.github/commit/2e5e092ba3f86b16d1aabbabcf0bfd2ae65b19c8(Influence: none) * chore(CI): Update obs tag build workflow * chore: always use qmake * fix: compatibility with libqtxdg2 * feat: support cmake and Qt6 * feat: imageformatplugins support cmake and Qt6 * feat: platformthemeplugin supports cmake and Qt6 * feat: styleplugins support cmake and Qt6 * feat: styles support cmake and Qt6 * fix: DLineEdit setAlert not work on DDialog(Issue: #91) * fix: missing 3rdparty sources and resources * chore: fix nodiscard warning * fix: do not compile and install dstyleplugin * fix: redirect styles output * feat: tests support cmake and Qt6 * Revert "fix(style): the list view item select rect subtraction the frame margins" * fix: dbusmenu related symbols are hidden in Qt6 * chore: delete deprecated project files * fix: dci icon cache key miss theme name(Issue: https://github.com/linuxdeepin/developer-center/issues/4517) * fix: Combobox's background is wrong when hover(Issue: #61) * fix: svg imageformat plugin not load * chore: Sync by https://github.com/linuxdeepin/.github/commit/559e91167d4919644f37bbcf123eb0651c1528ea(Influence: none) * chore: delete deprecated interface about iconengine * fix: diconengine load failed * tests: fix unit tests resource lacking * fix: file manage crash * fix: compatibility with orientation * refactor: remove unused old style * feat: add test coverage script * tests: add some unit tests * chore: add additional runtime control * chore: correct source file license * refactor: ut sources to linked form * chore: remove redundant macro * chore: use libfreetype-dev instead of libfreetype6-dev * fix: App failed to create multiple system trays -- Deepin Packages Builder Thu, 24 Aug 2023 15:36:34 +0800 qt5integration (5.6.11) unstable; urgency=medium * Release 5.6.11 * FIX dtk#53 dtk#55 dtk#64 dtk#65 developer-center#4122 -- Deepin Packages Builder Mon, 08 May 2023 13:50:24 +0800 qt5integration (5.6.10) unstable; urgency=medium * Release 5.6.10 * FIX dtkwidget/#399 dtkwidget/#409 * FIX developer-center/#4068 developer-center/#4077 * deepin theme plugin add DDE key -- Deepin Packages Builder Mon, 17 Apr 2023 17:18:59 +0800 qt5integration (5.6.9) unstable; urgency=medium * Release 5.6.9 -- Deepin Packages Builder Mon, 03 Apr 2023 10:20:50 +0800 qt5integration (5.6.6) unstable; urgency=medium * Release 5.6.6 -- Deepin Packages Builder Mon, 13 Mar 2023 10:13:11 +0800 qt5integration (5.6.5) unstable; urgency=medium * Release 5.6.5 -- Deepin Packages Builder Thu, 02 Feb 2023 14:10:21 +0800 qt5integration (5.6.4) unstable; urgency=medium * Release 5.6.4 -- Deepin Packages Builder Mon, 09 Jan 2023 11:13:35 +0800 qt5integration (5.6.3) unstable; urgency=medium * Release 5.6.3 -- Deepin Packages Builder Mon, 12 Dec 2022 17:19:33 +0800 qt5integration (5.6.0) unstable; urgency=medium * snipe release 5.6.0 -- Deepin Packages Builder Fri, 08 Jul 2022 15:24:31 +0800 qt5integration (5.5.21.1) unstable; urgency=medium * Release 5.5.21.1 -- Deepin Packages Builder Tue, 14 Jun 2022 10:45:17 +0800 qt5integration (1.0.0) unstable; urgency=medium * Initial release (Closes: #nnnn) -- Deepin Packages Builder Tue, 08 Nov 2016 15:10:02 +0800 qt5integration-5.7.12/debian/compat000066400000000000000000000000021476226661600172230ustar00rootroot000000000000009 qt5integration-5.7.12/debian/control000066400000000000000000000014521476226661600174320ustar00rootroot00000000000000Source: qt5integration Section: devel Priority: optional Maintainer: Deepin Packages Builder Build-Depends: debhelper (>=9), cmake, qtbase5-dev, qtbase5-private-dev, libqt5xdg-dev, libdtkgui-dev (>=5.6.13), libdtkwidget-dev, pkg-config, libqt5x11extras5-dev, libfontconfig1-dev, libfreetype-dev, libglib2.0-dev, libqt5svg5-dev, libqt5xdgiconloader-dev, libmtdev-dev, libegl1-mesa-dev, libxrender-dev, libgtest-dev, libgmock-dev Standards-Version: 3.9.8 Package: dde-qt5integration Architecture: any Provides: libqt5deepintheme-plugin Conflicts: libqt5deepintheme-plugin Depends: ${shlibs:Depends}, ${misc:Depends}, dde-qt5xcb-plugin Description: Qt platform theme integration plugins for DDE Multiple Qt plugins to provide better Qt5 integration for DDE is included. qt5integration-5.7.12/debian/copyright000066400000000000000000000017441476226661600177660ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: qt5integration Source: https://github.com/linuxdeepin/qt5integration Files: * Copyright: 2017 Deepin.Inc License: GPL-3+ This package 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 package 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 . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". qt5integration-5.7.12/debian/rules000077500000000000000000000001621476226661600171040ustar00rootroot00000000000000#!/usr/bin/make -f %: dh $@ override_dh_shlibdeps: dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info qt5integration-5.7.12/debian/source/000077500000000000000000000000001476226661600173255ustar00rootroot00000000000000qt5integration-5.7.12/debian/source/format000066400000000000000000000000151476226661600205340ustar00rootroot000000000000003.0 (native) qt5integration-5.7.12/iconengineplugins/000077500000000000000000000000001476226661600203235ustar00rootroot00000000000000qt5integration-5.7.12/iconengineplugins/CMakeLists.txt000066400000000000000000000002651476226661600230660ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later add_subdirectory(diconengine) add_subdirectory(svgiconengine) qt5integration-5.7.12/iconengineplugins/diconengine/000077500000000000000000000000001476226661600226055ustar00rootroot00000000000000qt5integration-5.7.12/iconengineplugins/diconengine/CMakeLists.txt000066400000000000000000000006261476226661600253510ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later dtk_add_plugin( NAME dicon OUTPUT_DIR ${PLUGIN_OUTPUT_BASE_DIR}/iconengines INSTALL_DIR ${PLUGIN_INSTALL_BASE_DIR}/iconengines SOURCES main.cpp HEADERS DEPENDENCIES Qt${QT_VERSION_MAJOR}::GuiPrivate Dtk${VERSION_SUFFIX}::Gui ) qt5integration-5.7.12/iconengineplugins/diconengine/diconengine.json000066400000000000000000000000471476226661600257630ustar00rootroot00000000000000{ "Keys": [ "DIconProxyEngine" ] } qt5integration-5.7.12/iconengineplugins/diconengine/main.cpp000066400000000000000000000013631476226661600242400ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include DGUI_USE_NAMESPACE QT_BEGIN_NAMESPACE class DIconEnginePlugin : public QIconEnginePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QIconEngineFactoryInterface" FILE "diconengine.json") public: QStringList keys() const; QIconEngine *create(const QString &iconName = QString()); }; QStringList DIconEnginePlugin::keys() const { return {"DIconProxyEngine"}; } QIconEngine *DIconEnginePlugin::create(const QString &iconName) { return DIconTheme::createIconEngine(iconName); } QT_END_NAMESPACE #include "main.moc" qt5integration-5.7.12/iconengineplugins/svgiconengine/000077500000000000000000000000001476226661600231615ustar00rootroot00000000000000qt5integration-5.7.12/iconengineplugins/svgiconengine/CMakeLists.txt000066400000000000000000000010641476226661600257220ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Concurrent) dtk_add_plugin( NAME dsvgicon OUTPUT_DIR ${PLUGIN_OUTPUT_BASE_DIR}/iconengines INSTALL_DIR ${PLUGIN_INSTALL_BASE_DIR}/iconengines SOURCES qsvgiconengine.cpp main.cpp HEADERS qsvgiconengine.h DEPENDENCIES Qt${QT_VERSION_MAJOR}::GuiPrivate Dtk${VERSION_SUFFIX}::Gui Qt${QT_VERSION_MAJOR}::Concurrent ) qt5integration-5.7.12/iconengineplugins/svgiconengine/main.cpp000066400000000000000000000021341476226661600246110ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-or-later OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #include #include "qsvgiconengine.h" #include #include #include QT_BEGIN_NAMESPACE class QSvgIconPlugin : public QIconEnginePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QIconEngineFactoryInterface" FILE "qsvgiconengine.json") public: QStringList keys() const; QIconEngine *create(const QString &filename = QString()); }; QStringList QSvgIconPlugin::keys() const { QStringList keys(QLatin1String("svg")); #ifndef QT_NO_COMPRESS if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { keys << QLatin1String("svgz") << QLatin1String("svg.gz"); } #endif return keys; } QIconEngine *QSvgIconPlugin::create(const QString &file) { QSvgIconEngine *engine = new QSvgIconEngine; if (!file.isNull()) engine->addFile(file, QSize(), QIcon::Normal, QIcon::Off); return engine; } QT_END_NAMESPACE #include "main.moc" qt5integration-5.7.12/iconengineplugins/svgiconengine/qsvgiconengine.cpp000066400000000000000000000376311476226661600267160ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-or-later OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qsvgiconengine.h" #ifndef QT_NO_SVGRENDERER #include "qpainter.h" #include "qpixmap.h" #include "qpixmapcache.h" #include "qfileinfo.h" #include #include #include #include "qdebug.h" #include #include #include #include #include #include #include DGUI_USE_NAMESPACE QT_BEGIN_NAMESPACE #ifdef QT_DEBUG Q_LOGGING_CATEGORY(lcDSvg, "dde.dsvg") #else Q_LOGGING_CATEGORY(lcDSvg, "dde.dsvg", QtInfoMsg) #endif class QSvgIconEnginePrivate : public QSharedData { public: QSvgIconEnginePrivate() : svgBuffers(0), addedPixmaps(0) { stepSerialNum(); } ~QSvgIconEnginePrivate() { delete addedPixmaps; delete svgBuffers; } static inline int hashKey(QIcon::Mode mode, QIcon::State state) { return (((mode)<<4)|state); } inline QString pmcKey(const QSize &size, QIcon::Mode mode, QIcon::State state) { return QLatin1String("$qt_svgicon_") + QString::number(serialNum, 16).append(QLatin1Char('_')) + QString::number((((((qint64(size.width()) << 11) | size.height()) << 11) | mode) << 4) | state, 16); } inline void stepSerialNum() { serialNum = lastSerialNum.fetchAndAddRelaxed(1); } void loadDataForModeAndState(DSvgRenderer *renderer, QIcon::Mode mode, QIcon::State state); QHash svgFiles; QHash *svgBuffers; QHash *addedPixmaps; int serialNum; static QAtomicInt lastSerialNum; }; QAtomicInt QSvgIconEnginePrivate::lastSerialNum; QSvgIconEngine::QSvgIconEngine() : d(new QSvgIconEnginePrivate) { } QSvgIconEngine::QSvgIconEngine(const QSvgIconEngine &other) : QIconEngine(other), d(new QSvgIconEnginePrivate) { d->svgFiles = other.d->svgFiles; if (other.d->svgBuffers) d->svgBuffers = new QHash(*other.d->svgBuffers); if (other.d->addedPixmaps) d->addedPixmaps = new QHash(*other.d->addedPixmaps); } QSvgIconEngine::~QSvgIconEngine() { } QSize QSvgIconEngine::actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) { if (d->addedPixmaps) { QPixmap pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return size; } QPixmap pm = pixmap(size, mode, state); if (pm.isNull()) return QSize(); return pm.size(); } void QSvgIconEnginePrivate::loadDataForModeAndState(DSvgRenderer *renderer, QIcon::Mode mode, QIcon::State state) { QByteArray buf; const QIcon::State oppositeState = state == QIcon::Off ? QIcon::On : QIcon::Off; if (svgBuffers) { buf = svgBuffers->value(hashKey(mode, state)); if (buf.isEmpty()) buf = svgBuffers->value(hashKey(QIcon::Normal, state)); if (buf.isEmpty()) buf = svgBuffers->value(hashKey(QIcon::Normal, oppositeState)); } if (!buf.isEmpty()) { #ifndef QT_NO_COMPRESS if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { buf = qUncompress(buf); } #endif renderer->load(buf); } else { QString svgFile = svgFiles.value(hashKey(mode, state)); if (svgFile.isEmpty()) svgFile = svgFiles.value(hashKey(QIcon::Normal, state)); if (svgFile.isEmpty()) svgFile = svgFiles.value(hashKey(QIcon::Normal, oppositeState)); if (!svgFile.isEmpty()) renderer->load(svgFile); } } static QString getIconCachePath() { QString path = qgetenv("D_ICON_CACHE_PATH"); if (!qEnvironmentVariableIsSet("D_ICON_CACHE_PATH")) { path = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation).append("/deepin/icons"); } if (path.isEmpty()) { qCInfo(lcDSvg) << "disable svg icon cache of dsvg plugin"; return path; } if (QDir::home().mkpath(path)) return path; qCWarning(lcDSvg) << "can't create a invalid icon cache path:" << path; return QString(); } QPixmap QSvgIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) { QPixmap pm; QString pmckey(d->pmcKey(size, mode, state)); if (Q_LIKELY(QPixmapCache::find(pmckey, &pm))) return pm; if (d->addedPixmaps) { pm = d->addedPixmaps->value(d->hashKey(mode, state)); if (!pm.isNull() && pm.size() == size) return pm; } const QIcon::State oppositeState = state == QIcon::Off ? QIcon::On : QIcon::Off; QString svgFile = d->svgFiles.value(d->hashKey(mode, state)); if (svgFile.isEmpty()) svgFile = d->svgFiles.value(d->hashKey(QIcon::Normal, state)); if (svgFile.isEmpty()) svgFile = d->svgFiles.value(d->hashKey(QIcon::Normal, oppositeState)); QString cacheFile; if (Q_LIKELY(!svgFile.startsWith(":/") && QFile::exists(svgFile))) { static const QString &cachePath = getIconCachePath(); if (Q_LIKELY(!cachePath.isEmpty())) { QByteArray mdst; if (d->svgBuffers && !d->svgBuffers->isEmpty()) mdst = QByteArray::number(d->hashKey(mode, state)).prepend("_"); // svgFiles[-1] 是为了取到额外的cache key,例如会跟随颜色变化的svg图标,将会添加此特殊的标记 const QByteArray extraKey = d->svgFiles.value(-1).isEmpty() ? QByteArrayLiteral("") : d->svgFiles.value(-1).toLocal8Bit() + mdst; const QByteArray cacheKey = svgFile.toLocal8Bit() + extraKey; // add mode state to cachekey const QString &svgFileSha1 = QString::fromLatin1(QCryptographicHash::hash(cacheKey, QCryptographicHash::Sha1).toHex()); cacheFile = QStringLiteral("%1/%2.png").arg(cachePath).arg(svgFileSha1); } } const QFileInfo cacheFileInfo(cacheFile); if (Q_LIKELY(cacheFileInfo.exists())) { const QFileInfo svgFileInfo(svgFile); if (Q_UNLIKELY(svgFileInfo.lastModified() != cacheFileInfo.lastModified())) { // clear invalid cache file QFile::remove(cacheFile); } else { qCDebug(lcDSvg()) << "found cache file:" << cacheFile << ", for:" << svgFile; QImageReader ir(cacheFile); const QSize &cacheSize = ir.size(); if (Q_LIKELY(cacheSize.isValid() && cacheSize.width() >= size.width())) { pm = QPixmap::fromImage(ir.read().scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } else { // 当对同一个图标文件有更大的size要求时,应当继续从源svg文件重新渲染图标并更新缓存文件 qCDebug(lcDSvg()) << "cache image size less then target size, cache size:" << cacheSize << ", request size:" << size; if (Q_UNLIKELY(!ir.canRead())) { qCWarning(lcDSvg()) << "can't read the cache image:" << cacheFile << "file size:" << cacheFileInfo.size() << ", permissions:" << cacheFileInfo.permissions(); QFile::remove(cacheFile); } } } } if (Q_UNLIKELY(pm.isNull())) { DSvgRenderer renderer; d->loadDataForModeAndState(&renderer, mode, state); if (Q_UNLIKELY(!renderer.isValid())) return pm; QSize actualSize = renderer.defaultSize(); if (actualSize.width() < size.width()) actualSize.scale(size, Qt::KeepAspectRatio); if (Q_UNLIKELY(actualSize.isEmpty())) return pm; const QImage image = renderer.toImage(actualSize); if (Q_LIKELY(!image.isNull() && !cacheFile.isEmpty())) { [[ maybe_unused ]] auto result = QtConcurrent::run(QThreadPool::globalInstance(), [image, cacheFile, svgFile] { QSaveFile file(cacheFile); // 增加cache文件能被成功保存的概率 file.setDirectWriteFallback(true); if (file.open(QFile::WriteOnly)) { if (image.save(&file, "png", 80) && file.commit()) { QFileInfo svgFileInfo(svgFile); // 不能直接使用QSaveFile改写文件的时间 QFile file(cacheFile); if (!file.open(QFile::ReadWrite) || !file.setFileTime(svgFileInfo.lastModified(), QFileDevice::FileModificationTime)) { qCWarning(lcDSvg()) << "set cache file modified date time failed, error message:" << file.errorString() << ", cache file:" << cacheFile << ", svg file:" << svgFile; } } else { file.cancelWriting(); qCWarning(lcDSvg()) << "save cache image failed, cache file:" << cacheFile << ", svg file:" << svgFile; } } else { qCWarning(lcDSvg()) << "open cache file failed, error message:" << file.errorString() << ", cache file:" << cacheFile << ", svg file:" << svgFile; } }); } // 缩放图标到目标大小 pm = QPixmap::fromImage(image.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation)); } if (Q_LIKELY(qobject_cast(QCoreApplication::instance()))) { const QPixmap generated = QGuiApplicationPrivate::instance()->applyQIconStyleHelper(mode, pm); if (Q_LIKELY(!generated.isNull())) pm = generated; } if (Q_LIKELY(!pm.isNull())) QPixmapCache::insert(pmckey, pm); return pm; } void QSvgIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state) { if (!d->addedPixmaps) d->addedPixmaps = new QHash; d->stepSerialNum(); d->addedPixmaps->insert(d->hashKey(mode, state), pixmap); } enum FileType { OtherFile, SvgFile, CompressedSvgFile }; static FileType fileType(const QFileInfo &fi) { const QString &abs = fi.absoluteFilePath(); if (abs.endsWith(QLatin1String(".svg"), Qt::CaseInsensitive)) return SvgFile; if (abs.endsWith(QLatin1String(".svgz"), Qt::CaseInsensitive) || abs.endsWith(QLatin1String(".svg.gz"), Qt::CaseInsensitive)) { return CompressedSvgFile; } #ifndef QT_NO_MIMETYPE const QString &mimeTypeName = QMimeDatabase().mimeTypeForFile(fi).name(); if (mimeTypeName == QLatin1String("image/svg+xml")) return SvgFile; if (mimeTypeName == QLatin1String("image/svg+xml-compressed")) return CompressedSvgFile; #endif // !QT_NO_MIMETYPE return OtherFile; } void QSvgIconEngine::addFile(const QString &fileName, const QSize &, QIcon::Mode mode, QIcon::State state) { if (!fileName.isEmpty()) { const QFileInfo fi(fileName); const QString abs = fi.absoluteFilePath(); const FileType type = fileType(fi); #ifndef QT_NO_COMPRESS if ((type == SvgFile || type == CompressedSvgFile) && Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { #else if (type == SvgFile) { #endif DSvgRenderer renderer(abs); if (renderer.isValid()) { d->stepSerialNum(); d->svgFiles.insert(d->hashKey(mode, state), abs); } } else if (type == OtherFile) { QPixmap pm(abs); if (!pm.isNull()) addPixmap(pm, mode, state); } } } void QSvgIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) { qreal ratio = 1.0; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (qApp->testAttribute(Qt::AA_UseHighDpiPixmaps)) ratio = painter->device() ? painter->device()->devicePixelRatioF() : qApp->devicePixelRatio(); #else ratio = painter->device() ? painter->device()->devicePixelRatioF() : qApp->devicePixelRatio(); #endif QSize pixmapSize = rect.size() * ratio; QPixmap pix = pixmap(pixmapSize, mode, state); pix.setDevicePixelRatio(ratio); painter->drawPixmap(rect, pix); } QString QSvgIconEngine::key() const { return QLatin1String("svg"); } QIconEngine *QSvgIconEngine::clone() const { return new QSvgIconEngine(*this); } bool QSvgIconEngine::read(QDataStream &in) { d = new QSvgIconEnginePrivate; d->svgBuffers = new QHash; if (in.version() >= QDataStream::Qt_4_4) { int isCompressed; QHash fileNames; // For memoryoptimization later in >> fileNames >> isCompressed >> *d->svgBuffers; #ifndef QT_NO_COMPRESS if (!isCompressed && Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { for (auto it = d->svgBuffers->begin(), end = d->svgBuffers->end(); it != end; ++it) it.value() = qCompress(it.value()); } #else if (isCompressed) { qWarning("QSvgIconEngine: Can not decompress SVG data"); d->svgBuffers->clear(); } #endif int hasAddedPixmaps; in >> hasAddedPixmaps; if (hasAddedPixmaps) { d->addedPixmaps = new QHash; in >> *d->addedPixmaps; } d->svgFiles = fileNames; } else { QPixmap pixmap; QByteArray data; uint mode; uint state; int num_entries; in >> data; if (!data.isEmpty()) { #ifndef QT_NO_COMPRESS if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { data = qUncompress(data); } #endif if (!data.isEmpty()) d->svgBuffers->insert(d->hashKey(QIcon::Normal, QIcon::Off), data); } in >> num_entries; for (int i=0; i> pixmap; in >> mode; in >> state; // The pm list written by 4.3 is buggy and/or useless, so ignore. //addPixmap(pixmap, QIcon::Mode(mode), QIcon::State(state)); } } return true; } bool QSvgIconEngine::write(QDataStream &out) const { if (out.version() >= QDataStream::Qt_4_4) { int isCompressed = 0; #ifndef QT_NO_COMPRESS if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { isCompressed = 1; } #endif QHash svgBuffers; if (d->svgBuffers) svgBuffers = *d->svgBuffers; for (auto it = d->svgFiles.cbegin(), end = d->svgFiles.cend(); it != end; ++it) { QByteArray buf; QFile f(it.value()); if (f.open(QIODevice::ReadOnly)) buf = f.readAll(); #ifndef QT_NO_COMPRESS if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { buf = qCompress(buf); } #endif svgBuffers.insert(it.key(), buf); } out << d->svgFiles << isCompressed << svgBuffers; if (d->addedPixmaps) out << (int)1 << *d->addedPixmaps; else out << (int)0; } else { QByteArray buf; if (d->svgBuffers) buf = d->svgBuffers->value(d->hashKey(QIcon::Normal, QIcon::Off)); if (buf.isEmpty()) { QString svgFile = d->svgFiles.value(d->hashKey(QIcon::Normal, QIcon::Off)); if (!svgFile.isEmpty()) { QFile f(svgFile); if (f.open(QIODevice::ReadOnly)) buf = f.readAll(); } } #ifndef QT_NO_COMPRESS if (Q_LIKELY(!qEnvironmentVariableIsSet("QT_NO_COMPRESS"))) { buf = qCompress(buf); } #endif out << buf; // 4.3 has buggy handling of added pixmaps, so don't write any out << (int)0; } return true; } QT_END_NAMESPACE #endif // QT_NO_SVGRENDERER qt5integration-5.7.12/iconengineplugins/svgiconengine/qsvgiconengine.h000066400000000000000000000022431476226661600263520ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-or-later OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QSVGICONENGINE_H #define QSVGICONENGINE_H #include #include QT_BEGIN_NAMESPACE class QSvgIconEnginePrivate; class QSvgIconEngine : public QIconEngine { public: QSvgIconEngine(); QSvgIconEngine(const QSvgIconEngine &other); ~QSvgIconEngine(); void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state); QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state); QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state); void addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon::State state); void addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state); QString key() const; QIconEngine *clone() const; bool read(QDataStream &in); bool write(QDataStream &out) const; private: QSharedDataPointer d; }; QT_END_NAMESPACE #endif qt5integration-5.7.12/iconengineplugins/svgiconengine/qsvgiconengine.json000066400000000000000000000000541476226661600270720ustar00rootroot00000000000000{ "Keys": [ "svg", "svgz", "svg.gz" ] } qt5integration-5.7.12/imageformatplugins/000077500000000000000000000000001476226661600205005ustar00rootroot00000000000000qt5integration-5.7.12/imageformatplugins/CMakeLists.txt000066400000000000000000000002431476226661600232370ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later add_subdirectory(dci) add_subdirectory(svg) qt5integration-5.7.12/imageformatplugins/dci/000077500000000000000000000000001476226661600212375ustar00rootroot00000000000000qt5integration-5.7.12/imageformatplugins/dci/CMakeLists.txt000066400000000000000000000006521476226661600240020ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later dtk_add_plugin( NAME dci OUTPUT_DIR ${PLUGIN_OUTPUT_BASE_DIR}/imageformats INSTALL_DIR ${PLUGIN_INSTALL_BASE_DIR}/imageformats SOURCES main.cpp qdciiohandler.cpp HEADERS qdciiohandler.h DEPENDENCIES Dtk${VERSION_SUFFIX}::Gui ) qt5integration-5.7.12/imageformatplugins/dci/dci.json000066400000000000000000000003701476226661600226710ustar00rootroot00000000000000{ "Keys": [ "dci", "dci-light-normal", "dci-light-disabled", "dci-light-hover", "dci-light-pressed", "dci-dark-normal", "dci-dark-disabled", "dci-dark-hover", "dci-dark-pressed" ], "MimeTypes": [ "image/dci" ] } qt5integration-5.7.12/imageformatplugins/dci/image-dci.xml000066400000000000000000000006751476226661600236100ustar00rootroot00000000000000 DSG Icon file format 深度图标文件格式 qt5integration-5.7.12/imageformatplugins/dci/main.cpp000066400000000000000000000025431476226661600226730ustar00rootroot00000000000000// Copyright (C) 2022 UnionTech Software Technology Co., Ltd. // SPDX-License-Identifier: LGPL-3.0-or-later #include "qdciiohandler.h" #include #include #include #include QT_BEGIN_NAMESPACE class QDciPlugin : public QImageIOPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "dci.json") public: QStringList keys() const; Capabilities capabilities(QIODevice *device, const QByteArray &format) const; QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; }; QStringList QDciPlugin::keys() const { return QStringList() << QLatin1String("dci"); } QImageIOPlugin::Capabilities QDciPlugin::capabilities(QIODevice *device, const QByteArray &format) const { if (format == QByteArrayLiteral("dci") || format.startsWith(QByteArrayLiteral("dci-"))) return Capabilities(CanRead); if (!format.isEmpty()) return {}; Capabilities cap; if (device->isReadable() && QDciIOHandler::canRead(device)) cap |= CanRead; return cap; } QImageIOHandler *QDciPlugin::create(QIODevice *device, const QByteArray &format) const { QDciIOHandler *hand = new QDciIOHandler(); hand->setDevice(device); hand->setFormat(format); return hand; } QT_END_NAMESPACE #include "main.moc" qt5integration-5.7.12/imageformatplugins/dci/qdciiohandler.cpp000066400000000000000000000114611476226661600245540ustar00rootroot00000000000000// Copyright (C) 2022 UnionTech Software Technology Co., Ltd. // SPDX-License-Identifier: LGPL-3.0-or-later #include "qdciiohandler.h" #ifndef QT_NO_SVGRENDERER #include "qimage.h" #include "qpixmap.h" #include "qpainter.h" #include "qvariant.h" #include "qbuffer.h" #include "qdebug.h" #include DGUI_USE_NAMESPACE QT_BEGIN_NAMESPACE class QDciIOHandlerPrivate { public: QDciIOHandlerPrivate(QDciIOHandler *qq) : q(qq) {} bool load(QIODevice *device); QDciIOHandler *q; DDciIcon icon; DDciIconMatchResult current = nullptr; DDciIcon::Theme theme = DDciIcon::Light; DDciIcon::Mode mode = DDciIcon::Normal; bool loaded = false; bool readDone = false; int defaultSize = 0; int scaledSize = 0; QColor backColor; }; bool QDciIOHandlerPrivate::load(QIODevice *device) { if (!device) return false; if (loaded) return current; if (q->format().isEmpty() && !q->canRead()) return false; loaded = true; QBuffer *buf = qobject_cast(device); if (buf) { const QByteArray &ba = buf->data(); icon = DDciIcon(QByteArray::fromRawData(ba.constData() + buf->pos(), ba.size() - buf->pos())); buf->seek(ba.size()); } else { icon = DDciIcon(device->readAll()); } current = nullptr; if (icon.isNull()) return false; if (q->format().startsWith(QByteArrayLiteral("dci-"))) { const auto sections = q->format().split('-'); if (sections.size() == 3) { if (sections[1] == QByteArrayLiteral("dark")) theme = DDciIcon::Dark; if (sections[2] == QByteArrayLiteral("disabled")) mode = DDciIcon::Disabled; else if (sections[2] == QByteArrayLiteral("hover")) mode = DDciIcon::Hover; else if (sections[2] == QByteArrayLiteral("pressed")) mode = DDciIcon::Pressed; } } current = icon.matchIcon(0, theme, mode, DDciIcon::DontFallbackMode); if (!current) return false; defaultSize = icon.actualSize(current); return true; } QDciIOHandler::QDciIOHandler() : d(new QDciIOHandlerPrivate(this)) { } QDciIOHandler::~QDciIOHandler() { delete d; } bool QDciIOHandler::canRead() const { if (!device()) return false; if (d->loaded && !d->readDone) return true; QByteArray buf = device()->peek(4); if (buf.startsWith(QByteArrayLiteral("DCI"))) { // Decide format from content.. if (format().isEmpty()) setFormat("dci"); return true; } return false; } QByteArray QDciIOHandler::name() const { return "dci"; } bool QDciIOHandler::read(QImage *image) { if (d->readDone || d->load(device())) { Q_ASSERT(d->current); int finalSize = d->scaledSize > 0 ? d->scaledSize : d->defaultSize; if (finalSize > 0) { DDciIconPalette palette(QColor::Invalid, d->backColor); *image = d->icon.pixmap(1.0, finalSize, d->current, palette).toImage(); } d->readDone = true; return true; } return false; } QVariant QDciIOHandler::option(ImageOption option) const { switch(option) { case ImageFormat: return QImage::Format_ARGB32_Premultiplied; case Size: d->load(device()); return QSize(d->defaultSize, d->defaultSize); case ScaledSize: return QSize(d->scaledSize, d->scaledSize); case BackgroundColor: return d->backColor; case Animation: // TODO: Support animation for DDciIcon return false; case Endianness: return QSysInfo::LittleEndian; case SupportedSubTypes: if (d->load(device()) && d->icon.isSupportedAttribute(d->current, DDciIcon::HasPalette)) return QVariant::fromValue(QByteArrayList { QByteArrayLiteral("HasPalette") }); return QVariant::fromValue(QByteArrayList()); default: break; } return QVariant(); } void QDciIOHandler::setOption(ImageOption option, const QVariant &value) { switch(option) { case ScaledSize: { const QSize &size = value.toSize(); d->scaledSize = qMin(size.width(), size.height()); break; } case BackgroundColor: d->backColor = qvariant_cast(value); default: break; } } bool QDciIOHandler::supportsOption(ImageOption option) const { switch(option) { case Size: case ScaledSize: case ImageFormat: case Animation: case BackgroundColor: case Endianness: case SupportedSubTypes: return true; default: break; } return false; } bool QDciIOHandler::canRead(QIODevice *device) { QByteArray buf = device->peek(4); return buf.startsWith(QByteArrayLiteral("DCI")); } QT_END_NAMESPACE #endif // QT_NO_SVGRENDERER qt5integration-5.7.12/imageformatplugins/dci/qdciiohandler.h000066400000000000000000000015001476226661600242120ustar00rootroot00000000000000// Copyright (C) 2022 UnionTech Software Technology Co., Ltd. // SPDX-License-Identifier: LGPL-3.0-or-later #ifndef QDCIIOHANDLER_H #define QDCIIOHANDLER_H #include QT_BEGIN_NAMESPACE class QImage; class QByteArray; class QIODevice; class QVariant; class QDciIOHandlerPrivate; class QDciIOHandler : public QImageIOHandler { public: QDciIOHandler(); ~QDciIOHandler(); virtual bool canRead() const; virtual QByteArray name() const; virtual bool read(QImage *image); static bool canRead(QIODevice *device); virtual QVariant option(ImageOption option) const; virtual void setOption(ImageOption option, const QVariant & value); virtual bool supportsOption(ImageOption option) const; private: QDciIOHandlerPrivate *d; }; QT_END_NAMESPACE #endif // QDCIIOHANDLER_H qt5integration-5.7.12/imageformatplugins/svg/000077500000000000000000000000001476226661600212775ustar00rootroot00000000000000qt5integration-5.7.12/imageformatplugins/svg/CMakeLists.txt000066400000000000000000000006531476226661600240430ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later dtk_add_plugin( NAME dsvg OUTPUT_DIR ${PLUGIN_OUTPUT_BASE_DIR}/imageformats INSTALL_DIR ${PLUGIN_INSTALL_BASE_DIR}/imageformats SOURCES main.cpp qsvgiohandler.cpp HEADERS qsvgiohandler.h DEPENDENCIES Dtk${VERSION_SUFFIX}::Gui ) qt5integration-5.7.12/imageformatplugins/svg/main.cpp000066400000000000000000000026701476226661600227340ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #include #if !defined(QT_NO_SVGRENDERER) #include "qsvgiohandler.h" #include #include #include QT_BEGIN_NAMESPACE class QSvgPlugin : public QImageIOPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QImageIOHandlerFactoryInterface" FILE "svg.json") public: QStringList keys() const; Capabilities capabilities(QIODevice *device, const QByteArray &format) const; QImageIOHandler *create(QIODevice *device, const QByteArray &format = QByteArray()) const; }; QStringList QSvgPlugin::keys() const { return QStringList() << QLatin1String("svg") << QLatin1String("svgz"); } QImageIOPlugin::Capabilities QSvgPlugin::capabilities(QIODevice *device, const QByteArray &format) const { if (format == "svg" || format == "svgz") return Capabilities(CanRead); Capabilities cap; if (!format.isEmpty()) return cap; if (device->isReadable() && QSvgIOHandler::canRead(device)) cap |= CanRead; return cap; } QImageIOHandler *QSvgPlugin::create(QIODevice *device, const QByteArray &format) const { QSvgIOHandler *hand = new QSvgIOHandler(); hand->setDevice(device); hand->setFormat(format); return hand; } QT_END_NAMESPACE #include "main.moc" #endif // !QT_NO_IMAGEFORMATPLUGIN qt5integration-5.7.12/imageformatplugins/svg/qsvgiohandler.cpp000066400000000000000000000132511476226661600246530ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qsvgiohandler.h" #ifndef QT_NO_SVGRENDERER #include "qimage.h" #include "qpixmap.h" #include "qpainter.h" #include "qvariant.h" #include "qbuffer.h" #include "qdebug.h" #include DGUI_USE_NAMESPACE QT_BEGIN_NAMESPACE #ifndef UT_QSVGIOHANDLERPRIVATE class QSvgIOHandlerPrivate { public: QSvgIOHandlerPrivate(QSvgIOHandler *qq) : q(qq), loaded(false), readDone(false), backColor(Qt::transparent) {} bool load(QIODevice *device); QSvgIOHandler *q; DSvgRenderer r; QSize defaultSize; QRect clipRect; QSize scaledSize; QRect scaledClipRect; bool loaded; bool readDone; QColor backColor; }; #endif bool QSvgIOHandlerPrivate::load(QIODevice *device) { if (!device) return false; if (loaded) return true; if (q->format().isEmpty()) q->canRead(); // # The SVG renderer doesn't handle trailing, unrelated data, so we must // assume that all available data in the device is to be read. bool res = false; QBuffer *buf = qobject_cast(device); if (buf) { const QByteArray &ba = buf->data(); res = r.load(QByteArray::fromRawData(ba.constData() + buf->pos(), ba.size() - buf->pos())); buf->seek(ba.size()); } else if (q->format() == "svgz") { res = r.load(device->readAll()); } else { res = r.load(device->readAll()); } if (res) { defaultSize = QSize(r.viewBox().width(), r.viewBox().height()); loaded = true; } return loaded; } QSvgIOHandler::QSvgIOHandler() : d(new QSvgIOHandlerPrivate(this)) { } QSvgIOHandler::~QSvgIOHandler() { delete d; } bool QSvgIOHandler::canRead() const { if (!device()) return false; if (d->loaded && !d->readDone) return true; // Will happen if we have been asked for the size QByteArray buf = device()->peek(8); if (buf.startsWith("\x1f\x8b")) { setFormat("svgz"); return true; } else if (buf.contains("readDone || d->load(device())) { bool xform = (d->clipRect.isValid() || d->scaledSize.isValid() || d->scaledClipRect.isValid()); QSize finalSize = d->defaultSize; QRectF bounds; if (xform && !d->defaultSize.isEmpty()) { bounds = QRectF(QPointF(0,0), QSizeF(d->defaultSize)); QPoint tr1, tr2; QSizeF sc(1, 1); if (d->clipRect.isValid()) { tr1 = -d->clipRect.topLeft(); finalSize = d->clipRect.size(); } if (d->scaledSize.isValid()) { sc = QSizeF(qreal(d->scaledSize.width()) / finalSize.width(), qreal(d->scaledSize.height()) / finalSize.height()); finalSize = d->scaledSize; } if (d->scaledClipRect.isValid()) { tr2 = -d->scaledClipRect.topLeft(); finalSize = d->scaledClipRect.size(); } QTransform t; t.translate(tr2.x(), tr2.y()); t.scale(sc.width(), sc.height()); t.translate(tr1.x(), tr1.y()); bounds = t.mapRect(bounds); } if (!finalSize.isEmpty()) { if (bounds.isEmpty() && d->backColor.alpha() == 0) { *image = d->r.toImage(finalSize); } else { *image = QImage(finalSize, QImage::Format_ARGB32_Premultiplied); image->fill(d->backColor.rgba()); QPainter p(image); p.setRenderHints(QPainter::SmoothPixmapTransform); d->r.render(&p, bounds); p.end(); } } d->readDone = true; return true; } return false; } QVariant QSvgIOHandler::option(ImageOption option) const { switch(option) { case ImageFormat: return QImage::Format_ARGB32_Premultiplied; break; case Size: d->load(device()); return d->defaultSize; break; case ClipRect: return d->clipRect; break; case ScaledSize: return d->scaledSize; break; case ScaledClipRect: return d->scaledClipRect; break; case BackgroundColor: return d->backColor; break; default: break; } return QVariant(); } void QSvgIOHandler::setOption(ImageOption option, const QVariant & value) { switch(option) { case ClipRect: d->clipRect = value.toRect(); break; case ScaledSize: d->scaledSize = value.toSize(); break; case ScaledClipRect: d->scaledClipRect = value.toRect(); break; case BackgroundColor: d->backColor = value.value(); break; default: break; } } bool QSvgIOHandler::supportsOption(ImageOption option) const { switch(option) { case ImageFormat: case Size: case ClipRect: case ScaledSize: case ScaledClipRect: case BackgroundColor: return true; default: break; } return false; } bool QSvgIOHandler::canRead(QIODevice *device) { QByteArray buf = device->peek(8); return buf.startsWith("\x1f\x8b") || buf.contains(" #ifndef QT_NO_SVGRENDERER QT_BEGIN_NAMESPACE class QImage; class QByteArray; class QIODevice; class QVariant; class QSvgIOHandlerPrivate; class QSvgIOHandler : public QImageIOHandler { public: QSvgIOHandler(); ~QSvgIOHandler(); virtual bool canRead() const; virtual QByteArray name() const; virtual bool read(QImage *image); static bool canRead(QIODevice *device); virtual QVariant option(ImageOption option) const; virtual void setOption(ImageOption option, const QVariant & value); virtual bool supportsOption(ImageOption option) const; private: QSvgIOHandlerPrivate *d; }; QT_END_NAMESPACE #endif // QT_NO_SVGRENDERER #endif // QSVGIOHANDLER_H qt5integration-5.7.12/imageformatplugins/svg/svg.json000066400000000000000000000001101476226661600227610ustar00rootroot00000000000000{ "Keys": [ "svg", "svgz" ], "MimeTypes": [ "image/svg+xml" ] } qt5integration-5.7.12/linglong.yaml000066400000000000000000000012341476226661600173000ustar00rootroot00000000000000package: id: qt5integration name: qt5integration kind: lib version: 5.6.3 description: | Qt platform theme integration plugins for DDE \ Multiple Qt plugins to provide better Qt5 integration for DDE is included. base: id: org.deepin.base/23.0.0 variables: extra_args: | VERSION=${VERSION} depends: - id: qtbase/5.15.7 - id: qttools/5.15.7 - id: qtx11extras/5.15.7 - id: qtsvg/5.15.7 - id: qtmultimedia/5.15.7 - id: gsettings-qt/0.3.1.1 - id: dtkcommon/5.6.3 - id: dtkcore/5.6.3 - id: dtkgui/5.6.3 - id: dtkwidget/5.6.3 - id: libqtxdg/3.6.0.1 #- id: googletest/1.8.1 source: kind: local build: kind: qmake qt5integration-5.7.12/platformthemeplugin/000077500000000000000000000000001476226661600206715ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/CMakeLists.txt000066400000000000000000000052061476226661600234340ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS DBus Widgets) set(QT_LIBS Qt${QT_VERSION_MAJOR}::DBus Qt${QT_VERSION_MAJOR}::Widgets) if(QT_VERSION_MAJOR EQUAL 5) find_package(Qt5X11Extras REQUIRED) list(APPEND QT_LIBS Qt5::X11Extras) if(QT_VERSION_MINOR GREATER_EQUAL 8) # Qt5.8 find_package(Qt5ThemeSupport REQUIRED) list(APPEND QT_LIBS Qt5::ThemeSupportPrivate) else() list(APPEND QT_LIBS Qt5::PlatformSupportPrivate) # TODO to be verified endif() set(3RD_PARTY_SOURCES ${CMAKE_SOURCE_DIR}/3rdparty/qdbustrayicon.cpp ${CMAKE_SOURCE_DIR}/3rdparty/qstatusnotifieritemadaptor.cpp ${CMAKE_SOURCE_DIR}/3rdparty/qdbusmenuconnection.cpp ) set(3RD_PARTY_HEADERS ${CMAKE_SOURCE_DIR}/3rdparty/qdbustrayicon_p.h ${CMAKE_SOURCE_DIR}/3rdparty/qstatusnotifieritemadaptor_p.h ${CMAKE_SOURCE_DIR}/3rdparty/qdbusmenuconnection_p.h ) else() list(APPEND QT_LIBS Qt6::GuiPrivate) endif() find_package(PkgConfig REQUIRED) pkg_check_modules(Deps REQUIRED IMPORTED_TARGET mtdev x11) if(ENABLE_QT_XDG_ICON_LOADER) set(DEFS -DXDG_ICON_VERSION_MAR=${XDG_ICON_VERSION_MAJOR}) list(APPEND QT_LIBS ${QT_XDG_ICON_DEPS}) endif() if(QT_VERSION_MAJOR EQUAL 5) qt5_add_dbus_interface(DBUS_INTERFACES ${CMAKE_CURRENT_LIST_DIR}/xmls/com.deepin.filemanager.filedialog.xml filedialog_interface) qt5_add_dbus_interface(DBUS_INTERFACES ${CMAKE_CURRENT_LIST_DIR}/xmls/com.deepin.filemanager.filedialogmanager.xml filedialogmanager_interface) else() qt6_add_dbus_interface(DBUS_INTERFACES ${CMAKE_CURRENT_LIST_DIR}/xmls/com.deepin.filemanager.filedialog.xml filedialog_interface) qt6_add_dbus_interface(DBUS_INTERFACES ${CMAKE_CURRENT_LIST_DIR}/xmls/com.deepin.filemanager.filedialogmanager.xml filedialogmanager_interface) endif() dtk_add_plugin( NAME qdeepin OUTPUT_DIR ${PLUGIN_OUTPUT_BASE_DIR}/platformthemes INSTALL_DIR ${PLUGIN_INSTALL_BASE_DIR}/platformthemes SOURCES dthemesettings.cpp qdeepinfiledialoghelper.cpp qdeepintheme.cpp ${3RD_PARTY_SOURCES} main.cpp ${DBUS_INTERFACES} HEADERS dthemesettings.h qdeepinfiledialoghelper.h qdeepintheme.h ${3RD_PARTY_HEADERS} RESOURCES icons/deepin-theme-plugin-icons.qrc deepin-theme-plugin.qrc DEPENDENCIES Dtk${VERSION_SUFFIX}::Gui ${QT_LIBS} PkgConfig::Deps DEFINITIONS ${DEFS} INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ) qt5integration-5.7.12/platformthemeplugin/deepin-theme-plugin.qrc000066400000000000000000000001441476226661600252370ustar00rootroot00000000000000 qtquickcontrols2.conf qt5integration-5.7.12/platformthemeplugin/deepin.json000066400000000000000000000000451476226661600230270ustar00rootroot00000000000000{ "Keys" : [ "deepin", "DDE" ] } qt5integration-5.7.12/platformthemeplugin/dthemesettings.cpp000066400000000000000000000200111476226661600244160ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "dthemesettings.h" #include #include #include #include #define ICON_THEME_NAME QStringLiteral("IconThemeName") #define F_ICON_THEME_NAME QStringLiteral("FallBackIconThemeName") #define STYLE_NAMES QStringLiteral("StyleNames") #define SYSTEM_FONT QStringLiteral("Font") #define SYSTEM_FIXED_FONT QStringLiteral("MonoFont") #define SYSTEM_FONT_POINT_SIZE QStringLiteral("FontSize") // 在某些情况下,触摸滚动视图的操作可能和其它的touch move行为冲突(例如文件管理器的视图滚动和文件内容多选) // 只能在时间上控制让两个冲突的逻辑错开。此处定义此时间(单位:ms),表示从touch begin到touch move比较在 // 此时间段内完成,否则不应该认为这个一个触摸滚动操作 #define TOUCH_FLICK_BEGIN_MOVE_DELAY QStringLiteral("TouchFlickBeginMoveDelay") #define SCREEN_SCALE_FACTORS QStringLiteral("ScreenScaleFactors") #define SCALE_FACTOR QStringLiteral("ScaleFactor") #define SCALE_LOGICAL_DPI QStringLiteral("ScaleLogicalDpi") // 当窗口从一个屏幕移动到另一个屏幕后,自动根据新的屏幕缩放比例更新窗口实际大小 #define AUTO_SCALE_WINDOW QStringLiteral("AutoScaleWindow") DCORE_USE_NAMESPACE DThemeSettings::DThemeSettings(bool watchFile, QObject *parent) : QObject(parent) , settings(makeSettings()) { if (!watchFile) return; QStringList list; list << settings->fileName(); list << QSettings(QSettings::IniFormat, QSettings::SystemScope, "deepin", "qt-theme").fileName(); DFileWatcherManager *watcher = new DFileWatcherManager(this); for (const QString &path : list) { QFile file(path); if (!file.exists()) { file.open(QFile::WriteOnly); file.close(); } if (QFile::exists(path)) watcher->add(path); } connect(watcher, &DFileWatcherManager::fileModified, this, &DThemeSettings::onConfigChanged); } QSettings * DThemeSettings::makeSettings() { QString saveConfigPath; do { // 需要自定义读取主题相关配置的存储路径,未定义时默认为 ~/.config // 适用于这样的情况:一个使用pkexec使用root权限启动的UI应用,需要跟随启动时的普通 // 用户的字体、缩放等设置,可通过在QCoreApplication构造之前设置此环境变量指定使用 // 某用户的主题配置文件。 static QByteArray theme_config_path = qgetenv("D_QT_THEME_CONFIG_PATH"); if (theme_config_path.isEmpty()) { break; } const QString suffix("/deepin/qt-theme.ini"); QFileInfo info(theme_config_path + suffix); // 忽略不存在的文件或软连接 if (!info.exists() || info.isSymLink()) { break; } // 先创建一个对象,用于获取默认配置文件的路径 QSettings s(QSettings::IniFormat, QSettings::UserScope, "deepin", "qt-theme"); QString file_path = s.fileName(); // 必须以此路径结尾,去除此路径的剩余部分为配置文件路径 if (!file_path.endsWith(suffix)) { break; } saveConfigPath = file_path.left(file_path.size() - suffix.size()); if (saveConfigPath.isEmpty()) { break; } // 设置自定义的主题配置文件存储目录 QSettings::setPath(s.format(), s.scope(), QString::fromLocal8Bit(theme_config_path)); } while (false); QSettings *s = new QSettings(QSettings::IniFormat, QSettings::UserScope, "deepin", "qt-theme"); // 恢复原本的配置目录 if (!saveConfigPath.isEmpty()) { QSettings::setPath(s->format(), s->scope(), saveConfigPath); } #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) s->setIniCodec("utf-8"); #endif s->beginGroup("Theme"); return s; } bool DThemeSettings::contains(const QString &key) const { return settings->contains(key); } QVariant DThemeSettings::value(const QString &key, const QVariant &defaultValue) const { return settings->value(key, defaultValue); } bool DThemeSettings::isSetIconThemeName() const { return contains(ICON_THEME_NAME); } QString DThemeSettings::iconThemeName() const { return value(ICON_THEME_NAME).toString(); } bool DThemeSettings::isSetFallbackIconThemeName() const { return contains(F_ICON_THEME_NAME); } QString DThemeSettings::fallbackIconThemeName() const { return value(F_ICON_THEME_NAME).toString(); } bool DThemeSettings::isSetSystemFont() const { return contains(SYSTEM_FONT); } QString DThemeSettings::systemFont() const { return value(SYSTEM_FONT).toString(); } bool DThemeSettings::isSetStyleNames() const { return contains(STYLE_NAMES); } QStringList DThemeSettings::styleNames() const { return value(STYLE_NAMES).toStringList(); } bool DThemeSettings::isSetSystemFontPixelSize() const { return contains(SYSTEM_FONT_POINT_SIZE); } qreal DThemeSettings::systemFontPointSize() const { return value(SYSTEM_FONT_POINT_SIZE, 9.0).toDouble(); } bool DThemeSettings::isSetSystemFixedFont() const { return contains(SYSTEM_FIXED_FONT); } QString DThemeSettings::systemFixedFont() const { return value(SYSTEM_FIXED_FONT).toString(); } int DThemeSettings::touchFlickBeginMoveDelay() const { return value(TOUCH_FLICK_BEGIN_MOVE_DELAY, 300).toInt(); } qreal DThemeSettings::scaleFactor() const { return value(SCALE_FACTOR).toReal(); } QByteArray DThemeSettings::screenScaleFactors() const { return value(SCREEN_SCALE_FACTORS).toByteArray(); } // 从配置文件中获取dpi相关数据,文件中存储的格式为 ScaleLogicalDpi=x,y // 会被QSettings解析为QStringList,此处需要将其转换为QPair static DDpi takePair(const QVariant &value) { if (!value.isValid()) { return qMakePair(0.0, 0.0); } const QStringList &l = value.toStringList(); if (l.count() < 2) { return qMakePair(0.0, 0.0); } DDpi ret; ret.first = l.first().toDouble(); ret.second = l.at(1).toDouble(); return ret; } DDpi DThemeSettings::scaleLogicalDpi() const { return takePair(value(SCALE_LOGICAL_DPI)); } bool DThemeSettings::autoScaleWindow() const { return value(AUTO_SCALE_WINDOW, true).toBool(); } void DThemeSettings::onConfigChanged() { QVariantMap config; for (const QString &v : settings->allKeys()) { config[v] = settings->value(v); } settings->sync(); for (const QString &v : settings->allKeys()) { const QVariant &old_value = config.value(v); const QVariant &new_value = settings->value(v); if (old_value != new_value) { if (v == ICON_THEME_NAME) emit iconThemeNameChanged(new_value.toString()); else if (v == F_ICON_THEME_NAME) emit fallbackIconThemeNameChanged(new_value.toString()); else if (v == SYSTEM_FONT) emit systemFontChanged(new_value.toString()); else if (v == STYLE_NAMES) emit styleNamesChanged(new_value.toStringList()); else if (v == SYSTEM_FIXED_FONT) emit systemFixedFontChanged(new_value.toString()); else if (v == SYSTEM_FONT_POINT_SIZE) emit systemFontPointSizeChanged(new_value.toInt()); else if (v == TOUCH_FLICK_BEGIN_MOVE_DELAY) emit touchFlickBeginMoveDelayChanged(new_value.toInt()); else if (v == SCREEN_SCALE_FACTORS) emit screenScaleFactorsChanged(new_value.toByteArray()); else if (v == SCALE_FACTOR) emit scaleFactorChanged(new_value.toReal()); else if (v == SCALE_LOGICAL_DPI) emit scaleLogicalDpiChanged(takePair(new_value)); emit valueChanged(v, old_value, new_value); } } } qt5integration-5.7.12/platformthemeplugin/dthemesettings.h000066400000000000000000000061461476226661600241000ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017-2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef DTHEMESETTINGS_H #define DTHEMESETTINGS_H #include #include /*! \typedef DDpi \relates DThemeSettings Synonym for QPair. */ typedef QPair DDpi; class DThemeSettings : public QObject { Q_OBJECT Q_PROPERTY(QString iconThemeName READ iconThemeName NOTIFY iconThemeNameChanged) Q_PROPERTY(QString fallbackIconThemeName READ fallbackIconThemeName NOTIFY fallbackIconThemeNameChanged) Q_PROPERTY(QString systemFont READ systemFont NOTIFY systemFontChanged) Q_PROPERTY(QString systemFixedFont READ systemFixedFont NOTIFY systemFixedFontChanged) Q_PROPERTY(qreal systemFontPointSize READ systemFontPointSize NOTIFY systemFontPointSizeChanged) Q_PROPERTY(QStringList styleNames READ styleNames NOTIFY styleNamesChanged) Q_PROPERTY(int touchFlickBeginMoveDelay READ touchFlickBeginMoveDelay NOTIFY touchFlickBeginMoveDelayChanged) Q_PROPERTY(qreal scaleFactor READ scaleFactor NOTIFY scaleFactorChanged) Q_PROPERTY(QByteArray screenScaleFactors READ screenScaleFactors NOTIFY screenScaleFactorsChanged) Q_PROPERTY(DDpi scaleLogicalDpi READ scaleLogicalDpi NOTIFY scaleLogicalDpiChanged) Q_PROPERTY(bool autoScaleWindow READ autoScaleWindow NOTIFY autoScaleWindowChanged) public: explicit DThemeSettings(bool watchFile = true, QObject *parent = 0); static QSettings *makeSettings(); bool contains(const QString &key) const; QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const; bool isSetIconThemeName() const; QString iconThemeName() const; bool isSetFallbackIconThemeName() const; QString fallbackIconThemeName() const; bool isSetSystemFont() const; QString systemFont() const; bool isSetStyleNames() const; QStringList styleNames() const; bool isSetSystemFontPixelSize() const; qreal systemFontPointSize() const; bool isSetSystemFixedFont() const; QString systemFixedFont() const; int touchFlickBeginMoveDelay() const; qreal scaleFactor() const; QByteArray screenScaleFactors() const; DDpi scaleLogicalDpi() const; bool autoScaleWindow() const; signals: void valueChanged(const QString &key, const QVariant &oldValue, const QVariant &newValue); void iconThemeNameChanged(QString iconThemeName); void fallbackIconThemeNameChanged(QString fallbackIconThemeName); void systemFontChanged(QString systemFont); void styleNamesChanged(QStringList styleNames); void systemFixedFontChanged(QString systemFixedFont); void systemFontPointSizeChanged(qreal systemFontPointSize); void touchFlickBeginMoveDelayChanged(int touchFlickBeginMoveDelay); void scaleFactorChanged(const qreal &scaleFactor); void screenScaleFactorsChanged(const QByteArray &screenScaleFactors); void scaleLogicalDpiChanged(const DDpi scaleLogicalDpi); void autoScaleWindowChanged(bool autoScaleWindow); private: QSettings *settings; void onConfigChanged(); }; #endif // DTHEMESETTINGS_H qt5integration-5.7.12/platformthemeplugin/icons/000077500000000000000000000000001476226661600220045ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/icons/actions/000077500000000000000000000000001476226661600234445ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-copy_16px.svg000066400000000000000000000023571476226661600267470ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-cut_16px.svg000066400000000000000000000030221476226661600265560ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-delete_16px.svg000066400000000000000000000031551476226661600272340ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-paste_16px.svg000066400000000000000000000065451476226661600271140ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-redo_16px.svg000066400000000000000000000015641476226661600267250ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-select-all_16px.svg000066400000000000000000000027141476226661600300170ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/actions/edit-undo_16px.svg000066400000000000000000000007271476226661600267410ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/deepin-theme-plugin-icons.qrc000066400000000000000000000103271476226661600274670ustar00rootroot00000000000000 texts/caps_lock_16px.svg texts/password_hide_24px.svg texts/password_show_24px.svg texts/edit_12px.svg icons/button_voice_active_30px.svg icons/button_voice_active_press_30px.svg icons/icon_fail_128px.svg icons/icon_success_128px.svg texts/button_add_20px.svg texts/button_reduce_12px.svg texts/combobox_arrow_12px.svg texts/audio-volume-left_24px.svg texts/audio-volume-low_24px.svg texts/audio-volume-medium_24px.svg texts/audio-volume-muted_24px.svg texts/audio-volume-right_24px.svg texts/go-down_12px.svg texts/go-next_12px.svg texts/go-previous_12px.svg texts/go-up_12px.svg texts/media-playback-pause_24px.svg texts/media-playback-start_24px.svg texts/media-skip-backward_24px.svg texts/media-skip-forward_24px.svg texts/mark_indicator_12px.svg texts/fork_indicator_24px.svg texts/lock_indicator_24px.svg texts/selected_indicator_16px.svg texts/selected_checked_indicator_16px.svg texts/selected_indicator_16px.svg.background texts/unlock_indicator_24px.svg texts/unselected_indicator_16px.svg texts/window-close_round_30px.svg texts/search_indicator_20px.svg texts/unchecked_20px.svg texts/checked_20px.svg texts/next_indicator_24px.svg texts/prev_indicator_24px.svg actions/edit-select-all_16px.svg actions/edit-copy_16px.svg actions/edit-cut_16px.svg actions/edit-delete_16px.svg actions/edit-paste_16px.svg actions/edit-redo_16px.svg actions/edit-undo_16px.svg icons/light/edit-clear_30px.svg icons/light/edit-clear_press_30px.svg icons/light/button_voice_30px.svg icons/light/button_voice_press_30px.svg icons/light/list_delete_16px.svg icons/light/list_add_16px.svg icons/light/window-close_round_30px.svg icons/light/window-close_round_press_30px.svg icons/dark/edit-clear_30px.svg icons/dark/edit-clear_press_30px.svg icons/dark/button_voice_30px.svg icons/dark/button_voice_press_30px.svg icons/dark/list_delete_16px.svg icons/dark/list_add_16px.svg icons/dark/window-close_round_30px.svg icons/dark/window-close_round_press_30px.svg qt5integration-5.7.12/platformthemeplugin/icons/icons/000077500000000000000000000000001476226661600231175ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/icons/icons/button_voice_active_30px.svg000066400000000000000000000033151476226661600305470ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/button_voice_active_press_30px.svg000066400000000000000000000033531476226661600317650ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/000077500000000000000000000000001476226661600240405ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/button_voice_30px.svg000066400000000000000000000041601476226661600301340ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/button_voice_press_30px.svg000066400000000000000000000042321476226661600313500ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/edit-clear_30px.svg000066400000000000000000000042261476226661600274500ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/edit-clear_press_30px.svg000066400000000000000000000043001476226661600306550ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/list_add_16px.svg000066400000000000000000000005671476226661600272320ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/list_delete_16px.svg000066400000000000000000000003621476226661600277350ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/window-close_round_30px.svg000066400000000000000000000042261476226661600312600ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dark/window-close_round_press_30px.svg000066400000000000000000000043001476226661600324650ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dialog-right_30px.svg000066400000000000000000000021511476226661600270630ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/dialog-warning_30px.svg000066400000000000000000000024341476226661600274170ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/icon_fail_128px.svg000066400000000000000000000035001476226661600265230ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/icon_success_128px.svg000066400000000000000000000032641476226661600272670ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/000077500000000000000000000000001476226661600242265ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/icons/icons/light/button_voice_30px.svg000066400000000000000000000035761476226661600303340ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/button_voice_press_30px.svg000066400000000000000000000040521476226661600315360ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/edit-clear_30px.svg000066400000000000000000000036441476226661600276410ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/edit-clear_press_30px.svg000066400000000000000000000056411476226661600310540ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/list_add_16px.svg000066400000000000000000000006551476226661600274160ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/list_delete_16px.svg000066400000000000000000000003621476226661600301230ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/window-close_round_30px.svg000066400000000000000000000036441476226661600314510ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/icons/light/window-close_round_press_30px.svg000066400000000000000000000056411476226661600326640ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/000077500000000000000000000000001476226661600231535ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/icons/texts/audio-volume-left_24px.svg000066400000000000000000000014141476226661600301070ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/audio-volume-low_24px.svg000066400000000000000000000011521476226661600277550ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/audio-volume-medium_24px.svg000066400000000000000000000021401476226661600304320ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/audio-volume-muted_24px.svg000066400000000000000000000021161476226661600302730ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/audio-volume-right_24px.svg000066400000000000000000000022441476226661600302740ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/button_add_20px.svg000066400000000000000000000004051476226661600266670ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/button_reduce_12px.svg000066400000000000000000000003011476226661600274020ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/caps_lock_16px.svg000066400000000000000000000007061476226661600265130ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/checked_20px.svg000066400000000000000000000032101476226661600261270ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/combobox_arrow_12px.svg000066400000000000000000000002721476226661600275710ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/edit_12px.svg000066400000000000000000000010171476226661600254720ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/fork_indicator_24px.svg000066400000000000000000000005721476226661600275520ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/go-down_12px.svg000066400000000000000000000003371476226661600261230ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/go-next_12px.svg000066400000000000000000000002721476226661600261300ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/go-previous_12px.svg000066400000000000000000000002631476226661600270260ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/go-up_12px.svg000066400000000000000000000003261476226661600255760ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/lock_indicator_24px.svg000066400000000000000000000017351476226661600275430ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/mark_indicator_12px.svg000066400000000000000000000003301476226661600275300ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/media-playback-pause_24px.svg000066400000000000000000000004631476226661600305320ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/media-playback-start_24px.svg000066400000000000000000000005531476226661600305520ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/media-skip-backward_24px.svg000066400000000000000000000015551476226661600303560ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/media-skip-forward_24px.svg000066400000000000000000000015131476226661600302360ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/next_indicator_24px.svg000066400000000000000000000004741476226661600275700ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/password_hide_24px.svg000066400000000000000000000024271476226661600274110ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/password_show_24px.svg000066400000000000000000000014301476226661600274510ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/prev_indicator_24px.svg000066400000000000000000000005511476226661600275620ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/search_indicator_20px.svg000066400000000000000000000021771476226661600300550ustar00rootroot00000000000000 画板 qt5integration-5.7.12/platformthemeplugin/icons/texts/selected_checked_indicator_16px.svg000066400000000000000000000013071476226661600320450ustar00rootroot00000000000000 selected_foreground qt5integration-5.7.12/platformthemeplugin/icons/texts/selected_indicator_16px.svg000066400000000000000000000013071476226661600303770ustar00rootroot00000000000000 selected_foreground qt5integration-5.7.12/platformthemeplugin/icons/texts/selected_indicator_16px.svg.background000066400000000000000000000010241476226661600325110ustar00rootroot00000000000000 selected_background qt5integration-5.7.12/platformthemeplugin/icons/texts/unchecked_20px.svg000066400000000000000000000013241476226661600264760ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/unlock_indicator_24px.svg000066400000000000000000000020201476226661600300720ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/unselected_indicator_16px.svg000066400000000000000000000007301476226661600307410ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/icons/texts/window-close_round_30px.svg000066400000000000000000000010251476226661600303650ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/main.cpp000066400000000000000000000017411476226661600223240ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include "qdeepintheme.h" #ifdef XDG_ICON_VERSION_MAR #include void updateXdgIconSystemTheme() { XdgIconLoader::instance()->updateSystemTheme(); } #endif QT_BEGIN_NAMESPACE class QDeepinThemePlugin : public QPlatformThemePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID QPlatformThemeFactoryInterface_iid FILE "deepin.json") public: QPlatformTheme *create(const QString &key, const QStringList ¶ms) Q_DECL_OVERRIDE; }; QPlatformTheme *QDeepinThemePlugin::create(const QString &key, const QStringList ¶ms) { Q_UNUSED(params); const QStringList &keys = {QLatin1String(QDeepinTheme::name), QLatin1String("DDE")}; if (keys.contains(key, Qt::CaseInsensitive)) return new QDeepinTheme; return nullptr; } QT_END_NAMESPACE #include "main.moc" qt5integration-5.7.12/platformthemeplugin/qdeepinfiledialoghelper.cpp000066400000000000000000000421121476226661600262420ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "qdeepinfiledialoghelper.h" #include "qdeepintheme.h" #include "filedialogmanager_interface.h" #include "filedialog_interface.h" #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include #define DISPLAY qApp->nativeInterface()->display() #else #include #define DISPLAY QX11Info::display() #endif #include #include #include #include #include #include DGUI_USE_NAMESPACE QT_BEGIN_NAMESPACE #ifndef DIALOG_SERVICE #define DIALOG_SERVICE "com.deepin.filemanager.filedialog" #endif Q_LOGGING_CATEGORY(fileDialogHelper, "dtk.qpa.fileDialogHelper"); QList stringList2UrlList(const QStringList &list) { QList urlList; for (const QString &str : list) urlList << str; return urlList; } QStringList urlList2StringList(const QList &list) { QStringList stringList; for (const QUrl &url : list) stringList << url.toString(); return stringList; } DFileDialogManager *QDeepinFileDialogHelper::manager = Q_NULLPTR; QString QDeepinFileDialogHelper::dialogService = QStringLiteral(); QDeepinFileDialogHelper::QDeepinFileDialogHelper() { connect(this, &QDeepinFileDialogHelper::accept, this, [this] { if (sourceDialog && filedlgInterface) { const QMap &map_lineedit = filedlgInterface->allCustomWidgetsValue(LineEditType); const QMap &map_combobox = filedlgInterface->allCustomWidgetsValue(ComboBoxType); auto map_eidt_begin = map_lineedit.constBegin(); while (map_eidt_begin != map_lineedit.constEnd()) { sourceDialog->setProperty(QString("_dtk_widget_lineedit_%1_value").arg(map_eidt_begin.key()).toUtf8(), map_eidt_begin.value()); ++map_eidt_begin; } auto map_combobox_begion = map_combobox.constBegin(); while (map_combobox_begion != map_combobox.constEnd()) { sourceDialog->setProperty(QString("_dtk_widget_combobox_%1_value").arg(map_combobox_begion.key()).toUtf8(), map_combobox_begion.value()); ++map_combobox_begion; } } }); } QDeepinFileDialogHelper::~QDeepinFileDialogHelper() { if (auxiliaryWindow) { // Note that we must hide auxiliaryWindow if it's modal to avoid direct invocation of deleteLater() to QDeepinFileDialogHelper // When someone creates a QFileDialog, runs exec amd uses a timer to invoke QFileDialog::deleteLater later. auxiliaryWindow // will just be deleted but not be hidden. Mainwindow will keep blocked by a dead modal window. hideAuxiliaryWindow(); auxiliaryWindow->deleteLater(); } if (filedlgInterface) { filedlgInterface->deleteLater(); // dbus filedlgInterface->QObject::deleteLater(); } } void QDeepinFileDialogHelper::onApplicationStateChanged(Qt::ApplicationState state) { if (state == Qt::ApplicationActive && filedlgInterface) filedlgInterface->activateWindow(); } static inline void setTransientForHint(WId wid, WId propWid) { if (!qApp->platformName().contains("xcb")) return; // set WM_TRANSIENT_FOR propWid for wid // to make sure filedialog window on the top of app window XSetTransientForHint(DISPLAY, wid, propWid); } void QDeepinFileDialogHelper::onWindowActiveChanged() { if (!filedlgInterface) return; // FIX dtk#65 // XSetTransientForHint 有可能被覆盖为桌面的 id,当窗口激活时再次设置一次 if (filedlgInterface->windowActive() && auxiliaryWindow && auxiliaryWindow->parent(QWindow::IncludeTransients)) { Window fileDlgWId = filedlgInterface->winId(); Window parentWId = auxiliaryWindow->parent(QWindow::IncludeTransients)->winId(); setTransientForHint(fileDlgWId, parentWId); } if (DPlatformHandle::isDXcbPlatform()) { QWindow *focus_window = qApp->focusWindow(); if (!focus_window) return; if (focus_window->type() != Qt::Widget && focus_window->type() != Qt::Window && focus_window->type() != Qt::Dialog) { return; } if (!filedlgInterface->windowActive() && qApp->applicationState() == Qt::ApplicationActive) { filedlgInterface->activateWindow(); } } } bool QDeepinFileDialogHelper::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) { ensureDialog(); applyOptions(); if (filedlgInterface) { if (parent) activeWindow = parent; else activeWindow = QGuiApplication::focusWindow(); filedlgInterface->setParent(parent); Qt::WindowFlags nd_flags = static_cast(filedlgInterface->windowFlags()); Qt::WindowFlags need_flags = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowContextHelpButtonHint | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnBottomHint | Qt::WindowCloseButtonHint | Qt::BypassWindowManagerHint; if (flags & need_flags) filedlgInterface->setWindowFlags(nd_flags | (flags & need_flags)); static bool i_am_dbus_server = iAmFileDialogDBusServer(); if (i_am_dbus_server) { WId native_dialog_winId = filedlgInterface->winId(); QWindow *real_native_dialog = nullptr; for (QWindow *window : qGuiApp->topLevelWindows()) { if (window->winId() == native_dialog_winId) { real_native_dialog = window; break; } } if (real_native_dialog) { real_native_dialog->setTransientParent(parent); real_native_dialog->setModality(modality); // call later QMetaObject::invokeMethod(filedlgInterface.data(), "show", Qt::QueuedConnection); return true; } } auxiliaryWindow->setParent(parent); auxiliaryWindow->setFlags(flags); auxiliaryWindow->setModality(modality); if (modality != Qt::NonModal) { QGuiApplicationPrivate::showModalWindow(auxiliaryWindow); if (modality == Qt::ApplicationModal) { connect(qApp, &QGuiApplication::applicationStateChanged, this, &QDeepinFileDialogHelper::onApplicationStateChanged, Qt::UniqueConnection); connect(filedlgInterface, &DFileDialogHandle::windowActiveChanged, this, &QDeepinFileDialogHelper::onWindowActiveChanged, Qt::UniqueConnection); } } } if (filedlgInterface) filedlgInterface->show(); if (filedlgInterface && parent) { setTransientForHint(filedlgInterface->winId(), parent->winId()); } // 如果没有dbus接口 return false 至少可以显示默认的文件选择对话框 return filedlgInterface; } void QDeepinFileDialogHelper::exec() { qCDebug(fileDialogHelper) << "exec"; ensureDialog(); // 快速打开关闭多次有一定概率出现没有调用 show 的情况,这里先 show // 保证exec一定会显示出现 if (filedlgInterface) filedlgInterface->show(); // block input to the window, allow input to other GTK dialogs QEventLoop loop; execLoop = &loop; connect(this, &QPlatformDialogHelper::accept, &loop, &QEventLoop::quit); connect(this, &QPlatformDialogHelper::reject, &loop, &QEventLoop::quit); connect(this, &QObject::destroyed, &loop, &QEventLoop::quit); loop.exec(); qCDebug(fileDialogHelper) << "Exec finished, dispose event loop."; } void QDeepinFileDialogHelper::hide() { qCDebug(fileDialogHelper) << "hide"; ensureDialog(); if (filedlgInterface) filedlgInterface->hide(); if (auxiliaryWindow) hideAuxiliaryWindow(); if (execLoop && execLoop->isRunning()) { execLoop->quit(); } } bool QDeepinFileDialogHelper::defaultNameFilterDisables() const { qCDebug(fileDialogHelper) << __FUNCTION__; return true; } void QDeepinFileDialogHelper::setDirectory(const QUrl &directory) { if (QDeepinFileDialogHelper::directory() == directory) { return; } qCDebug(fileDialogHelper) << __FUNCTION__ << directory; ensureDialog(); if (filedlgInterface) filedlgInterface->setDirectoryUrl(directory.toString()); else options()->setInitialDirectory(directory); } QUrl QDeepinFileDialogHelper::directory() const { qCDebug(fileDialogHelper) << __FUNCTION__; ensureDialog(); if (filedlgInterface) return QUrl(filedlgInterface->directoryUrl()); return options()->initialDirectory(); } void QDeepinFileDialogHelper::selectFile(const QUrl &fileUrl) { qCDebug(fileDialogHelper) << __FUNCTION__ << fileUrl; ensureDialog(); if (filedlgInterface) filedlgInterface->selectUrl(fileUrl.toString()); else options()->setInitiallySelectedFiles({fileUrl}); } QList QDeepinFileDialogHelper::selectedFiles() const { qCDebug(fileDialogHelper) << __FUNCTION__; ensureDialog(); if (filedlgInterface) return stringList2UrlList(filedlgInterface->selectedUrls()); return options()->initiallySelectedFiles(); } void QDeepinFileDialogHelper::setFilter() { qCDebug(fileDialogHelper) << __FUNCTION__; ensureDialog(); if (filedlgInterface) filedlgInterface->setFilter(options()->filter()); } void QDeepinFileDialogHelper::selectNameFilter(const QString &filter) { qCDebug(fileDialogHelper) << __FUNCTION__ << filter; ensureDialog(); if (filedlgInterface) filedlgInterface->selectNameFilter(filter); else options()->setInitiallySelectedNameFilter(filter); } QString QDeepinFileDialogHelper::selectedNameFilter() const { qCDebug(fileDialogHelper) << __FUNCTION__; ensureDialog(); if (filedlgInterface) return filedlgInterface->selectedNameFilter(); return options()->initiallySelectedNameFilter(); } void QDeepinFileDialogHelper::initDBusFileDialogManager() { if (manager) return; if (qEnvironmentVariableIsSet("_d_fileDialogServiceName")) { dialogService = qgetenv("_d_fileDialogServiceName"); } else { dialogService = DIALOG_SERVICE; } const auto *managerObjectPath = "/com/deepin/filemanager/filedialogmanager"; auto conn = QDBusConnection::sessionBus(); auto reply = conn.call(QDBusMessage::createMethodCall(dialogService, managerObjectPath , "org.freedesktop.DBus.Peer", "Ping")); if(reply.type() != QDBusMessage::ReplyMessage) { qCWarning(fileDialogHelper) << reply.errorMessage(); } if (QDBusConnection::sessionBus().interface()->isServiceRegistered(dialogService).value() || !QStandardPaths::findExecutable("dde-desktop").isEmpty()) { manager = new DFileDialogManager(dialogService, managerObjectPath, QDBusConnection::sessionBus()); } } bool QDeepinFileDialogHelper::iAmFileDialogDBusServer() { static bool _value = manager->connection().interface()->servicePid(manager->service()) == static_cast(getpid()); return _value; } void QDeepinFileDialogHelper::ensureDialog() const { if (filedlgInterface) return; if (manager) { QDBusPendingReply reply = manager->createDialog(QString()); reply.waitForFinished(); const QString &path = reply.value().path(); if (path.isEmpty()) { qCWarning(fileDialogHelper) << "Can not create native dialog, Will be use QFileDialog"; } else { filedlgInterface = new DFileDialogHandle(dialogService, path, QDBusConnection::sessionBus()); auxiliaryWindow = new QWindow(); auxiliaryWindow->setObjectName("QDeepinFileDialogHelper_auxiliaryWindow"); connect(filedlgInterface, &QObject::destroyed, auxiliaryWindow, &QWindow::deleteLater); connect(filedlgInterface, &QObject::destroyed, filedlgInterface, &DFileDialogHandle::deleteLater); connect(filedlgInterface, &DFileDialogHandle::accepted, this, &QDeepinFileDialogHelper::accept); connect(filedlgInterface, &DFileDialogHandle::rejected, this, &QDeepinFileDialogHelper::reject); connect(filedlgInterface, &DFileDialogHandle::destroyed, this, &QDeepinFileDialogHelper::reject); connect(filedlgInterface, &DFileDialogHandle::destroyed, this, [this](){ qCWarning(fileDialogHelper) << "filedialog dbus service destroyed."; if (filedlgInterface) { filedlgInterface->QObject::deleteLater(); filedlgInterface = nullptr; } if (auxiliaryWindow && auxiliaryWindow->isModal() && qApp->modalWindow() == auxiliaryWindow) hideAuxiliaryWindow(); }); QTimer *heartbeatTimer = new QTimer(filedlgInterface); connect(heartbeatTimer, &QTimer::timeout, this, [this, heartbeatTimer] { if (!filedlgInterface) return ; QDBusPendingReply<> reply = filedlgInterface->makeHeartbeat(); reply.waitForFinished(); if (reply.isError()) { qCWarning(fileDialogHelper) << "Make heartbeat is failed:" << reply.error(); if (reply.error().type() == QDBusError::UnknownMethod) { qCWarning(fileDialogHelper) << "Make heartbeat is't support for current dbus file dialog, Will be stop heartbeat timer."; heartbeatTimer->stop(); return; } filedlgInterface->QObject::deleteLater(); const_cast(this)->reject(); } }); int heartbeatInterval = filedlgInterface->heartbeatInterval(); heartbeatTimer->setInterval(qMax(1 * 1000, qMin(int(heartbeatInterval / 1.5), heartbeatInterval - 5 * 1000))); heartbeatTimer->start(); } } if (!filedlgInterface && qobject_cast(qGuiApp)) { QDeepinTheme::m_usePlatformNativeDialog = false; } } void QDeepinFileDialogHelper::applyOptions() { QFileDialogOptions *options = this->options().data(); for (int i = 0; i < QFileDialogOptions::DialogLabelCount; ++i) { if (options->isLabelExplicitlySet((QFileDialogOptions::DialogLabel)i)) { if (filedlgInterface) filedlgInterface->setLabelText(i, options->labelText((QFileDialogOptions::DialogLabel)i)); else qCWarning(fileDialogHelper) << "DFileDialogHandle invalid!!"; } } if (filedlgInterface) { filedlgInterface->setOptions(int(options->options())); filedlgInterface->setFilter(int(options->filter())); filedlgInterface->setWindowTitle(options->windowTitle()); filedlgInterface->setViewMode(int(options->viewMode())); filedlgInterface->setFileMode(int(options->fileMode())); filedlgInterface->setAcceptMode(int(options->acceptMode())); filedlgInterface->setNameFilters(options->nameFilters()); } if (options->initialDirectory().isLocalFile()) setDirectory(options->initialDirectory()); foreach (const QUrl &filename, options->initiallySelectedFiles()) selectFile(filename); selectNameFilter(options->initiallySelectedNameFilter()); if (!sourceDialog) { sourceDialog = reinterpret_cast(qvariant_cast(property("_dtk_widget_QFileDialog"))); if (sourceDialog && filedlgInterface) { const QStringList lineedit_list = sourceDialog->property("_dtk_widget_custom_lineedit_list").toStringList(); const QStringList combobox_list = sourceDialog->property("_dtk_widget_custom_combobox_list").toStringList(); filedlgInterface->beginAddCustomWidget(); for (const QString &i : lineedit_list) filedlgInterface->addCustomWidget(LineEditType, i); for (const QString &i : combobox_list) filedlgInterface->addCustomWidget(ComboBoxType, i); filedlgInterface->endAddCustomWidget(); const QVariant & mixedSelection = sourceDialog->property("_dtk_widget_filedialog_mixed_selection"); if (mixedSelection.isValid()) { filedlgInterface->setAllowMixedSelection(mixedSelection.toBool()); } } } } void QDeepinFileDialogHelper::hideAuxiliaryWindow() const { QGuiApplicationPrivate::hideModalWindow(auxiliaryWindow); if (activeWindow) activeWindow->requestActivate(); } QT_END_NAMESPACE qt5integration-5.7.12/platformthemeplugin/qdeepinfiledialoghelper.h000066400000000000000000000040121476226661600257040ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef QDEEPINFILEDIALOGHELPER_H #define QDEEPINFILEDIALOGHELPER_H #include #include #include QT_BEGIN_NAMESPACE class ComDeepinFilemanagerFiledialogInterface; typedef ComDeepinFilemanagerFiledialogInterface DFileDialogHandle; class ComDeepinFilemanagerFiledialogmanagerInterface; typedef ComDeepinFilemanagerFiledialogmanagerInterface DFileDialogManager; class QDeepinFileDialogHelper : public QPlatformFileDialogHelper { public: enum CustomWidgetType { LineEditType = 0, ComboBoxType = 1 }; QDeepinFileDialogHelper(); ~QDeepinFileDialogHelper(); bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) Q_DECL_OVERRIDE; void exec() Q_DECL_OVERRIDE; void hide() Q_DECL_OVERRIDE; bool defaultNameFilterDisables() const Q_DECL_OVERRIDE; void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE; QUrl directory() const Q_DECL_OVERRIDE; void selectFile(const QUrl &filename) Q_DECL_OVERRIDE; QList selectedFiles() const Q_DECL_OVERRIDE; void setFilter() Q_DECL_OVERRIDE; void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE; QString selectedNameFilter() const Q_DECL_OVERRIDE; static void initDBusFileDialogManager(); static bool iAmFileDialogDBusServer(); protected: void onApplicationStateChanged(Qt::ApplicationState state); void onWindowActiveChanged(); private: mutable QPointer filedlgInterface; mutable QPointer auxiliaryWindow; QPointer activeWindow; QPointer sourceDialog; QPointer execLoop; static DFileDialogManager *manager; static QString dialogService; void ensureDialog() const; void applyOptions(); void hideAuxiliaryWindow() const; friend class QDeepinTheme; }; QT_END_NAMESPACE #endif // QDEEPINFILEDIALOGHELPER_H qt5integration-5.7.12/platformthemeplugin/qdeepintheme.cpp000066400000000000000000000651031476226661600240520ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "qdeepintheme.h" #include "qdeepinfiledialoghelper.h" #include "filedialogmanager_interface.h" #include "dthemesettings.h" #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include "../3rdparty/qdbustrayicon_p.h" #endif #include #include #include #include #include #include #define private public #include #undef private #include #include #include #include #include #undef signals #include DGUI_USE_NAMESPACE #ifdef XDG_ICON_VERSION_MAR #include extern void updateXdgIconSystemTheme(); #if XDG_ICON_VERSION_MAR >= 3 namespace DEEPIN_QT_THEME { QThreadStorage colorScheme; void(*setFollowColorScheme)(bool); bool(*followColorScheme)(); } #endif #endif #define DISABLE_UPDATE_WINDOW_GEOMETRY "D_DISABLE_UPDATE_WINDOW_GEOMETRY_FOR_SCALE" #define DNOT_UPDATE_WINDOW_GEOMETRY "_d_disable_update_geometry_for_scale" #define HOOK_UPDATE_WINDOW_GEOMETRY_OBJECT "_d_hookUpdateGeometryForScaleObject" #define UPDATE_WINDOW_GEOMETRY_ENTRY "_d_updateGeometryForScaleEntry" #define UPDATE_WINDOW_GEOMETRY_GEOMETRY "_d_updateGeometryForScaleGeometry" #define UPDATE_WINDOW_GEOMETRY_EXIT "_d_updateGeometryForScaleExit" QT_BEGIN_NAMESPACE const char *QDeepinTheme::name = "deepin"; bool QDeepinTheme::m_usePlatformNativeDialog = true; QMimeDatabase QDeepinTheme::m_mimeDatabase; DThemeSettings *QDeepinTheme::m_settings = 0; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) static bool isDBusTrayAvailable() { static bool dbusTrayAvailable = false; static bool dbusTrayAvailableKnown = false; if (!dbusTrayAvailableKnown) { thirdparty::QDBusMenuConnection conn; if (conn.isStatusNotifierHostRegistered()) dbusTrayAvailable = true; dbusTrayAvailableKnown = true; qCDebug(thirdparty::dLcTray) << "D-Bus tray available:" << dbusTrayAvailable; } return dbusTrayAvailable; } #endif static void onIconThemeSetCallback() { QIconLoader::instance()->updateSystemTheme(); #ifdef XDG_ICON_VERSION_MAR updateXdgIconSystemTheme(); #endif if (qApp->inherits("Dtk::Widget::DApplication")) { // emit the signal: DApplication::iconThemeChanged qApp->metaObject()->invokeMethod(qApp, QT_STRINGIFY(iconThemeChanged)); } // 通知所有窗口重绘制 QEvent update(QEvent::UpdateRequest); for (QWindow *window : qGuiApp->allWindows()) { if (window->type() == Qt::Desktop) continue; qApp->sendEvent(window, &update); } } static inline uint resolveMask(const QFont &f) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) return f.resolve(); #else return f.resolveMask(); #endif } static inline void setResolveMask(QFont &f, uint mask) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) return f.resolve(mask); #else return f.setResolveMask(mask); #endif } static void onFontChanged() { // 插件中初始化 appFont 时会 resolve(0) 即清空 resolve_mask // 如果用户再主动设置字体会改变 resolve_mask 即 app_font->resolve() > 0 // qApp->setFont(resolvedFont) 将不再响应 xsettings 字体变化 if (QGuiApplicationPrivate::app_font && resolveMask(*QGuiApplicationPrivate::app_font)) return; // 先清理旧的font对象 if (QGuiApplicationPrivate::app_font) delete QGuiApplicationPrivate::app_font; QGuiApplicationPrivate::app_font = nullptr; QFont appFont = qGuiApp->font(); // Refresh the font QEvent event(QEvent::ApplicationFontChange); qApp->sendEvent(qApp, &event); // 通知所有窗口字体改变了 for (QWindow *window : qGuiApp->allWindows()) { if (window->type() == Qt::Desktop) continue; qApp->sendEvent(window, &event); } qApp->sendEvent(DGuiApplicationHelper::instance(), &event); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_EMIT qGuiApp->fontChanged(appFont); #else Q_UNUSED(appFont) #endif } static void updateWindowGeometry(QWindow *w) { if (w->type() == Qt::ForeignWindow || w->type() == Qt::Desktop) { return; } if (!w->handle() || !w->isTopLevel()) return; if (w->property(DNOT_UPDATE_WINDOW_GEOMETRY).toBool()) { QWindowSystemInterfacePrivate::GeometryChangeEvent gce(w, QHighDpi::fromNativePixels(w->handle()->geometry(), w) #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) , QRect() #endif ); QGuiApplicationPrivate::processGeometryChangeEvent(&gce); } else {// 通知窗口大小发送改变 const QRect currentGeo = QWindowPrivate::get(w)->geometry; if (!currentGeo.isValid()) return; // 对外提供能hook自动更新窗口大小的方法 QObject *hook_obj = qvariant_cast(w->property(HOOK_UPDATE_WINDOW_GEOMETRY_OBJECT)); if (!hook_obj) { hook_obj = w; } bool accept = true; // 通知窗口即将开始更新其geometry if (hook_obj->metaObject()->indexOfMethod(UPDATE_WINDOW_GEOMETRY_ENTRY "()") >= 0) { QMetaObject::invokeMethod(hook_obj, UPDATE_WINDOW_GEOMETRY_ENTRY, Qt::DirectConnection, Q_RETURN_ARG(bool, accept)); } if (!accept) { // 中断操作 return; } QRect nativeGeo; // 尝试从窗口对象获取新的geometry if (hook_obj->metaObject()->indexOfMethod(UPDATE_WINDOW_GEOMETRY_GEOMETRY "()") >= 0) { QMetaObject::invokeMethod(hook_obj, UPDATE_WINDOW_GEOMETRY_GEOMETRY, Qt::DirectConnection, Q_RETURN_ARG(QRect, nativeGeo)); } if (!nativeGeo.isValid()) { nativeGeo = w->handle()->geometry(); qreal scale = QHighDpiScaling::factor(w); const QPoint &cursor_pos = w->screen()->handle()->cursor()->pos(); // 如果窗口是active的,且鼠标处于窗口内,应当移动窗口位置以保持鼠标相对窗口的位置 if (w->isActive()) { const QMargins &frame_margins = w->handle()->frameMargins(); const QRect &frame_rect = nativeGeo.marginsAdded(frame_margins); if (frame_rect.contains(cursor_pos)) { nativeGeo.moveTopLeft(cursor_pos + (nativeGeo.topLeft() - cursor_pos) * currentGeo.width() * scale / nativeGeo.width()); } } nativeGeo.setSize(currentGeo.size() * scale); } bool positionAutomaticSave = QWindowPrivate::get(w)->positionAutomatic; QWindowPrivate::get(w)->positionAutomatic = false; w->handle()->setGeometry(nativeGeo); QWindowPrivate::get(w)->positionAutomatic = positionAutomaticSave; // 请求重绘 QGuiApplication::sendEvent(w, new QEvent(QEvent::UpdateRequest)); // 通知窗口geometry更新结束 if (hook_obj->metaObject()->indexOfMethod(UPDATE_WINDOW_GEOMETRY_EXIT "()") >= 0) { QMetaObject::invokeMethod(hook_obj, UPDATE_WINDOW_GEOMETRY_EXIT); } } } static void updateAllWindowGeometry() { for (QWindow *w : qGuiApp->allWindows()) { updateWindowGeometry(w); } } // 延迟一段时间更新窗口geometry,防止屏幕缩放比在短时间内连续变化时导致窗口闪动 static void updateAllWindowGeometryDelay(int interval = 500) { static QTimer *t = new QTimer(); t->setSingleShot(true); t->setInterval(interval); t->connect(t, &QTimer::timeout, t, updateAllWindowGeometry, Qt::UniqueConnection); t->start(); } static void notifyScreenScaleUpdated() { for (QScreen *s : qGuiApp->screens()) { Q_EMIT s->geometryChanged(s->geometry()); // 发射信号通知屏幕缩放比发生变化,DApplication中会定义此信号 if (qGuiApp->metaObject()->indexOfSignal("screenDevicePixelRatioChanged(QScreen*)")) { qGuiApp->metaObject()->invokeMethod(qGuiApp, "screenDevicePixelRatioChanged", Q_ARG(QScreen*, s)); } } } static bool updateScaleFactor(qreal value) { if (qIsNull(value)) { value = 1.0; } if (qFuzzyCompare(QHighDpiScaling::m_factor, value)) { return false; } QHighDpiScaling::setGlobalFactor(value); return true; } static void onScaleFactorChanged(qreal value) { if (updateScaleFactor(value)) { notifyScreenScaleUpdated(); updateAllWindowGeometryDelay(); } } // 用于窗口屏幕改变时更新窗口大小 class AutoScaleWindowObject : public QObject { Q_OBJECT public: explicit AutoScaleWindowObject(QObject *parent = nullptr) : QObject(parent) { qGuiApp->installEventFilter(this); } void onScreenChanged(QScreen *s) { Q_UNUSED(s); if (QWindow *w = qobject_cast(sender())) { updateWindowGeometry(w); } } private: bool eventFilter(QObject *watched, QEvent *event) override { if (event->type() != QEvent::PlatformSurface) return false; if (QWindow *w = qobject_cast(watched)) { QPlatformSurfaceEvent *se = static_cast(event); if (se->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) { // 监听窗口屏幕变化信号,自动根据新的屏幕缩放比更新窗口大小 connect(w, &QWindow::screenChanged, this, &AutoScaleWindowObject::onScreenChanged, Qt::DirectConnection); } else { disconnect(w, &QWindow::screenChanged, this, &AutoScaleWindowObject::onScreenChanged); } } return false; } }; // 判断ScreenScaleFactor的值是否应该应用于所有屏幕 static bool isGenericScreenScaleFactors(const QByteArray &value) { for (char ch : value) { if (ch == '=' || ch == ';') return false; } return true; } static void onAutoScaleWindowChanged() { bool on = QDeepinTheme::getSettings()->autoScaleWindow(); if (on) { const QByteArray &multi_scale = QDeepinTheme::getSettings()->screenScaleFactors(); // 只在针对多个屏幕分别设置了缩放比时开启此功能 if (isGenericScreenScaleFactors(multi_scale)) { on = false; } } static AutoScaleWindowObject *event_fileter = nullptr; if (on) { if (event_fileter) return; event_fileter = new AutoScaleWindowObject(qGuiApp); } else { if (!event_fileter) return; event_fileter->deleteLater(); event_fileter = nullptr; } } // 使用 QT_SCREEN_SCALE_FACTORS 为每个屏幕设置不同的缩放比之后,Qt会自动将 dpi 除以主屏的 // 缩放倍数,以此来避免字体被放大。font dpi会影响未设置pixel size的QFont,默认情况下, // QGuiApplication::font() 不会设置pixel size,因此,使用分屏幕设置不同缩放比后,字体却还 // 是缩放前的大小。 // 此处,如果设置了 ScreenScaleFactors,但未指定 ScaleLogcailDpi 时,默认将其重设回主屏 // 的 logicalDpi。 static bool updateScaleLogcailDpi(const QPair &dpi) { bool ok = dpi.first >= 0 && dpi.second >= 0; #if QT_VERSION < QT_VERSION_CHECK(5,14,0) if (dpi.first > 0) { QHighDpiScaling::m_logicalDpi.first = dpi.first; } else if (qIsNull(dpi.first)) { QHighDpiScaling::m_logicalDpi.first = qGuiApp->primaryScreen()->handle()->logicalDpi().first; } if (dpi.second > 0) { QHighDpiScaling::m_logicalDpi.second = dpi.second; } else if (qIsNull(dpi.second)) { QHighDpiScaling::m_logicalDpi.second = qGuiApp->primaryScreen()->handle()->logicalDpi().second; } #elif QT_VERSION < QT_VERSION_CHECK(6,0,0) QHighDpiScaling::m_usePixelDensity = false; // Do not use dpi from platform plugin #else QHighDpiScaling::m_usePlatformPluginDpi = false; // Do not use dpi from platform plugin #endif return ok; } static QByteArray getEnvValueByScreenScaleFactors(const QByteArray &data) { QByteArray envValue; if (!isGenericScreenScaleFactors(data)) { envValue = data; } else if (!data.isEmpty()) { // 这种情况下,在Qt的实现中,只会将值应用给第一个屏幕,因此此处需要给所有屏幕都设置通用的值 int screen_count = qApp->screens().count(); // 为除了最后一个屏幕的其它屏幕添加缩放比 while (--screen_count) { envValue.append(data).append(';'); } // 为最后一个屏幕添加缩放比 envValue.append(data); } return envValue; } static bool updateScreenScaleFactors(DThemeSettings *s, const QByteArray &value, bool unsetenv = false) { const QByteArray &envValue = getEnvValueByScreenScaleFactors(value); if (qgetenv("QT_SCREEN_SCALE_FACTORS") == envValue) return false; if (envValue.isEmpty()) { if (!unsetenv) return false; qunsetenv("QT_SCREEN_SCALE_FACTORS"); } else { qputenv("QT_SCREEN_SCALE_FACTORS", envValue); } QHighDpiScaling::updateHighDpiScaling(); #if QT_VERSION < QT_VERSION_CHECK(5,14,0) qDebug() << QHighDpiScaling::logicalDpi(); #else qDebug() << QHighDpiScaling::logicalDpi(QGuiApplication::primaryScreen()); #endif updateScaleLogcailDpi(s->scaleLogicalDpi()); #if QT_VERSION < QT_VERSION_CHECK(5,14,0) qDebug() << QHighDpiScaling::logicalDpi(); #else qDebug() << QHighDpiScaling::logicalDpi(QGuiApplication::primaryScreen()); #endif return true; } static void onScreenScaleFactorsChanged(const QByteArray &value) { if (updateScreenScaleFactors(QDeepinTheme::getSettings(), value, true)) { notifyScreenScaleUpdated(); updateAllWindowGeometryDelay(); } } static bool enabledRTScreenScale() { #if QT_VERSION < QT_VERSION_CHECK(6,0,0) // 应用中设置了和屏幕缩放相关的环境变量或启动相关属性后后不开启自动缩放功能 static bool enable = !qEnvironmentVariableIsSet("D_DISABLE_RT_SCREEN_SCALE") && !qEnvironmentVariableIsSet("QT_DEVICE_PIXEL_RATIO") && !qEnvironmentVariableIsSet("QT_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS") && !QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling) && !QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling) && qGuiApp->platformName().endsWith("xcb"); #else static bool enable = false; // TODO What is the enable logic under Qt6 when Qt::AA_EnableHighDpiScaling is always true #endif return enable; } QDeepinTheme::QDeepinTheme() { #if XDG_ICON_VERSION_MAR >= 3 // 注意!!!, 此处还没有开始启动事件循环, 很多Qt类无法使用, 例如QTimer DEEPIN_QT_THEME::setFollowColorScheme = XdgIcon::setFollowColorScheme; DEEPIN_QT_THEME::followColorScheme = XdgIcon::followColorScheme; #endif if (enabledRTScreenScale()) { QScopedPointer setting(new DThemeSettings(false)); // 程序启动时初始设置屏幕缩放比 updateScaleFactor(setting->scaleFactor()); if (!updateScreenScaleFactors(setting.data(), setting->screenScaleFactors())) { updateScaleLogcailDpi(setting->scaleLogicalDpi()); } } } QDeepinTheme::~QDeepinTheme() { if (QDeepinFileDialogHelper::manager) { QDeepinFileDialogHelper::manager->deleteLater(); QDeepinFileDialogHelper::manager = Q_NULLPTR; } } bool QDeepinTheme::usePlatformNativeDialog(DialogType type) const { if (type == FileDialog) { if (qgetenv("_d_disableDBusFileDialog") == "true") return false; static bool dbusDialogManagerInitialized = false; if (!dbusDialogManagerInitialized) { dbusDialogManagerInitialized = true; QDeepinFileDialogHelper::initDBusFileDialogManager(); } return m_usePlatformNativeDialog && QDeepinFileDialogHelper::manager && QDeepinFileDialogHelper::manager->isUseFileChooserDialog(); } return QGenericUnixTheme::usePlatformNativeDialog(type); } QPlatformDialogHelper *QDeepinTheme::createPlatformDialogHelper(DialogType type) const { if (type == FileDialog && usePlatformNativeDialog(type)) return new QDeepinFileDialogHelper(); return QGenericUnixTheme::createPlatformDialogHelper(type); } static QIconEnginePlugin *getIconEngineFactory(const QString &key) { static QFactoryLoader loader(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseSensitive); int index = loader.indexOf(key); if (index != -1) return qobject_cast(loader.instance(index)); return nullptr; } static QIconEngine *createIconEngineWithKey(const QString &iconName, const QString &key) { QIconEnginePlugin *plugin = getIconEngineFactory(key); if (!plugin) return nullptr; QIconEngine *iconEngine = plugin->create(iconName); if (!iconEngine) return nullptr; if (iconEngine->isNull()) { delete iconEngine; return nullptr; } return iconEngine; } QIconEngine *QDeepinTheme::createIconEngine(const QString &iconName) const { QIconEngine *engine = createIconEngineWithKey(iconName, "DIconProxyEngine"); return engine ? engine : QGenericUnixTheme::createIconEngine(iconName); } QPixmap QDeepinTheme::standardPixmap(QPlatformTheme::StandardPixmap sp, const QSizeF &size) const { return QGenericUnixTheme::standardPixmap(sp, size); } #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) QIcon QDeepinTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const { Q_UNUSED(iconOptions); return QIcon::fromTheme(m_mimeDatabase.mimeTypeForFile(fileInfo).iconName()); } #else QPixmap QDeepinTheme::fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, QPlatformTheme::IconOptions iconOptions) const { Q_UNUSED(iconOptions); return QIcon::fromTheme(m_mimeDatabase.mimeTypeForFile(fileInfo).iconName()).pixmap(size.toSize()); } #endif #if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPlatformSystemTrayIcon *QDeepinTheme::createPlatformSystemTrayIcon() const { if (isDBusTrayAvailable()) return new thirdparty::QDBusTrayIcon(); return nullptr; } #endif static DPlatformTheme *appTheme() { static QPointer theme; if (!theme) { theme = DGuiApplicationHelper::instance()->applicationTheme(); QObject::connect(theme, &DPlatformTheme::iconThemeNameChanged, &onIconThemeSetCallback); QObject::connect(theme, &DPlatformTheme::fontNameChanged, &onFontChanged); QObject::connect(theme, &DPlatformTheme::fontPointSizeChanged, [] { if (theme->fontName().isEmpty()) return; onFontChanged(); }); QObject::connect(theme, &DPlatformTheme::gtkFontNameChanged, [] { if (theme->fontName().isEmpty()) { onFontChanged(); } }); } return theme; } QVariant QDeepinTheme::themeHint(QPlatformTheme::ThemeHint hint) const { switch (hint) { case QPlatformTheme::StyleNames: { return QStringList({"chameleon", "fusion"}); } case QPlatformTheme::SystemIconThemeName: return appTheme()->iconThemeName(); case QPlatformTheme::SystemIconFallbackThemeName: return "bloom"; case QPlatformTheme::IconThemeSearchPaths: return QVariant(QGenericUnixTheme::xdgIconThemePaths() << QDir::homePath() + "/.local/share/icons"); case UseFullScreenForPopupMenu: return true; case ShowShortcutsInContextMenus: return false; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) case ButtonPressKeys: return QVariant::fromValue(QList({ Qt::Key_Enter, Qt::Key_Return, Qt::Key_Space, Qt::Key_Select } )); #endif default: break; } return QGenericUnixTheme::themeHint(hint); } const QPalette *QDeepinTheme::palette(QPlatformTheme::Palette type) const { if (type != SystemPalette) { return QGenericUnixTheme::palette(type); } static QPalette palette; palette = DGuiApplicationHelper::instance()->applicationPalette(); return &palette; } static QFont *createUnresolveFont(const QString &family, qreal pointSize) { auto font = new QFont(family); font->setPointSizeF(pointSize); setResolveMask(*font, QFont::NoPropertiesResolved); return font; } const QFont *QDeepinTheme::font(QPlatformTheme::Font type) const { if (!qApp->desktopSettingsAware()) return QGenericUnixTheme::font(type); switch (type) { case SystemFont: if (DPlatformTheme *theme = appTheme()) { QByteArray font_name = theme->fontName(); qreal font_size = 0; static QScopedPointer sysFont; if (font_name.isEmpty()) { font_name = theme->gtkFontName(); int font_size_index = font_name.lastIndexOf(' '); if (font_size_index <= 0) { const QFont *defaultFont = QGenericUnixTheme::font(type); sysFont.reset(createUnresolveFont(defaultFont->family(), defaultFont->pointSizeF())); return sysFont.data(); } font_size = font_name.mid(font_size_index + 1).toDouble(); font_name = font_name.left(font_size_index); } else { font_size = theme->fontPointSize(); } if (font_size <= 0) { font_size = 10.5; } // We need to re-contruct a new QFont each time, inorder to refresh font dpi sysFont.reset(createUnresolveFont(font_name, font_size)); return sysFont.data(); } break; case FixedFont: { if (DPlatformTheme *theme = appTheme()) { QByteArray font_name = theme->monoFontName(); static QScopedPointer fixedFont; if (font_name.isEmpty()) { const QFont *defaultFont = QGenericUnixTheme::font(type); fixedFont.reset(createUnresolveFont(defaultFont->family(), defaultFont->pointSizeF())); return fixedFont.data(); } qreal font_size = theme->fontPointSize(); if (font_size <= 0) { font_size = 10.5; } // We need to re-contruct a new QFont each time, inorder to refresh font dpi fixedFont.reset(createUnresolveFont(font_name, font_size)); return fixedFont.data(); } break; } default: break; } return QGenericUnixTheme::font(type); } static void compelledUpdateScaleLogcailDpi() { updateScaleLogcailDpi(QDeepinTheme::getSettings()->scaleLogicalDpi()); } static void onScreenAdded(QScreen *s) { if (QHighDpiScaling::m_screenFactorSet) { auto setting = QDeepinTheme::getSettings(); auto value = setting->screenScaleFactors(); if (!value.isEmpty() && isGenericScreenScaleFactors(value)) { const QByteArray &envValue = getEnvValueByScreenScaleFactors(value); qputenv("QT_SCREEN_SCALE_FACTORS", envValue); bool ok = false; qreal scale = value.toDouble(&ok); // 为新的屏幕设置缩放比 if (ok) QHighDpiScaling::setScreenFactor(s, scale); } } compelledUpdateScaleLogcailDpi(); } DThemeSettings *QDeepinTheme::settings() const { if (!m_settings) { m_settings = new DThemeSettings(); qApp->setProperty("_d_theme_settings_object", (quintptr)m_settings); if (enabledRTScreenScale()) { #ifdef QT_NO_DEBUG if (!qEnvironmentVariableIsSet("D_ENABLE_RT_SCALE")) return m_settings; #endif QObject::connect(m_settings, &DThemeSettings::scaleFactorChanged, m_settings, onScaleFactorChanged, Qt::UniqueConnection); QObject::connect(m_settings, &DThemeSettings::screenScaleFactorsChanged, m_settings, onScreenScaleFactorsChanged, Qt::UniqueConnection); QObject::connect(m_settings, &DThemeSettings::scaleLogicalDpiChanged, m_settings, updateScaleLogcailDpi, Qt::UniqueConnection); // 当屏幕connected时,Qt库中会更新缩放值,导致dpi的设置被覆盖,此处应该再重新设置dpi值。 // TODO(zccrs): 当最后一个屏幕disconnectd时,Qt不会移除它,在这种状态下,插入一个新的 // 屏幕时,Qt只会更新遗留的screen对象的信息,因此不会有screenAdded信号, // 而且同样会更新dpi的值,因为目前无法通过Qt api检测到此状态,所以这种情 // 况下无法自动更新dpi值,将导致应用字体显示大小不受缩放比控制。 // !!! // 针对 dtk 应用,将在dxcb插件中通知应用更新dpi值。 qApp->setProperty("_d_updateScaleLogcailDpi", (quintptr)&compelledUpdateScaleLogcailDpi); QObject::connect(qApp, &QGuiApplication::screenAdded, m_settings, onScreenAdded, Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection)); if (!qEnvironmentVariableIsSet(DISABLE_UPDATE_WINDOW_GEOMETRY)) { QObject::connect(m_settings, &DThemeSettings::autoScaleWindowChanged, m_settings, onAutoScaleWindowChanged, Qt::UniqueConnection); QObject::connect(m_settings, &DThemeSettings::screenScaleFactorsChanged, m_settings, onAutoScaleWindowChanged, Qt::UniqueConnection); onAutoScaleWindowChanged(); } } } return m_settings; } DThemeSettings *QDeepinTheme::getSettings() { return m_settings; } QT_END_NAMESPACE #include "qdeepintheme.moc" qt5integration-5.7.12/platformthemeplugin/qdeepintheme.h000066400000000000000000000034771476226661600235250ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017-2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef QDEEPINTHEME_H #define QDEEPINTHEME_H #include #include #include #include class DThemeSettings; class QDeepinTheme : public QGenericUnixTheme { public: QDeepinTheme(); ~QDeepinTheme(); bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE; QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE; QIconEngine *createIconEngine(const QString &iconName) const Q_DECL_OVERRIDE; QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE; #if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = {}) const Q_DECL_OVERRIDE; #else QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, QPlatformTheme::IconOptions iconOptions = 0) const Q_DECL_OVERRIDE; #endif #if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override; #endif QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE; const QPalette *palette(Palette type) const override; const QFont *font(Font type) const Q_DECL_OVERRIDE; DThemeSettings *settings() const; static DThemeSettings *getSettings(); static const char *name; private: static bool m_usePlatformNativeDialog; static QMimeDatabase m_mimeDatabase; static DThemeSettings *m_settings; friend class QDeepinFileDialogHelper; friend class QDeepinPlatformMenu; }; #endif // QDEEPINTHEME_H qt5integration-5.7.12/platformthemeplugin/qtquickcontrols2.conf000066400000000000000000000000321476226661600250620ustar00rootroot00000000000000[Controls] Style=Chameleonqt5integration-5.7.12/platformthemeplugin/xmls/000077500000000000000000000000001476226661600216545ustar00rootroot00000000000000qt5integration-5.7.12/platformthemeplugin/xmls/com.deepin.filemanager.filedialog.xml000066400000000000000000000115671476226661600310000ustar00rootroot00000000000000 qt5integration-5.7.12/platformthemeplugin/xmls/com.deepin.filemanager.filedialogmanager.xml000066400000000000000000000014341476226661600323230ustar00rootroot00000000000000 qt5integration-5.7.12/rpm/000077500000000000000000000000001476226661600154015ustar00rootroot00000000000000qt5integration-5.7.12/rpm/deepin-qt5integration.spec000066400000000000000000000046231476226661600225010ustar00rootroot00000000000000%global repo qt5integration Name: deepin-qt5integration Version: 5.1.5 Release: 1%{?dist} Summary: Qt platform theme integration plugins for DDE # The entire source code is GPLv3+ except styles/ which is BSD, # styleplugins/dstyleplugin/dstyleanimation* which is LGPL License: GPLv3+ and BSD and LGPLv2+ URL: https://github.com/linuxdeepin/qt5integration Source0: %{url}/archive/%{version}/%{repo}-%{version}.tar.gz BuildRequires: gcc-c++ BuildRequires: pkgconfig(atk) BuildRequires: pkgconfig(dtkcore) BuildRequires: pkgconfig(dtkwidget) >= 2.0.6 BuildRequires: pkgconfig(fontconfig) BuildRequires: pkgconfig(freetype2) BuildRequires: pkgconfig(gtk+-2.0) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gdk-pixbuf-2.0) BuildRequires: pkgconfig(ice) BuildRequires: pkgconfig(libinput) BuildRequires: pkgconfig(libudev) BuildRequires: pkgconfig(pango) BuildRequires: pkgconfig(Qt5Core) BuildRequires: pkgconfig(Qt5OpenGL) BuildRequires: pkgconfig(Qt5Svg) BuildRequires: pkgconfig(Qt5Xdg) >= 3.0.0 BuildRequires: pkgconfig(Qt5X11Extras) BuildRequires: pkgconfig(x11) BuildRequires: pkgconfig(xext) BuildRequires: pkgconfig(xrender) BuildRequires: pkgconfig(xcb) BuildRequires: pkgconfig(mtdev) BuildRequires: pkgconfig(Qt5Multimedia) BuildRequires: pkgconfig(Qt5MultimediaWidgets) BuildRequires: qt5-qtbase-common # for libQt5ThemeSupport.a BuildRequires: qt5-qtbase-static BuildRequires: qt5-qtbase-private-devel BuildRequires: make %{?_qt5:Requires: %{_qt5}%{?_isa} = %{_qt5_version}} Requires: deepin-qt5dxcb-plugin%{?_isa} %description Multiple Qt plugins to provide better Qt5 integration for DDE is included. %prep %autosetup -p1 -n %{repo}-%{version} %build %qmake_qt5 PREFIX=%{_prefix} BASED_DTK_DIR=based-dtk %make_build %install %make_install INSTALL_ROOT=%{buildroot} %files %doc README.md %license LICENSE # chooser %{_qt5_plugindir}/platformthemes/libqdeepin.so %{_qt5_plugindir}/iconengines/libdsvgicon.so %{_qt5_plugindir}/imageformats/libdsvg.so %{_qt5_plugindir}/iconengines/libdtkbuiltin.so %{_qt5_plugindir}/styles/libchameleon.so # target %{_qt5_plugindir}/platformthemes/based-dtk/libqdeepin.so %{_qt5_plugindir}/iconengines/based-dtk/libdsvgicon.so %{_qt5_plugindir}/imageformats/based-dtk/libdsvg.so %{_qt5_plugindir}/iconengines/based-dtk/libdtkbuiltin.so %{_qt5_plugindir}/styles/based-dtk/libchameleon.so %changelog qt5integration-5.7.12/styleplugins/000077500000000000000000000000001476226661600173455ustar00rootroot00000000000000qt5integration-5.7.12/styleplugins/CMakeLists.txt000066400000000000000000000002221476226661600221010ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later add_subdirectory(chameleon) qt5integration-5.7.12/styleplugins/chameleon/000077500000000000000000000000001476226661600213005ustar00rootroot00000000000000qt5integration-5.7.12/styleplugins/chameleon/CMakeLists.txt000066400000000000000000000011521476226661600240370ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later dtk_add_plugin( NAME chameleon OUTPUT_DIR ${PLUGIN_OUTPUT_BASE_DIR}/styles INSTALL_DIR ${PLUGIN_INSTALL_BASE_DIR}/styles SOURCES main.cpp chameleonstyle.cpp dstyleanimation.cpp HEADERS chameleonstyle.h common.h dstyleanimation.h DEPENDENCIES Dtk${VERSION_SUFFIX}::Widget Qt${QT_VERSION_MAJOR}::CorePrivate Qt${QT_VERSION_MAJOR}::GuiPrivate Qt${QT_VERSION_MAJOR}::WidgetsPrivate ) qt5integration-5.7.12/styleplugins/chameleon/chameleon.json000066400000000000000000000000371476226661600241260ustar00rootroot00000000000000{ "Keys" : ["chameleon"] } qt5integration-5.7.12/styleplugins/chameleon/chameleonstyle.cpp000066400000000000000000006704471476226661600250420ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2024 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "chameleonstyle.h" #include "common.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dstyleanimation.h" DGUI_USE_NAMESPACE DWIDGET_USE_NAMESPACE namespace chameleon { // 判断是TabBar否为竖直方向 inline static bool verticalTabs(QTabBar::Shape shape) { return shape == QTabBar::RoundedWest || shape == QTabBar::RoundedEast || shape == QTabBar::TriangularWest || shape == QTabBar::TriangularEast; } inline static int menuItemShortcutWidth(const QStyleOptionMenuItem *menuItem) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) return menuItem->reservedShortcutWidth; #else return menuItem->tabWidth; #endif } static QWidget *getSbarParentWidget(QScrollBar *sbar) { if (!sbar) return nullptr; QWidget *pw = sbar->parentWidget(); if (!pw) return nullptr; bool isContainer = !pw->objectName().compare(QLatin1String("qt_scrollarea_vcontainer")) || !pw->objectName().compare(QLatin1String("qt_scrollarea_hcontainer")) ; return isContainer ? pw->parentWidget() : pw; } static inline bool hoveredOrPressed(const QStyleOption *opt) { return opt->state.testFlag(QStyle::State_MouseOver) || opt->state.testFlag(QStyle::State_Sunken); } // Calculating indicator's size for spinbox. static QRect spinboxIndicatorRect(const QRect &r) { int size = qMin(r.width(), r.height()); int xOffset = r.x() + (r.width() - size) / 2; int yOffset = r.y() + (r.height() - size) / 2; return QRect(xOffset, yOffset, size, size); } // the object is the class's instance. template inline static bool isTheClassObject(QObject *object) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) return object->metaObject()->className() == T::staticMetaObject.className(); #else return object->metaObject()->metaType() == T::staticMetaObject.metaType(); #endif } ChameleonMovementAnimation::ChameleonMovementAnimation(QWidget *targetWidget) : QVariantAnimation(targetWidget) { setDuration(150); connect(this, &QVariantAnimation::valueChanged, targetWidget, [this] (const QVariant &value) { if (!isRuning()) return; const auto rect = value.toRect(); Q_ASSERT(!m_currentRect.isEmpty()); this->targetWidget()->update(m_currentRect.united(rect)); m_currentRect = rect; }); connect(this, &QVariantAnimation::finished, targetWidget, [this] { Q_ASSERT(m_currentRect == m_targetRect); // 确保动画结束后有一帧的刷新,因为在菜单的动画过程中会修改菜单文字的 opacity // 对opacity的修改会根据是否处于动画状态进行判断,因此要确保动画结束后刷新它 this->targetWidget()->update(m_currentRect); }); } QWidget *ChameleonMovementAnimation::targetWidget() const { return qobject_cast(parent()); } void ChameleonMovementAnimation::setTargetRect(const QRect &rect) { if (m_targetRect == rect) return; m_lastTargetRect = m_targetRect; m_targetRect = rect; if (m_currentRect.isEmpty()) m_currentRect = m_lastTargetRect; // 当目标绘制区域改变时,说明当前正在进行的动画过期了,应该重新开始动画 stop(); setStartValue(m_currentRect); setEndValue(rect); if (!m_currentRect.isEmpty()) { start(); } else { // 这种情况说明不需要进行动画,往往发生在首次显示,这时候应该直接绘制到目标区域 m_currentRect = rect; } } void ChameleonMovementAnimation::setCurrentRect(const QRect &rect) { if (m_currentRect == rect) return; m_currentRect = rect; m_targetRect = QRect(); } ChameleonStyle::ChameleonStyle() : DStyle() { } static QColor getThemTypeColor(QColor lightColor, QColor darkColor) { if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) return lightColor; else return darkColor; } static DDciIconPalette makeIconPalette(const QPalette &pal) { DDciIconPalette iconPalette; iconPalette.setForeground(pal.color(QPalette::WindowText)); iconPalette.setBackground(pal.color(QPalette::Window)); iconPalette.setHighlight(pal.color(QPalette::Highlight)); iconPalette.setHighlightForeground(pal.color(QPalette::HighlightedText)); return iconPalette; } static void playDci(DDciIconPlayer *player, const DDciIcon &icon, DDciIcon::Mode mode) { player->setIcon(icon); player->play(mode); } void ChameleonStyle::drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const { switch (static_cast(pe)) { case PE_PanelButtonCommand: { // qDebug() << "### pushbutton state " << (int)opt->state; const QMargins &margins = frameExtentMargins(); // checked if (opt->state & State_On) { p->setBrush(getColor(opt, QPalette::Highlight)); } else { drawShadow(p, opt->rect - margins, getColor(opt, QPalette::Shadow)); // 初始化button的渐变背景色 QLinearGradient lg(QPointF(0, opt->rect.top()), QPointF(0, opt->rect.bottom())); lg.setColorAt(0, getColor(opt, QPalette::Light)); lg.setColorAt(1, getColor(opt, QPalette::Dark)); p->setBrush(lg); } p->setPen(Qt::NoPen); p->setRenderHint(QPainter::Antialiasing); int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); p->drawRoundedRect(opt->rect - margins, frame_radius, frame_radius); // draw border,border应该是完全叠加到按钮的背景上 p->setPen(QPen(getColor(opt, DPalette::FrameBorder, w), Metrics::Painter_PenWidth)); p->setBrush(Qt::NoBrush); const QMarginsF border_margins(Metrics::Painter_PenWidth, Metrics::Painter_PenWidth, Metrics::Painter_PenWidth, Metrics::Painter_PenWidth); p->drawRoundedRect(QRectF(opt->rect) - margins - border_margins / 2.0, frame_radius, frame_radius); return; } case PE_FrameFocusRect: { //设计要求QTreeView选中整行,这里不绘制focus rect if (qobject_cast(w)) { return; } //QListView不需要绘制focus rect if (qobject_cast(w)) { return; } if (w && w->property("_d_dtk_noFocusRect").toBool()) return; //设计要求DDateTimeEdit focus只绘制边缘 if (qobject_cast(w) && qobject_cast(w->parentWidget())) { return; } drawBorder(p, opt, w); return; } case PE_PanelItemViewItem: { if (w && w->objectName() == "qt_calendar_calendarview") { if (opt->state & QStyle::State_Selected) { QRect textRect = opt->rect; textRect.setWidth(textRect.height()); p->setBrush(opt->palette.brush(QPalette::Highlight)); textRect.moveCenter(opt->rect.center()); p->setPen(Qt::NoPen); p->setRenderHint(QPainter::Antialiasing); p->drawEllipse(textRect.adjusted(1, 1, -1, -1)); } return; } //QTreeView的绘制复制了QCommonStyle的代码,添加了圆角的处理,hover的处理 if (qobject_cast(w)) { const auto delegate = qobject_cast(w)->itemDelegate(); //如果QTreeView使用的不是默认代理 QStyledItemDelegate,则采取DStyle的默认绘制(备注:这里的QtCreator不会有hover效果和圆角) if (!isTheClassObject(delegate)) { break; } if (const QStyleOptionViewItem *vopt = qstyleoption_cast(opt)) { QPalette::ColorGroup cg = (w ? w->isEnabled() : (vopt->state & QStyle::State_Enabled)) ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) cg = QPalette::Inactive; int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); if (vopt->showDecorationSelected && (vopt->state & (QStyle::State_Selected | QStyle::State_MouseOver))) { p->setRenderHint(QPainter::Antialiasing, true); p->setPen(Qt::NoPen); p->setBrush(vopt->palette.brush(cg, (vopt->state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Midlight)); if ((vopt->state & QStyle::State_Selected) && (vopt->state & QStyle::State_MouseOver)) { p->setBrush(p->brush().color().lighter(120)); } //只对最后一列的item绘制圆角 if (vopt->viewItemPosition == QStyleOptionViewItem::End || vopt->viewItemPosition == QStyleOptionViewItem::OnlyOne) { p->drawRoundedRect(vopt->rect.adjusted(-frame_radius, 0, 0, 0), frame_radius, frame_radius); } else if (vopt->viewItemPosition != QStyleOptionViewItem::Invalid) { p->drawRoundedRect(vopt->rect.adjusted(-frame_radius, 0, frame_radius, 0), frame_radius, frame_radius); } } else { if (vopt->backgroundBrush.style() != Qt::NoBrush) { QPointF oldBO = p->brushOrigin(); p->setBrushOrigin(vopt->rect.topLeft()); p->fillRect(vopt->rect, vopt->backgroundBrush); p->setBrushOrigin(oldBO); } if (vopt->state & QStyle::State_Selected) { QRect textRect = subElementRect(QStyle::SE_ItemViewItemText, opt, w); p->fillRect(textRect, vopt->palette.brush(cg, QPalette::Highlight)); } } } return; } if (drawTableViewItem(pe, opt, p, w)) return; if (const QStyleOptionViewItem *vopt = qstyleoption_cast(opt)) { int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); if (vopt->state & QStyle::State_Selected) { QRect select_rect = opt->rect; if (!vopt->showDecorationSelected) { select_rect = proxy()->subElementRect(QStyle::SE_ItemViewItemText, opt, w); } p->setPen(Qt::NoPen); p->setBrush(getColor(opt, QPalette::Highlight)); p->setRenderHint(QPainter::Antialiasing); p->drawRoundedRect(select_rect, frame_radius, frame_radius); return; } else { if (vopt->backgroundBrush.style() != Qt::NoBrush) { p->save(); p->setPen(Qt::NoPen); p->setBrush(vopt->backgroundBrush); p->setRenderHint(QPainter::Antialiasing); p->drawRoundedRect(opt->rect, frame_radius, frame_radius); p->restore(); return; } } } break; } case PE_PanelLineEdit: { if (w && w->parentWidget()) { //lineEdit作为子控件时不进行绘制 if (qobject_cast(w->parent())) return; if (auto edit = qobject_cast(w->parentWidget())) { if (edit->calendarPopup()) return; } } if (auto fopt = qstyleoption_cast(opt)) { // Flat时不绘制输入框的背景 if (fopt->features == QStyleOptionFrame::Flat) { if (opt->state.testFlag(QStyle::State_HasFocus)) { proxy()->drawPrimitive(PE_FrameFocusRect, opt, p, w); } return; } if (fopt->lineWidth > 0) { proxy()->drawPrimitive(PE_FrameLineEdit, fopt, p, w); } } // 此处设置painter的行为不应该影响外面的绘制,会导致lineedit光标不对 Bug-20967。 p->save(); bool isTransBg = false; if (w) { auto prop = w->property("_d_dtk_lineedit_opacity"); if (prop.isValid()) { isTransBg = prop.toBool(); } else { const auto windowFlags = w->window()->windowFlags(); const bool hasTransAttr = w->window()->testAttribute(Qt::WA_TranslucentBackground); const bool isDialog = windowFlags.testFlag(Qt::Dialog); const bool isPopup = windowFlags.testFlag(Qt::Popup); // if we set palette to lineedit (e.g. DLineEdit::setAlert ) const bool isResolved = opt->palette.isBrushSet(QPalette::Current, QPalette::Button); isTransBg = hasTransAttr && isDialog && !isPopup && !isResolved; } } if (isTransBg) p->setBrush(getThemTypeColor(QColor(0, 0, 0, 255* 0.08), QColor(255, 255, 255, 255 * 0.15))); else p->setBrush(opt->palette.button()); p->setPen(Qt::NoPen); p->setRenderHints(QPainter::Antialiasing); int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); if ((w && qobject_cast(w->parentWidget()))) { if (w->parentWidget()->property("_d_dtk_spinBox").toBool()) { DDrawUtils::drawRoundedRect(p, opt->rect, frame_radius, frame_radius, DDrawUtils::TopLeftCorner | DDrawUtils::BottomLeftCorner); } else { p->drawRoundedRect(opt->rect - frameExtentMargins(), frame_radius, frame_radius); } } else { p->drawRoundedRect(opt->rect, frame_radius, frame_radius); } if (opt->state.testFlag(QStyle::State_HasFocus)) { proxy()->drawPrimitive(PE_FrameFocusRect, opt, p, w); } p->restore(); return; } case PE_FrameLineEdit: { // lineedit no frame return; } case PE_IndicatorRadioButton: { if (ENABLE_ANIMATIONS && ENABLE_ANIMATION_RADIOBUTTON) { auto radioButton = qobject_cast(opt->styleObject); if (!radioButton) radioButton = dynamic_cast(p->device()); if (!radioButton) return; DDciIconPlayer *dciIconPlayer = nullptr; dciIconPlayer = radioButton->findChild("_d_radio_dciplayer", Qt::FindDirectChildrenOnly); DDciIcon icon = radioButton->isChecked() ? DDciIcon::fromTheme("radio_checked") : DDciIcon::fromTheme("radio_unchecked"); if (!dciIconPlayer) { dciIconPlayer = new DDciIconPlayer(radioButton); dciIconPlayer->setObjectName("_d_radio_dciplayer"); dciIconPlayer->setDevicePixelRatio(qApp->devicePixelRatio()); dciIconPlayer->setIcon(icon); dciIconPlayer->setMode(DDciIcon::Normal); connect(dciIconPlayer, &DDciIconPlayer::updated, radioButton, [radioButton]() { radioButton->update(); }); } auto pa = DDciIconPalette::fromQPalette(radioButton->palette()); dciIconPlayer->setPalette(pa); dciIconPlayer->setTheme(DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? DDciIcon::Theme::Dark : DDciIcon::Theme::Light); p->setRenderHint(QPainter::SmoothPixmapTransform); p->drawImage(opt->rect.adjusted(-1, -1, 1, 1), dciIconPlayer->currentImage()); static bool onceFlag = false; // 保证动画只触发一次 if (opt->state & QStyle::StateFlag::State_Sunken) { DDciIcon icon = !radioButton->isChecked() ? DDciIcon::fromTheme("radio_checked") : DDciIcon::fromTheme("radio_unchecked"); playDci(dciIconPlayer, icon, DDciIcon::Pressed); } else if (opt->state & QStyle::StateFlag::State_MouseOver) { if (!onceFlag) { playDci(dciIconPlayer, icon, DDciIcon::Hover); onceFlag = true; } } else { if (onceFlag) { playDci(dciIconPlayer, icon, DDciIcon::Normal); onceFlag = false; } } } else { QRect standard = opt->rect; p->setRenderHint(QPainter::Antialiasing, true); if (opt->state & State_On) { //Qt::Checked int padding = qCeil(standard.width() / 2.0 / 2.0); QPainterPath path; path.addEllipse(standard); path.addEllipse(standard.adjusted(padding, padding, -padding, -padding)); p->fillPath(path, getColor(opt, DPalette::Highlight)); // 内圈填充 QPainterPath innerCirclePath; innerCirclePath.addEllipse(standard.adjusted(padding, padding, -padding, -padding)); p->fillPath(innerCirclePath, getThemTypeColor(Qt::white, Qt::black)); } else if (opt->state & State_Off) { p->setPen(QPen(getColor(opt, DPalette::WindowText), 1)); p->drawEllipse(standard.adjusted(1, 1, -1, -1)); // 内圈填充 QPainterPath innerCirclePath; innerCirclePath.addEllipse(standard.adjusted(1, 1, -1, -1)); p->fillPath(innerCirclePath, getThemTypeColor(Qt::transparent, QColor(0, 0, 0, qCeil(255 * 0.5)))); } } return; } case PE_IndicatorCheckBox: { if (ENABLE_ANIMATIONS && ENABLE_ANIMATION_CHECKBOX) { auto checkBox = qobject_cast(opt->styleObject); if (!checkBox) checkBox = dynamic_cast(p->device()); if (!checkBox) return; DDciIconPlayer *dciIconPlayer = nullptr; dciIconPlayer = checkBox->findChild("_d_checkbox_dciplayer", Qt::FindDirectChildrenOnly); DDciIcon icon = checkBox->isChecked() ? DDciIcon::fromTheme("checkbox_checked") : DDciIcon::fromTheme("checkbox_unchecked"); if (!dciIconPlayer) { dciIconPlayer = new DDciIconPlayer(checkBox); dciIconPlayer->setObjectName("_d_checkbox_dciplayer"); dciIconPlayer->setDevicePixelRatio(qApp->devicePixelRatio()); dciIconPlayer->setIcon(icon); dciIconPlayer->setMode(DDciIcon::Normal); connect(dciIconPlayer, &DDciIconPlayer::updated, checkBox, [checkBox]() { checkBox->update(); }); } auto pa = DDciIconPalette::fromQPalette(checkBox->palette()); dciIconPlayer->setPalette(pa); dciIconPlayer->setTheme(DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? DDciIcon::Theme::Dark : DDciIcon::Theme::Light); p->setRenderHint(QPainter::SmoothPixmapTransform); p->drawImage(opt->rect.adjusted(-1, -1, 1, 1), dciIconPlayer->currentImage()); static bool onceFlag = false; // 保证动画只触发一次 if (opt->state & QStyle::StateFlag::State_Sunken) { DDciIcon icon = !checkBox->isChecked() ? DDciIcon::fromTheme("checkbox_checked") : DDciIcon::fromTheme("checkbox_unchecked"); auto pa = DDciIconPalette::fromQPalette(checkBox->palette()); playDci(dciIconPlayer, icon, DDciIcon::Pressed); } else if (opt->state & QStyle::StateFlag::State_MouseOver) { if (!onceFlag) { playDci(dciIconPlayer, icon, DDciIcon::Hover); onceFlag = true; } } else { if (onceFlag) { playDci(dciIconPlayer, icon, DDciIcon::Normal); onceFlag = false; } } } else { QRectF standard = opt->rect; if (opt->state & State_NoChange) { //Qt::PartiallyChecked DDrawUtils::drawBorder(p, standard, getColor(opt, DPalette::WindowText), 1, 2); // 内部矩形填充 p->setBrush(getThemTypeColor(Qt::transparent, QColor(0, 0, 0, qCeil(255 * 0.5)))); p->drawRoundedRect(standard.adjusted(1, 1, -1, -1), 2, 2); QRectF lineRect(0, 0, standard.width() / 2.0, 2); lineRect.moveCenter(standard.center()); p->fillRect(lineRect, getColor(opt, DPalette::TextTitle, w)); } else if (opt->state & State_On) { //Qt::Checked // 填充整个矩形 p->setPen(Qt::NoPen); p->setBrush(getThemTypeColor(Qt::transparent, Qt::black)); p->drawRoundedRect(standard.adjusted(1, 1, -1, -1), 2, 2); p->setPen(getColor(opt, DPalette::Highlight)); p->setBrush(Qt::NoBrush); QIcon icon = QIcon::fromTheme("checked"); icon.paint(p, opt->rect.adjusted(-1, -1, 1, 1)); } else { DDrawUtils::drawBorder(p, standard, getColor(opt, DPalette::WindowText), 1, 2); // 内部矩形填充 p->setBrush(getThemTypeColor(Qt::transparent, getThemTypeColor(Qt::transparent, QColor(0, 0, 0, qCeil(255 * 0.5))))); p->drawRoundedRect(standard.adjusted(1, 1, -1, -1), 2, 2); } } return; } case PE_IndicatorTabClose: { QIcon icon = DStyle::standardIcon(SP_CloseButton, opt, w); if (DGuiApplicationHelper::isTabletEnvironment()) { // 在平板中点击区域为36px 显示区域22px QRect iconRect(0, 0, TabBar_TabButtonSize, TabBar_TabButtonSize); iconRect.moveCenter(opt->rect.center()); icon.paint(p, iconRect); return; } icon.paint(p, opt->rect); return; } case PE_FrameTabWidget: { p->setPen(QPen(getColor(opt, QPalette::Dark), proxy()->pixelMetric(PM_DefaultFrameWidth, opt, w))); p->setBrush(getColor(opt, QPalette::Window)); p->drawRect(opt->rect); return; } case PE_IndicatorItemViewItemCheck: { QRectF standard = opt->rect; p->setRenderHint(QPainter::Antialiasing, true); QIcon::Mode mode = opt->state & State_Enabled ? QIcon::Normal : QIcon::Disabled; if (opt->state & State_NoChange) { //Qt::PartiallyChecked DStyle::standardIcon(SP_IndicatorChecked, opt, w).paint(p, standard.toRect(), Qt::AlignCenter, mode); } else if (opt->state & State_On) { //Qt::Checked p->setPen(getColor(opt, DPalette::Highlight)); DStyle::standardIcon(SP_IndicatorChecked, opt, w).paint(p, standard.toRect(), Qt::AlignCenter, mode); } else if (opt->state & State_Off) { //Qt::Unchecked if (w && w->property("_d_dtk_UncheckedItemIndicator").toBool()) { DStyle::standardIcon(SP_IndicatorUnchecked, opt, w).paint(p, standard.toRect(), Qt::AlignCenter, mode); } if (w && !w->property("_d_dtk_UncheckedItemIndicator").isValid() && !qobject_cast(w)) { DStyle::standardIcon(SP_IndicatorUnchecked, opt, w).paint(p, standard.toRect(), Qt::AlignCenter, mode); } } return; } case PE_PanelMenu: { if (opt->palette.window().color().isValid() && DWindowManagerHelper::instance()->hasBlurWindow()) { QColor color = opt->palette.window().color(); color.setAlphaF(0.3); p->fillRect(opt->rect, color); } else { p->fillRect(opt->rect, opt->palette.window()); } break; } case PE_Frame: { if (const QStyleOptionFrame *f = qstyleoption_cast(opt)) { const bool hasProp = w && w->property("_d_dtk_frameRadius").isValid(); if (f->features & QStyleOptionFrame::Rounded || hasProp) { p->setRenderHint(QPainter::Antialiasing); p->setBrush(p->background()); if (f->lineWidth <= 0) { p->setPen(Qt::NoPen); } int radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); QRectF rect(opt->rect); rect.adjust(f->lineWidth / 2.0, f->lineWidth / 2.0, -f->lineWidth / 2.0, -f->lineWidth / 2.0); p->drawRoundedRect(rect, radius, radius); return; } } break; } case PE_PanelTipLabel: { return; } case PE_FrameGroupBox: { if (auto group_opt = qstyleoption_cast(opt)) { if (group_opt->features & QStyleOptionFrame::Flat) return; } DStyleOptionBackgroundGroup option; option.init(w); option.position = DStyleOptionBackgroundGroup::OnlyOne; static_cast(&option)->operator =(*opt); DStyle::drawPrimitive(PE_ItemBackground, &option, p, w); return; } case PE_IndicatorArrowUp: { QIcon icon = DStyle::standardIcon(SP_ArrowUp, opt, w); icon.paint(p, spinboxIndicatorRect(opt->rect)); return; } case PE_IndicatorArrowDown: { QIcon icon = DStyle::standardIcon(SP_ArrowDown, opt, w); icon.paint(p, spinboxIndicatorRect(opt->rect)); return; } case PE_IndicatorArrowRight: { QIcon icon = DStyle::standardIcon(SP_ArrowRight, opt, w); icon.paint(p, opt->rect); return; } case PE_IndicatorArrowLeft: { QIcon icon = DStyle::standardIcon(SP_ArrowLeft, opt, w); icon.paint(p, opt->rect); return; } case PE_FrameTabBarBase: return; case PE_IndicatorBranch: { // tree QRect rect = DStyle::subElementRect(SE_HeaderArrow, opt, w); int rect_width = rect.width(); int rect_height = rect.height(); rect.setWidth(rect_width > rect_height ? rect_width : rect_height); rect.setHeight(rect_width > rect_height ? rect_width: rect_height); rect.moveCenter(opt->rect.center()); if (opt->state & State_Children) { if (!(opt->state & State_Open)) { p->save(); //在选中时进行反白处理 if (opt->state & State_Selected) { p->setPen(QColor(Qt::white)); } DStyle::standardIcon(SP_ArrowRight, opt, w).paint(p, rect); p->restore(); return; } p->save(); //在选中时进行反白处理 if (opt->state & State_Selected) { p->setPen(QColor(Qt::white)); } DStyle::standardIcon(SP_ArrowDown, opt, w).paint(p, rect); p->restore(); } return; } case PE_PanelItemViewRow: { // 不绘制选中的item背景,已经绘制了一个圆了 if (w && qobject_cast(w->parentWidget())) { return; } //这里QTreeView的绘制复制了QCommonStyle的代码,添加了圆角的处理,hover的处理 if (qobject_cast(w)) { const auto delegate = qobject_cast(w)->itemDelegate(); //如果QTreeView使用的不是默认代理 QStyledItemDelegate,则采取DStyle的默认绘制(备注:这里的QtCreator不会有hover效果和圆角) if (!isTheClassObject(delegate)) { break; } if (const QStyleOptionViewItem *vopt = qstyleoption_cast(opt)) { QPalette::ColorGroup cg = (w ? w->isEnabled() : (vopt->state & QStyle::State_Enabled)) ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) cg = QPalette::Inactive; int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); if ((vopt->state & (QStyle::State_Selected | QStyle::State_MouseOver)) && proxy()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, opt, w)) { p->setRenderHint(QPainter::Antialiasing, true); p->setPen(Qt::NoPen); p->setBrush(vopt->palette.brush(cg, (vopt->state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Midlight)); if ((vopt->state & QStyle::State_Selected) && (vopt->state & QStyle::State_MouseOver)) { p->setBrush(p->brush().color().lighter(120)); } if (vopt->viewItemPosition != QStyleOptionViewItem::End) { // TODO: determine the positon(left and right) by a flag, draw rounded rect respectively. if (vopt->rect.x() == 0) { // left component DDrawUtils::drawRoundedRect(p, vopt->rect, frame_radius, frame_radius, DDrawUtils::TopLeftCorner | DDrawUtils::BottomLeftCorner); } else { // right component DDrawUtils::drawRoundedRect(p, vopt->rect, frame_radius, frame_radius, DDrawUtils::TopRightCorner | DDrawUtils::BottomRightCorner); } } else if(vopt->viewItemPosition != QStyleOptionViewItem::Invalid){ p->drawRoundedRect(vopt->rect, frame_radius, frame_radius); } } else if (vopt->features & QStyleOptionViewItem::Alternate) { p->fillRect(vopt->rect, vopt->palette.brush(cg, QPalette::AlternateBase)); } } return; } break; } case PE_FrameStatusBarItem: { return; } case PE_PanelStatusBar: { QColor bgcolor; QColor lineColor; if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType) { bgcolor = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Base), 0, 0, -10, 0, 0, 0, 95); lineColor = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Button), 0, 0, 0, 0, 0, 0, 5); } else { bgcolor = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Base), 0, 0, 0, 0, 0, 0, 70); lineColor = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Button), 0, 0, 60, 0, 0, 0, 0); } p->setPen(lineColor); p->setBrush(bgcolor); p->drawLine(opt->rect.topLeft(), opt->rect.topRight()); p->drawRect(opt->rect); return; } default: break; } DStyle::drawPrimitive(pe, opt, p, w); } // 按动画效果渐变隐藏滚动条,返回值为`true`表示隐藏滚动条,`false`表示继续绘制滚动条(改变了透明度) bool ChameleonStyle::hideScrollBarByAnimation(const QStyleOptionSlider *scrollBar, QPainter *p) const { QScrollBar *sbar = qobject_cast(scrollBar->styleObject); if (!sbar) return false; // QScrollBar 可以通过设置属性 _d_slider_always_show 为 true 的方式,使得 Slider 一直显示 // scrollBarObj 获取的即应用界面上 QScrollBar 控件本身的指针值 if (sbar->property("_d_dtk_slider_always_show").toBool()) return false; // ScrollBarAlwaysOn 也可以控制一直显示 QAbstractScrollArea *sa = qobject_cast(getSbarParentWidget(sbar)); if (sa) { const QScrollBar *hsb = sa->horizontalScrollBar(); const bool hsbAlwaysOn = sa->horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn; if (hsb == sbar && hsbAlwaysOn) return false; const QScrollBar *vsb = sa->verticalScrollBar(); const bool vsbAlwaysOn = sa->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn; if (vsb == sbar && vsbAlwaysOn) return false; } // 如果应用没有自行控制则查看是否 dcc 有设置相关 xsettings DPlatformTheme *theme = DGuiApplicationHelper::instance()->systemTheme(); if (theme && theme->isValid()) { int sb = theme->scrollBarPolicy(); switch (sb) { case Qt::ScrollBarAlwaysOff: return true; case Qt::ScrollBarAlwaysOn: return false; default: break; } } auto styleAnimation = qobject_cast(this->animation(sbar)); if (!styleAnimation) { // styleAnimation -> updateTarget --sendEvent--> StyleAnimationUpdate -> repaint styleAnimation = new dstyle::DScrollbarStyleAnimation(dstyle::DScrollbarStyleAnimation::Deactivating, sbar); styleAnimation->setDeletePolicy(QAbstractAnimation::KeepWhenStopped); connect(styleAnimation, &dstyle::DStyleAnimation::destroyed, this, &ChameleonStyle::_q_removeAnimation, Qt::UniqueConnection); animations.insert(styleAnimation->target(), styleAnimation); // 滚动和滚动条大小变化时,重启动画改变显示和隐藏 QObject::connect(sbar, &QAbstractSlider::valueChanged, styleAnimation, &dstyle::DScrollbarStyleAnimation::restart); QObject::connect(sbar, &QAbstractSlider::rangeChanged, styleAnimation, &dstyle::DScrollbarStyleAnimation::restart); } if (!styleAnimation) return false; QAbstractAnimation::State st = styleAnimation->state(); // underMouse ==> State_MouseOver sometimes not work well ? // underMouse true but State_MouseOver false... bool isHoveredOrPressed = hoveredOrPressed(scrollBar) || sbar->underMouse(); if (isHoveredOrPressed) { // 标记一下,鼠标移开时需要重新开启隐藏动画 sbar->setProperty("_d_dtk_scrollbar_visible", true); return false; } if (sbar->property("_d_dtk_scrollbar_visible").toBool()) { sbar->setProperty("_d_dtk_scrollbar_visible", false); styleAnimation->restart(true); return false; } if (st == QAbstractAnimation::Running) { p->setOpacity(styleAnimation->currentValue()); } // 动画停止时不再绘制滚动条 return st == QAbstractAnimation::Stopped; } void ChameleonStyle::drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const { switch (element) { case CE_RadioButton: case CE_CheckBox: if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { bool isRadio = (element == CE_RadioButton); QStyleOptionButton subopt = *btn; subopt.rect = subElementRect(isRadio ? SE_RadioButtonIndicator : SE_CheckBoxIndicator, btn, w); proxy()->drawPrimitive(isRadio ? PE_IndicatorRadioButton : PE_IndicatorCheckBox, &subopt, p, w); subopt.rect = subElementRect(SE_CheckBoxContents, btn, w); proxy()->drawControl(CE_CheckBoxLabel, &subopt, p, w); if (btn->state & State_HasFocus) { QRect rect(subElementRect(isRadio ? SE_RadioButtonFocusRect : SE_CheckBoxFocusRect, btn, w)); if (isRadio) { p->setPen(QPen(getColor(opt, DPalette::Highlight), DStyle::pixelMetric(PM_FocusBorderWidth))); p->drawEllipse(rect.adjusted(1, 1, -1, -1)); } else { DDrawUtils::drawBorder(p, rect, getColor(opt, DPalette::Highlight), DStyle::pixelMetric(PM_FocusBorderWidth), DStyle::pixelMetric(PM_FocusBorderSpacing) + 2); } } } return; case CE_CheckBoxLabel: if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { int alignment = static_cast(visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter)); if (!proxy()->styleHint(SH_UnderlineShortcut, btn, w)) alignment |= Qt::TextHideMnemonic; QPixmap pix; QRect textRect = btn->rect; if (!btn->icon.isNull()) { auto icon_mode_state = toIconModeState(opt); // 与PushButton一致,转换成icon的mode和state. #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) pix = btn->icon.pixmap(btn->iconSize, w ? w->devicePixelRatio() : qApp->devicePixelRatio(), icon_mode_state.first, icon_mode_state.second); #else pix = btn->icon.pixmap(w ? w->window()->windowHandle() : nullptr, btn->iconSize, icon_mode_state.first, icon_mode_state.second); #endif proxy()->drawItemPixmap(p, btn->rect, alignment, pix); if (btn->direction == Qt::RightToLeft) textRect.setRight(textRect.right() - btn->iconSize.width() - 4); else textRect.setLeft(textRect.left() + btn->iconSize.width() + 4); } if (!btn->text.isEmpty()) { proxy()->drawItemText(p, textRect, alignment | Qt::TextShowMnemonic, btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText); } } return; case CE_ScrollBarSlider: { if (const QStyleOptionSlider* scrollBar = qstyleoption_cast(opt)) { // 非特效不需要动画,只有显示和隐藏 if (!DGuiApplicationHelper::isSpecialEffectsEnvironment()) { if (!hoveredOrPressed(scrollBar)) return; } bool hidden = hideScrollBarByAnimation(scrollBar, p); if (hidden) return; p->save(); p->setBrush(getColor(opt, QPalette::Highlight)); p->setPen(Qt::NoPen); p->setRenderHint(QPainter::Antialiasing); QRectF rect = opt->rect; int realRadius = 0; QPoint scrollBarRectCenter; int spacing = DStyle::pixelMetric(DStyle::PM_FocusBorderSpacing); //用于判断滚动条是否被圆角区域遮住或特殊要求(滚动条上下不到顶、末端),使用方法是 在对应的控件的滚动条, 设置添加间隔,其中左、右和上、下每一个都是分开的,且没有遮挡长度的限制; //若是超出滚动条的总长度,则表现无变化(不作处理) //eg: scrollbar->setProperty("_d_slider_leftOrRight_spacing", 100); bool okLeft = false; bool okRight = false; bool okUp = false; bool okDown = false; int spacLeft = 0; int spacRight = 0; int spacUp = 0; int spacDown = 0; if (opt->styleObject->property("_d_slider_spaceLeft").isValid()) spacLeft = opt->styleObject->property("_d_slider_spaceLeft").toInt(&okLeft); if (opt->styleObject->property("_d_slider_spaceRight").isValid()) spacRight = opt->styleObject->property("_d_slider_spaceRight").toInt(&okRight); if (opt->styleObject->property("_d_slider_spaceUp").isValid()) spacUp = opt->styleObject->property("_d_slider_spaceUp").toInt(&okUp); if (opt->styleObject->property("_d_slider_spaceDown").isValid()) spacDown = opt->styleObject->property("_d_slider_spaceDown").toInt(&okDown); if (opt->state & QStyle::State_Horizontal) { rect.setHeight(rect.height() / 2); if ((okLeft && spacLeft > 0) || (okRight && spacRight > 0)) { if ((2 * spacing + spacLeft + spacRight) < rect.width()) { rect = rect.adjusted(spacing + spacLeft, 0, -spacing - spacRight, 0); } } else { rect = rect.adjusted(spacing, 0, -spacing, 0); } if (!(opt->state & QStyle::State_MouseOver)) rect.setHeight(rect.height() - 2); realRadius = rect.height() / 2.0; scrollBarRectCenter.setX(scrollBar->rect.x() + scrollBar->rect.width() / 2); scrollBarRectCenter.setY((scrollBar->rect.y() + scrollBar->rect.height()) / 2); rect.moveCenter(scrollBarRectCenter); rect.moveBottom(scrollBar->rect.bottom() - 2); } else { rect.setWidth(rect.width() / 2); if ((okUp && spacUp > 0) || (okDown && spacDown > 0)) { if ((2 * spacing + spacUp + spacDown) < rect.height()) { rect = rect.adjusted(0, spacing + spacUp, 0, -spacing - spacDown); } } else { rect = rect.adjusted(0, spacing, 0, -spacing); } if (!(opt->state & QStyle::State_MouseOver)) rect.setWidth(rect.width() - 2); realRadius = rect.width() / 2.0; scrollBarRectCenter.setX((scrollBar->rect.x() + scrollBar->rect.width()) / 2); scrollBarRectCenter.setY(scrollBar->rect.y() + scrollBar->rect.height() / 2); rect.moveCenter(scrollBarRectCenter); rect.moveRight(scrollBar->rect.right() - 1); } QColor lineColor(opt->palette.color(QPalette::Base)); if (DGuiApplicationHelper::toColorType(lineColor) == DGuiApplicationHelper::LightType) { // 外侧拓展一个像素的outside border p->setPen(QPen(QColor(255, 255, 255, 0.1 * 255), Metrics::Painter_PenWidth)); p->setBrush(Qt::NoBrush); p->drawRoundedRect(rect.adjusted(-1, -1, 1, 1), realRadius, realRadius); // 内侧绘制一个像素的inside border p->setPen(QPen(QColor(0, 0, 0, 0.1 * 255), Metrics::Painter_PenWidth)); p->drawRoundedRect(rect.adjusted(1, 1, -1, -1), realRadius, realRadius); // normal状态 p->setBrush(QColor(0, 0, 0, 0.5 * 255)); if (scrollBar->state & QStyle::State_MouseOver) // hover 状态 p->setBrush(QColor(0, 0, 0, 0.7 * 255)); if (scrollBar->state & QStyle::State_Sunken) // active状态 p->setBrush(QColor(0, 0, 0, 0.6 * 255)); } else { // 外侧拓展一个像素的outside border p->setPen(QPen(QColor(0, 0, 0, 0.1 * 255), Metrics::Painter_PenWidth)); p->setBrush(Qt::NoBrush); p->drawRoundedRect(rect.adjusted(-1, -1, 1, 1), realRadius, realRadius); // 内侧绘制一个像素的inside border p->setPen(QPen(QColor(255, 255, 255, 0.1 * 255), Metrics::Painter_PenWidth)); p->drawRoundedRect(rect.adjusted(1, 1, -1, -1), realRadius, realRadius); // normal状态 p->setBrush(QColor(255, 255, 255, 0.2 * 255)); if (scrollBar->state & QStyle::State_MouseOver) // hover 状态 p->setBrush(QColor(255, 255, 255, 0.5 * 255)); if (scrollBar->state & QStyle::State_Sunken) // active状态 p->setBrush(QColor(255, 255, 255, 0.4 * 255)); } p->setPen(Qt::NoPen); p->drawRoundedRect(rect, realRadius, realRadius); p->restore(); } break; } case CE_MenuBarItem: { if (const QStyleOptionMenuItem *mbi = qstyleoption_cast(opt)) { p->save(); QRect rect = mbi->rect; drawMenuBarItem(mbi, rect, p, w); p->restore(); return; } } break; case CE_MenuBarEmptyArea: { p->save(); QRect menubarRect = opt->rect; p->setPen(Qt::NoPen); p->setBrush(getColor(opt, QPalette::Window)); p->drawRect(menubarRect); p->restore(); return; } case CE_MenuItem: { if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(opt)) { p->save(); drawMenuItem(menuItem, p, w); p->restore(); return; } break; } case CE_MenuEmptyArea: { drawMenuItemBackground(opt, p, QStyleOptionMenuItem::EmptyArea); return; } case CE_MenuScroller: { QStyleOption arrowOpt = *opt; arrowOpt.state |= State_Enabled; int minSize = qMin(arrowOpt.rect.width(), arrowOpt.rect.height()); arrowOpt.rect.setWidth(minSize); arrowOpt.rect.setHeight(minSize); arrowOpt.rect.moveCenter(opt->rect.center()); proxy()->drawPrimitive(((opt->state & State_DownArrow) ? PE_IndicatorArrowDown : PE_IndicatorArrowUp), &arrowOpt, p, w); return; } case CE_PushButton: { if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { proxy()->drawControl(CE_PushButtonBevel, btn, p, w); QStyleOptionButton subopt = *btn; subopt.rect -= frameExtentMargins(); subopt.rect = proxy()->subElementRect(SE_PushButtonContents, &subopt, w); proxy()->drawControl(CE_PushButtonLabel, &subopt, p, w); if (btn->state & State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*btn); fropt.rect = proxy()->subElementRect(SE_PushButtonFocusRect, btn, w); proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, p, w); } return; } break; } case CE_PushButtonBevel: { if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { QRect br = btn->rect; int dbi = proxy()->pixelMetric(PM_ButtonDefaultIndicator, btn, w); if (btn->features & QStyleOptionButton::DefaultButton) proxy()->drawPrimitive(PE_FrameDefaultButton, opt, p, w); if (btn->features & QStyleOptionButton::AutoDefaultButton) br.setCoords(br.left() + dbi, br.top() + dbi, br.right() - dbi, br.bottom() - dbi); if (!(btn->features & (QStyleOptionButton::Flat | QStyleOptionButton::CommandLinkButton)) || btn->state & (State_Sunken | State_On) || (btn->features & QStyleOptionButton::CommandLinkButton && btn->state & State_MouseOver)) { QStyleOptionButton tmpBtn = *btn; tmpBtn.rect = br; proxy()->drawPrimitive(PE_PanelButtonCommand, &tmpBtn, p, w); } } return; } case CE_TabBarTabShape: { if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { if (drawTabBar(p, tab, w)) return; } } break; case CE_TabBarTabLabel: { if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { if (drawTabBarLabel(p, tab, w)) return; } } break; case CE_TabBarTab: { if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { QStyleOptionButton btn; btn.rect = tab->rect; bool type_check = false; if (w) type_check = w->property("_d_dtk_tabbartab_type").toBool(); int leftMarge = 0; int rightMarge = 0; if (!type_check) { leftMarge = TabBar_TabMargin / 2; rightMarge = TabBar_TabMargin / 2; } if (verticalTabs(tab->shape)) { btn.rect.adjust(0, leftMarge, 0, -(rightMarge)); } else { btn.rect.adjust(leftMarge, 0, -(rightMarge), 0); } btn.state = tab->state; if (tab->state & QStyle::State_Selected) { btn.state |= QStyle::State_On; } if (type_check) { QColor inactive; if (btn.state & State_On) { inactive = getColor(opt, QPalette::ToolTipBase); if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::DarkType) { inactive = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::ToolTipBase), 0, 0, 0, -10, -10, -10, 0); } p->setBrush(inactive); } else { // 初始化 tabbar 的背景色 if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::LightType || (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType && DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::UnknownType)) { inactive = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Light), 0, 0, 0, +20, +20, +20, 0); } else if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::DarkType || (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType && DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::UnknownType)) { inactive = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Light), 0, 0, 0, -57, -57, -57, 0); } else { inactive = DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Light), 0, 0, 0, +20, +20, +20, 0); } p->setBrush(inactive); // Bug:33899 此处添加update出现重复触发绘图事件 导致cpu占用过高 目前注释未发现问题 // const_cast(w)->update(); } p->setPen(Qt::NoPen); p->setRenderHint(QPainter::Antialiasing); p->drawRect(opt->rect); // 绘制边框线 if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::LightType || (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::UnknownType && DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)) { p->setPen(QPen(getColor(opt, DPalette::FrameBorder, w), Metrics::Painter_PenWidth)); } else if (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::DarkType || (DGuiApplicationHelper::instance()->paletteType() == DGuiApplicationHelper::UnknownType && DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType)){ p->setPen(QPen(QColor(0, 0, 0, static_cast(0.05 * 255)), Metrics::Painter_PenWidth)); } else { p->setPen(QPen(getColor(opt, DPalette::FrameBorder, w), Metrics::Painter_PenWidth)); } p->setBrush(Qt::NoBrush); p->drawRect(opt->rect); //对中间的tabbar尾后加一根明显的线 if (QStyleOptionTab::End != tab->position && QStyleOptionTab::OnlyOneTab != tab->position) { const QRect &lintRect = opt->rect; if (verticalTabs(tab->shape)) { p->drawLine(lintRect.bottomLeft(), lintRect.bottomRight()); } else { p->drawLine(lintRect.topRight(), lintRect.bottomRight()); } } } else { DStyle::drawControl(CE_PushButtonBevel, &btn, p, w); } QStyleOptionTab* newTab = const_cast(tab); newTab->rect = btn.rect; proxy()->drawControl(CE_TabBarTabLabel, newTab, p, w); return; } break; } case CE_RubberBand: { if (qstyleoption_cast(opt)) { p->save(); QColor color = opt->palette.highlight().color(); color.setAlphaF(0.1); // draw rectangle p->setRenderHint(QPainter::Antialiasing, false); p->fillRect(opt->rect, color); // draw inner border // 保证border绘制在矩形内部,且不超越了矩形范围 color.setAlphaF(0.2); p->setClipRegion(QRegion(opt->rect) - opt->rect.adjusted(1, 1, -1, -1)); p->fillRect(opt->rect, color); p->restore(); return; } break; } case CE_Header: if (const QStyleOptionHeader *header = qstyleoption_cast(opt)) { QRegion clipRegion = p->clipRegion(); p->setClipRect(opt->rect); proxy()->drawControl(CE_HeaderSection, header, p, w); QStyleOptionHeader subopt = *header; subopt.rect = subElementRect(SE_HeaderLabel, header, w); if (subopt.rect.isValid()) proxy()->drawControl(CE_HeaderLabel, &subopt, p, w); if (header->sortIndicator != QStyleOptionHeader::None) { subopt.rect = subElementRect(SE_HeaderArrow, opt, w); proxy()->drawPrimitive(PE_IndicatorHeaderArrow, &subopt, p, w); } p->setClipRegion(clipRegion); } return; case CE_ShapedFrame: { if (const QStyleOptionFrame *f = qstyleoption_cast(opt)) { int frameShape = f->frameShape; int frameShadow = QFrame::Plain; if (f->state & QStyle::State_Sunken) { frameShadow = QFrame::Sunken; } else if (f->state & QStyle::State_Raised) { frameShadow = QFrame::Raised; } int lw = f->lineWidth; int mlw = f->midLineWidth; QPalette::ColorRole foregroundRole = QPalette::WindowText; if (w) foregroundRole = w->foregroundRole(); switch (frameShape) { case QFrame::Box: if (qobject_cast(const_cast(w)) && DGuiApplicationHelper::isTabletEnvironment()) break; if (frameShadow == QFrame::Plain) { qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw); } else { qDrawShadeRect(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw, mlw); } break; case QFrame::StyledPanel: //keep the compatibility with Qt 4.4 if there is a proxy style. //be sure to call drawPrimitive(QStyle::PE_Frame) on the proxy style if (w) { w->style()->drawPrimitive(QStyle::PE_Frame, opt, p, w); } else { proxy()->drawPrimitive(QStyle::PE_Frame, opt, p, w); } break; case QFrame::Panel: if (frameShadow == QFrame::Plain) { qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw); } else { qDrawShadePanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken, lw); } break; case QFrame::WinPanel: if (frameShadow == QFrame::Plain) { qDrawPlainRect(p, f->rect, f->palette.color(foregroundRole), lw); } else { qDrawWinPanel(p, f->rect, f->palette, frameShadow == QFrame::Sunken); } break; case QFrame::HLine: case QFrame::VLine: { QPoint p1, p2; if (frameShape == QFrame::HLine) { p1 = QPoint(opt->rect.x(), opt->rect.y() + opt->rect.height() / 2); p2 = QPoint(opt->rect.x() + opt->rect.width(), p1.y()); } else { p1 = QPoint(opt->rect.x() + opt->rect.width() / 2, opt->rect.y()); p2 = QPoint(p1.x(), p1.y() + opt->rect.height()); } if (frameShadow == QFrame::Plain) { QPen oldPen = p->pen(); QColor color = opt->palette.color(foregroundRole); color.setAlphaF(0.1); p->setPen(QPen(color, lw)); p->drawLine(p1, p2); p->setPen(oldPen); } else { qDrawShadeLine(p, p1, p2, f->palette, frameShadow == QFrame::Sunken, lw, mlw); } break; } } return; } break; } case CE_ComboBoxLabel: { if (const QStyleOptionComboBox *cb = qstyleoption_cast(opt)) { if (drawComboBoxLabel(p, cb, w)) return; } break; } case CE_PushButtonLabel: if (const QStyleOptionButton *button = qstyleoption_cast(opt)) { QRect textRect = button->rect; uint tf = Qt::AlignVCenter | Qt::TextShowMnemonic; if (!proxy()->styleHint(SH_UnderlineShortcut, button, w)) tf |= Qt::TextHideMnemonic; const QPalette::ColorRole &text_color_role = opt->state & State_On ? QPalette::HighlightedText : QPalette::ButtonText; QPalette pa = button->palette; if (button->features & DStyleOptionButton::WarningButton) { pa.setBrush(QPalette::ButtonText, getColor(opt, DPalette::TextWarning, w)); } else if (button->features & DStyleOptionButton::SuggestButton) { pa.setBrush(QPalette::ButtonText, getColor(opt, QPalette::HighlightedText)); } else { pa.setBrush(QPalette::ButtonText, getColor(opt, text_color_role)); } // 设置文字和图标的绘制颜色 p->setPen(QPen(pa.buttonText(), 1)); const DStyleOptionButton *dciButton = qstyleoption_cast(opt); bool hasDciIcon = (dciButton->features & DStyleOptionButton::HasDciIcon); QRect iconRect; if (hasDciIcon || !button->icon.isNull()) { int pixmapWidth = button->iconSize.width(); int pixmapHeight = button->iconSize.height(); int labelWidth = pixmapWidth; int labelHeight = pixmapHeight; int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint() int textWidth = button->fontMetrics.boundingRect(opt->rect, tf, button->text).width(); if (!button->text.isEmpty()) labelWidth += (textWidth + iconSpacing); iconRect = QRect(textRect.x() + (textRect.width() - labelWidth) / 2, textRect.y() + (textRect.height() - labelHeight) / 2, pixmapWidth, pixmapHeight); iconRect = visualRect(button->direction, textRect, iconRect); tf |= Qt::AlignLeft; //left align, we adjust the text-rect instead if (button->direction == Qt::RightToLeft) textRect.setRight(iconRect.left() - iconSpacing); else textRect.setLeft(iconRect.left() + iconRect.width() + iconSpacing); if (button->state & (State_On | State_Sunken)) iconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, w), proxy()->pixelMetric(PM_ButtonShiftVertical, opt, w)); } if (hasDciIcon) { auto dciTheme = (DGuiApplicationHelper::toColorType(opt->palette) == DGuiApplicationHelper::LightType) ? DDciIcon::Light : DDciIcon::Dark; auto icon_mode_state = toDciIconMode(opt); const DDciIconPalette &iconPalette = makeIconPalette(opt->palette); dciButton->dciIcon.paint(p, iconRect, p->device() ? p->device()->devicePixelRatioF() : qApp->devicePixelRatio(), dciTheme, icon_mode_state, Qt::AlignCenter, iconPalette); } else if (!button->icon.isNull()) { //Center both icon and text auto icon_mode_state = toIconModeState(opt); button->icon.paint(p, iconRect, Qt::AlignCenter, icon_mode_state.first, icon_mode_state.second); } else { tf |= Qt::AlignHCenter; } if (button->state & (State_On | State_Sunken)) textRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, opt, w), proxy()->pixelMetric(PM_ButtonShiftVertical, opt, w)); if (button->features & QStyleOptionButton::HasMenu) { QRect rectArrowAndLine = drawButtonDownArrow(opt, nullptr, w); int frameRadius = DStyle::pixelMetric(PM_FrameRadius); drawButtonDownArrow(button, p, w); if (button->direction == Qt::LeftToRight) { textRect.setRight(rectArrowAndLine.left() - frameRadius); } else { textRect.setLeft(rectArrowAndLine.right() + frameRadius); } } proxy()->drawItemText(p, textRect, tf, pa, (button->state & State_Enabled), button->text, QPalette::ButtonText); return; } break; case CE_ProgressBar: { //显示进度区域 if (const QStyleOptionProgressBar *progBar = qstyleoption_cast(opt)) { p->setRenderHint(QPainter::Antialiasing); p->setPen(Qt::NoPen); p->drawRect(opt->rect); QStyleOptionProgressBar progGroove = *progBar; proxy()->drawControl(CE_ProgressBarGroove, &progGroove, p, w); QRect rect = progBar->rect; //滑块区域矩形 int min = progBar->minimum; int max = progBar->maximum; int val = progBar->progress; int drawWidth = 0; bool horizontal = progBar->state & State_Horizontal; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) horizontal |= progBar->orientation == Qt::Horizontal; #endif if (horizontal) { drawWidth = (val * 1.0 / (max - min)) * rect.width(); rect = QRect(rect.left(), rect.top(), drawWidth, rect.height()); } else { drawWidth = (val * 1.0 / (max - min)) * rect.height(); rect = QRect(rect.left(), rect.bottom() - drawWidth, rect.width(), drawWidth); } p->setPen(Qt::NoPen); QStyleOptionProgressBar subopt = *progBar; proxy()->drawControl(CE_ProgressBarContents, &subopt, p, w); if (progBar->textVisible && horizontal) { subopt.rect = proxy()->subElementRect(SE_ProgressBarLabel, progBar, w); proxy()->drawControl(CE_ProgressBarLabel, &subopt, p, w); } } return; } case CE_ProgressBarGroove: { //滑槽显示 if (const QStyleOptionProgressBar *progBar = qstyleoption_cast(opt)) { int frameRadius = DStyle::pixelMetric(PM_FrameRadius, opt, w); bool horizontal = progBar->state & State_Horizontal; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) horizontal |= progBar->orientation == Qt::Horizontal; #endif int height = horizontal ? opt->rect.height() : opt->rect.width(); if (frameRadius * 2 >= height) { frameRadius = qMin(height / 2, 4); } p->setBrush(getColor(opt, DPalette::ObviousBackground, w)); if (ENABLE_ANIMATIONS && ENABLE_ANIMATION_PROGRESSBAR) { p->setPen(Qt::NoPen); p->drawRoundedRect(opt->rect, frameRadius, frameRadius); QPen pen; pen.setColor(DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? QColor(255, 255, 255, 0.1 * 255) : QColor(0, 0, 0, 0.1 * 255)); pen.setWidth(1); p->setPen(pen); p->setBrush(Qt::NoBrush); } p->drawRoundedRect(opt->rect, frameRadius, frameRadius); } return; } case CE_ProgressBarContents: { //进度滑块显示 if (const QStyleOptionProgressBar *progBar = qstyleoption_cast(opt)) { QStyleOptionProgressBar* progBarTemp = const_cast(progBar); progBarTemp->state &= (~State_MouseOver); progBarTemp = nullptr; QRect rect = progBar->rect; //滑块区域矩形 int min = progBar->minimum; int max = progBar->maximum; int val = progBar->progress; int drawWidth = 0; int frameRadius = DStyle::pixelMetric(PM_FrameRadius, opt, w); bool horizontal = progBar->state & State_Horizontal; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) horizontal |= progBar->orientation == Qt::Horizontal; #endif int height = horizontal ? rect.height() : rect.width(); if (frameRadius * 2 >= height) { frameRadius = qMin(height / 2, 4); } if (horizontal) { drawWidth = (val * 1.0 / (max - min)) * rect.width(); rect = QRect(rect.left(), rect.top(), drawWidth, rect.height()); } else { drawWidth = (val * 1.0 / (max - min)) * rect.height(); rect = QRect(rect.left(), rect.bottom() - drawWidth, rect.width(), drawWidth); } QPointF pointStart(rect.left(), rect.center().y()); QPointF pointEnd(rect.right(), rect.center().y()); QLinearGradient linear(pointStart, pointEnd); QColor startColor = getColor(opt, DPalette::Highlight); QColor endColor = DGuiApplicationHelper::adjustColor(startColor, 0, 0, +30, 0, 0, 0, 0); linear.setColorAt(0, startColor); linear.setColorAt(1, endColor); linear.setSpread(QGradient::PadSpread); if (ENABLE_ANIMATIONS && ENABLE_ANIMATION_PROGRESSBAR) p->setBrush(startColor); else p->setBrush(QBrush(linear)); if (progBar->textVisible) { QPainterPath pathRect; pathRect.addRect(rect); QPainterPath pathRoundRect; pathRoundRect.addRoundedRect(opt->rect, frameRadius, frameRadius); QPainterPath inter = pathRoundRect.intersected(pathRect); if (ENABLE_ANIMATIONS && ENABLE_ANIMATION_PROGRESSBAR) { QPainterPath clipPath; clipPath.addRoundedRect(rect, frameRadius, frameRadius); p->setClipPath(clipPath); p->setClipping(true); p->drawPath(inter); p->setClipping(false); QPen pen; QColor borderColor = DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Highlight), 0, 0, +10, 0, 0, 0, 0) : DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Highlight), 0, 0, -20, 0, 0, 0, -20); pen.setColor(borderColor); pen.setWidth(1); p->setPen(pen); p->setBrush(Qt::NoBrush); p->setClipping(true); p->drawRoundedRect(rect, frameRadius, frameRadius); p->setClipping(false); } else { p->drawPath(inter); } } else { //进度条高度 <= 8px && 进度条宽度 <= 8px && value有效 if (rect.height() <= ProgressBar_MinimumStyleHeight && rect.width() <= ProgressBar_MinimumStyleHeight && progBar->progress > 0) { QPainterPath path; QRect startRect = rect; startRect.setWidth(rect.height()); startRect.setHeight(rect.height()); path.moveTo(rect.x() + startRect.width() / 2.0, rect.y()); //绘制进度条最小样式前半圆 path.arcTo(startRect, 90, 180); p->drawPath(path); //绘制进度条最小样式后半圆 if (rect.width() > startRect.width() / 2) { QRect endRect = startRect; int width = rect.width() - startRect.width() / 2; endRect.setX(startRect.x() + startRect.width() / 2 - width); endRect.setWidth(width * 2); QPainterPath path2; path2.moveTo(endRect.x() + endRect.width() / 2.0, rect.y()); path2.arcTo(endRect, 90, -180); p->drawPath(path2); } } else { if (ENABLE_ANIMATIONS && ENABLE_ANIMATION_PROGRESSBAR) { QPainterPath clipPath; clipPath.addRoundedRect(opt->rect, frameRadius, frameRadius); p->setClipPath(clipPath); p->setClipping(true); p->drawRoundedRect(rect, frameRadius, frameRadius); p->setClipping(false); QPen pen; QColor borderColor = DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::DarkType ? DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Highlight), 0, 0, +10, 0, 0, 0, 0) : DGuiApplicationHelper::adjustColor(getColor(opt, QPalette::Highlight), 0, 0, -20, 0, 0, 0, -20); pen.setColor(borderColor); pen.setWidth(1); p->setPen(pen); p->setBrush(Qt::NoBrush); p->setClipping(true); p->drawRoundedRect(rect, frameRadius, frameRadius); p->setClipping(false); } else { p->drawRoundedRect(rect, frameRadius, frameRadius); } } } if (!ENABLE_ANIMATIONS || !ENABLE_ANIMATION_PROGRESSBAR) return; // 进度条光斑 auto progressbar = qobject_cast(opt->styleObject); if (!progressbar) progressbar = dynamic_cast(p->device()); if (!progressbar) return; bool isHorizontal = (progressbar->orientation() == Qt::Horizontal); constexpr int spotWidth = 100; if (isHorizontal ? rect.width() >= spotWidth : rect.height() >= spotWidth) { p->setPen(Qt::NoPen); ChameleonMovementAnimation *progressAnimation = nullptr; progressAnimation = progressbar->findChild("_d_progress_spot_animation", Qt::FindDirectChildrenOnly); if (!progressAnimation) { progressAnimation = new ChameleonMovementAnimation(progressbar); progressAnimation->setObjectName("_d_progress_spot_animation"); } QColor highLightColor(getColor(opt, DPalette::Highlight)); QColor spotColor = DGuiApplicationHelper::adjustColor(highLightColor, 0, +30, +30, 0, 0, 0, 0); QPointF pointStart, pointEnd; if (isHorizontal) { pointStart = QPointF(progressAnimation->currentValue().toRect().left(), progressAnimation->currentValue().toRect().center().y()); pointEnd = QPointF(progressAnimation->currentValue().toRect().right(), progressAnimation->currentValue().toRect().center().y()); } else { pointStart = QPointF(progressAnimation->currentValue().toRect().center().x(), progressAnimation->currentValue().toRect().bottom()); pointEnd = QPointF(progressAnimation->currentValue().toRect().center().x(), progressAnimation->currentValue().toRect().top()); } QLinearGradient linear(pointStart, pointEnd); linear.setColorAt(0, highLightColor); linear.setColorAt(0.5, spotColor); linear.setColorAt(1, highLightColor); linear.setSpread(QGradient::PadSpread); linear.setInterpolationMode(QLinearGradient::InterpolationMode::ColorInterpolation); p->setBrush(linear); QPainterPath clipPath; clipPath.addRoundedRect(rect.marginsRemoved(QMargins(1, 1, 1, 1)), frameRadius - 1, frameRadius - 1); p->setClipPath(clipPath); p->setClipping(true); p->drawRect(progressAnimation->currentValue().toRect()); p->setClipping(false); if (progressAnimation->state() == QVariantAnimation::Running) { QRect startRect, endRect; if (isHorizontal) { startRect = QRect(rect.x() - spotWidth, rect.y(), spotWidth, rect.height()); endRect = startRect; endRect.moveRight(rect.width() + spotWidth); } else { endRect = QRect(rect.x(), rect.y() - spotWidth, rect.width(), spotWidth); startRect = endRect; startRect.moveTop(rect.bottom()); } progressAnimation->setTargetRect(endRect); return; } // 动画之间需要间隔1s QTimer::singleShot(1000, progressAnimation, [progressAnimation, isHorizontal, rect]() { QRect startRect, endRect; if (isHorizontal) { startRect = QRect(rect.x() - spotWidth, rect.y(), spotWidth, rect.height()); endRect = startRect; endRect.moveRight(rect.width() + spotWidth); } else { endRect = QRect(rect.x(), rect.y() - spotWidth, rect.width(), spotWidth); startRect = endRect; startRect.moveTop(rect.bottom()); } progressAnimation->setDuration(2500); progressAnimation->setEasingCurve(QEasingCurve::InQuad); progressAnimation->setCurrentRect(startRect); progressAnimation->setTargetRect(endRect); }); } } return; } case CE_ProgressBarLabel: { if (const QStyleOptionProgressBar *progBar = qstyleoption_cast(opt)) { double val = progBar->progress * 1.0 / (progBar->maximum - progBar->minimum); int radius = DStyle::pixelMetric(PM_FrameRadius); int drawWidth = val * (opt->rect.width() + 2 * radius); QRect rect = progBar->fontMetrics.boundingRect(progBar->rect, progBar->textAlignment, progBar->text); if (rect.left() <= drawWidth && drawWidth <= rect.right()) { double division = (drawWidth - rect.left()) / (rect.width() * 1.0); QPointF pointStart(rect.left(), rect.center().y()); QPointF pointEnd(rect.right(), rect.center().y()); QLinearGradient linear(pointStart, pointEnd); linear.setColorAt(0, getColor(opt, DPalette::HighlightedText)); linear.setColorAt(division, getColor(opt, DPalette::HighlightedText)); linear.setColorAt(division + 0.01, getColor(opt, DPalette::ButtonText)); linear.setColorAt(1, getColor(opt, DPalette::ButtonText)); linear.setSpread(QGradient::PadSpread); p->setPen(QPen(QBrush(linear), 1)); //设置画笔渐变色 } else if (drawWidth < rect.left()) { p->setPen(getColor(opt, DPalette::ButtonText)); } else { p->setPen(getColor(opt, DPalette::HighlightedText)); } p->drawText(progBar->rect, progBar->textAlignment, progBar->text); } return; } case CE_ToolButtonLabel: { if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt)) { QRect rect = toolbutton->rect; int toolButtonAlign = Qt::AlignLeft; if (w) toolButtonAlign = w->property("_d_dtk_toolButtonAlign").toInt(); // 设置tool button的对齐方式 int radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); //在绘画icon和text之前,先绘画一层表示靠近或按下状态 p->setRenderHint(QPainter::Antialiasing); p->setPen(Qt::NoPen); p->setBrush(Qt::NoBrush); int menuButtonIndicatorMargin = 4; if (toolbutton->state & (State_MouseOver | State_Sunken)) //hover状态 、press状态 p->setBrush(getBrush(toolbutton, DPalette::Button)); // 繪制背景 if (toolbutton->state & State_Enabled) { if ((toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) && (toolbutton->state & (QStyle::State_MouseOver | QStyle::State_Sunken))) { // 绘制外层背景色 auto btn = *toolbutton; if (btn.state & (QStyle::State_MouseOver)) btn.state &= ~ QStyle::State_MouseOver; if (btn.state & (QStyle::State_Sunken)) btn.state &= ~ QStyle::State_Sunken; p->setPen(getColor(&btn, DPalette::Button)); p->setBrush(getBrush(&btn, DPalette::Button)); QRect tmp = rect; tmp.adjust(0, 0, proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, w) + 2 * menuButtonIndicatorMargin, 0); p->drawRoundedRect(tmp, radius, radius); // 绘制子控件背景色 p->setPen(getColor(toolbutton, DPalette::Button)); p->setBrush(getBrush(toolbutton, DPalette::Button)); if (toolbutton->activeSubControls & QStyle::SC_ToolButton) { DDrawUtils::drawRoundedRect(p, rect, radius, radius, DDrawUtils::TopLeftCorner | DDrawUtils::BottomLeftCorner); } else if (toolbutton->activeSubControls & QStyle::SC_ToolButtonMenu) { QRect r = rect; r.adjust(r.width(), 0, proxy()->pixelMetric(PM_MenuButtonIndicator , toolbutton, w) + 2 * menuButtonIndicatorMargin, 0); DDrawUtils::drawRoundedRect(p, r, radius, radius, DDrawUtils::TopRightCorner | DDrawUtils::BottomRightCorner); } } else { p->drawRoundedRect(rect, radius, radius); } } // Arrow type always overrules and is always shown bool hasArrow = toolbutton->features & QStyleOptionToolButton::Arrow; if (((!hasArrow && toolbutton->icon.isNull()) && !toolbutton->text.isEmpty()) || toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) { //只显示文字的情景 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic; if (!proxy()->styleHint(SH_UnderlineShortcut, opt, w)) alignment |= Qt::TextHideMnemonic; p->setFont(toolbutton->font); if (toolbutton->state & State_On) { p->setPen(getColor(toolbutton, DPalette::Highlight)); } else { p->setPen(getColor(toolbutton, DPalette::ButtonText)); } // 只显示文字且为PopupDelay模式且有菜单则文字和箭头整体居中显示(日历中的选择月份和年份的toolButton也遵循这个规则) if ((toolbutton->features & QStyleOptionToolButton::HasMenu && toolbutton->features & QStyleOptionToolButton::PopupDelay && toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) || w->property("_d_calendarToolBtn").toBool()) { QFontMetrics metrics(toolbutton->font); int fontWidth = metrics.horizontalAdvance(toolbutton->text); int indicatorWidth = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, w); int subRectWidth = fontWidth + indicatorWidth + menuButtonIndicatorMargin; QRect subRect = QRect(rect.left() + (rect.width() - subRectWidth) / 2, rect.top(), subRectWidth, rect.height()); QRect textRect = QRect(subRect.topLeft(), QSize(fontWidth, rect.height())); p->drawText(textRect, alignment, toolbutton->text); } else { p->drawText(rect, alignment, toolbutton->text); } } else { //只显示文字的情景 的 补集 QIcon icon; QSize pmSize = toolbutton->iconSize; switch (toolbutton->arrowType) { case Qt::UpArrow: icon = DStyle::standardIcon(SP_ArrowUp); break; case Qt::DownArrow: icon = DStyle::standardIcon(SP_ArrowDown); break; case Qt::LeftArrow: icon = DStyle::standardIcon(SP_ArrowLeft); break; case Qt::RightArrow: icon = DStyle::standardIcon(SP_ArrowRight); break; default: icon = toolbutton->icon; break; } p->setRenderHint(QPainter::Antialiasing); p->setPen(Qt::NoPen); p->setBrush(Qt::NoBrush); if (toolbutton->state & (State_MouseOver | State_Sunken)) //hover状态 、press状态 p->setBrush(getBrush(toolbutton, DPalette::Button)); if (toolbutton->state & State_HasFocus) p->setPen(getColor(toolbutton, DPalette::Highlight)); //强制绘制 日历 左右翻页背景 if (w && (w->objectName() == "qt_calendar_prevmonth" || w->objectName() == "qt_calendar_nextmonth")) { p->setBrush(getColor(toolbutton, DPalette::Button)); } // pr为图标的大小 QRect pr = rect; // tr为文字的大小 QRect tr = rect; pr.setHeight(pmSize.height()); pr.setWidth(pmSize.width()); if (toolbutton->state & State_On) //active状态 p->setPen(getColor(toolbutton, DPalette::Highlight)); else p->setPen(getColor(toolbutton, DPalette::ButtonText)); if (toolbutton->toolButtonStyle != Qt::ToolButtonIconOnly) { //只显示icon 的补集情况 p->setFont(toolbutton->font); int alignment = Qt::TextShowMnemonic; if (!proxy()->styleHint(SH_UnderlineShortcut, opt, w)) alignment |= Qt::TextHideMnemonic; if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { //文字在图标下面 pr.moveCenter(QPoint(rect.center().x(), rect.center().y() / 2)); tr.adjust(0, pr.height(), 0, 0); drawIcon(toolbutton, p, pr, icon); alignment |= Qt::AlignCenter; } else if (toolbutton->toolButtonStyle == Qt::ToolButtonTextBesideIcon) { if (toolButtonAlign == Qt::AlignCenter) { //toolButton居中对齐 //计算文字宽度 int textWidget = w->fontMetrics().horizontalAdvance(toolbutton->text); //图标 spacing 文字的矩形 QRect textIcon = QRect(0, 0, pr.width() + ToolButton_MarginWidth + textWidget, rect.height()); textIcon.moveCenter(rect.center()); pr.moveCenter(rect.center()); //图标padding pr.moveLeft(textIcon.x() > ToolButton_ItemSpacing ? textIcon.x() : ToolButton_ItemSpacing ); //调整text距离 tr.adjust(pr.width() + ToolButton_AlignCenterPadding, 0, 0, 0); drawIcon(toolbutton, p, pr, icon); alignment |= Qt::AlignCenter; } else if (toolButtonAlign == Qt::AlignRight) { //toolButton右对齐 int textWidget = w->fontMetrics().horizontalAdvance(toolbutton->text); pr.moveCenter(rect.center()); pr.moveRight(tr.width() - textWidget - ToolButton_AlignLeftPadding - ToolButton_ItemSpacing); tr.adjust(-ToolButton_AlignLeftPadding - pr.width() - ToolButton_MarginWidth, 0, -ToolButton_AlignLeftMargin, 0); drawIcon(toolbutton, p, pr, icon); alignment |= Qt::AlignVCenter | Qt::AlignRight; } else { //toolButton左对齐 pr.moveCenter(rect.center()); pr.moveLeft(ToolButton_AlignRightPadding); tr.adjust(ToolButton_AlignRightPadding + pr.width() + ToolButton_MarginWidth, 0, -ToolButton_ItemSpacing, 0); drawIcon(toolbutton, p, pr, icon); alignment |= Qt::AlignVCenter | Qt::AlignLeft; } } else { //其他几种(文字和icon布局)方式 int radius = DStyle::pixelMetric(PM_FrameRadius); pr.moveCenter(QPoint(rect.left(), rect.center().y())); pr.moveLeft(radius); tr.adjust(pr.width() + radius, 0, 0, 0); drawIcon(toolbutton, p, pr, icon); alignment |= Qt::AlignLeft | Qt::AlignVCenter; } p->drawText(tr, alignment, toolbutton->text); } else { //只显示icon情况 if (toolbutton->features & QStyleOptionToolButton::HasMenu && !(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup)) { rect.adjust(0, 0, - (proxy()->pixelMetric(PM_MenuButtonIndicator , toolbutton, w) + 4), 0); } pr.moveCenter(rect.center()); drawIcon(toolbutton, p, pr, icon); } } } return; } case CE_HeaderSection: { const auto headerOption( qstyleoption_cast( opt ) ); if (!headerOption) return; const bool horizontal( headerOption->orientation == Qt::Horizontal ); const bool isLast( headerOption->position == QStyleOptionHeader::End ); // fill background QColor color(opt->palette.color(QPalette::Base)); QColor lineColor(opt->palette.color(QPalette::Button)); // 挑选一个比较接近的基准色 Button,基于此做微调 if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType) { color = DGuiApplicationHelper::adjustColor(color, 0, 0, 0, 0, 0, 0, 60); lineColor = DGuiApplicationHelper::adjustColor(lineColor, 0, 0, 0, 0, 0, 0, 10); } else { color = DGuiApplicationHelper::adjustColor(color, 0, 0, -20, 0, 0, 0, 80); lineColor = DGuiApplicationHelper::adjustColor(lineColor, 0, 0, -25, 0, 0, 0, 0); } p->fillRect(opt->rect, QBrush(color)); p->setPen(lineColor); if (horizontal) { if (!isLast) { QPoint unit(0, opt->rect.height() / 5); p->drawLine(opt->rect.topRight() + unit, opt->rect.bottomRight() - unit); } p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight()); } else { if (!isLast) { p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight()); } p->drawLine(opt->rect.topRight(), opt->rect.bottomRight()); } return; } case CE_SizeGrip: { p->save(); int x, y, w, h; opt->rect.getRect(&x, &y, &w, &h); int sw = qMin(h, w); if (h > w) p->translate(0, h - w); else p->translate(w - h, 0); Qt::Corner corner; if (const QStyleOptionSizeGrip *sgOpt = qstyleoption_cast(opt)) corner = sgOpt->corner; else if (opt->direction == Qt::RightToLeft) corner = Qt::BottomLeftCorner; else corner = Qt::BottomRightCorner; bool ok = false; int radius = DStyle::pixelMetric(PM_FrameRadius, opt) / 2; int _d_radius = 0; if (opt->styleObject->property("_d_radius").isValid()) _d_radius = opt->styleObject->property("_d_radius").toInt(&ok); if (ok && _d_radius >= 0 && _d_radius != radius) radius = _d_radius; p->setRenderHint(QPainter::Antialiasing, true); DGuiApplicationHelper *guiAppHelp = DGuiApplicationHelper::instance(); if (guiAppHelp->themeType() == DGuiApplicationHelper::ColorType::DarkType) { //暗色主题 p->setPen(QPen(QColor(255, 255, 255, 0.2 * 255), 1)); } else { p->setPen(QPen(QColor(0, 0, 0, 0.2 * 255), 1)); } QRectF rectInner(0, 0, 1.4 * sw, 1.4 * sw); // 内侧弧线的外切正方形 QRectF rectExternal(0, 0, 2 * sw, 2 * sw); // 外侧弧线的外切正方形 if (corner == Qt::BottomLeftCorner) { rectExternal.moveBottomLeft(QPointF(opt->rect.bottomLeft().x() + radius, opt->rect.bottomLeft().y() - radius)); rectInner.moveCenter(rectExternal.center()); p->drawArc(rectInner, 205 * 16, 40 * 16); p->drawArc(rectExternal, 200 * 16, 50 * 16); } else if (corner == Qt::BottomRightCorner) { rectExternal.moveBottomRight(QPointF(opt->rect.bottomRight().x() - radius, opt->rect.bottomRight().y() - radius)); rectInner.moveCenter(rectExternal.center()); p->drawArc(rectInner, 295 * 16, 40 * 16); p->drawArc(rectExternal, 290 * 16, 50 * 16); } else if (corner == Qt::TopRightCorner) { rectExternal.moveTopRight(QPointF(opt->rect.topRight().x() - radius, opt->rect.topRight().y() + radius)); rectInner.moveCenter(rectExternal.center()); p->drawArc(rectInner, 25 * 16, 40 * 16); p->drawArc(rectExternal, 25 * 16, 50 * 16); } else if (corner == Qt::TopLeftCorner) { rectExternal.moveTopLeft(QPointF(opt->rect.topLeft().x() + radius, opt->rect.topLeft().y() + radius)); rectInner.moveCenter(rectExternal.center()); p->drawArc(rectInner, 115 * 16, 40 * 16); p->drawArc(rectExternal, 110 * 16, 50 * 16); } p->restore(); return; } case CE_ItemViewItem: { if (w && w->objectName() == "qt_calendar_calendarview") { if (const QStyleOptionViewItem *vopt = qstyleoption_cast(opt)) { p->save(); p->setClipRect(opt->rect); //绘制禁用项 if (!(vopt->state & QStyle::State_Enabled)) { p->save(); p->setPen(Qt::NoPen); p->setBrush(getColor(vopt, DPalette::Window)); p->drawRect(vopt->rect); p->restore(); } // 绘制当前选中项 proxy()->drawPrimitive(PE_PanelItemViewItem, opt, p, w); // draw the text if (!vopt->text.isEmpty()) { QPalette::ColorGroup cg = vopt->state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active)) cg = QPalette::Inactive; if (vopt->state & QStyle::State_Selected) { p->setPen(vopt->palette.color(cg, QPalette::HighlightedText)); } else { p->setPen(vopt->palette.color(cg, QPalette::Text)); } QCommonStylePrivate *d = reinterpret_cast(qGetPtrHelper(d_ptr)); d->viewItemDrawText(p, vopt, opt->rect); } //绘制日历分割线 if (vopt->index.row() == 0) { p->save(); QColor color = getColor(vopt, DPalette::FrameBorder, w); color.setAlpha(static_cast(255 * 0.05)); QPen pen(color, 2); p->setPen(pen); const QTableView *view = static_cast(w); int margins = DStyle::pixelMetric(proxy(), DStyle::PM_ContentsMargins); if (vopt->index.column() == 0) p->drawLine(vopt->rect.bottomLeft() + QPoint(margins, 0), vopt->rect.bottomRight()); else if (vopt->index.column() == view->model()->columnCount() - 1) { p->drawLine(vopt->rect.bottomLeft(), vopt->rect.bottomRight() - QPoint(margins, 0)); } else { p->drawLine(vopt->rect.bottomLeft(), vopt->rect.bottomRight()); } p->restore(); } // draw the focus rect if (vopt->state & QStyle::State_HasFocus) { QStyleOptionFocusRect o; o.QStyleOption::operator=(*vopt); o.rect = proxy()->subElementRect(SE_ItemViewItemFocusRect, vopt, w); o.state |= QStyle::State_KeyboardFocusChange; o.state |= QStyle::State_Item; QPalette::ColorGroup cg = (vopt->state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled; o.backgroundColor = vopt->palette.color(cg, (vopt->state & QStyle::State_Selected) ? QPalette::Highlight : QPalette::Window); proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, p, w); } p->restore(); } return; } break; } default: break; } DStyle::drawControl(element, opt, p, w); } bool ChameleonStyle::drawTabBar(QPainter *painter, const QStyleOptionTab *tab, const QWidget *widget) const { const QTabBar *m_tabbar = qobject_cast(widget); if (!m_tabbar) return false; painter->fillRect(tab->rect, getColor(tab, QPalette::Window)); painter->save(); bool isTriangularMode = false; bool rtlHorTabs = (tab->direction == Qt::RightToLeft && (tab->shape == QTabBar::RoundedNorth || tab->shape == QTabBar::RoundedSouth)); bool selected = tab->state & State_Selected && tab->state & State_Enabled; bool lastTab = ((!rtlHorTabs && tab->position == QStyleOptionTab::End) || (rtlHorTabs && tab->position == QStyleOptionTab::Beginning)); bool onlyOne = tab->position == QStyleOptionTab::OnlyOneTab; int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, tab, widget); QRect rect = tab->rect.adjusted(0, 0, (onlyOne || lastTab) ? 0 : tabOverlap, 0); QRect r2(rect); int x1 = r2.left(); int x2 = r2.right(); int y1 = r2.top(); int y2 = r2.bottom(); QTransform rotMatrix; bool flip = false; painter->setPen(getColor(tab, DPalette::Shadow)); switch (tab->shape) { case QTabBar::TriangularNorth: rect.adjust(0, 0, 0, -tabOverlap); isTriangularMode = true; break; case QTabBar::TriangularSouth: rect.adjust(0, tabOverlap, 0, 0); isTriangularMode = true; break; case QTabBar::TriangularEast: rect.adjust(tabOverlap, 0, 0, 0); isTriangularMode = true; break; case QTabBar::TriangularWest: rect.adjust(0, 0, -tabOverlap, 0); isTriangularMode = true; break; case QTabBar::RoundedNorth: break; case QTabBar::RoundedSouth: rotMatrix.rotate(180); rotMatrix.translate(0, -rect.height() + 1); rotMatrix.scale(-1, 1); painter->setTransform(rotMatrix, true); break; case QTabBar::RoundedWest: rotMatrix.rotate(180 + 90); rotMatrix.scale(-1, 1); flip = true; painter->setTransform(rotMatrix, true); break; case QTabBar::RoundedEast: rotMatrix.rotate(90); rotMatrix.translate(0, - rect.width() + 1); flip = true; painter->setTransform(rotMatrix, true); break; } if (flip) { QRect tmp = rect; rect = QRect(tmp.y(), tmp.x(), tmp.height(), tmp.width()); int temp = x1; x1 = y1; y1 = temp; temp = x2; x2 = y2; y2 = temp; } QColor lineColor = !isTriangularMode || selected ? Qt::transparent : getColor(tab, QPalette::Light); QColor tabFrameColor = selected ? getColor(tab, QPalette::Window) : getColor(tab, QPalette::Button); if (!(tab->features & QStyleOptionTab::HasFrame)) tabFrameColor = getColor(tab, QPalette::Shadow); if (!isTriangularMode) tabFrameColor = selected ? getColor(tab, QPalette::Highlight) : getColor(tab, QPalette::Button); QPen outlinePen(lineColor, proxy()->pixelMetric(PM_DefaultFrameWidth, tab, widget)); QRect drawRect = rect; painter->setPen(outlinePen); painter->setBrush(tabFrameColor); painter->setRenderHint(QPainter::Antialiasing, true); if (!isTriangularMode) { int buttonRadius = DStyle::pixelMetric(PM_FrameRadius, tab, widget); int buttonBorder = DStyle::pixelMetric(PM_FrameMargins, tab, widget); painter->drawRoundedRect(drawRect.adjusted(buttonBorder, buttonBorder, -buttonBorder, -buttonBorder), buttonRadius, buttonRadius); } else { painter->drawRect(drawRect); } painter->restore(); return true; } bool ChameleonStyle::drawTabBarLabel(QPainter *painter, const QStyleOptionTab *tab, const QWidget *widget) const { if (!widget) return false; bool type_check = false; bool selected = tab->state & State_Selected && tab->state & State_Enabled; if (widget) type_check = widget->property("_d_dtk_tabbartab_type").toBool(); bool visible_close_button = selected; if (visible_close_button) { if (const DTabBar *tb = qobject_cast(widget)) { visible_close_button = tb->tabsClosable(); } else { visible_close_button = false; } } QStyleOptionTab newTab = *tab; if (selected) { QPalette::ColorRole role = type_check ? QPalette::Highlight : QPalette::HighlightedText; newTab.palette.setBrush(QPalette::WindowText, adjustColor(getColor(tab, role), 0, 0, 0, 0, 0, 0, 50)); // 拖拽的tab不需要绘制渐变到透明,因为没有关闭按钮。拖拽标签时是生成图片 QPaintDevice 是 QPixMap bool is_moving_tab = painter->device()->devType() != QInternal::Widget; if (visible_close_button && !is_moving_tab) { QRect tr = proxy()->subElementRect(SE_TabBarTabText, tab, widget); QRect text_rect; if (const DTabBar *tabbar = qobject_cast(widget)) { int alignment = tabbar->property("_d_dtk_tabbar_alignment").toInt(); text_rect = tab->fontMetrics.boundingRect(tr, alignment | Qt::TextShowMnemonic, tab->text); } else { text_rect = tab->fontMetrics.boundingRect(tr, Qt::AlignCenter | Qt::TextShowMnemonic, tab->text); } int close_button_width = proxy()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, tab, widget); // 防止在平板中错误的对文字渐变 if (DGuiApplicationHelper::isTabletEnvironment()) close_button_width = TabBar_TabButtonSize; QBrush brush; //选中状态下文字颜色 if (type_check) { brush = getColor(tab, QPalette::Highlight); } else { brush = newTab.palette.windowText(); } // 小心除以 0 qreal stop = text_rect.width() > 0 ? qreal(tr.right() - close_button_width - text_rect.x() - 5) / text_rect.width() : 1.0; if (stop < 1 && stop > 0 && tr.right() - close_button_width < text_rect.right()) { QLinearGradient lg(0, 0, 1, 0); QGradientStops stops; qreal offset = 5.0 / text_rect.width(); // 接近关闭按钮部分的颜色渐变到透明 stops << QGradientStop{0, brush.color()}; stops << QGradientStop{qMax(0.0, stop - offset), brush.color()}; stops << QGradientStop{stop, QColor(brush.color().red(), brush.color().green(), brush.color().blue(), 100)}; // 保证文字超出最大可显示区域的部分为透明 if (text_rect.right() > tr.right()) stops << QGradientStop{1 - (text_rect.right() - tr.right()) / qreal(text_rect.width()), Qt::transparent}; stops << QGradientStop{1, Qt::transparent}; lg.setCoordinateMode(QLinearGradient::ObjectBoundingMode); lg.setStops(stops); newTab.palette.setBrush(QPalette::WindowText, lg); } else { newTab.palette.setBrush(QPalette::WindowText, brush); } } // 禁止QCommonStyle中绘制默认的焦点颜色 newTab.state &= ~QStyle::State_HasFocus; if (tab->state & QStyle::State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*tab); proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); } } else { if (type_check) { newTab.palette.setBrush(QPalette::WindowText, QColor("#798190")); } //靠近边缘的文字渐变 if (const DTabBar *tab = qobject_cast(widget)) { if (!tab->expanding()) { QRect tr = proxy()->subElementRect(SE_TabBarTabText, &newTab, widget); int alignment = tab->property("_d_dtk_tabbar_alignment").toInt(); QRect text_rect = newTab.fontMetrics.boundingRect(tr, alignment | Qt::TextShowMnemonic, newTab.text); QRect tabbar_rect = widget->findChild()->rect(); bool vertTabs = verticalTabs(newTab.shape); int stopx = tabbar_rect.x() + (vertTabs ? tabbar_rect.height() : tabbar_rect.width()); int tabX = (vertTabs ? newTab.rect.y() : text_rect.x()) + (vertTabs ? tabbar_rect.y() : tabbar_rect.x()); int tabWidth = tabX + text_rect.width(); if (text_rect.width() > 0 && tabX < stopx && stopx < tabWidth) { const QBrush &brush = newTab.palette.windowText(); QLinearGradient lg(0, 0, 1, 0); QGradientStops stops; qreal stop = static_cast(tabWidth - stopx) / text_rect.width(); stops << QGradientStop{0, brush.color()}; stops << QGradientStop{qMax(0.0, 1 - stop - 0.2), brush.color()}; stops << QGradientStop{qMax(0.0, 1 - stop), Qt::transparent}; lg.setCoordinateMode(QLinearGradient::ObjectBoundingMode); lg.setStops(stops); newTab.palette.setBrush(QPalette::WindowText, lg); } } } } if (const DTabBar *tb = qobject_cast(widget)) { //Qt源码 QRect tr = tab->rect; bool verticalTabs = tab->shape == QTabBar::RoundedEast || tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularEast || tab->shape == QTabBar::TriangularWest; int alignment = tb->property("_d_dtk_tabbar_alignment").toInt() | Qt::TextShowMnemonic; if (!proxy()->styleHint(SH_UnderlineShortcut, &newTab, widget)) alignment |= Qt::TextHideMnemonic; if (verticalTabs) { painter->save(); int newX, newY, newRot; if (tab->shape == QTabBar::RoundedEast || tab->shape == QTabBar::TriangularEast) { newX = tr.width() + tr.x(); newY = tr.y(); newRot = 90; } else { newX = tr.x(); newY = tr.y() + tr.height(); newRot = -90; } QTransform m = QTransform::fromTranslate(newX, newY); m.rotate(newRot); painter->setTransform(m, true); } QRect iconRect; tabLayout(tab, widget, &tr, &iconRect); tr = proxy()->subElementRect(SE_TabBarTabText, &newTab, widget); if (!tab->icon.isNull()) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QPixmap tabIcon = tab->icon.pixmap( tab->iconSize, widget ? widget->devicePixelRatio() : qApp->devicePixelRatio(), (tab->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled, (tab->state & State_Selected) ? QIcon::On : QIcon::Off); #else QPixmap tabIcon = tab->icon.pixmap(widget ? widget->window()->windowHandle() : 0, tab->iconSize, (tab->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled, (tab->state & State_Selected) ? QIcon::On : QIcon::Off); #endif painter->drawPixmap(iconRect, tabIcon); } proxy()->drawItemText(painter, tr.adjusted(1, 0, 0, 0), alignment, newTab.palette, newTab.state & State_Enabled, newTab.text, QPalette::WindowText); if (verticalTabs) painter->restore(); } else { QCommonStyle::drawControl(CE_TabBarTabLabel, &newTab, painter, widget); } return true; } void ChameleonStyle::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const { QRect tr = opt->rect; bool verticalTabs = opt->shape == QTabBar::RoundedEast || opt->shape == QTabBar::RoundedWest || opt->shape == QTabBar::TriangularEast || opt->shape == QTabBar::TriangularWest; if (verticalTabs) tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget); int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget); int hpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2; int vpadding = proxy()->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2; if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth) verticalShift = -verticalShift; tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding); bool selected = opt->state & QStyle::State_Selected; if (selected) { tr.setTop(tr.top() - verticalShift); tr.setRight(tr.right() - horizontalShift); } // left widget if (!opt->leftButtonSize.isEmpty()) { tr.setLeft(tr.left() + 4 + (verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width())); } // right widget if (!opt->rightButtonSize.isEmpty()) { tr.setRight(tr.right() - 4 - (verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width())); } // icon if (!opt->icon.isNull()) { QSize iconSize = opt->iconSize; if (!iconSize.isValid()) { int iconExtent = proxy()->pixelMetric(QStyle::PM_SmallIconSize); iconSize = QSize(iconExtent, iconExtent); } QSize tabIconSize = opt->icon.actualSize(iconSize, (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled, (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off); // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height())); // 由于Qt的历史原因 center 返回的坐标总是比矩形的真是中心坐标少一个像素 导致绘制图标时竖直方向无法对齐 *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2 + 1, tabIconSize.width(), tabIconSize.height()); if (!verticalTabs) *iconRect = proxy()->visualRect(opt->direction, opt->rect, *iconRect); tr.setLeft(tr.left() + tabIconSize.width() + 4); } if (!verticalTabs) tr = proxy()->visualRect(opt->direction, opt->rect, tr); *textRect = tr; } bool ChameleonStyle::drawTableViewItem(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const { if(!qobject_cast(w)) return false; const QStyleOptionViewItem *vopt = qstyleoption_cast(opt); if (!vopt) return false; int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); QRect select_rect = opt->rect; // 设置item的背景颜色 p->setPen(Qt::NoPen); if (vopt->state & QStyle::State_Selected) { if (!vopt->showDecorationSelected) { select_rect = proxy()->subElementRect(QStyle::SE_ItemViewItemText, opt, w); } else { select_rect -= frameExtentMargins(); } p->setBrush(getColor(opt, QPalette::Highlight)); } else { p->setBrush(vopt->backgroundBrush); } // 绘制背景,选中的item圆角由属性来控制 if (w->property("_d_dtk_enable_tableviewitem_radius").toBool()) { p->setRenderHint(QPainter::Antialiasing); p->drawRoundedRect(select_rect, frame_radius, frame_radius); } else { // 所有的item都是非圆角 const_cast(vopt)->palette.setBrush(vopt->palette.currentColorGroup(), QPalette::Highlight, getColor(opt, QPalette::Highlight)); DStyle::drawPrimitive(pe, vopt, p, w); } return true; } bool ChameleonStyle::drawTabBarCloseButton(QPainter *painter, const QStyleOption *tab, const QWidget *widget) const { if (!widget) return false; const QTabBar *tb = qobject_cast(widget->parent()); if (!tb) { if (const QWidget *w = dynamic_cast(painter->device())) widget = w; tb = qobject_cast(widget->parent()); } if (Q_UNLIKELY(!tb)) return false; int index = -1; for (int i = 0; i < tb->count(); ++i) { if (Q_LIKELY(tb->tabButton(i, QTabBar::LeftSide) != widget && tb->tabButton(i, QTabBar::RightSide) != widget)) { continue; } index = i; break; } if (Q_UNLIKELY(index < 0)) return true; QStyleOptionButton buttonOpt; buttonOpt.rect = tab->rect; buttonOpt.state = tab->state; QColor iconColor = getColor(&buttonOpt, QPalette::ButtonText); painter->setPen(QPen(iconColor, 2)); painter->setBrush(getColor(&buttonOpt, QPalette::Button)); DDrawUtils::drawCloseButton(painter, buttonOpt.rect); return true; } bool ChameleonStyle::drawTabBarScrollButton(QPainter *painter, const QStyleOption *opt, const QWidget *buttonWidget) const { const QToolButton *tabButton = qobject_cast(buttonWidget); if (!tabButton) return false; if (tabButton->arrowType() == Qt::NoArrow || !tabButton->icon().isNull()) return false; bool isTriangularMode = false; if (QTabBar *tabBar = qobject_cast(buttonWidget->parent())) { switch (tabBar->shape()) { case QTabBar::TriangularNorth: case QTabBar::TriangularSouth: case QTabBar::TriangularEast: case QTabBar::TriangularWest: isTriangularMode = true; break; default: break; } } QStyleOptionToolButton toolButton(*qstyleoption_cast(opt)); int frameMargin = DStyle::pixelMetric(PM_FrameMargins); toolButton.rect -= QMargins(frameMargin, frameMargin, frameMargin, frameMargin); QPoint center = toolButton.rect.center(); qreal sizeRatio = isTriangularMode ? (4.0 / 7.0) : 1.0; int minBoundWidth = qMin(toolButton.rect.width(), toolButton.rect.height()); toolButton.rect.setWidth(qRound(minBoundWidth * sizeRatio)); toolButton.rect.setHeight(qRound(minBoundWidth * sizeRatio)); toolButton.rect.moveCenter(center); DDrawUtils::Corners corner = static_cast(0xff); int radius = isTriangularMode ? toolButton.rect.width() / 2 : DStyle::pixelMetric(PM_FrameRadius); QLinearGradient lg(QPointF(0, opt->rect.top()), QPointF(0, opt->rect.bottom())); lg.setColorAt(0, getColor(opt, QPalette::Light)); lg.setColorAt(1, getColor(opt, QPalette::Dark)); painter->setPen(QPen(getColor(opt, DPalette::FrameBorder, buttonWidget), Metrics::Painter_PenWidth)); painter->setBrush(lg); painter->setRenderHint(QPainter::Antialiasing); drawShadow(painter, toolButton.rect + frameExtentMargins() * 1.5, getColor(&toolButton, QPalette::Shadow)); DDrawUtils::drawRoundedRect(painter, toolButton.rect, radius, radius, corner); QPoint originCenter = toolButton.rect.center(); qreal buttonSizeRatio = isTriangularMode ? 3.0 / 4.0 : 1.0 / 2.0; toolButton.rect.setWidth(qRound(toolButton.rect.width() * buttonSizeRatio)); toolButton.rect.setHeight(qRound(toolButton.rect.height() * buttonSizeRatio)); toolButton.rect.moveCenter(originCenter); proxy()->drawControl(CE_ToolButtonLabel, &toolButton, painter, buttonWidget); return true; } bool ChameleonStyle::drawComboBox(QPainter *painter, const QStyleOptionComboBox *comboBox, const QWidget *widget) const { QRect rect(comboBox->rect); QStyleOptionComboBox comboBoxCopy = *comboBox; QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, &comboBoxCopy, SC_ComboBoxArrow, widget); if (comboBox->frame && comboBox->subControls & SC_ComboBoxFrame) { int frameRadius = DStyle::pixelMetric(PM_FrameRadius); painter->setPen(Qt::NoPen); painter->setRenderHint(QPainter::Antialiasing); if (comboBox->editable) { QBrush brush = getThemTypeColor(QColor(0, 0, 0, 255 * 0.08), QColor(255, 255, 255, 255 * 0.15)); if (widget->testAttribute(Qt::WA_SetPalette)) { brush = comboBox->palette.button(); } else if (const QComboBox *combobox = qobject_cast(widget)) { if (auto lineEdit = combobox->lineEdit()) { if (lineEdit->testAttribute(Qt::WA_SetPalette)) { brush = lineEdit->palette().button(); } else { brush = getBrush(comboBox, QPalette::Button); } } } painter->setBrush(brush); } else { painter->setBrush(Qt::transparent); } DDrawUtils::drawRoundedRect(painter, comboBoxCopy.rect, frameRadius, frameRadius, DDrawUtils::Corner::TopLeftCorner | DDrawUtils::Corner::TopRightCorner | DDrawUtils::Corner::BottomLeftCorner | DDrawUtils::Corner::BottomRightCorner); } QStyleOptionButton buttonOption; buttonOption.QStyleOption::operator=(*comboBox); if (comboBox->editable) { buttonOption.rect = rect; buttonOption.state = (comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus)) | State_KeyboardFocusChange; // Always show hig if (comboBox->state & State_Sunken) { buttonOption.state |= State_Sunken; buttonOption.state &= ~State_MouseOver; } if (comboBox->direction == Qt::LeftToRight) buttonOption.rect.setLeft(downArrowRect.left()); else buttonOption.rect.setRight(downArrowRect.right()); downArrowRect.moveCenter(buttonOption.rect.center()); proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); } else { buttonOption.rect = rect; buttonOption.state = comboBox->state & (State_Enabled | State_MouseOver | State_HasFocus | State_KeyboardFocusChange); if (comboBox->state & State_Sunken) { buttonOption.state |= State_Sunken; buttonOption.state &= ~State_MouseOver; } downArrowRect.moveCenter(buttonOption.rect.center()); if (comboBox->direction == Qt::LeftToRight) { downArrowRect.moveRight(buttonOption.rect.right()); } else { downArrowRect.moveLeft(buttonOption.rect.left()); } proxy()->drawPrimitive(PE_PanelButtonCommand, &buttonOption, painter, widget); } if (comboBox->subControls & SC_ComboBoxArrow) { QStyleOption arrowOpt = *comboBox; arrowOpt.rect = downArrowRect - frameExtentMargins(); if (comboBox->editable) { arrowOpt.rect.setSize(QSize(qRound(buttonOption.rect.width() / 3.0), qRound(buttonOption.rect.height() / 3.0))); arrowOpt.rect.moveCenter(buttonOption.rect.center()); } else { QPoint center = arrowOpt.rect.center(); arrowOpt.rect.setSize(QSize(qRound(arrowOpt.rect.height() / 2.4), qRound(arrowOpt.rect.height() / 2.4))); arrowOpt.rect.moveCenter(center); int radius = DStyle::pixelMetric(PM_FrameRadius); if (comboBox->direction == Qt::RightToLeft) { arrowOpt.rect = arrowOpt.rect.adjusted(radius, 0, radius, 0); } else { arrowOpt.rect = arrowOpt.rect.adjusted(-radius , 0, -radius, 0); } } painter->setPen(getColor(comboBox, DPalette::ButtonText)); proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); } if (comboBox->state.testFlag(QStyle::State_HasFocus)) { proxy()->drawPrimitive(PE_FrameFocusRect, comboBox, painter, widget); } return true; } bool ChameleonStyle::drawComboBoxLabel(QPainter *painter, const QStyleOptionComboBox *cb, const QWidget *widget) const { const bool hasText(!cb->currentText.isEmpty()); const bool hasIcon(!cb->currentIcon.isNull()); // const bool enabled(cb->state & QStyle::State_Enabled); const bool sunken(cb->state & (QStyle::State_On | QStyle::State_Sunken)); // const bool mouseOver(cb->state & QStyle::State_MouseOver); // const bool hasFocus(cb->state & QStyle::State_HasFocus); const bool flat(!cb->frame); const bool editable(cb->editable); QRect contentsRect(cb->rect); if (sunken && !flat) contentsRect.translate(1, 1); contentsRect.adjust(Metrics::Layout_ChildMarginWidth, 0, -Metrics::Layout_ChildMarginWidth - DStyle::pixelMetric(PM_FrameRadius) * 2, 0); QSize iconSize; if (hasIcon) { iconSize = cb->iconSize; if (!iconSize.isValid() && widget) { const int metric(widget->style()->pixelMetric(QStyle::PM_SmallIconSize, cb, widget)); iconSize = QSize(metric, metric); } } int textFlags(Qt::AlignVCenter | Qt::AlignLeft); const QSize textSize(cb->fontMetrics.size(textFlags, cb->currentText)); if (styleHint(SH_UnderlineShortcut, cb, widget)) textFlags |= Qt::TextShowMnemonic; else textFlags |= Qt::TextHideMnemonic; QRect iconRect; QRect textRect; QRect downArrowRect = proxy()->subControlRect(CC_ComboBox, cb, SC_ComboBoxArrow, widget); if (hasText && !hasIcon) { textRect = contentsRect; int leftMargin = Metrics::ComboBox_ContentLeftMargin; textRect.adjust(leftMargin, 0, 0, 0); textRect.setWidth(textRect.width() - downArrowRect.width()); } else { const int contentsWidth(iconSize.width() + textSize.width() + Metrics::Button_ItemSpacing); const int contentLeftPadding = flat ? (contentsRect.width() - contentsWidth) / 2 : Metrics::ComboBox_ContentLeftMargin; iconRect = QRect(QPoint(contentsRect.left() + contentLeftPadding, contentsRect.top() + (contentsRect.height() - iconSize.height()) / 2), iconSize); const int availableTextWidth = contentsRect.width() - contentLeftPadding - iconSize.width() - Metrics::Icon_Margins - downArrowRect.width(); textRect = QRect(QPoint(iconRect.right() + Metrics::Icon_Margins + 1, contentsRect.top() + (contentsRect.height() - textSize.height()) / 2), QSize(availableTextWidth, textSize.height())); } // handle right to left if (iconRect.isValid()) iconRect = visualRect(cb->direction, contentsRect, iconRect); if (textRect.isValid()) textRect = visualRect(cb->direction, contentsRect, textRect); // render icon if (hasIcon && iconRect.isValid()) { // icon state and mode cb->currentIcon.paint(painter, iconRect, Qt::AlignLeft); } // render text if (hasText && textRect.isValid() && !editable) { painter->setPen(getColor(cb, QPalette::ButtonText)); QString text = painter->fontMetrics().elidedText(cb->currentText, Qt::ElideRight, textRect.width()); textRect.setWidth(textRect.width() + downArrowRect.width()); painter->drawText(textRect, textFlags, text); } return true; } void ChameleonStyle::drawSliderHandle(const QStyleOptionComplex *opt, QRectF& rectHandle, QPainter *p, const QWidget *w) const { if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { const DSlider *dslider = qobject_cast(w); QSlider::TickPosition tickPosition = slider->tickPosition; if (dslider) tickPosition = dslider->tickPosition(); if (tickPosition == QSlider::NoTicks) { p->drawRoundedRect(rectHandle, DStyle::pixelMetric(DStyle::PM_FrameRadius), DStyle::pixelMetric(DStyle::PM_FrameRadius)); } else { qreal radius = DStyle::pixelMetric(DStyle::PM_FrameRadius); QRectF rectRoundedPart(0, 0, 0, 0); if (slider->orientation == Qt::Horizontal) { if (tickPosition == QSlider::TicksAbove) { //尖角朝上 rectRoundedPart = QRectF(rectHandle.left(), rectHandle.bottom() - 2 * radius, rectHandle.width(), 2 * radius); QPointF polygon[5] = { QPointF(rectHandle.left(), rectHandle.bottom() - radius) , QPointF(rectHandle.left(), rectHandle.top() + radius) , QPointF(rectHandle.center().x(), rectHandle.top()) , QPointF(rectHandle.right(), rectHandle.top() + radius) , QPointF(rectHandle.right(), rectHandle.bottom() - radius)}; p->drawPolygon(polygon, 5); } else { //尖角朝下 rectRoundedPart = QRectF(rectHandle.left(), rectHandle.top(), rectHandle.width(), 2 * radius); QPointF polygon[5] = { QPointF(rectHandle.left(), rectHandle.top() + radius) , QPointF(rectHandle.left(), rectHandle.bottom() - radius) , QPointF(rectHandle.center().x(), rectHandle.bottom()) , QPointF(rectHandle.right(), rectHandle.bottom() - radius) , QPointF(rectHandle.right(), rectHandle.top() + radius)}; p->drawPolygon(polygon, 5); } } else { if (tickPosition == QSlider::TicksLeft) { //尖角朝左 rectRoundedPart = QRectF(rectHandle.right() - 2 * radius, rectHandle.top(), 2 * radius, rectHandle.height()); QPointF polygon[5] = { QPointF(rectHandle.right() - radius, rectHandle.top()) , QPointF(rectHandle.left() + radius, rectHandle.top()) , QPointF(rectHandle.left(), rectHandle.center().y()) , QPointF(rectHandle.left() + radius, rectHandle.bottom()) , QPointF(rectHandle.right() - radius, rectHandle.bottom())}; p->drawPolygon(polygon, 5); } else { //尖角朝右 rectRoundedPart = QRectF(rectHandle.left(), rectHandle.top(), 2 * radius, rectHandle.height()); QPointF polygon[5] = { QPointF(rectHandle.left() + radius, rectHandle.top()) , QPointF(rectHandle.right() - radius, rectHandle.top()) , QPointF(rectHandle.right(), rectHandle.center().y()) , QPointF(rectHandle.right() - radius, rectHandle.bottom()) , QPointF(rectHandle.left() + radius, rectHandle.bottom())}; p->drawPolygon(polygon, 5); } } p->drawRoundedRect(rectRoundedPart, DStyle::pixelMetric(DStyle::PM_FrameRadius), DStyle::pixelMetric(DStyle::PM_FrameRadius)); } } } void ChameleonStyle::drawSliderHandleFocus(const QStyleOptionComplex *opt, QRectF &rectHandle, QPainter *p, const QWidget *w) const { if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { const DSlider *dslider = qobject_cast(w); QSlider::TickPosition tickPosition = slider->tickPosition; int lineOffset = DStyle::pixelMetric(PM_FocusBorderWidth) / 2; int margin = DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing); int marginRect = DStyle::pixelMetric(PM_FocusBorderSpacing) + lineOffset; if (dslider) tickPosition = dslider->tickPosition(); if (tickPosition == QSlider::NoTicks) { p->drawRoundedRect(rectHandle.adjusted(-marginRect, -marginRect, marginRect, marginRect), DStyle::pixelMetric(DStyle::PM_FrameRadius) + marginRect, DStyle::pixelMetric(DStyle::PM_FrameRadius) + marginRect); } else { qreal radius = DStyle::pixelMetric(DStyle::PM_FrameRadius); QPainterPath focusPath; if (slider->orientation == Qt::Horizontal) { if (tickPosition == QSlider::TicksAbove) { //尖角朝上 focusPath.moveTo(QPointF(rectHandle.left() - marginRect, rectHandle.bottom() - radius)); focusPath.lineTo(QPointF(rectHandle.left() - marginRect, rectHandle.top() + radius - lineOffset)); focusPath.lineTo(QPointF(rectHandle.center().x(), rectHandle.top() - margin)); focusPath.lineTo(QPointF(rectHandle.right() + marginRect, rectHandle.top() + radius - lineOffset)); focusPath.lineTo(QPointF(rectHandle.right() + marginRect, rectHandle.bottom() - radius)); focusPath.arcTo(QRectF(rectHandle.right() - radius -radius - marginRect, rectHandle.bottom() - radius - radius -marginRect, 2 *(radius + marginRect), 2 * (radius + marginRect)), -0, -90); focusPath.lineTo(QPointF(rectHandle.left() + radius, rectHandle.bottom() + marginRect)); focusPath.arcTo(QRectF(rectHandle.left() - marginRect, rectHandle.bottom() - radius -radius -marginRect, 2 * (radius + marginRect), 2 * (radius + marginRect)), -90, -90); } else { //尖角朝下 focusPath.moveTo(QPointF(rectHandle.left() - marginRect, rectHandle.top() + radius)); focusPath.lineTo(QPointF(rectHandle.left() - marginRect, rectHandle.bottom() - radius + lineOffset)); focusPath.lineTo(QPointF(rectHandle.center().x(), rectHandle.bottom() + margin)); focusPath.lineTo(QPointF(rectHandle.right() + marginRect, rectHandle.bottom() - radius + lineOffset)); focusPath.lineTo(QPointF(rectHandle.right() + marginRect, rectHandle.top() + radius)); focusPath.arcTo(QRectF(rectHandle.right() - radius -radius - marginRect, rectHandle.top() - marginRect, 2 *(radius + marginRect), 2 * (radius + marginRect)), 0, 90); focusPath.lineTo(QPointF(rectHandle.left() + radius, rectHandle.top() - marginRect)); focusPath.arcTo(QRectF(rectHandle.left() - marginRect, rectHandle.top() - marginRect, 2 * (radius + marginRect), 2 * (radius + marginRect)), 90, 90); } } else { if (tickPosition == QSlider::TicksLeft) { //尖角朝左 focusPath.moveTo(QPointF(rectHandle.right() - radius, rectHandle.top() - marginRect)); focusPath.lineTo(QPointF(rectHandle.left() + radius - lineOffset, rectHandle.top() - marginRect)); focusPath.lineTo(QPointF(rectHandle.left() - margin, rectHandle.center().y())); focusPath.lineTo(QPointF(rectHandle.left() + radius - lineOffset, rectHandle.bottom() + marginRect)); focusPath.lineTo(QPointF(rectHandle.right() - radius, rectHandle.bottom() + marginRect)); focusPath.arcTo(QRectF(rectHandle.right() - radius - radius - marginRect, rectHandle.bottom() - radius - radius - marginRect, 2 *(radius + marginRect), 2 * (radius + marginRect)), -90, 90); focusPath.lineTo(QPointF(rectHandle.right() + marginRect, rectHandle.top() + radius)); focusPath.arcTo(QRectF(rectHandle.right() - radius - radius - marginRect, rectHandle.top() - marginRect, 2 * (radius + marginRect), 2 * (radius + marginRect)), 0, 90); } else { //尖角朝右 focusPath.moveTo(QPointF(rectHandle.left() + radius, rectHandle.top() - marginRect)); focusPath.lineTo(QPointF(rectHandle.right() - radius + lineOffset, rectHandle.top() - marginRect)); focusPath.lineTo(QPointF(rectHandle.right() + margin, rectHandle.center().y())); focusPath.lineTo(QPointF(rectHandle.right() - radius + lineOffset, rectHandle.bottom() + marginRect)); focusPath.lineTo(QPointF(rectHandle.left() + radius, rectHandle.bottom() + marginRect)); focusPath.arcTo(QRectF(rectHandle.left() - marginRect, rectHandle.bottom() - radius - radius - marginRect, 2 *(radius + marginRect), 2 * (radius + marginRect)), -90, -90); focusPath.lineTo(QPointF(rectHandle.left() - marginRect, rectHandle.top() + radius)); focusPath.arcTo(QRectF(rectHandle.left() - marginRect, rectHandle.top() - marginRect, 2 * (radius + marginRect), 2 * (radius + marginRect)), 180, -90); } } p->drawPath(focusPath); } } } void ChameleonStyle::drawIcon(const QStyleOption *opt, QPainter *p, QRect& rect, const QIcon& icon, bool checked) const { bool enabled = opt->state & State_Enabled; bool selected = opt->state & State_Selected && enabled; QIcon::Mode mode = !enabled ? QIcon::Disabled : (selected ? QIcon::Selected : QIcon::Normal); if (mode == QIcon::Normal && opt->state & State_On) mode = QIcon::Selected; icon.paint(p, rect, Qt::AlignCenter, mode, checked ? QIcon::On : QIcon::Off); } #ifndef QT_NO_ANIMATION dstyle::DStyleAnimation *ChameleonStyle::animation(const QObject *target) const { return animations.value(target, nullptr); } void ChameleonStyle::startAnimation(dstyle::DStyleAnimation *animation, int delay) const { connect(animation, &dstyle::DStyleAnimation::destroyed, this, &ChameleonStyle::_q_removeAnimation, Qt::UniqueConnection); animations.insert(animation->target(), animation); if (delay > 0) { QTimer::singleShot(delay, animation, SLOT(start())); } else { animation->start(); } } void ChameleonStyle::_q_removeAnimation() { QObject* animation = sender(); if (animation) animations.remove(animation->parent()); } #endif bool ChameleonStyle::drawMenuBarItem(const QStyleOptionMenuItem *option, QRect &rect, QPainter *painter, const QWidget *widget) const { bool enabled(option->state & QStyle::State_Enabled); bool mouseOver((option->state & QStyle::State_MouseOver) && enabled); bool sunken((option->state & QStyle::State_Sunken) && enabled); if (mouseOver || sunken) { QBrush background(getColor(option, QPalette::Highlight)); qreal radius = DStyle::pixelMetric(DStyle::PM_FrameRadius); painter->setRenderHint(QPainter::Antialiasing); painter->setPen(Qt::NoPen); painter->setBrush(background); painter->drawRoundedRect(rect, radius, radius); } if (option) { int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!proxy()->styleHint(SH_UnderlineShortcut, option, widget)) alignment |= Qt::TextHideMnemonic; int iconExtent = proxy()->pixelMetric(PM_SmallIconSize); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) QPixmap pix = option->icon.pixmap( QSize(iconExtent, iconExtent), widget ? widget->devicePixelRatio() : qApp->devicePixelRatio(), (enabled) ? (mouseOver ? QIcon::Active : QIcon::Normal) : QIcon::Disabled); #else QPixmap pix = option->icon.pixmap( widget ? widget->window()->windowHandle() : nullptr, QSize(iconExtent, iconExtent), (enabled) ? (mouseOver ? QIcon::Active : QIcon::Normal) : QIcon::Disabled); #endif if (!pix.isNull()) { proxy()->drawItemPixmap(painter, option->rect, alignment, pix); } else { QStyleOptionMenuItem itemOption = *option; if (mouseOver || sunken) itemOption.palette.setBrush(QPalette::ButtonText, itemOption.palette.highlightedText()); proxy()->drawItemText(painter, itemOption.rect, alignment, itemOption.palette, enabled, itemOption.text, QPalette::ButtonText); } } return true; } ChameleonMovementAnimation *ChameleonStyle::drawMenuItemBackground(const QStyleOption *option, QPainter *painter, QStyleOptionMenuItem::MenuItemType type) const { QBrush color; constexpr int margin = 6; // margin of MenuItem's bounding. const auto rect = option->rect.marginsRemoved(QMargins(margin, 0, margin, 0)); bool selected = (option->state & QStyle::State_Enabled) && option->state & QStyle::State_Selected; if (selected && (DGuiApplicationHelper::isTabletEnvironment() || !DGuiApplicationHelper::isSpecialEffectsEnvironment())) { painter->setPen(Qt::NoPen); painter->setBrush(getColor(option, QPalette::Highlight)); painter->drawRect(rect); return nullptr; } if (!selected) { do { color = option->palette.window().color(); if (color.color().isValid() && color.color().alpha() != 0) { QColor c = color.color(); // 未开启窗口混成时不应该设置背景色的alpha通道,应当显示纯色背景(设置StyleSheet时,不加载此设置,防止alpha通道等对其造成影响) if (DWindowManagerHelper::instance()->hasComposite() && qobject_cast(option->styleObject) && !qobject_cast(option->styleObject)->testAttribute(Qt::WA_StyleSheet)) { if (DGuiApplicationHelper::toColorType(c) == DGuiApplicationHelper::LightType) { c = Qt::white; c.setAlphaF(0.4); } else { //在深色背景下,为了处理QComboBox的ListView的背景色和menuItem的背景色不一致的问题,加一个判断 if (qobject_cast(option->styleObject)) c = DGuiApplicationHelper::adjustColor(c, 0, 0, -10, 0, 0, 0, 0); c.setAlphaF(0.8); } } color = c; } if (type == QStyleOptionMenuItem::Separator) { QColor colorSeparator; DGuiApplicationHelper *guiAppHelp = DGuiApplicationHelper::instance(); if (guiAppHelp->themeType() == DGuiApplicationHelper::ColorType::DarkType) colorSeparator = QColor(255, 255, 255, 255 * 0.05); else colorSeparator = QColor(0, 0, 0, 255 * 0.1); painter->fillRect(rect, colorSeparator); } if (!option->styleObject) break; } while (false); } { // 无论如何都尝试绘制,因为可能有动画存在 color = option->palette.highlight(); QWidget *animationTargetWidget = qobject_cast(option->styleObject); if (!option->styleObject) animationTargetWidget = dynamic_cast(painter->device()); ChameleonMovementAnimation *animation = nullptr; if (DGuiApplicationHelper::testAttribute(DGuiApplicationHelper::HasAnimations) && animationTargetWidget) { animation = animationTargetWidget->findChild("_d_menu_select_animation", Qt::FindDirectChildrenOnly); if (!animation) { animation = new ChameleonMovementAnimation(animationTargetWidget); animation->setObjectName("_d_menu_select_animation"); } if (selected) animation->setTargetRect(rect); } const int round = 6; if (animation && animation->isRuning()) { painter->save(); auto opacity = painter->opacity(); // 一些状态为 disable 的 menu item 在绘制时会修改不透明度,这里暂时改回1.0。 painter->setOpacity(1.0); painter->setBrush(color); painter->setPen(Qt::NoPen); painter->setRenderHint(QPainter::Antialiasing); painter->drawRoundedRect(animation->currentRect(), round, round); painter->setOpacity(opacity); painter->restore(); return animation; } else if (selected) { painter->save(); painter->setBrush(color); painter->setPen(Qt::NoPen); painter->setRenderHint(QPainter::Antialiasing); painter->drawRoundedRect(rect, round, round); painter->restore(); } } return nullptr; } void ChameleonStyle::drawMenuItemRedPoint(const QStyleOptionMenuItem *option, QPainter *painter, const QWidget *widget) const { if (!(option->state & QStyle::State_Enabled)) return; QAction *action = nullptr; if (const QMenu *menu = qobject_cast(widget)) { action = menu->actionAt(option->rect.center()); } if (!action) return; QObject *obj = action; if (option->menuItemType == QStyleOptionMenuItem::SubMenu) { obj = action->menu(); } if (!obj->property("_d_menu_item_redpoint").toBool()) return; int h = 6, w = 6; // red point size 6x6 #ifdef ENABLE_RED_POINT_TEXT QString text = obj->property("_d_menu_item_info").toString(); QFont f = option->font; f.setPointSize(8); if (!text.isEmpty()) { QFontMetrics fontMetrics(f); h = fontMetrics.height(); w = fontMetrics.horizontalAdvance(text) + Menu_ItemVTextMargin * 2; // margin left/right 4 } #endif QPainterPath path; QRectF rcf(option->rect); rcf.setWidth(w); rcf.setHeight(h); rcf.moveTop(option->rect.top() + (option->rect.height() - h) / 2.0); // vcenter rcf.moveLeft(option->rect.right() - w - 24); // 离右侧24像素 #ifdef ENABLE_RED_POINT_TEXT if (!text.isEmpty()) { path.addRoundRect(rcf, 50, 99); // 0 is angled corners, 99 is maximum roundedness. } else #endif { path.addEllipse(rcf); } painter->save(); painter->setRenderHint(QPainter::Antialiasing); painter->fillPath(path, QColor("#FF3B30")); // color from ui.ds QPen oldpen = painter->pen(); painter->setPen(QColor("#14000000")); // 外描边,边边颜色为8%的黑 hex(255*8/100) painter->drawEllipse(rcf); painter->setPen(oldpen); #ifdef ENABLE_RED_POINT_TEXT if (!text.isEmpty()) { painter->setPen(Qt::white); // 文字白色 painter->setFont(f); painter->drawText(QPointF(rcf.left() + 4, rcf.bottom() - 4), text.left(3)); } #endif painter->restore(); } bool ChameleonStyle::drawMenuItem(const QStyleOptionMenuItem *option, QPainter *painter, const QWidget *widget) const { if (const QStyleOptionMenuItem *menuItem = option) { //绘制背景 QRect menuRect = menuItem->rect; bool enabled = menuItem->state & State_Enabled; bool selected = menuItem->state & State_Selected && enabled; bool checkable = menuItem->checkType != QStyleOptionMenuItem::NotCheckable; bool checked = menuItem->checked; bool sunken = menuItem->state & State_Sunken; //绘制背景 auto animation = drawMenuItemBackground(option, painter, menuItem->menuItemType); //绘制分段 if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { if (!menuItem->text.isEmpty()) { painter->setFont(menuItem->font); painter->setPen(Qt::NoPen); painter->setBrush(Qt::NoBrush); proxy()->drawItemText(painter, menuRect , menuItem->direction == Qt::LeftToRight ? (Qt::AlignLeft | Qt::AlignVCenter) : (Qt::AlignRight | Qt::AlignVCenter) , menuItem->palette, menuItem->state & State_Enabled, menuItem->text , QPalette::WindowText); } return true; } const bool useHighlightedText = selected && !animation; if (!useHighlightedText && selected) { // 在动画中时,selected item 的文字颜色不会使用 HighlightedText,当动画结束后会立即 // 变为 HighlightedText,会显得比较突然,因此使用不透明度对文本等内容进行过渡 painter->setOpacity(1.0 - animation->progress()); } //绘制选择框 bool ignoreCheckMark = false; int frameRadius = DStyle::pixelMetric(PM_FrameRadius); //打钩矩形的左侧距离item的左边缘; 也是 打钩矩形的右侧距离 图文内容的左边缘 int smallIconSize = proxy()->pixelMetric(PM_ButtonIconSize, option, widget);//打钩的宽度 int realMargins = smallIconSize + 2 * frameRadius; //左侧固定预留的margin,无论是否能够打钩都要预留 if (!ignoreCheckMark) { /*checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);*/ QRect checkRect(menuItem->rect); if (checkable) { checkRect.setLeft(frameRadius); checkRect.setWidth(smallIconSize - 2); checkRect.setHeight(smallIconSize - 4); checkRect.moveCenter(QPoint(checkRect.left() + smallIconSize / 2, menuItem->rect.center().y())); painter->setRenderHint(QPainter::Antialiasing); if (useHighlightedText) painter->setPen(getColor(option, QPalette::HighlightedText)); else painter->setPen(getColor(option, QPalette::BrightText)); if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) { //单选框 if (checked || sunken) { QIcon markIcon = DStyle::standardIcon(SP_MarkElement, option, widget); markIcon.paint(painter, checkRect); } } else if (checked) { //复选框 QIcon markIcon = DStyle::standardIcon(SP_MarkElement, option, widget); markIcon.paint(painter, checkRect); } else { } } } else { //ignore checkmark //用于combobox } if (useHighlightedText) { painter->setPen(getColor(option, QPalette::HighlightedText)); } else { if ((option->state & QStyle::State_Enabled)) { painter->setPen(getColor(option, QPalette::BrightText)); } else { QColor color = option->palette.color(QPalette::Active, QPalette::BrightText); color = DStyle::adjustColor(color, 0, 0, 0, 0, 0, 0, -60); painter->setPen(color); } } QSize iconSize(0, 0); // 绘制图标 if (!menuItem->icon.isNull()) { /*= visualRect(opt->direction, menuItem->rect,QRect(menuItem->rect.x() + checkColHOffset, menuItem->rect.y(),checkcol, menuitem->rect.height()));*/ iconSize.setWidth(smallIconSize); iconSize.setHeight(smallIconSize); #if QT_CONFIG(combobox) if (const QComboBox *combo = qobject_cast(widget)) iconSize = combo->iconSize(); #endif //计算icon的绘制区域(icon需要居中显示) QRect pmr(menuRect.x() + realMargins, menuRect.center().y() - iconSize.height() / 2, iconSize.width(), iconSize.height()); drawIcon(option, painter, pmr, option->icon, checked); } // 绘制文本 int x, y, w, h; menuRect.getRect(&x, &y, &w, &h); int tab = menuItemShortcutWidth(menuItem); int xpos = menuRect.x(); //1.只有文本 2.只有图片加文本 ,xpos为文本的起始坐标 if (iconSize.width() > 0) { xpos += realMargins + frameRadius + iconSize.width(); } else { xpos += realMargins; } QRect textRect(xpos, y + Menu_ItemHTextMargin, w - xpos - tab, h - 2 * Menu_ItemVTextMargin); QRect vTextRect = textRect /*visualRect(option->direction, menuRect, textRect)*/; // 区分左右方向 QStringView textRef(menuItem->text); painter->setBrush(Qt::NoBrush); if (!textRef.isEmpty()) { int tabIndex = textRef.indexOf(QLatin1Char('\t')); int text_flags = Qt::AlignVCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; if (!styleHint(SH_UnderlineShortcut, menuItem, widget)) text_flags |= Qt::TextHideMnemonic; text_flags |= Qt::AlignLeft; if (tabIndex >= 0) { QPoint vShortcutStartPoint = textRect.topRight(); //快捷键设置显示 vShortcutStartPoint.setX(vShortcutStartPoint.x() - Menu_PanelRightPadding - realMargins); QRect vShortcutRect = QRect(vShortcutStartPoint, QPoint(menuRect.right(), textRect.bottom())); /* = visualRect(option->direction,menuRect,QRect(vShortcutStartPoint, QPoint(menuRect.right(), textRect.bottom())))*/; const QString textToDraw = textRef.mid(tabIndex + 1).toString(); painter->drawText(vShortcutRect, text_flags, textToDraw); textRef = textRef.left(tabIndex); } QFont font = menuItem->font; font.setPointSizeF(QFontInfo(menuItem->font).pointSizeF()); painter->setFont(font); const QString textToDraw = textRef.left(tabIndex).toString(); painter->setBrush(Qt::NoBrush); painter->drawText(vTextRect, text_flags, textToDraw); drawMenuItemRedPoint(option, painter, widget); } // 绘制箭头 if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow int dim = (menuRect.height() - 4) / 2; int xpos = menuRect.left() + menuRect.width() - 3 - dim; QStyleOptionMenuItem newMI = *menuItem; xpos += realMargins + iconSize.width() + frameRadius; QPoint topLeft(menuItem->rect.right() - frameRadius - smallIconSize / 2, menuItem->rect.center().y() - smallIconSize / 3); //箭头rect: Size(smallIconSize, smallIconSize*2/3) QPoint RightButtom(topLeft.x() + smallIconSize / 2, menuItem->rect.center().y() + smallIconSize / 3 ); QRect rectArrow(topLeft, RightButtom); newMI.rect = rectArrow; newMI.state = !enabled ? State_None : State_Enabled; if (selected) newMI.palette.setColor(QPalette::WindowText, newMI.palette.highlightedText().color()); QIcon markIcon = DStyle::standardIcon(SP_ArrowEnter, &newMI, widget); markIcon.paint(painter, newMI.rect); } } return true; } QRect ChameleonStyle::subElementRect(QStyle::SubElement r, const QStyleOption *opt, const QWidget *widget) const { switch (r) { case SE_HeaderArrow:{ QRect rect; int h = opt->rect.height(); int w = opt->rect.width(); int x = opt->rect.x(); int y = opt->rect.y(); int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget); if (opt->state & State_Horizontal) { // designer: whatever how big the QHeaderView it is, the arrow size is fixed. // size the same as the arrow in combobox. PM_MenuButtonIndicator int horiz_size = 12; int vert_size = 12; rect.setRect(x + w - margin * 2 - horiz_size, y + (h - vert_size) / 2, horiz_size, vert_size); } else { int horiz_size = 12; int vert_size = 12; rect.setRect(x + (w - horiz_size) / 2, y + h - margin * 2 - vert_size, horiz_size, vert_size); } rect = visualRect(opt->direction, opt->rect, rect); return rect; } case SE_PushButtonFocusRect: case SE_ItemViewItemFocusRect: return opt->rect; case SE_ItemViewItemCheckIndicator: Q_FALLTHROUGH(); case SE_ItemViewItemDecoration: Q_FALLTHROUGH(); case SE_ItemViewItemText: if (const QStyleOptionViewItem *vopt = qstyleoption_cast(opt)) { int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, widget); QStyleOptionViewItem option(*vopt); option.rect = opt->rect.adjusted(frame_radius, 0, -frame_radius, 0); QStyleOptionViewItem::ViewItemFeatures old_features = option.features; // 默认把checkbox放置在右边,因此使用QCommonStyle的Item布局时先移除HasCheckIndicator标志 option.features &= ~QStyleOptionViewItem::HasCheckIndicator; if (r == SE_ItemViewItemDecoration) { return DStyle::subElementRect(r, &option, widget); } QRect text_rect = DStyle::subElementRect(SE_ItemViewItemText, &option, widget); int indicator_width = proxy()->pixelMetric(PM_IndicatorWidth, &option, widget); int indicator_height = proxy()->pixelMetric(PM_IndicatorHeight, &option, widget); const QRect indicator_rect = alignedRect(opt->direction, Qt::AlignRight | Qt::AlignVCenter, QSize(indicator_width, indicator_height), text_rect); if (old_features.testFlag(QStyleOptionViewItem::HasCheckIndicator)) { int margin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, widget); text_rect.setRight(qMin(text_rect.right(), indicator_rect.left() - margin)); } return r == SE_ItemViewItemText ? text_rect : indicator_rect; } break; case SE_LineEditContents: { int frame_margins = DStyle::pixelMetric(PM_FrameMargins, opt, widget); int left_margins = DStyle::pixelMetric(PM_ContentsMargins, opt, widget); if (widget && qobject_cast(widget->parentWidget())) { return opt->rect.adjusted(frame_margins / 2, 0, -left_margins / 2, 0); } return opt->rect.adjusted(frame_margins + left_margins, 0, -(frame_margins + left_margins), 0); } case SE_RadioButtonFocusRect: case SE_CheckBoxFocusRect: { QRect re; re = subElementRect(SE_CheckBoxIndicator, opt, widget); int margin = DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing); re.adjust(-margin, -margin, margin, margin); return re; } case SE_RadioButtonClickRect: case SE_CheckBoxClickRect: { QRect re = DStyle::subElementRect(SE_CheckBoxIndicator, opt, widget); if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { int spacing = proxy()->pixelMetric(PM_CheckBoxLabelSpacing, opt, widget); re.setWidth(re.width() + widget->fontMetrics().horizontalAdvance(btn->text) + spacing * 2); } return re; } case SE_RadioButtonIndicator: case SE_RadioButtonContents: case SE_CheckBoxContents: case SE_CheckBoxIndicator: if (const QStyleOptionButton *vopt = qstyleoption_cast(opt)) { QStyleOptionButton option(*vopt); int margin = DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing); //来自SE_CheckBoxFocusRect状态时 option.rect.translate(margin, 0); //需往右偏margin数值,FocusRect框显示正常;故对应其size的width也增加margin return DStyle::subElementRect(r, &option, widget); } break; case SE_PushButtonContents: if (const QStyleOptionButton *vopt = qstyleoption_cast(opt)) { QRect buttonContentRect = vopt->rect; int buttonIconMargin = proxy()->pixelMetric(QStyle::PM_ButtonMargin, opt, widget) ; buttonContentRect.adjust(buttonIconMargin, 0, -buttonIconMargin, 0); return buttonContentRect; } break; case SE_TabBarScrollLeftButton: { const bool vertical = opt->rect.width() < opt->rect.height(); const int buttonWidth = proxy()->pixelMetric(PM_TabBarScrollButtonWidth, opt, widget); QRect buttonRect = vertical ? QRect(0, 0, opt->rect.width(), buttonWidth) : QRect(0, 0, buttonWidth, opt->rect.height()); return buttonRect; } case SE_TabBarScrollRightButton: { const bool vertical = opt->rect.width() < opt->rect.height(); const int buttonWidth = proxy()->pixelMetric(PM_TabBarScrollButtonWidth, opt, widget); QRect buttonRect = vertical ? QRect(0, opt->rect.height() - buttonWidth, opt->rect.width(), buttonWidth) : QRect(opt->rect.width() - buttonWidth, 0, buttonWidth, opt->rect.height()); return buttonRect; } case SE_ProgressBarLabel: { int radius = DStyle::pixelMetric(PM_FrameRadius); return opt->rect.marginsRemoved(QMargins(radius, radius, radius, radius)); } case SE_TabBarTearIndicatorLeft: case SE_TabBarTearIndicatorRight: // DTabBar有自己的scroll按钮 if (widget && qobject_cast(widget->parent())) return QRect(0, 0, 0, 0); break; default: break; } return DStyle::subElementRect(r, opt, widget); } void ChameleonStyle::drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *w) const { switch (cc) { case CC_SpinBox: { if (const QStyleOptionSpinBox *option = qstyleoption_cast(opt)) { if (drawSpinBox(option, p, w)) return; } break; } case CC_ToolButton: { if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt)) { QRect button, menuarea; button = proxy()->subControlRect(cc, toolbutton, SC_ToolButton, w); menuarea = proxy()->subControlRect(cc, toolbutton, SC_ToolButtonMenu, w); State bflags = toolbutton->state & ~State_Sunken; if (bflags & State_AutoRaise) { if (!(bflags & State_MouseOver) || !(bflags & State_Enabled)) { bflags &= ~State_Raised; } } State mflags = bflags; if (toolbutton->state & State_Sunken) { if (toolbutton->activeSubControls & SC_ToolButton) bflags |= State_Sunken; mflags |= State_Sunken; } int menuButtonIndicatorMargin = 4; // 菜单按钮右边距 QStyleOption tool = *toolbutton; if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) { if (w && !w->property("_d_calendarToolBtn").toBool()) { button.adjust(0, 0, -2 * menuButtonIndicatorMargin, 0); menuarea.adjust(-2 * menuButtonIndicatorMargin, 0, 0, 0); } if (bflags & (State_Sunken | State_On | State_Raised)) { tool.rect = button; tool.state = bflags; //proxy()->drawPrimitive(PE_PanelButtonTool, &tool, p, w); } } QStyleOptionToolButton label = *toolbutton; label.state = bflags; int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, w); label.rect = button.adjusted(fw, fw, -fw, -fw); if (w && w->property("_d_calendarToolBtn").toBool()) { label.palette = DGuiApplicationHelper::instance()->applicationPalette(); } proxy()->drawControl(CE_ToolButtonLabel, &label, p, w); if (toolbutton->state & State_HasFocus) { QStyleOptionFocusRect fr; fr.QStyleOption::operator=(*toolbutton); //fr.rect.adjust(3, 3, -3, -3); if (toolbutton->features & QStyleOptionToolButton::MenuButtonPopup) fr.rect.adjust(0, 0, -proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, toolbutton , w) - 2 * menuButtonIndicatorMargin, 0); proxy()->drawPrimitive(PE_FrameFocusRect, &fr, p, w); } if (toolbutton->subControls & SC_ToolButtonMenu) { tool.rect = menuarea; tool.state = mflags; tool.rect.adjust(menuButtonIndicatorMargin, 0, -menuButtonIndicatorMargin, 0); if ((toolbutton->state & (QStyle::State_Sunken)) && (toolbutton->activeSubControls & QStyle::SC_ToolButton)) { p->setPen(Qt::NoPen); } if((toolbutton->state & (QStyle::State_Sunken)) && toolbutton->activeSubControls & QStyle::SC_ToolButtonMenu) { p->setPen(getColor(toolbutton, DPalette::Highlight)); } proxy()->drawPrimitive(PE_IndicatorArrowDown, &tool, p, w); } else if (toolbutton->features & QStyleOptionToolButton::HasMenu) { int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, w); QRect ir = toolbutton->rect; QStyleOptionToolButton newBtn = *toolbutton; newBtn.rect = QRect(ir.right() - mbi - menuButtonIndicatorMargin, (ir.height() - mbi) / 2, mbi, mbi); newBtn.rect = visualRect(toolbutton->direction, button, newBtn.rect); //仅文字,DelayedPopup 模式,文字和箭头整体居中 if (toolbutton->features & QStyleOptionToolButton::PopupDelay && toolbutton->toolButtonStyle == Qt::ToolButtonTextOnly) { QFontMetrics metrics(toolbutton->font); int fontWidth = metrics.horizontalAdvance(toolbutton->text); int subRectWidth = fontWidth + mbi + menuButtonIndicatorMargin; QRect subRect = QRect(tool.rect.left() + (tool.rect.width() - subRectWidth) / 2, tool.rect.top(), subRectWidth, tool.rect.height()); QRect indicatorRect = QRect(subRect.topLeft() + QPoint(fontWidth + menuButtonIndicatorMargin, (tool.rect.height() - mbi) / 2), QSize(mbi, mbi)); newBtn.rect = indicatorRect; } proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, w); } //日历 年按钮 特制 文字和箭头整体居中 if (w && w->objectName() == "qt_calendar_yearbutton") { QStyleOptionToolButton newBtn = *toolbutton; int mbi = proxy()->pixelMetric(PM_MenuButtonIndicator, toolbutton, w); QFontMetrics metrics(toolbutton->font); int fontWidth = metrics.horizontalAdvance(toolbutton->text); int subRectWidth = fontWidth + mbi + menuButtonIndicatorMargin; QRect subRect = QRect(tool.rect.left() + (tool.rect.width() - subRectWidth) / 2, tool.rect.top(), subRectWidth, tool.rect.height()); QRect indicatorRect = QRect(subRect.topLeft() + QPoint(fontWidth + menuButtonIndicatorMargin, (tool.rect.height() - mbi) / 2), QSize(mbi, mbi)); newBtn.rect = indicatorRect; proxy()->drawPrimitive(PE_IndicatorArrowDown, &newBtn, p, w); } } return; } case CC_Slider : { if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { const DSlider *dslider = qobject_cast(w); //各个使用的矩形大小和位置 QRectF rect = opt->rect; //Slider控件最大的矩形(包含如下三个) QRectF rectHandle = proxy()->subControlRect(CC_Slider, opt, SC_SliderHandle, w); //滑块矩形 QRectF rectSliderTickmarks = proxy()->subControlRect(CC_Slider, opt, SC_SliderTickmarks, w); //刻度的矩形 QRect rectGroove = proxy()->subControlRect(CC_Slider, opt, SC_SliderGroove, w); //滑槽的矩形 int margin = DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing); // //测试(保留不删) // p->fillRect(rect, Qt::gray); // p->fillRect(rectSliderTickmarks, Qt::blue); // p->fillRect(rectGroove, Qt::red); // p->fillRect(rectHandle, Qt::green); // qDebug()<<"---rect:"<subControls & SC_SliderGroove) { pen.setStyle(Qt::CustomDashLine); pen.setWidth(4); // 默认高亮色滑槽颜色 pen.setBrush((opt->activeSubControls & SC_SliderHandle) ? getColor(opt, QPalette::Highlight) : opt->palette.highlight()); pen.setDashOffset(0); pen.setDashPattern(QVector()<< 0.5 << 0.25); pen.setCapStyle(Qt::FlatCap); p->setPen(pen); p->setRenderHint(QPainter::Antialiasing); QColor color = adjustColor(getColor(opt, DPalette::ObviousBackground, w), 0, 0, 0, 0, 0, 0, +15); //绘画的右侧/上侧的滑槽颜色一定是灰 // 属性启用灰色滑槽 QVariant prop = dslider ? const_cast(dslider)->slider()->property("_d_dtk_sldier_across") : QVariant(); bool hasProperty = prop.isValid(); // 0. dslider 默认没有设置此属性(设置在d->slider上了...) // 1. 设置了属性 true 则灰色滑槽 // 2. 如果设置了 false 高亮 // 3. 没有设置属性时,没有刻度的(圆角) slider 默认高亮色,有刻度(尖角) slider 默认灰色 if (prop.toBool() || (!hasProperty && !isNoticks(slider, p, w))) { pen.setColor(color); p->setPen(pen); } if (slider->orientation == Qt::Horizontal) { // 绘制最左边到滑块的位置的滑槽 qreal rectWidth = rectHandle.width() / 2.0; p->drawLine(QPointF(rectGroove.left() + rectWidth, rectHandle.center().y()), QPointF(rectHandle.center().x(), rectHandle.center().y())); // 绘制滑块到最右的位置的滑槽 pen.setColor(color); p->setPen(pen); p->drawLine(QPointF(rectGroove.right() - rectWidth, rectHandle.center().y()), QPointF(rectHandle.center().x(), rectHandle.center().y())); } else { // 绘制最上边到滑块的位置的滑槽 qreal rectWidth = rectHandle.height() / 2.0; p->drawLine(QPointF(rectGroove.center().x(), rectGroove.bottom() - rectWidth), QPointF(rectGroove.center().x(), rectHandle.center().y())); // 绘制滑块到最下的位置的滑槽 pen.setColor(color); p->setPen(pen); p->drawLine(QPointF(rectGroove.center().x(), rectGroove.top() + rectWidth), QPointF(rectGroove.center().x(), rectHandle.center().y())); } } //绘画 滑块 if (opt->subControls & SC_SliderHandle) { pen.setStyle(Qt::SolidLine); p->setPen(Qt::NoPen); p->setBrush((opt->activeSubControls & SC_SliderHandle) ? getColor(opt, QPalette::Highlight) : opt->palette.highlight()); drawSliderHandle(opt, rectHandle, p, w); // 绘画 滑块焦点 if (slider->state & State_HasFocus) { pen.setColor(getColor(opt, DPalette::Highlight)); pen.setWidth(DStyle::pixelMetric(PM_FocusBorderWidth)); p->setPen(pen); p->setBrush(Qt::NoBrush); drawSliderHandleFocus(opt, rectHandle, p, w); } } //绘画 刻度,绘画方式了参考qfusionstyle.cpp if ((opt->subControls & SC_SliderTickmarks) && slider->tickInterval) { //需要绘画刻度 p->setPen(opt->palette.windowText().color()); int available = proxy()->pixelMetric(PM_SliderSpaceAvailable, slider, w); //可用空间 int interval = slider->tickInterval; //标记间隔 // int tickSize = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, w); //标记偏移 // int ticks = slider->tickPosition; //标记位置 int v = slider->minimum; int len = proxy()->pixelMetric(PM_SliderLength, slider, w); while (v <= slider->maximum + 1) { //此处不添加+1的话, 会少绘画一根线 const int v_ = qMin(v, slider->maximum); int pos = margin + sliderPositionFromValue(slider->minimum, slider->maximum, v_, available - (2 * margin)) + len / 2; if (slider->orientation == Qt::Horizontal) { if (slider->tickPosition == QSlider::TicksBothSides) { //两侧都会绘画, 总的矩形-中心滑槽滑块最小公共矩形 p->drawLine(pos, rect.top(), pos, rectHandle.top()); p->drawLine(pos, rect.bottom(), pos, rectHandle.bottom()); } else { p->drawLine(pos, rectSliderTickmarks.top(), pos, rectSliderTickmarks.bottom()); } } else { if (slider->tickPosition == QSlider::TicksBothSides) { p->drawLine(rect.left(), pos, rectHandle.left(), pos); p->drawLine(rect.right(), pos, rectHandle.right(), pos); } else { p->drawLine(rectSliderTickmarks.left(), pos, rectSliderTickmarks.right(), pos); } } // in the case where maximum is max int int nextInterval = v + interval; if (nextInterval < v) break; v = nextInterval; } } } break; } case CC_ComboBox: { if (const QStyleOptionComboBox *comboBox = qstyleoption_cast(opt)) { if (drawComboBox(p, comboBox, w)) return; } break; } default: break; } DStyle::drawComplexControl(cc, opt, p, w); } bool ChameleonStyle::drawSpinBox(const QStyleOptionSpinBox *opt, QPainter *painter, const QWidget *widget) const { qreal borderRadius = DStyle::pixelMetric(DStyle::PM_FrameRadius); if (opt->frame && (opt->subControls & SC_SpinBoxFrame)) { QRect frameRect = proxy()->subControlRect(CC_SpinBox, opt, SC_SpinBoxFrame, widget); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); painter->setBrush(opt->palette.button()); painter->drawRoundedRect(frameRect, borderRadius, borderRadius); } if (opt->subControls & SC_SpinBoxUp) { bool upIsActive = opt->activeSubControls == SC_SpinBoxUp; bool upIsEnabled = opt->stepEnabled & QAbstractSpinBox::StepUpEnabled && opt->state.testFlag(State_Enabled); QRect subRect = proxy()->subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, widget); QStyleOptionButton buttonOpt; buttonOpt.rect = subRect; buttonOpt.palette = opt->palette; updateSpinBoxButtonState(opt, buttonOpt, upIsActive, upIsEnabled); bool isPlusMinus = opt->buttonSymbols & QAbstractSpinBox::PlusMinus; if (widget && widget->property("_d_dtk_spinBox").toBool()) { painter->setPen(Qt::NoPen); painter->setBrush(buttonOpt.palette.color(QPalette::Button)); DDrawUtils::drawRoundedRect(painter, subRect.adjusted(-2, -1, 0, 0), borderRadius, borderRadius, DDrawUtils::TopRightCorner); painter->setPen(getColor(opt, DPalette::FrameBorder, widget)); painter->drawLine(subRect.x() - 2, subRect.y() - 1, subRect.x() - 2, subRect.y() - 1 + subRect.height()); } else { proxy()->drawControl(CE_PushButton, &buttonOpt, painter, widget); } if (isPlusMinus) { //绘制 "+" 符号 buttonOpt.rect -= frameExtentMargins(); QRectF plusRect = proxy()->subElementRect(SE_PushButtonContents, &buttonOpt, widget); QRectF cent_rect(0, 0, plusRect.width() / 2, plusRect.width() / 2); cent_rect.moveCenter(plusRect.center()); if (opt->activeSubControls == SC_SpinBoxUp) { DDrawUtils::drawPlus(painter, cent_rect, getColor(opt, QPalette::ButtonText), 1); } else { DDrawUtils::drawPlus(painter, cent_rect, DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType ? QColor("#536076") : QColor("#c5cfe0"), 1); } } else { QStyleOptionButton arrowDrawBtn = buttonOpt; if (widget && widget->property("_d_dtk_spinBox").toBool()) { if (opt->activeSubControls == SC_SpinBoxDown) { painter->setPen(buttonOpt.palette.color(QPalette::ButtonText)); } else { painter->setPen(getColor(opt, QPalette::ButtonText)); } arrowDrawBtn.rect = subRect; arrowDrawBtn.rect.setWidth(subRect.width() / 2); arrowDrawBtn.rect.setHeight(subRect.height() / 1.3); arrowDrawBtn.rect.moveCenter(subRect.center()); proxy()->drawPrimitive(PE_IndicatorArrowUp, &arrowDrawBtn, painter, widget); } else { arrowDrawBtn.rect = subRect; arrowDrawBtn.rect.setSize(subRect.size() / 3); arrowDrawBtn.rect.moveCenter(subRect.center()); proxy()->drawPrimitive(PE_IndicatorArrowUp, &arrowDrawBtn, painter, widget); } } } if (opt->subControls & SC_SpinBoxDown) { bool downIsActive = opt->activeSubControls == SC_SpinBoxDown; bool downIsEnabled = opt->stepEnabled & QAbstractSpinBox::StepDownEnabled && opt->state.testFlag(State_Enabled); QRect subRect = proxy()->subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, widget); QStyleOptionButton buttonOpt; buttonOpt.rect = subRect; buttonOpt.palette = opt->palette; updateSpinBoxButtonState(opt, buttonOpt, downIsActive, downIsEnabled); bool isPlusMinus = opt->buttonSymbols & QAbstractSpinBox::PlusMinus; if (widget && widget->property("_d_dtk_spinBox").toBool()) { painter->setPen(Qt::NoPen); painter->setBrush(buttonOpt.palette.color(QPalette::Button)); DDrawUtils::drawRoundedRect(painter, subRect.adjusted(-2, 0, 0, +1), borderRadius, borderRadius, DDrawUtils::BottomRightCorner); painter->setPen(getColor(opt, DPalette::FrameBorder, widget)); painter->drawLine(subRect.x() - 2, subRect.y(), subRect.x() + subRect.width(), subRect.y()); painter->drawLine(subRect.x() - 2, subRect.y(), subRect.x() - 2, subRect.y() + subRect.height() + 1); } else { proxy()->drawControl(CE_PushButton, &buttonOpt, painter, widget); } if (isPlusMinus) { buttonOpt.rect -= frameExtentMargins(); QRectF subtractRect = proxy()->subElementRect(SE_PushButtonContents, &buttonOpt, widget); QRectF cent_rect(0, 0, subtractRect.width() / 2, subtractRect.height() / 2); cent_rect.moveCenter(subtractRect.center()); if (opt->activeSubControls == SC_SpinBoxDown) { DDrawUtils::drawSubtract(painter, cent_rect, getColor(opt, QPalette::ButtonText), 1); } else { DDrawUtils::drawSubtract(painter, cent_rect, DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType ? QColor("#536076") : QColor("#c5cfe0"), 1); } } else { QStyleOptionButton arrowDrawBtn = buttonOpt; if (widget && widget->property("_d_dtk_spinBox").toBool()) { if (opt->activeSubControls == SC_SpinBoxDown) { painter->setPen(getColor(opt, QPalette::ButtonText)); } else { painter->setPen(buttonOpt.palette.color(QPalette::ButtonText)); } arrowDrawBtn.rect = subRect; arrowDrawBtn.rect.setWidth(subRect.width() / 2); arrowDrawBtn.rect.setHeight(subRect.height() / 1.3); arrowDrawBtn.rect.moveCenter(subRect.center()); proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowDrawBtn, painter, widget); } else { //更换了一种绘制箭头方式,使36 *36情况下箭头无瑕疵 arrowDrawBtn.rect = subRect; arrowDrawBtn.rect.setSize(subRect.size() / 3); arrowDrawBtn.rect.moveCenter(subRect.center()); proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowDrawBtn, painter, widget); } } } return true; } void ChameleonStyle::updateSpinBoxButtonState(const QStyleOptionSpinBox *opt, QStyleOptionButton &buttonOpt, bool isActive, bool isEnabled) const { State buttonState = opt->state; if (!isActive) { buttonState &= ~State_MouseOver; buttonState &= ~State_Sunken; buttonState &= ~State_Active; buttonState &= ~State_HasFocus; } if (!isEnabled) { buttonState &= ~State_Enabled; buttonState &= ~State_MouseOver; buttonState &= ~State_Sunken; buttonState &= ~State_On; } if (buttonState & State_Sunken || buttonState & State_MouseOver || buttonState & State_Active) { buttonState &= ~State_HasFocus; } buttonOpt.state = buttonState; } QStyle::SubControl ChameleonStyle::hitTestComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *w) const { return DStyle::hitTestComplexControl(cc, opt, pt, w); } QRect ChameleonStyle::subControlRect(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QStyle::SubControl sc, const QWidget *w) const { switch (cc) { case CC_SpinBox: { if (const QStyleOptionSpinBox *option = qstyleoption_cast(opt)) { switch (sc) { case SC_SpinBoxEditField: { if (option->buttonSymbols == QAbstractSpinBox::NoButtons) return proxy()->subControlRect(CC_SpinBox, opt, SC_SpinBoxFrame, w); int rightBorder = option->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, opt, w) * 2 : 0; int border = w && w->property("_d_dtk_spinBox").toBool() ? 0 : DStyle::pixelMetric(PM_ContentsMargins); QRect spinboxRect = option->rect; QRect dButtonRect = proxy()->subControlRect(CC_SpinBox, opt, SC_SpinBoxUp, w); spinboxRect.setRight(dButtonRect.left() - rightBorder - frameExtentMargins().left() - border); return spinboxRect; } case SC_SpinBoxUp: { if (w && w->property("_d_dtk_spinBox").toBool()) { break; } if (option->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); int rectHeight = option->rect.height(); int border = w && w->property("_d_dtk_spinBox").toBool() ? 0 : DStyle::pixelMetric(PM_ContentsMargins); rectHeight -= (option->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, opt, w) * 2 : 0); if (opt->rect.width() < rectHeight * 3) break; QRect uButtonRect = proxy()->subControlRect(CC_SpinBox, opt, SC_SpinBoxDown, w); QRect buttonRect = option->rect; buttonRect.setLeft(uButtonRect.left() - rectHeight - border); buttonRect.setRight(uButtonRect.left()); buttonRect.setSize(QSize(rectHeight, rectHeight)); return buttonRect; } case SC_SpinBoxDown: { if (w && w->property("_d_dtk_spinBox").toBool()) { break; } if (option->buttonSymbols == QAbstractSpinBox::NoButtons) return QRect(); int rectHeight = option->rect.height(); rectHeight -= (option->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, opt, w) * 2 : 0); if (opt->rect.width() < rectHeight * 3) break; QRect buttonRect(option->rect.topLeft(), QSize(rectHeight, rectHeight)); //按高度计算 buttonRect.moveRight(option->rect.right()); return buttonRect; } case SC_SpinBoxFrame: { return option->rect - frameExtentMargins() ; } default: break; } } break; } case CC_Slider: { if (const QStyleOptionSlider *option = qstyleoption_cast(opt)) { int margin = DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing); QRectF rect = option->rect; //Slider控件总的大小矩形 int slider_size = proxy()->pixelMetric(PM_SliderControlThickness, opt, w); //滑块的高度 // int tick_size = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, w); //刻度的高度 QRectF slider_handle_rect = rect; //滑块和滑漕的的最小公共矩形 (后面被用作临时且被改变的) if (option->orientation == Qt::Horizontal) { slider_handle_rect.setHeight(slider_size); slider_handle_rect.adjust(margin, 0, -margin, 0); if (option->tickPosition == QSlider::TicksAbove) slider_handle_rect.moveBottom(rect.bottom() - margin); if (option->tickPosition == QSlider::TicksBelow) slider_handle_rect.moveTop(rect.top() + margin); if (option->tickPosition == QSlider::TicksBothSides || option->tickPosition == QSlider::NoTicks) slider_handle_rect.moveCenter(rect.center()); } else { slider_handle_rect.setWidth(slider_size); slider_handle_rect.adjust(0, margin, 0, -margin); if (option->tickPosition == QSlider::TicksRight) slider_handle_rect.moveLeft(rect.left() + margin); if (option->tickPosition == QSlider::TicksLeft) slider_handle_rect.moveRight(rect.right() - margin); if (option->tickPosition == QSlider::TicksBothSides || option->tickPosition == QSlider::NoTicks) slider_handle_rect.moveCenter(rect.center()); } QRectF rectStatic = slider_handle_rect; //rectStatic作为 滑块和滑漕的的最小公共矩形(不改变) switch (sc) { case SC_SliderGroove: { //滑漕 qreal groove_size = slider_size / 4.0; QRectF groove_rect; if (option->orientation == Qt::Horizontal) { groove_rect.setWidth(slider_handle_rect.width()); groove_rect.setHeight(groove_size); } else { groove_rect.setWidth(groove_size); groove_rect.setHeight(slider_handle_rect.height()); } groove_rect.moveCenter(slider_handle_rect.center()); return groove_rect.toRect(); } case SC_SliderHandle: { //滑块 int sliderPos = 0; int len = proxy()->pixelMetric(PM_SliderLength, option, w); bool horizontal = option->orientation == Qt::Horizontal; sliderPos = sliderPositionFromValue(option->minimum, option->maximum, option->sliderPosition, (horizontal ? slider_handle_rect.width() : slider_handle_rect.height()) - len, option->upsideDown); if (horizontal) { slider_handle_rect.moveLeft(slider_handle_rect.left() + sliderPos); slider_handle_rect.setWidth(len); slider_handle_rect.moveTop(rectStatic.top()); } else { slider_handle_rect.moveTop(slider_handle_rect.top() + sliderPos); slider_handle_rect.setHeight(len); slider_handle_rect.moveLeft(rectStatic.left()); } return slider_handle_rect.toRect(); } case SC_SliderTickmarks: { //刻度的矩形 if (option->tickPosition & QSlider::NoTicks) return QRect(0, 0, 0, 0); QRectF tick_rect = rect; if (option->orientation == Qt::Horizontal) { tick_rect.setHeight(rect.height() - slider_handle_rect.height() - ( 2 * margin)); tick_rect.adjust(margin, 0, -margin, 0); if (option->tickPosition == QSlider::TicksAbove) { tick_rect.moveTop(rect.top() + margin); } else if (option->tickPosition == QSlider::TicksBelow) { tick_rect.moveBottom(rect.bottom() -margin); } } else { tick_rect.setWidth(rect.width() - slider_handle_rect.width() - (2 *margin)); tick_rect.adjust(0, margin, 0, -margin); if (option->tickPosition == QSlider::TicksLeft) { tick_rect.moveLeft(rect.left() + margin); } else if (option->tickPosition == QSlider::TicksRight) { tick_rect.moveRight(rect.right() - margin); } } return tick_rect.toRect(); } default: break; } } break; } case CC_ComboBox: { if (qstyleoption_cast(opt)) { DStyleHelper dstyle(proxy()); int frameMargins = dstyle.pixelMetric(PM_FrameMargins, opt, w); switch (sc) { case SC_ComboBoxArrow: { QRect rect(0, 0, qMax(static_cast(Metrics::ComboBox_ArrowButtonWidth), opt->rect.height()), opt->rect.height()) ; int boxHeight = qAbs(rect.height()); if (w && qobject_cast(w) && !qobject_cast(w)->isEditable()) break; if (opt->direction == Qt::LeftToRight) rect.moveRight(opt->rect.right()); else rect.moveLeft(opt->rect.left()); int buttonRectSize = boxHeight; rect.setSize(QSize(buttonRectSize, buttonRectSize)); return rect; } case SC_ComboBoxEditField: { QRect rect = opt->rect; const QRect arrow_rect = proxy()->subControlRect(cc, opt, SC_ComboBoxArrow, w); if (opt->direction == Qt::LeftToRight) { rect.setRight(arrow_rect.left()); rect.adjust(frameMargins, 0, 0, 0); } else { rect.setLeft(arrow_rect.right()); rect.adjust(0, 0, -frameMargins, 0); } return rect; } case SC_ComboBoxFrame: { return opt->rect; } case SC_ComboBoxListBoxPopup: { QSize size = proxy()->sizeFromContents(CT_Menu, opt, opt->rect.size(), w); QRect rect = opt->rect; if (auto styopt = static_cast(opt)) { if (auto menuItem = static_cast(styopt)) { if (menuItem->icon.isNull()) { rect.setWidth(size.width() + Menu_CheckMarkWidth); } } } return rect; } default: break; } } break; } default: break; } return DStyle::subControlRect(cc, opt, sc, w); } QSize ChameleonStyle::sizeFromContents(QStyle::ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *widget) const { QSize size = DStyle::sizeFromContents(ct, opt, contentsSize, widget); switch (ct) { case CT_LineEdit: { int button_margin = proxy()->pixelMetric(QStyle::PM_ButtonMargin, opt, widget); size += QSize(button_margin, button_margin); Q_FALLTHROUGH(); } case CT_ComboBox: { if (const QStyleOptionComboBox *cmb = qstyleoption_cast(opt)) { if (cmb->editable) { //这是从lineedit设置margin处拿来 int frame_margins = DStyle::pixelMetric(PM_FrameMargins, opt, widget); int left_margins = DStyle::pixelMetric(PM_ContentsMargins, opt, widget); size.setWidth(size.width() + frame_margins + left_margins); } else { size.setWidth(size.width() + opt->fontMetrics.horizontalAdvance("...")); //设置宽度为最小省略号("...")的宽度 } } Q_FALLTHROUGH(); } case CT_TabBarTab: { if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { QStyleOptionButton button; button.QStyleOption::operator =(*opt); button.text = tab->text; size = DStyle::sizeFromContents(QStyle::CT_PushButton, &button, tab->fontMetrics.size(0, tab->text), widget); int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, widget); // 获得Icon引起的增量 int iconSizeDelta = 0; if (!tab->icon.isNull()) { iconSizeDelta += tab->iconSize.width(); if (!tab->text.isEmpty()) iconSizeDelta += Icon_Margins; } size.rwidth() += 2 * frame_radius + proxy()->pixelMetric(PM_TabCloseIndicatorWidth, opt, widget) + TabBar_TabMargin; size.rwidth() += iconSizeDelta; // TabBar 竖直方向改变其宽高 if (verticalTabs(tab->shape)) { qSwap(size.rwidth(), size.rheight()); } } Q_FALLTHROUGH(); } case CT_PushButton: { // 只将width加上ButtonMargin,对于height的margin通过frame_margins体现 size.rheight() -= proxy()->pixelMetric(PM_ButtonMargin, opt, widget); int frame_margins = DStyle::pixelMetric(PM_FrameMargins, opt, widget); size += QSize(frame_margins * 2, frame_margins * 2); if (const QStyleOptionButton *bopt = qstyleoption_cast(opt)) { int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, widget); // 为文本添加额外的margin if (!bopt->text.isEmpty()) { size.rwidth() += 2 * frame_radius; } if (bopt->features & QStyleOptionButton::HasMenu) size.rwidth() += frame_margins; //qt源码会在带有menu的btn样式中,添加一个箭头矩形的width } int button_min_size = DStyle::pixelMetric(PM_ButtonMinimizedSize, opt, widget); size = size.expandedTo(QSize(button_min_size, button_min_size)); break; } case CT_ItemViewItem: { if (const QStyleOptionViewItem *vopt = qstyleoption_cast(opt)) { const QMargins &item_margins = qvariant_cast(vopt->index.data(Dtk::MarginsRole)); if (!item_margins.isNull()) { //加上Item自定义的margins size = QRect(QPoint(0, 0), size).marginsAdded(item_margins).size(); } size.setWidth(size.width() + opt->fontMetrics.horizontalAdvance("xxx")); return size; } break; } case CT_Slider: { if (const QStyleOptionSlider *slider = qstyleoption_cast(opt)) { /*2019-09-19 约定枚举值含义     中文含义 * PM_SliderThickness:      Slider总的高度 = 滑块高度+刻度高度 * PM_SliderControlThickness: 只是滑块的单独高度 * PM_SliderLength: 只是滑块的长度 * PM_SliderTickmarkOffset: 用作slider的刻度线的高度 * PM_SliderSpaceAvailable 暂时未用到 */ int sliderContHeight = proxy()->pixelMetric(PM_SliderControlThickness, opt, widget); int tickMarkHeight = proxy()->pixelMetric(PM_SliderTickmarkOffset, opt, widget); sliderContHeight += tickMarkHeight; if (slider->tickPosition == QSlider::NoTicks) { sliderContHeight -= tickMarkHeight; } else if (slider->tickPosition == QSlider::TicksBothSides) { sliderContHeight += tickMarkHeight; } else { } int margin = DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing); if (slider->orientation == Qt::Horizontal){ size.setHeight(qMax(size.height(), sliderContHeight) + (2 * margin)); size.setWidth(50); } else { size.setWidth(qMax(size.width(), sliderContHeight) + (2 * margin)); } } break; } case CT_MenuBarItem: { int frame_margins = DStyle::pixelMetric(PM_FrameMargins, opt, widget); size += QSize(frame_margins * 2, frame_margins * 2); break; } case CT_MenuItem: { if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast(opt)) { int m_width = size.width(); bool hideShortcutText = false; if (hideShortcutText) { m_width -= menuItemShortcutWidth(menuItem); int tabIndex = menuItem->text.indexOf(QLatin1Char('\t')); if (tabIndex != -1) { int textWidth = menuItem->fontMetrics.horizontalAdvance(menuItem->text.mid(tabIndex + 1)); if (menuItemShortcutWidth(menuItem) == 0) m_width -= textWidth; } } int frameRadius = DStyle::pixelMetric(PM_FrameRadius); //打钩矩形的左侧距离item的左边缘; 也是 打钩矩形的右侧距离 图文内容的左边缘 int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize, opt, widget); //打钩的宽度 int realMargins = smallIconSize + 2 * frameRadius; //左侧固定预留的margin,无论是否能够打钩都要预留 m_width = realMargins; #ifdef ENABLE_RED_POINT_TEXT int redPointWith = opt->fontMetrics.size(Qt::TextSingleLine, QLatin1String("99+")).width(); m_width += redPointWith; #endif int tabSpacing = MenuItem_TabSpacing; if (menuItem->text.contains(QLatin1Char('\t'))) { //若是项有快捷键,文本内容会以'\t'连接快捷键文本 if (!hideShortcutText) m_width += tabSpacing; } else { if (menuItem->menuItemType == QStyleOptionMenuItem::SubMenu) { m_width += 2 * Menu_ArrowHMargin; } } int textWidth = opt->fontMetrics.size(Qt::TextSingleLine, menuItem->text).width(); if (!menuItem->text.isEmpty()) m_width += (textWidth + frameRadius); if (!menuItem->icon.isNull()) m_width += (smallIconSize + frameRadius); m_width += (smallIconSize + frameRadius); size.setWidth(m_width); if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { if (!menuItem->text.isEmpty()) { size.setHeight(menuItem->fontMetrics.height()); } else { size.setHeight(2); } } else if (!menuItem->icon.isNull()) { if (const QComboBox *combo = qobject_cast(widget)) { size.setHeight(qMax(combo->iconSize().height() + 2, size.height())); } } } size.setWidth(qMax(162, size.width())); size.setHeight(size.height() + qMax(Menu_ItemVMargin * 2, 0)); break; } case CT_ScrollBar: { if (size.width() > size.height()) size.setHeight(ScrollBar_SliderWidth); if (size.width() < size.height()) size.setWidth(ScrollBar_SliderWidth); return size; } case CT_RadioButton: case CT_CheckBox: { size.rwidth() += 2 * (DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing)); // fix 当没有文字的时候高度不够绘制焦点圈 auto button = qobject_cast(widget); if (button && button->text().isEmpty()) size.rheight() += 2 * (DStyle::pixelMetric(PM_FocusBorderWidth) + DStyle::pixelMetric(PM_FocusBorderSpacing)); break; } case CT_ToolButton: { qreal radius = DStyle::pixelMetric(DStyle::PM_FrameRadius); if (widget && widget->property("_d_calendarToolBtn").toBool()) { return QSize(size.width() + radius, size.height() + radius); } int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget); int menuButtonIndicatorWidth = 0; if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast(opt)) { if (toolbutton->toolButtonStyle == Qt::ToolButtonIconOnly && !toolbutton->features.testFlag(QStyleOptionToolButton::Arrow) && !toolbutton->features.testFlag(QStyleOptionToolButton::HasMenu)) return DSizeModeHelper::element(QSize(24, 24), QSize(36, 36)); if ((toolbutton->features & QStyleOptionToolButton::HasMenu) && (!(toolbutton->features & QStyleOptionToolButton::MenuButtonPopup))) { menuButtonIndicatorWidth = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, opt, widget); } } int menuButtonIndicatorMargin = 4; return QSize(size.width() + radius + 2 * menuButtonIndicatorMargin + 2 * fw + menuButtonIndicatorWidth, size.height() + radius + 2 * fw); } case CT_ProgressBar: { if (const QStyleOptionProgressBar *pbo = qstyleoption_cast(opt)) { int radius = DStyle::pixelMetric(PM_FrameRadius); if (!pbo->textVisible) { size.setWidth(qMax(size.width(), 2 * radius)); size.setHeight(qMax(size.height(), 2 * radius)); } else { QSize text_size = opt->fontMetrics.size(0, pbo->text.isEmpty() ? "%" : pbo->text); size.setWidth(qMax(size.width(), 2 * radius + text_size.width())); size.setHeight(qMax(size.height(), 2 * radius + text_size.height())); } } break; } case CT_SpinBox: if (auto vopt = qstyleoption_cast(opt)) { int spacing = widget && widget->property("_d_dtk_spinBox").toBool() ? 0 : DStyle::pixelMetric(PM_ContentsMargins); const int fw = vopt->frame ? proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget) : 0; // 增加左右箭头对应的宽和焦点边框的边距,(正方形箭头宽 + 边距 + 箭头控件左右边距, 焦点边框的宽). size += QSize((size.height() + spacing + fw * 2) * 2, LineEdit_FrameWidth); return size; } break; case CT_SizeGrip: { size = QSize(16, 16); break; } default: break; } return size; } int ChameleonStyle::pixelMetric(QStyle::PixelMetric m, const QStyleOption *opt, const QWidget *widget) const { switch (static_cast(m)) { case PM_SpinBoxSliderHeight: return SpinBox_MiniHeight; case PM_SpinBoxFrameWidth: return SpinBox_FrameWidth; case PM_TabCloseIndicatorWidth: case PM_TabCloseIndicatorHeight: // 平板需求 return DGuiApplicationHelper::isTabletEnvironment() ? TabletTabBar_TabButtonSize : TabBar_TabButtonSize; case PM_TabBarTabVSpace: case PM_TabBarTabHSpace : return DStyle::pixelMetric(PM_FrameRadius, opt, widget) * 2; case PM_TabBarTabOverlap: return TabBar_TabOverlap; case PM_TabBarBaseOverlap: return TabBar_BaseOverlap; case PM_TabBarTabShiftHorizontal: case PM_TabBarTabShiftVertical: return 0; case PM_TabBarScrollButtonWidth: // DTabBar有自己的scroll按钮,需要隐藏QTabBar的按钮 if (widget && qobject_cast(widget->parent())) return 0; return DStyle::pixelMetric(PM_ButtonMinimizedSize, opt, widget); case PM_MenuScrollerHeight: return 10 + Metrics::Frame_FrameWidth ; case PM_MenuPanelWidth: //非特效效果则 menu border 为 1 return DWindowManagerHelper::instance()->hasComposite() ? 0 : 1; case PM_SubMenuOverlap: return 0; case PM_ComboBoxFrameWidth: { //这是ComboBox VMargin const QStyleOptionComboBox *comboBoxOption(qstyleoption_cast< const QStyleOptionComboBox *>(opt)); return comboBoxOption && comboBoxOption->editable ? Metrics::ComboBox_FrameWidth : Metrics::LineEdit_FrameWidth ; } case PM_MenuVMargin: return 8; case PM_MenuHMargin: return 0; default: break; } return DStyle::pixelMetric(m, opt, widget); } int ChameleonStyle::styleHint(QStyle::StyleHint sh, const QStyleOption *opt, const QWidget *w, QStyleHintReturn *shret) const { switch (sh) { case SH_ItemView_ShowDecorationSelected: case SH_ScrollBar_Transient: return true; //增加菜单鼠标事件跟踪 case SH_MenuBar_MouseTracking: case SH_Menu_MouseTracking: return true; //增加TabBar超出范围的左右导航按钮 case SH_TabBar_PreferNoArrows: return false; case SH_ComboBox_Popup: return true; case SH_ComboBox_PopupFrameStyle: return QFrame::NoFrame | QFrame::Plain; case SH_Slider_AbsoluteSetButtons: return Qt::LeftButton | Qt::MiddleButton; case SH_ToolTipLabel_Opacity: return 255; default: break; } return DStyle::styleHint(sh, opt, w, shret); } void ChameleonStyle::resetAttribute(QWidget *w, bool polish) { if (!w) return; bool enableHover = w->testAttribute(Qt::WA_Hover); if (qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w)) { enableHover = polish; } if (auto view = qobject_cast(w)) { enableHover = polish; w = view->viewport(); } // TODO: 是平板环境统一设置所有的控件的 WA_Hover 为 false, // 不过在插入鼠标时还是有问题,现阶段先不考虑,以后 Qt 如果优化了如有更好的方案这里再改掉。 if (DGuiApplicationHelper::isTabletEnvironment()) enableHover = false; w->setAttribute(Qt::WA_Hover, enableHover); if (auto scrollbar = qobject_cast(w)) { // 默认初始显示滚动条,然后启动隐藏动画 scrollbar->setProperty("_d_dtk_scrollbar_visible", true); scrollbar->setAttribute(Qt::WA_OpaquePaintEvent, !polish); } } static void updateWeekendTextFormat(QCalendarWidget *calendar, QColor) { if (!calendar) return ; QTextCharFormat fmt; fmt.setForeground(QBrush(calendar->palette().highlight())); calendar->setWeekdayTextFormat(Qt::Saturday, fmt); calendar->setWeekdayTextFormat(Qt::Sunday, fmt); } // 最大圆角18, 原来默认是8 static inline void setWindowRadius(QWidget *w, int radius) { DPlatformWindowHandle handle(w); handle.setWindowRadius(radius); } void ChameleonStyle::polish(QWidget *w) { DStyle::polish(w); resetAttribute(w, true); if (qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w) || qobject_cast(w)) { w->setAttribute(Qt::WA_Hover, true); } if (auto view = qobject_cast(w)) { view->viewport()->setAttribute(Qt::WA_Hover, true); } if (auto listview = qobject_cast(w)) { if (listview->parentWidget() == nullptr) setWindowRadius(listview, DStyle::pixelMetric(PM_FrameRadius)); } if (auto container = qobject_cast(w)) { if (DWindowManagerHelper::instance()->hasComposite()) setWindowRadius(container, DStyle::pixelMetric(PM_FrameRadius)); if (!DGuiApplicationHelper::isTabletEnvironment()) container->setFrameStyle(QFrame::NoFrame); } if (auto calendar = qobject_cast(w)) { int radius = DStyle::pixelMetric(PM_TopLevelWindowRadius); // 只有dtk的应用绘制日历窗口圆角 if (dynamic_cast(QCoreApplication::instance())) setWindowRadius(calendar, radius); calendar->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); // 更改日历Saturday Sunday 活动色改变时跟随 DPlatformTheme *theme = DGuiApplicationHelper::instance()->applicationTheme(); updateWeekendTextFormat(calendar, QColor()); connect(theme, &DPlatformTheme::activeColorChanged, calendar, std::bind(&updateWeekendTextFormat, calendar, std::placeholders::_1)); auto topWidget = calendar->findChild("qt_calendar_navigationbar"); topWidget->setBackgroundRole(QPalette::Base); auto layout = qobject_cast(topWidget->layout()); int margin = radius / 2; layout->setContentsMargins(margin, margin, margin, margin); } if (w && (w->objectName() == "qt_calendar_yearbutton" || w->objectName() == "qt_calendar_monthbutton")) { w->setProperty("_d_calendarToolBtn", true); DFontSizeManager *fontManager = DFontSizeManager::instance(); fontManager->bind(w, DFontSizeManager::T5, QFont::Normal); } if (w && w->objectName() == "qt_calendar_yearedit") { w->setProperty("_d_dtk_spinBox", true); //直接取用spinBox最大年限 int width = w->fontMetrics().horizontalAdvance("9999"); w->setMaximumWidth(width * 3); } if (w && (w->objectName() == "qt_calendar_prevmonth" || w->objectName() == "qt_calendar_nextmonth")) { int btnWidget = DStyle::pixelMetric(DStyle::PM_ButtonMinimizedSize); w->setMinimumSize(btnWidget, btnWidget); } if (w && w->objectName() == "qt_calendar_calendarview") { auto view = qobject_cast(w); view->setItemDelegate(new QStyledItemDelegate); } if (DApplication::isDXcbPlatform() || (qApp->platformName() == "dwayland" || qApp->property("_d_isDwayland").toBool())) { bool is_menu = qobject_cast(w); bool is_tip = w->inherits("QTipLabel"); // 当窗口已经创建对应的native窗口,要判断当前是否已经设置了窗口背景透明 // Bug: https://github.com/linuxdeepin/internal-discussion/issues/323 if (is_menu && w->windowHandle()) { if (const QPlatformWindow *handle = w->windowHandle()->handle()) { if (!w->testAttribute(Qt::WA_TranslucentBackground) && !handle->isExposed()) { // 销毁现有的native窗口,否则设置Qt::WA_TranslucentBackground不会生效 class DQWidget : public QWidget {public: using QWidget::destroy;}; reinterpret_cast(w)->destroy(true, false); } } } // fix qtcreator QDesignerMenu setnotitlebar qmainwindow if (is_menu && w->isWindow()) { DPlatformWindowHandle handle(w); if (DPlatformWindowHandle::isEnabledDXcb(w)) { handle.setEnableBlurWindow(true); DPlatformTheme *theme = DGuiApplicationHelper::instance()->applicationTheme(); if (theme->isValid()) setWindowRadius(w, qMax(0, qMin(theme->windowRadius(), 18))); connect(theme, &DPlatformTheme::windowRadiusChanged, w, [w](int r){ setWindowRadius(w, qMax(0, qMin(r, 18))); }); w->setAttribute(Qt::WA_TranslucentBackground); connect(DWindowManagerHelper::instance(), SIGNAL(hasCompositeChanged()), w, SLOT(update())); } } else if (is_tip) { if (DWindowManagerHelper::instance()->hasComposite()) { DPlatformWindowHandle handle(w); handle.setWindowRadius(DStyle::pixelMetric(PM_FrameRadius)); } QLabel *label = qobject_cast(w); label->setTextFormat(DToolTip::toolTipTextFormat()); } } } void ChameleonStyle::unpolish(QWidget *w) { DStyle::unpolish(w); resetAttribute(w, false); if (w && qobject_cast(w)) { w->setProperty("_d_dtk_lineeditActionWidth", QVariant()); w->setProperty("_d_dtk_lineeditActionMargin", QVariant()); } } void ChameleonStyle::unpolish(QApplication *application) { DStyle::unpolish(application); } void ChameleonStyle::drawShadow(QPainter *p, const QRect &rect, const QColor &color) const { int frame_radius = DStyle::pixelMetric(PM_FrameRadius); int shadow_xoffset = DStyle::pixelMetric(PM_ShadowHOffset); int shadow_yoffset = DStyle::pixelMetric(PM_ShadowVOffset); QRect shadow = rect; QPoint pointOffset(rect.center().x() + shadow_xoffset, rect.center().y() + shadow_yoffset); shadow.moveCenter(pointOffset); p->setBrush(color); p->setPen(Qt::NoPen); p->setRenderHint(QPainter::Antialiasing); p->drawRoundedRect(shadow, frame_radius, frame_radius); } void ChameleonStyle::drawBorder(QPainter *p, const QStyleOption *opt, const QWidget *w) const { const QColor &focus_color = getColor(opt, QPalette::Highlight); if (!focus_color.isValid() || focus_color.alpha() == 0) return; int frame_radius = DStyle::pixelMetric(PM_FrameRadius, opt, w); int margins = DStyle::pixelMetric(PM_FrameMargins, opt, w); QRect border = opt->rect.adjusted(margins, margins, -margins, -margins); p->setRenderHint(QPainter::Antialiasing); QPen pen; pen.setWidth(2); pen.setColor(focus_color); p->setPen(pen); p->setBrush(Qt::NoBrush); if (w && w->property("_d_dtk_tabbartab_type").toBool()) { p->drawRect(opt->rect.adjusted(-1, 1, 1, -1)); return; } if (w && w->parentWidget() && w->parentWidget()->property("_d_dtk_spinBox").toBool()) { DDrawUtils::drawRoundedRect(p, opt->rect.adjusted(1, 1, -1, -1), frame_radius, frame_radius, DDrawUtils::TopLeftCorner | DDrawUtils::BottomLeftCorner); return; } bool table = qobject_cast(w) && !w->property("_d_dtk_enable_tableviewitem_radius").toBool(); //QCalendarWidget的QTableView焦点状态与QTableView不同 bool calendar = w && (w->objectName() == "qt_calendar_calendarview"); // DButtonBoxButton在不同位置焦点不同 const DButtonBoxButton *buttonBoxButton = qobject_cast(w); const DStyleOptionButtonBoxButton *btnopt = qstyleoption_cast(opt); pen.setWidth(2); int offset = 1; QRect rect = border.adjusted(offset, offset, -offset, -offset); // 先画内框(黑or白) pen.setColor(getColor(opt, QPalette::Base)); p->setPen(pen); if (calendar) { pen.setWidth(3); p->setPen(pen); offset = 2; drawCalenderEllipse(p, opt->rect, offset); } else if (table) { p->drawRect(rect); } else if (buttonBoxButton && btnopt) { drawButtonBoxButton(btnopt, p, rect, frame_radius); } else { p->drawRoundedRect(rect, frame_radius, frame_radius); } // 再画外框(活动色即焦点) pen.setColor(focus_color); p->setPen(pen); if (calendar) { pen.setWidth(2); p->setPen(pen); offset = 1; drawCalenderEllipse(p, opt->rect, offset); } else if (table) { p->drawRect(border); } else if (buttonBoxButton && btnopt) { drawButtonBoxButton(btnopt, p, border, frame_radius); } else { // FIX focus rect not covering corners [frame_radius - margins] p->drawRoundedRect(border, frame_radius - margins, frame_radius - margins); } } void ChameleonStyle::drawCalenderEllipse(QPainter *p, const QRect &rect, int offset) const { QRect ellipese = rect; ellipese.setWidth(ellipese.height()); ellipese.moveCenter(rect.center()); p->drawEllipse(ellipese.adjusted(offset, offset, -offset, -offset)); } void ChameleonStyle::drawButtonBoxButton(const DStyleOptionButtonBoxButton *btnopt, QPainter *p, const QRect &rect, int radius) const { if (btnopt->position == DStyleOptionButtonBoxButton::Beginning) { // Begin if (btnopt->orientation == Qt::Horizontal) { DDrawUtils::drawRoundedRect(p, rect, radius, radius, DDrawUtils::TopLeftCorner | DDrawUtils::BottomLeftCorner); } else { DDrawUtils::drawRoundedRect(p, rect, radius, radius, DDrawUtils::TopLeftCorner | DDrawUtils::TopRightCorner); } } else if (btnopt->position == DStyleOptionButtonBoxButton::End) { // End if (btnopt->orientation == Qt::Horizontal) { DDrawUtils::drawRoundedRect(p, rect, radius, radius, DDrawUtils::TopRightCorner | DDrawUtils::BottomRightCorner); } else { DDrawUtils::drawRoundedRect(p, rect, radius, radius, DDrawUtils::BottomLeftCorner | DDrawUtils::BottomRightCorner); } } else if (btnopt->position == DStyleOptionButtonBoxButton::Middle) { // Middle p->drawRect(rect); } else if (btnopt->position == DStyleOptionButtonBoxButton::OnlyOne) { // OnlyOne p->drawRoundedRect(rect, radius, radius); } } bool ChameleonStyle::isNoticks(const QStyleOptionSlider *slider, QPainter *p, const QWidget *w) const { Q_UNUSED(p) if (const DSlider *dslider = qobject_cast(w)) { QSlider::TickPosition tickPosition = slider->tickPosition; if (dslider) tickPosition = dslider->tickPosition(); return tickPosition == QSlider::NoTicks; } return false; } QBrush ChameleonStyle::generatedBrush(StateFlags flags, const QBrush &base, QPalette::ColorGroup cg, QPalette::ColorRole role, const QStyleOption *option) const { return DStyle::generatedBrush(flags, base, cg, role, option); } QBrush ChameleonStyle::generatedBrush(DStyle::StateFlags flags, const QBrush &base, QPalette::ColorGroup cg, DPalette::ColorType type, const QStyleOption *option) const { return DStyle::generatedBrush(flags, base, cg, type, option); } QColor ChameleonStyle::getColor(const QStyleOption *option, QPalette::ColorRole role) const { return DStyle::generatedBrush(option, option->palette.brush(role), option->palette.currentColorGroup(), role).color(); } QColor ChameleonStyle::getColor(const QStyleOption *option, DPalette::ColorType type, const QWidget *widget) const { const DPalette &pa = DPaletteHelper::instance()->palette(widget, option->palette); return DStyle::generatedBrush(option, pa.brush(type), pa.currentColorGroup(), type).color(); } QBrush ChameleonStyle::getBrush(const QStyleOption *option, DPalette::ColorRole type) const { QWidget *widget = qobject_cast(option->styleObject); if (widget && !widget->testAttribute(Qt::WA_Hover) && DGuiApplicationHelper::isTabletEnvironment()) { return QBrush(Qt::NoBrush); } return QBrush(getColor(option, type)); } QMargins ChameleonStyle::frameExtentMargins() const { int margins = DStyle::pixelMetric(PM_FrameMargins); return QMargins(margins, margins, margins, margins); } QRect ChameleonStyle::drawButtonDownArrow(const QStyleOption *opt, QPainter *p, const QWidget *w) const { const QStyleOptionButton *btn = qstyleoption_cast(opt); if (!btn) return QRect(-1, -1, -1, -1); QRect rectOpt = btn->rect; //实际绘画箭头所占的小矩形 int arrowWidth = DStyle::pixelMetric(PM_MenuButtonIndicator, opt, w); int arrowHeight = arrowWidth; QRect rectArrow(0, 0 , arrowWidth, arrowHeight); rectArrow.moveCenter(rectOpt.center()); QStyleOptionButton newBtn = *btn; //绘画箭头的大矩形(不要竖线) QRect &newRect = newBtn.rect; newRect.setHeight(rectOpt.height()); newRect.setWidth(arrowWidth); newRect.moveCenter(rectOpt.center()); if (btn->direction == Qt::LeftToRight) { rectArrow.moveRight(rectOpt.right()); newRect.moveRight(rectOpt.right()); } else { rectArrow.moveLeft(rectOpt.left()); newRect.moveLeft(rectOpt.left()); } if (p == nullptr || w == nullptr) return newRect; QStyleOptionButton arrowDrawBtn = newBtn; arrowDrawBtn.rect = rectArrow; proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowDrawBtn, p, w); return newRect; } } // namespace chameleon qt5integration-5.7.12/styleplugins/chameleon/chameleonstyle.h000066400000000000000000000145541476226661600244760ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2024 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef CHAMELEONSTYLE_H #define CHAMELEONSTYLE_H #include #include #include DWIDGET_USE_NAMESPACE namespace dstyle { class DStyleAnimation; } DWIDGET_BEGIN_NAMESPACE class DStyleOptionButtonBoxButton; DWIDGET_END_NAMESPACE namespace chameleon { class ChameleonMovementAnimation : public QVariantAnimation { Q_OBJECT public: explicit ChameleonMovementAnimation(QWidget *targetWidget); inline QRect currentRect() const { return m_currentRect; } inline bool isRuning() const { return state() == QVariantAnimation::Running; } inline float progress() const { return float(currentLoopTime()) / duration(); } QWidget *targetWidget() const; void setTargetRect(const QRect &rect); void setCurrentRect(const QRect &rect); private: QRect m_currentRect; QRect m_targetRect; QRect m_lastTargetRect; }; class ChameleonStyle : public DStyle { public: explicit ChameleonStyle(); void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = nullptr) const override; void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w = nullptr) const override; QRect subElementRect(QStyle::SubElement r, const QStyleOption *opt, const QWidget *widget = nullptr) const override; void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *w = nullptr) const override; SubControl hitTestComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, const QPoint &pt, const QWidget *w = nullptr) const override; QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *w = nullptr) const override; QSize sizeFromContents(QStyle::ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *widget = nullptr) const override; int pixelMetric(QStyle::PixelMetric m, const QStyleOption *opt = nullptr, const QWidget *widget = nullptr) const override; int styleHint(StyleHint sh, const QStyleOption *opt = nullptr, const QWidget *w = nullptr, QStyleHintReturn *shret = nullptr) const override; void polish(QWidget *w) override; void unpolish(QWidget *w) override; void unpolish(QApplication *application) override; QBrush generatedBrush(StateFlags flags, const QBrush &base, QPalette::ColorGroup cg, QPalette::ColorRole role, const QStyleOption *option) const; QBrush generatedBrush(StateFlags flags, const QBrush &base, DPalette::ColorGroup cg = DPalette::Normal, DPalette::ColorType type = DPalette::ItemBackground, const QStyleOption *option = nullptr) const; private: void drawShadow(QPainter *p, const QRect &rect, const QColor &color) const; void drawBorder(QPainter *p, const QStyleOption *opt, const QWidget *w) const; void drawCalenderEllipse(QPainter *p, const QRect &rect, int offset) const; void drawButtonBoxButton(const DStyleOptionButtonBoxButton *btnopt, QPainter *p, const QRect &rect, int radius) const; void drawRoundedShadow(QPainter *p, const QRect &rect, const QColor &color,int frame_radius) const; bool isNoticks(const QStyleOptionSlider *slider, QPainter *p, const QWidget *w) const; QColor getColor(const QStyleOption *option, QPalette::ColorRole role) const; QColor getColor(const QStyleOption *option, DPalette::ColorType type, const QWidget *widget) const; QBrush getBrush(const QStyleOption *option, DPalette::ColorRole type) const; QMargins frameExtentMargins() const; QRect drawButtonDownArrow(const QStyleOption *opt, QPainter *p, const QWidget *w) const; bool drawSpinBox(const QStyleOptionSpinBox *opt, QPainter *p, const QWidget *w) const; void updateSpinBoxButtonState(const QStyleOptionSpinBox *opt, QStyleOptionButton& button, bool isActive, bool isEnabled) const; bool drawMenuBarItem(const QStyleOptionMenuItem *option, QRect &rect, QPainter *painter, const QWidget *widget) const; ChameleonMovementAnimation *drawMenuItemBackground(const QStyleOption *option, QPainter *painter, QStyleOptionMenuItem::MenuItemType type) const; bool drawMenuItem(const QStyleOptionMenuItem *option, QPainter *painter, const QWidget *widget) const; bool drawTabBar(QPainter *painter ,const QStyleOptionTab *tab, const QWidget *widget) const; bool drawTabBarLabel(QPainter *painter ,const QStyleOptionTab *tab, const QWidget *widget) const; bool drawTabBarCloseButton(QPainter *painter,const QStyleOption *tab , const QWidget *widget) const; bool drawTabBarScrollButton(QPainter *painter, const QStyleOption *opt, const QWidget *buttonWidget) const; bool drawComboBox(QPainter *painter, const QStyleOptionComboBox *comboBox, const QWidget *widget) const; bool drawComboBoxLabel(QPainter *painter, const QStyleOptionComboBox *comboBox, const QWidget *widget) const; void drawSliderHandle(const QStyleOptionComplex *opt, QRectF& rectHandle, QPainter *p, const QWidget *w) const; void drawSliderHandleFocus(const QStyleOptionComplex *opt, QRectF& rectHandle, QPainter *p, const QWidget *w) const; void drawIcon(const QStyleOption *opt, QPainter *p, QRect &rect, const QIcon &icon, bool checked = false) const; void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const; bool drawTableViewItem(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = nullptr) const; bool hideScrollBarByAnimation(const QStyleOptionSlider *scrollBar, QPainter *p) const; public: #ifndef QT_NO_ANIMATION dstyle::DStyleAnimation *animation(const QObject *target) const; void startAnimation(dstyle::DStyleAnimation *animation, int delay = 0) const; void _q_removeAnimation(); #endif protected: void drawMenuItemRedPoint(const QStyleOptionMenuItem *option, QPainter *painter, const QWidget *widget) const; void resetAttribute(QWidget *w, bool polish); private: mutable QHash animations; }; } // namespace chameleon #endif // CHAMELEONSTYLE_H qt5integration-5.7.12/styleplugins/chameleon/common.h000066400000000000000000000112361476226661600227440ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef COMMON_H #define COMMON_H #include namespace chameleon { enum Metrics { // painter Painter_PenWidth = 1, // frames Frame_FrameWidth = 2, Frame_FrameRadius = 8, Frame_BorderSpacing = 2, // shadow Shadow_Radius = 6, Shadow_XOffset = 0, Shadow_YOffset = 2, // layout Layout_TopLevelMarginWidth = 10, Layout_ChildMarginWidth = 4, Layout_DefaultSpacing = 6, // line editors LineEdit_FrameWidth = 2, LineEdit_LeftMargin = 3, // combobox ComboBox_FrameWidth = 5, ComboBox_ArrowButtonWidth = 40, ComboBox_ContentLeftMargin = 6, // spinbox SpinBox_FrameWidth = 1, SpinBox_ArrowButtonWidth = 20, SpinBox_ButtonIconWidth = 2, SpinBox_MiniHeight = 44, // groupbox title margin GroupBox_TitleMarginWidth = 4, // buttons Button_MinWidth = 80, Button_MarginWidth = 6, Button_ItemSpacing = 4, // tool buttons ToolButton_MarginWidth = 6, ToolButton_ItemSpacing = 4, ToolButton_InlineIndicatorWidth = 12, ToolButton_AlignLeftPadding = 10, ToolButton_AlignCenterPadding = 8, ToolButton_AlignRightPadding = 9, ToolButton_AlignLeftMargin = 7, // checkboxes and radio buttons CheckBox_Size = 20, CheckBox_FocusMarginWidth = 2, CheckBox_ItemSpacing = 4, CheckBox_FrameWidth = 14, // menu Menu_ItemHMargin = 0, Menu_ItemVMargin = -1, Menu_ArrowHMargin = 6, Menu_CheckMarkWidth = 12, Menu_RightBorder = 10, Menu_ItemFrameWidth = 8, Menu_ItemHTextMargin = 3, Menu_ItemVTextMargin = 4, Menu_FrameWidth = 0, Menu_HMargin = 0, Menu_VMargin = 10, Menu_SeparatorItemHMargin = 5, Menu_PanelRightPadding = 10, MenuItem_MarginWidth = 3, MenuItem_ItemSpacing = 4, MenuItem_AcceleratorSpace = 16, MenuItem_TabSpacing = 16, MenuButton_IndicatorMargin = 8, // menu bar MenuBar_ItemSpacing = 6, MenuBarItem_MarginWidth = 10, MenuBarItem_MarginHeight = 6, // scrollbars ScrollBar_Extend = 12, ScrollBar_SliderWidth = 16, ScrollBar_MinSliderHeight = 40, ScrollBar_NoButtonHeight = (ScrollBar_Extend-ScrollBar_SliderWidth)/2, ScrollBar_SingleButtonHeight = ScrollBar_Extend, ScrollBar_DoubleButtonHeight = 2*ScrollBar_Extend, ScrollBar_SliderMinWidget = 36, // toolbars ToolBar_FrameWidth = 2, ToolBar_HandleExtent = 10, ToolBar_HandleWidth = 6, ToolBar_SeparatorWidth = 8, ToolBar_ExtensionWidth = 20, ToolBar_ItemSpacing = 0, // progressbars ProgressBar_BusyIndicatorSize = 14, ProgressBar_ItemSpacing = 4, ProgressBar_MinimumStyleHeight = 8, // mdi title bar TitleBar_MarginWidth = 4, // sliders Slider_TickLength = 20, //滑块的长度 Slider_TickMarginWidth = 6, Slider_GrooveThickness = 2, Slider_ControlThickness = 24, //滑块的高度 Slider_TickmarkOffset = 14, //刻度的高度 // tabbar TabBar_TabMarginHeight = 8, TabBar_TabMarginWidth = 12, TabBar_TabMinWidth = 80, TabBar_TabMinHeight = 20, TabBar_TabItemSpacing = 8, TabBar_TabOverlap = 0, TabBar_BaseOverlap = 0, TabBar_TabMargin = 10, TabBar_TabButtonSize = 22, // 标签页按钮大小 TabletTabBar_TabButtonSize = 36,// 平板环境标签页按钮大小 // tab widget TabWidget_MarginWidth = 4, // toolbox ToolBox_TabMinWidth = 80, ToolBox_TabItemSpacing = 4, ToolBox_TabMarginWidth = 8, // tooltips ToolTip_FrameWidth = 3, // list headers Header_MarginWidth = 6, Header_ItemSpacing = 4, Header_ArrowSize = 12, // tree view ItemView_ArrowSize = 10, ItemView_ItemMarginWidth = 3, SidePanel_ItemMarginWidth = 4, // splitter Splitter_SplitterWidth = 1, // shadow dimensions Shadow_Overlap = 2, // group box GroupBox_TopMargin = 3, // progress bar ProgressBar_BorderWidth = 1, ProgressBar_Radius = 4, // icon Icon_Size = 64, Icon_Margins = 10 }; //* corners enum Corner { CornerTopLeft = 0x1, CornerTopRight = 0x2, CornerBottomLeft = 0x4, CornerBottomRight = 0x8, CornersTop = CornerTopLeft|CornerTopRight, CornersBottom = CornerBottomLeft|CornerBottomRight, CornersLeft = CornerTopLeft|CornerBottomLeft, CornersRight = CornerTopRight|CornerBottomRight, AllCorners = CornerTopLeft|CornerTopRight|CornerBottomLeft|CornerBottomRight }; Q_DECLARE_FLAGS(Corners, Corner) } // namespace chameleon Q_DECLARE_OPERATORS_FOR_FLAGS(chameleon::Corners) #endif // COMMON_H qt5integration-5.7.12/styleplugins/chameleon/dstyleanimation.cpp000066400000000000000000000173251476226661600252200ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "dstyleanimation.h" #ifndef QT_NO_ANIMATION #include #include #include namespace dstyle { static const qreal ScrollBarFadeOutDuration = 1500.0; static const qreal ScrollBarFadeOutDelay = 450.0; DStyleAnimation::DStyleAnimation(QObject *target) : QAbstractAnimation(target), _delay(0), _duration(-1), _startTime(QTime::currentTime()), _fps(ThirtyFps), _skip(0) { } DStyleAnimation::~DStyleAnimation() { } QObject *DStyleAnimation::target() const { return parent(); } int DStyleAnimation::duration() const { return _duration; } void DStyleAnimation::setDuration(int duration) { _duration = duration; } int DStyleAnimation::delay() const { return _delay; } void DStyleAnimation::setDelay(int delay) { _delay = delay; } QTime DStyleAnimation::startTime() const { return _startTime; } void DStyleAnimation::setStartTime(const QTime &time) { _startTime = time; } QAbstractAnimation::DeletionPolicy DStyleAnimation::deletePolicy() const { return QAbstractAnimation::DeletionPolicy(_policy); } // policy will be applied the next time start() is called. void DStyleAnimation::setDeletePolicy(QAbstractAnimation::DeletionPolicy policy) { if (_policy == policy) return; _policy = policy; } DStyleAnimation::FrameRate DStyleAnimation::frameRate() const { return _fps; } void DStyleAnimation::setFrameRate(FrameRate fps) { _fps = fps; } void DStyleAnimation::updateTarget() { QEvent event(QEvent::StyleAnimationUpdate); event.setAccepted(false); QCoreApplication::sendEvent(target(), &event); if (!event.isAccepted()) stop(); } void DStyleAnimation::start() { _skip = 0; QAbstractAnimation::start(deletePolicy()); } bool DStyleAnimation::isUpdateNeeded() const { return currentTime() > _delay; } void DStyleAnimation::updateCurrentTime(int) { if (++_skip >= _fps) { _skip = 0; if (target() && isUpdateNeeded()) updateTarget(); } } DProgressStyleAnimation::DProgressStyleAnimation(int speed, QObject *target) : DStyleAnimation(target), _speed(speed), _step(-1) { } int DProgressStyleAnimation::animationStep() const { return currentTime() / (1000.0 / _speed); } int DProgressStyleAnimation::progressStep(int width) const { int step = animationStep(); int progress = (step * width / _speed) % width; if (((step * width / _speed) % (2 * width)) >= width) progress = width - progress; return progress; } int DProgressStyleAnimation::speed() const { return _speed; } void DProgressStyleAnimation::setSpeed(int speed) { _speed = speed; } bool DProgressStyleAnimation::isUpdateNeeded() const { if (DStyleAnimation::isUpdateNeeded()) { int current = animationStep(); if (_step == -1 || _step != current) { _step = current; return true; } } return false; } DNumberStyleAnimation::DNumberStyleAnimation(QObject *target) : DStyleAnimation(target), _start(0.0), _end(1.0), _prev(0.0) { setDuration(250); } qreal DNumberStyleAnimation::startValue() const { return _start; } void DNumberStyleAnimation::setStartValue(qreal value) { _start = value; } qreal DNumberStyleAnimation::endValue() const { return _end; } void DNumberStyleAnimation::setEndValue(qreal value) { _end = value; } qreal DNumberStyleAnimation::currentValue() const { qreal step = qreal(currentTime() - delay()) / (duration() - delay()); return _start + qMax(qreal(0), step) * (_end - _start); } bool DNumberStyleAnimation::isUpdateNeeded() const { if (DStyleAnimation::isUpdateNeeded()) { qreal current = currentValue(); if (!qFuzzyCompare(_prev, current)) { _prev = current; return true; } } return false; } DBlendStyleAnimation::DBlendStyleAnimation(Type type, QObject *target) : DStyleAnimation(target), _type(type) { setDuration(250); } QImage DBlendStyleAnimation::startImage() const { return _start; } void DBlendStyleAnimation::setStartImage(const QImage& image) { _start = image; } QImage DBlendStyleAnimation::endImage() const { return _end; } void DBlendStyleAnimation::setEndImage(const QImage& image) { _end = image; } QImage DBlendStyleAnimation::currentImage() const { return _current; } /*! \internal A helper function to blend two images. The result consists of ((alpha)*startImage) + ((1-alpha)*endImage) */ static QImage blendedImage(const QImage &start, const QImage &end, float alpha) { if (start.isNull() || end.isNull()) return QImage(); QImage blended; const int a = qRound(alpha*256); const int ia = 256 - a; const int sw = start.width(); const int sh = start.height(); const int bpl = start.bytesPerLine(); switch (start.depth()) { case 32: { blended = QImage(sw, sh, start.format()); blended.setDevicePixelRatio(start.devicePixelRatio()); uchar *mixed_data = blended.bits(); const uchar *back_data = start.bits(); const uchar *front_data = end.bits(); for (int sy = 0; sy < sh; sy++) { quint32* mixed = (quint32*)mixed_data; const quint32* back = (const quint32*)back_data; const quint32* front = (const quint32*)front_data; for (int sx = 0; sx < sw; sx++) { quint32 bp = back[sx]; quint32 fp = front[sx]; mixed[sx] = qRgba ((qRed(bp)*ia + qRed(fp)*a)>>8, (qGreen(bp)*ia + qGreen(fp)*a)>>8, (qBlue(bp)*ia + qBlue(fp)*a)>>8, (qAlpha(bp)*ia + qAlpha(fp)*a)>>8); } mixed_data += bpl; back_data += bpl; front_data += bpl; } } default: break; } return blended; } void DBlendStyleAnimation::updateCurrentTime(int time) { DStyleAnimation::updateCurrentTime(time); float alpha = 1.0; if (duration() > 0) { if (_type == Pulse) { time = time % duration() * 2; if (time > duration()) time = duration() * 2 - time; } alpha = time / static_cast(duration()); if (_type == Transition && time > duration()) { alpha = 1.0; stop(); } } else if (time > 0) { stop(); } _current = blendedImage(_start, _end, alpha); } DScrollbarStyleAnimation::DScrollbarStyleAnimation(Mode mode, QObject *target) : DNumberStyleAnimation(target), _mode(mode), _active(false) { switch (mode) { case Activating: setDuration(ScrollBarFadeOutDuration); setStartValue(0.0); setEndValue(1.0); break; case Deactivating: setDuration(ScrollBarFadeOutDelay + ScrollBarFadeOutDuration); setDelay(ScrollBarFadeOutDelay); setStartValue(1.0); setEndValue(0.0); break; } } DScrollbarStyleAnimation::Mode DScrollbarStyleAnimation::mode() const { return _mode; } void DScrollbarStyleAnimation::restart(bool blocksig/* = false*/) { if (signalsBlocked() != blocksig) { blockSignals(blocksig); } if (blocksig) blockSignals(true); if (state() == Running) stop(); start(); if (blocksig) blockSignals(false); } bool DScrollbarStyleAnimation::wasActive() const { return _active; } void DScrollbarStyleAnimation::setActive(bool active) { _active = active; } } // end namespace dstyle #endif //QT_NO_ANIMATION qt5integration-5.7.12/styleplugins/chameleon/dstyleanimation.h000066400000000000000000000064041476226661600246610ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QSTYLEANIMATION #define QSTYLEANIMATION #include "qabstractanimation.h" #include "qdatetime.h" #include "qimage.h" namespace dstyle { #ifndef QT_NO_ANIMATION // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience of // qcommonstyle.cpp. This header file may change from version to version // without notice, or even be removed. // // We mean it. // class DStyleAnimation : public QAbstractAnimation { Q_OBJECT public: DStyleAnimation(QObject *target); virtual ~DStyleAnimation(); QObject *target() const; int duration() const Q_DECL_OVERRIDE; void setDuration(int duration); int delay() const; void setDelay(int delay); QTime startTime() const; void setStartTime(const QTime &time); QAbstractAnimation::DeletionPolicy deletePolicy() const ; void setDeletePolicy(QAbstractAnimation::DeletionPolicy policy); enum FrameRate { DefaultFps, SixtyFps, ThirtyFps, TwentyFps }; FrameRate frameRate() const; void setFrameRate(FrameRate fps); void updateTarget(); public Q_SLOTS: void start(); protected: virtual bool isUpdateNeeded() const; virtual void updateCurrentTime(int time) Q_DECL_OVERRIDE; private: int _delay; int _duration; QTime _startTime; FrameRate _fps; int _skip; int _policy = QAbstractAnimation::DeletionPolicy::DeleteWhenStopped; }; class DProgressStyleAnimation : public DStyleAnimation { Q_OBJECT public: DProgressStyleAnimation(int speed, QObject *target); int animationStep() const; int progressStep(int width) const; int speed() const; void setSpeed(int speed); protected: bool isUpdateNeeded() const Q_DECL_OVERRIDE; private: int _speed; mutable int _step; }; class DNumberStyleAnimation : public DStyleAnimation { Q_OBJECT public: DNumberStyleAnimation(QObject *target); qreal startValue() const; void setStartValue(qreal value); qreal endValue() const; void setEndValue(qreal value); qreal currentValue() const; protected: bool isUpdateNeeded() const Q_DECL_OVERRIDE; private: qreal _start; qreal _end; mutable qreal _prev; }; class DBlendStyleAnimation : public DStyleAnimation { Q_OBJECT public: enum Type { Transition, Pulse }; DBlendStyleAnimation(Type type, QObject *target); QImage startImage() const; void setStartImage(const QImage& image); QImage endImage() const; void setEndImage(const QImage& image); QImage currentImage() const; protected: virtual void updateCurrentTime(int time) Q_DECL_OVERRIDE; private: Type _type; QImage _start; QImage _end; QImage _current; }; class DScrollbarStyleAnimation : public DNumberStyleAnimation { Q_OBJECT public: enum Mode { Activating, Deactivating }; DScrollbarStyleAnimation(Mode mode, QObject *target); Mode mode() const; void restart(bool blocksig = false); bool wasActive() const; void setActive(bool active); private: Mode _mode; bool _active; }; #endif // QT_NO_ANIMATION } // end namespace dstyle #endif // QSTYLEANIMATION_P qt5integration-5.7.12/styleplugins/chameleon/main.cpp000066400000000000000000000010741476226661600227320ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2017 - 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "chameleonstyle.h" #include class ChameleonStylePlugin : public QStylePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "chameleon.json") public: QStyle* create(const QString &key) override { if (QStringLiteral("chameleon") != key) { return nullptr; } return new chameleon::ChameleonStyle(); } }; #include "main.moc" qt5integration-5.7.12/styles/000077500000000000000000000000001476226661600161265ustar00rootroot00000000000000qt5integration-5.7.12/styles/CMakeLists.txt000066400000000000000000000006451476226661600206730ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later add_executable(gallery norwegianwoodstyle.h widgetgallery.h main.cpp norwegianwoodstyle.cpp widgetgallery.cpp styles.qrc ) target_link_libraries(gallery PRIVATE Dtk${VERSION_SUFFIX}::Widget) set_target_properties(gallery PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) qt5integration-5.7.12/styles/images/000077500000000000000000000000001476226661600173735ustar00rootroot00000000000000qt5integration-5.7.12/styles/images/woodbackground.png000066400000000000000000000170131476226661600231130ustar00rootroot00000000000000PNG  IHDR``F pHYsHHFk>PLTEVDbDfdaKfLgdhZJ4P\Z8_Ob@gLhWjŸGtlߴC7Lɡ*rKEwmI3Ȳr J6]f;i{^BO*"]T v^*g$L,imJmfbi0!?ǰ a^߬ =!+$1a2:pQw6M QAqY`:u=o8 lTy#WP|0:k"锲cę׻,*P҉T c&rW)V*Fm4A˃,$#rJy#g~LJgd"JoJ\25+e@;W[ i 0i0dž8J|ܴ0¤>3Ÿ>,rB1Ef$+7ƪkTp/V/I< `VmCMccc5G; N# 8f vQsr(\@bj|}0C:X0a(B:E !nvhQ ~s\퍆2".:EAg0v)b}nwdTRMdzRnVlSKh:-pxV{]f/?e2ɔ:lػv? 9^6+DZ:Fl_˲N7_{5 5]36yq,B7#̀%i:9~t]#q!aͺEAd{0ggrq"nNF_W#dP'9mss1m?i;z2kX%/_>jCb0U: .yyx>3|ZۣA8FGUwMhh,F BմB ˽{頜WHv/T&&SG:aڿݘ5r¢|*SOٟHŋY;.Gi}{39b-O*,Y&޷7fkjg< {@lnx}EEذawGwAT*i|U'IkhnzǷ(T碦 zC/YxSo5"XumCwn{(.H8mFҗ3#[j8V;: v=3Й0f˗yZo=ѻ&`ڜjG/$Kˣ/9  *Y/ xz^QcϨ@E v޸tBlqϞLpv@ m*)8~q7ralo$Ⱦf0U:/`ޙ>7O6_ٱ^d01Nep}y=u0ħJt`lrL}]^anM"t0#u&ioׇCW+jc{ OLFSJ|9v;s&Q/Ub8VoO?3jl :2tǯ힒*&[RybѥJvB?'e]sܡGRl!̦Xvjeks15lsF]+3i._~X+HNgx񏽭J!i/is9r Qq (?&f%W ?P1nHS+϶ ojJ&A+o"CUhG3jڷk)~0B*o0XHDj_6?}HD|KZC} ywZ'JYQCt$ed'vl$n윀Sß@ߢu)8N9ഭR*_qk_8䍓?cgo3qzHp2h,GMIfpF' w?ةM`! @@::k.Rݫ0[[(GǙEU>KC=9qbxW}ܷ̆w]NObyˑʳ^8 UpgHc)aӳe!9il=hɅ/ؽ,~'z[aܡi /͕nj@\ [97f$3= fԸbW?XՃ ^= c ÑMY%?( Q `qת4DV|UklFx^;\Wn-c1_'7ڧQFIc;Bv Z+E< ƭ08g=Қu7md9j*?Qh'>_ֳN?$~e`V[%RHmH;Nj\||;/ރ {8c "KGsG_ޓzX&C;ήJ˪*vZ#9zPJݘBʹ3=?WY,g~?&EY)в$a ƇZ(.A`*.+pЁT)9Ecg>!},G%oE%<~w)/EO)"{R^[i[6S[w+! mAR#8Sw r7nhj&ܥEm7TOP1N]?xv0gH˓c%0®UeǮm v|ܹ7.B&!!\1҈ue{Ftz? ~xK$@__uWT( E EhV4z]m״1u_:Re%d~_<,?(9ycWv`U2k]۵yG4sLm`a:kb[ar.jhɃ-*rZ]|=qNaPV[Lʠ{K#fɭ:7#L Ic};vLMc1P7Rs|p`[=rO@; "~e(JnL~}:O3/i]tygWW-652[<3[[5B FGFW"=x;jݎudL+Ϋn!Ci/D|@Th{j L6F*U,(#/:)kŰPVL_0r*dn_܋1[SO+eiq&IN];wv*ݤdT-;?kEb1G0C3=g*Ԅ{xtv=f N+U6JTT.\M2\E_qWT+yHMh cT[dsvVvBJ~dny5*p-I(=QqI[8]O]fCns;8"28?}zlXV[4]N;T|ً?;EKK#{8Ўh8f޻w I7%:&q2(^ٶ"(_l}b8ٳov_kZd~?~㷼&̺`tsVۍlĥWTEjwS%-UkߔOK_y KefV^;?F*~*!Gk`ɺ&c&(M!~t:.2ؾy^w<.EfUY'8~*볫t篯n a+.փy 3Yݠݿ/a(+(˖ӯ.6]~ywdF7dPgџwdHu Rŵ]h8o_j1TE~^A우'δr+"ps]y>,9ilqo$|Qoy?&w{w݃p³If:$ψk0/@yR ĵ,ȧ,jBJn#rh߿%HXqcɮ0ܡKͯ߰ouA* ЅnRV51!9yO:P,0tE߇s39 _1R5:d},~(}ISN8>#XU׎vH+ʪ1:߈=gݹ@gmYdOpla_6=Y)r]сQτ/_Plg0$aSy?mr#If`{~zsavTeyJFܘc(.ZFhnʫՕb5O׽eU@AVQuAhW\o=":{+Ha LƓ[&7)`+>#C rvIoBY]p^kM:]i ؃5,Wt Ly {_ik*e, m+ raHyNqcMa5Fy\Zwgn[@m׹?1;WOQ2G:;[RYGƯ4VC;(|t[x{fHtYc4(DY˿o,ǶWvW %2N]zJ*@[yBE+,&ق73Q=>p,'"M{;ޘgI)|Tߕ3R+x0_}dZ3<8e)y5UJ!t+z!A/̃Ng\M 9${ ['^{u @;WEY]aJiF%m0G'Sh "60SU9Ab̚HEm^} `@E%(7$xz($^Ih sE,BǮUF}.Y?@^ï+I% OMA|DV07‡<./ۋ"z d gEk;vDB/| gCrz/5e WhSi ? r[h'N&uq Qc5AZ~(?A2#ݕ0"BrcGy3Wď?dzYttyfad-ڍyY[u6~p4y4#/FPUֆ:涠f~B,y6IENDB`qt5integration-5.7.12/styles/images/woodbutton.png000066400000000000000000000170111476226661600223050ustar00rootroot00000000000000PNG  IHDR``F pHYsHHFk>PLTEC+NKR+MIN0S?T124EGH3P$R;T0X@Z ^b_#aCk09?3DMM!R+R6[9_*bCk.s>uKm:iF<CF1KKKNP6Q-R"THY,Z7a^` `RaEb!e/e:i kCl:p.t"uHy6K ^-GN(EIDATߏ$IboDFdUwOWWUVedVfVwL,]z{l |@X~'$̃@$d #9A6|vfw5w;=3#2#z2#2χ<ӷ?rx; Ξ^w_^ڤ;;\)G+۳{sq)C͆rj5 \ 7b!tMW_a>T@\Va dZƷJe5; [F3k!pIZ@S}@@NS,J; T{OІo-rjFl⭝|2q2sdcVȽj淭O+q{$WF7>Μ @: @ @r3KiTsog],dx|y00h^]FeԬ+>H%S:eU{!{ '{@nssw>hWf}xPUwq4+1 HTPjЖz U;="8p ueVAbrBK$m8hTJf4@+lnj<[OXrzus0ъhR'GgVmܾ0@`9}o0CdeI.He!1{> ղJMu:'KtN'GAj_Í~uҴb@|`A,hu 'μBcBIlփܐ",qLr=ިP1 ,+OWhP9 7MzBm> {-3 BgX/'JMc"/b<׍qM:}yȔv קѕY*g<<Rqh deaU{jYS:8mcKAv>-b3* ^/GWLʗ[|ߚ=zrfuzMYЊ~kƠ5v`0f鍦x_GڣqB@ ȝ7)p'q"@'o:C3t*`~)6;]$xq.ʝ je  Љ%%b'lD27.T@<7B'_Gxjȼ̻ho;\eeQ7L!Aԭ:|*؆[9ž2PXRc7Xd%c#PDFs=')g.m|[9vR`Hl>2Qjj^9^y<pmUm]JW2v)sO;9oS2vg=L7ȳRW=& @1kw@;s-fvPa=Pփyt.Vh=q ~1Óf6R+E.}nqtȀIDi #I#A1:^e&`(m. 3F -AgR[C1tE p7Թ)=j\>W<g~A8_$jBԑ{IA8f`ĵWT#;k+|nLg|1<b-Rcx|?_@n7[&p0}dF?"(The^t.}cam;tLfP!_eK'+P.ǗV+ѱwz4?J[-.5C[O;gJCN[oG<_TDO*!UKj1M>M=e'$|+D+ǧ5 s+ܢ-d7pus`Wf@5Sda0ѣyJv@ȅoW Z"wɨD/Zcy*? Sdv o9xt:F!02(|8uoRn;u<`H" F]o@˚2o fyRC[8܁/{ҚCڹ o;!Zs `t\n9eԄN^tEZ#VGjXޠ/`nb| m(* ɘXrINkx1( ~5iI[&@藫֒OyŹ XbK*>#!B <KT8״۷1>  (`g"NOmwbDP^! ^ df?O&zzSyQu>Ab{[|`Y%|#Ѫ{\j~Jo/mMo։\ Վ N?WNqTNZ)RQ (^%H^ ܐ-0w "ܧ\XyKuʦ5 w1+9n[k5X FCS5 68ʎ jqҳ8:(ٯlۯ! 6w%< G4mL'8+ŀLpܶ)peN20A+:|ܧr-ޡO>:8$?㵪&7LwxxV;/_?|պ*n^bl[j17/7˧>y:sV<ԚYz,o{7ɕc~YxV8`3rWFzy9]0C1 yu]v2@L))@6nP`5H@ H|**TM.|y3\ʊ*P*=U`]s@-`0 ?DC*pp5/ 0w1_w\r s@u3` BՋWOnWՀod97YR8yҮ-Ptq4ȤW6aA-ƣˁ~|z̕k5&n@br^ab6` OH0G:XEEfɒ*iHP}_E`8}nP(:C00~D0hJ!00lQI)x+͒@ X>8KLZ_X?@W~9P_/& wO疽t.-+SuZݙg_T ϖw@Ygx_C,HUFr(3dT#%nzF7@#huj+{^f?p{街`R :oǧב{6_(p=N}gYp{{Ozs^uXA;ϗymbTJ q/ \C!)hub}>)7?bj9XUTY%蓯A` @*80@G'FJ2ihqAm >Rh@ĺ3 x?}9/\Q;7>2]\/T2x+mp^] rQк1>FJ*SVpܚh^"sB"ە@j)P.Zΰ}@/ҷn8:Հ_%! 栶9sۣޏP>4޳Mo 88߼v~;6={>sD|_L&xՌ?5 nI0ʧFܴF>w9o# `o冁<&4@:;f''-?hi} xY4aѳl`QeJ !PƈKlB֘GDotր,! !n/,6{u)5=P<$ A<8^,RsvQk[5Ɓb 1tu01t^f-weU441Lͱ#vhkjrUZق@qoT ^ xހS3cX"X%Jzl:@aP\yeHT]l"3b=&ZXm1N5 QI}`L1ƹ͂EWO v4w_aOz_f[_m^Sey˹z}M;!yl{Sd_gƳl s$Kjw/h fG(P[ʀDgЙ\V@P3 QHk 9ָiS#  sRYE(2NFXƺU`cb Hqdh=@`ig84ztHɌemP`]`aKAʚh`&$^nvâqϬ***F"٘m1:y6_녨:)7ʐs1Xk{K|4`oO> XQqS[* \9f,~ɓ9_fuH P&̤#OL k>IprѪ^w?ydH)$bi;iߏs?OYX+?]t3V4C,=c׮#g{?|aɽ +k#C'Қ^P+B˘Ĩ4nS`UmʭT b.3 4@ a&t/mcgwyxIJZŐߩHTr =6( i^*&Q#@a=O|$H))[A@{@z\1`0^jٔO@Аr-{кA&d`,.-a])Q33PL~ѷ :*9V +Y9/.4YzݑTWt1@cƩ1X$B:# dRH7+m !#EtE&,&l(yI@ESxjL$I5S+ojhԡ^[uZ;aGV҅5wO;ۉY 54 ")`Xݏ2Y?5,i%~wȺp=ÿƝb#eOVs/~bEgtkY[P`퓓tDoZ,LڐB'iH{7[jcQpPo ^ae 2-AsA ,o_A59+e2椉46he{ ZgS<3+8#|q,kuibQ!ak?fx$$pYn#IF͉. Jwg[!!o а@LZP-3UXh~ta|5N>4hcpehʡ˄RҌ~=. yj6jqc' T@I~6RYv@/kA\k}WVۨ6Fa Q >Z!Wnd$gxPVUbK+t ̳8;R<;m[d.7d[J!#dXӻlq(fD Mנ*0Va8}9ƻYUOkmbNIo<w@`ZJ8,ѲCgIENDB`qt5integration-5.7.12/styles/main.cpp000066400000000000000000000011241476226661600175540ustar00rootroot00000000000000// Copyright (C) 2015 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #include #include #include "widgetgallery.h" int main(int argc, char *argv[]) { Q_INIT_RESOURCE(styles); // qputenv("QT_DEBUG_PLUGINS", "1"); QStringList paths = QApplication::libraryPaths(); paths.prepend(QFileInfo(QString::fromUtf8(argv[0])).path() + "/plugins"); QApplication::setLibraryPaths(paths); QApplication app(argc, argv); WidgetGallery gallery; gallery.show(); return app.exec(); } qt5integration-5.7.12/styles/norwegianwoodstyle.cpp000066400000000000000000000217201476226661600225770ustar00rootroot00000000000000// Copyright (C) 2015 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #include "norwegianwoodstyle.h" NorwegianWoodStyle::NorwegianWoodStyle() : QProxyStyle(QStyleFactory::create("windows")) { } //! [0] void NorwegianWoodStyle::polish(QPalette &palette) { QColor brown(212, 140, 95); QColor beige(236, 182, 120); QColor slightlyOpaqueBlack(0, 0, 0, 63); QPixmap backgroundImage(":/images/woodbackground.png"); QPixmap buttonImage(":/images/woodbutton.png"); QPixmap midImage = buttonImage; QPainter painter; painter.begin(&midImage); painter.setPen(Qt::NoPen); painter.fillRect(midImage.rect(), slightlyOpaqueBlack); painter.end(); //! [0] //! [1] palette = QPalette(brown); palette.setBrush(QPalette::BrightText, Qt::white); palette.setBrush(QPalette::Base, beige); palette.setBrush(QPalette::Highlight, Qt::darkGreen); setTexture(palette, QPalette::Button, buttonImage); setTexture(palette, QPalette::Mid, midImage); setTexture(palette, QPalette::Window, backgroundImage); QBrush brush = palette.window(); brush.setColor(brush.color().darker()); palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush); palette.setBrush(QPalette::Disabled, QPalette::Text, brush); palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush); palette.setBrush(QPalette::Disabled, QPalette::Base, brush); palette.setBrush(QPalette::Disabled, QPalette::Button, brush); palette.setBrush(QPalette::Disabled, QPalette::Mid, brush); } //! [1] //! [3] void NorwegianWoodStyle::polish(QWidget *widget) //! [3] //! [4] { if (qobject_cast(widget) || qobject_cast(widget)) widget->setAttribute(Qt::WA_Hover, true); } //! [4] //! [5] void NorwegianWoodStyle::unpolish(QWidget *widget) //! [5] //! [6] { if (qobject_cast(widget) || qobject_cast(widget)) widget->setAttribute(Qt::WA_Hover, false); } //! [6] //! [7] int NorwegianWoodStyle::pixelMetric(PixelMetric metric, //! [7] //! [8] const QStyleOption *option, const QWidget *widget) const { switch (metric) { case PM_ComboBoxFrameWidth: return 8; case PM_ScrollBarExtent: return QProxyStyle::pixelMetric(metric, option, widget) + 4; default: return QProxyStyle::pixelMetric(metric, option, widget); } } //! [8] //! [9] int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option, //! [9] //! [10] const QWidget *widget, QStyleHintReturn *returnData) const { switch (hint) { case SH_DitherDisabledText: return int(false); case SH_EtchDisabledText: return int(true); default: return QProxyStyle::styleHint(hint, option, widget, returnData); } } //! [10] //! [11] void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element, //! [11] //! [12] const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { case PE_PanelButtonCommand: { int delta = (option->state & State_MouseOver) ? 64 : 0; QColor slightlyOpaqueBlack(0, 0, 0, 63); QColor semiTransparentWhite(255, 255, 255, 127 + delta); QColor semiTransparentBlack(0, 0, 0, 127 - delta); int x, y, width, height; option->rect.getRect(&x, &y, &width, &height); //! [12] //! [13] QPainterPath roundRect = roundRectPath(option->rect); //! [13] //! [14] int radius = qMin(width, height) / 2; //! [14] //! [15] QBrush brush; //! [15] //! [16] bool darker; const QStyleOptionButton *buttonOption = qstyleoption_cast(option); if (buttonOption && (buttonOption->features & QStyleOptionButton::Flat)) { brush = option->palette.window(); darker = (option->state & (State_Sunken | State_On)); } else { if (option->state & (State_Sunken | State_On)) { brush = option->palette.mid(); darker = !(option->state & State_Sunken); } else { brush = option->palette.button(); darker = false; //! [16] //! [17] } //! [17] //! [18] } //! [18] //! [19] painter->save(); //! [19] //! [20] painter->setRenderHint(QPainter::Antialiasing, true); //! [20] //! [21] painter->fillPath(roundRect, brush); //! [21] //! [22] if (darker) //! [22] //! [23] painter->fillPath(roundRect, slightlyOpaqueBlack); //! [23] //! [24] int penWidth; //! [24] //! [25] if (radius < 10) penWidth = 3; else if (radius < 20) penWidth = 5; else penWidth = 7; QPen topPen(semiTransparentWhite, penWidth); QPen bottomPen(semiTransparentBlack, penWidth); if (option->state & (State_Sunken | State_On)) qSwap(topPen, bottomPen); //! [25] //! [26] int x1 = x; int x2 = x + radius; int x3 = x + width - radius; int x4 = x + width; if (option->direction == Qt::RightToLeft) { qSwap(x1, x4); qSwap(x2, x3); } QPolygon topHalf; topHalf << QPoint(x1, y) << QPoint(x4, y) << QPoint(x3, y + radius) << QPoint(x2, y + height - radius) << QPoint(x1, y + height); painter->setClipPath(roundRect); painter->setClipRegion(topHalf, Qt::IntersectClip); painter->setPen(topPen); painter->drawPath(roundRect); //! [26] //! [32] QPolygon bottomHalf = topHalf; bottomHalf[0] = QPoint(x4, y + height); painter->setClipPath(roundRect); painter->setClipRegion(bottomHalf, Qt::IntersectClip); painter->setPen(bottomPen); painter->drawPath(roundRect); painter->setPen(option->palette.windowText().color()); painter->setClipping(false); painter->drawPath(roundRect); painter->restore(); } break; //! [32] //! [33] default: //! [33] //! [34] QProxyStyle::drawPrimitive(element, option, painter, widget); } } //! [34] //! [35] void NorwegianWoodStyle::drawControl(ControlElement element, //! [35] //! [36] const QStyleOption *option, QPainter *painter, const QWidget *widget) const { switch (element) { case CE_PushButtonLabel: { QStyleOptionButton myButtonOption; const QStyleOptionButton *buttonOption = qstyleoption_cast(option); if (buttonOption) { myButtonOption = *buttonOption; if (myButtonOption.palette.currentColorGroup() != QPalette::Disabled) { if (myButtonOption.state & (State_Sunken | State_On)) { myButtonOption.palette.setBrush(QPalette::ButtonText, myButtonOption.palette.brightText()); } } } QProxyStyle::drawControl(element, &myButtonOption, painter, widget); } break; default: QProxyStyle::drawControl(element, option, painter, widget); } } //! [36] //! [37] void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role, //! [37] //! [38] const QPixmap &pixmap) { for (int i = 0; i < QPalette::NColorGroups; ++i) { QColor color = palette.brush(QPalette::ColorGroup(i), role).color(); palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap)); } } //! [38] //! [39] QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect) //! [39] //! [40] { int radius = qMin(rect.width(), rect.height()) / 2; int diam = 2 * radius; int x1, y1, x2, y2; rect.getCoords(&x1, &y1, &x2, &y2); QPainterPath path; path.moveTo(x2, y1 + radius); path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0); path.lineTo(x1 + radius, y1); path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0); path.lineTo(x1, y2 - radius); path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0); path.lineTo(x1 + radius, y2); path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0); path.closeSubpath(); return path; } //! [40] qt5integration-5.7.12/styles/norwegianwoodstyle.h000066400000000000000000000025201476226661600222410ustar00rootroot00000000000000// Copyright (C) 2015 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef NORWEGIANWOODSTYLE_H #define NORWEGIANWOODSTYLE_H #include #include QT_BEGIN_NAMESPACE class QPainterPath; QT_END_NAMESPACE //! [0] class NorwegianWoodStyle : public QProxyStyle { Q_OBJECT public: NorwegianWoodStyle(); void polish(QPalette &palette) Q_DECL_OVERRIDE; void polish(QWidget *widget) Q_DECL_OVERRIDE; void unpolish(QWidget *widget) Q_DECL_OVERRIDE; int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const Q_DECL_OVERRIDE; int styleHint(StyleHint hint, const QStyleOption *option, const QWidget *widget, QStyleHintReturn *returnData) const Q_DECL_OVERRIDE; void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const Q_DECL_OVERRIDE; void drawControl(ControlElement control, const QStyleOption *option, QPainter *painter, const QWidget *widget) const Q_DECL_OVERRIDE; private: static void setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap); static QPainterPath roundRectPath(const QRect &rect); }; //! [0] #endif qt5integration-5.7.12/styles/styles.qrc000066400000000000000000000002241476226661600201560ustar00rootroot00000000000000 images/woodbutton.png images/woodbackground.png qt5integration-5.7.12/styles/widgetgallery.cpp000066400000000000000000000416011476226661600214770ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include #include #include #include "norwegianwoodstyle.h" #include "widgetgallery.h" inline static void setUnifiedMargin(QLayout* layout, int margin) { layout->setContentsMargins(margin, margin, margin, margin); } //! [0] WidgetGallery::WidgetGallery(QWidget *parent) : QMainWindow(parent) { originalPalette = QApplication::palette(); styleComboBox = new QComboBox; styleComboBox->addItem("NorwegianWood"); styleComboBox->addItems(QStyleFactory::keys()); styleComboBox->setToolTip("Hello"); styleComboBox->setCurrentIndex(0); styleLabel = new QLabel(tr("&Style:")); styleLabel->setBuddy(styleComboBox); useStylePaletteCheckBox = new QCheckBox(tr("&Use style's standard palette")); useStylePaletteCheckBox->setChecked(false); disableWidgetsCheckBox = new QCheckBox(tr("&Disable widgets")); changeStyle(0); createTopLeftGroupBox(); createTopRightGroupBox(); createBottomLeftTabWidget(); createBottomRightGroupBox(); createProgressBar(); //! [0] //! [1] connect(styleComboBox, static_cast(&QComboBox::activated), this, static_cast(&WidgetGallery::changeStyle)); //! [1] //! [2] connect(useStylePaletteCheckBox, SIGNAL(toggled(bool)), this, SLOT(changePalette())); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), topLeftGroupBox, SLOT(setDisabled(bool))); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), topRightGroupBox, SLOT(setDisabled(bool))); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), bottomLeftTabWidget, SLOT(setDisabled(bool))); connect(disableWidgetsCheckBox, SIGNAL(toggled(bool)), bottomRightGroupBox, SLOT(setDisabled(bool))); //! [2] //! [3] QWidget *mainWidget = new QWidget(); QHBoxLayout *topLayout = new QHBoxLayout; //! [3] //! [4] topLayout->addWidget(styleLabel); topLayout->addWidget(styleComboBox); topLayout->addStretch(1); topLayout->addWidget(useStylePaletteCheckBox); topLayout->addWidget(disableWidgetsCheckBox); QGridLayout *mainLayout = new QGridLayout(mainWidget); mainLayout->addLayout(topLayout, 0, 0, 1, 2); mainLayout->addWidget(topLeftGroupBox, 1, 0); mainLayout->addWidget(topRightGroupBox, 1, 1); mainLayout->addWidget(bottomLeftTabWidget, 2, 0); mainLayout->addWidget(bottomRightGroupBox, 2, 1); mainLayout->addWidget(progressBar, 3, 0, 1, 2); mainLayout->setRowStretch(1, 1); mainLayout->setRowStretch(2, 1); mainLayout->setColumnStretch(0, 1); mainLayout->setColumnStretch(1, 1); setWindowTitle(tr("Styles")); setCentralWidget(mainWidget); QMenu *firstLayer = new QMenu("first"); menuBar()->addAction("chameleon")->setMenu(firstLayer); firstLayer->addAction("menu 1")->setIcon(QIcon::fromTheme("document-open")); firstLayer->addAction("menu 2")->setEnabled(false); firstLayer->addSection("Section"); firstLayer->addAction("menu 3")->setCheckable(true); firstLayer->addSeparator(); QMenu *secondLayer = new QMenu("second"); firstLayer->addMenu(secondLayer); QActionGroup *group = new QActionGroup(this); group->setExclusive(true); QAction *sa1 = new QAction("submenu 1"); sa1->setCheckable(true); group->addAction(sa1); QAction *sa2 = new QAction("submenu 2"); sa2->setCheckable(true); sa2->setIcon(QIcon::fromTheme("application-exit")); group->addAction(sa2); QAction *sa3 = new QAction("submenu 3"); sa3->setCheckable(true); sa3->setShortcut(QKeySequence::New); group->addAction(sa3); secondLayer->addActions(group->actions()); secondLayer->setLayoutDirection(Qt::RightToLeft); menuBar()->addAction("dlight"); menuBar()->addAction("ddark"); menuBar()->addAction("dsemidark"); menuBar()->addAction("dsemilight"); connect(menuBar(), &QMenuBar::triggered, this, [this](const QAction * action) { changeStyle(action->text()); }); } //! [4] //! [5] void WidgetGallery::changeStyle(int index) //! [5] //! [6] { changeStyle(styleComboBox->itemText(index)); } //! [6] void WidgetGallery::changeStyle(const QString &styleName) { if (styleName == "NorwegianWood") { QApplication::setStyle(new NorwegianWoodStyle); } else { QApplication::setStyle(QStyleFactory::create(styleName)); } changePalette(); } //! [7] void WidgetGallery::changePalette() //! [7] //! [8] { if (useStylePaletteCheckBox->isChecked()) { QApplication::setPalette(QApplication::style()->standardPalette()); } else { // QApplication::setPalette(originalPalette); QApplication::setAttribute(Qt::AA_SetPalette, false); } } //! [8] //! [9] void WidgetGallery::advanceProgressBar() //! [9] //! [10] { int curVal = progressBar->value(); int maxVal = progressBar->maximum(); progressBar->setValue(curVal + (maxVal - curVal) / 100); } //! [10] //! [11] void WidgetGallery::createTopLeftGroupBox() //! [11] //! [12] { topLeftGroupBox = new QGroupBox(tr("Group 1")); radioButton1 = new QRadioButton(tr("Radio button 1")); radioButton2 = new QRadioButton(tr("Radio button 2")); radioButton3 = new QRadioButton(tr("Radio button 3")); radioButton1->setChecked(true); checkBox = new QCheckBox(tr("Tri-state check box")); checkBox->setTristate(true); checkBox->setCheckState(Qt::PartiallyChecked); connect(radioButton1, &QRadioButton::clicked, this, [&] { bottomLeftTabWidget->setDocumentMode(!bottomLeftTabWidget->documentMode()); }); connect(radioButton2, &QRadioButton::clicked, this, [&] { bottomLeftTabWidget->setTabShape(QTabWidget::Rounded); bottomLeftTabWidget->update(); }); connect(radioButton3, &QRadioButton::clicked, this, [&] { bottomLeftTabWidget->setTabShape(QTabWidget::Triangular); bottomLeftTabWidget->update(); }); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(radioButton1); layout->addWidget(radioButton2); layout->addWidget(radioButton3); layout->addWidget(checkBox); layout->addStretch(1); topLeftGroupBox->setLayout(layout); } //! [12] void WidgetGallery::createTopRightGroupBox() { topRightGroupBox = new QGroupBox(tr("Group 2")); defaultPushButton = new QPushButton(tr("Default Push Button")); defaultPushButton->setDefault(true); togglePushButton = new QPushButton(tr("Toggle Push Button")); togglePushButton->setCheckable(true); togglePushButton->setChecked(true); flatPushButton = new QPushButton(tr("Flat Push Button")); flatPushButton->setFlat(true); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(defaultPushButton); layout->addWidget(togglePushButton); layout->addWidget(flatPushButton); layout->addStretch(1); topRightGroupBox->setLayout(layout); } void WidgetGallery::createBottomLeftTabWidget() { bottomLeftTabWidget = new QTabWidget; bottomLeftTabWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored); bottomLeftTabWidget->setTabsClosable(true); bottomLeftTabWidget->setTabShape(QTabWidget::Triangular); QWidget *tab1 = new QWidget; tableWidget = new QTableWidget(10, 10); tableWidget->setAlternatingRowColors(true); QHBoxLayout *tab1hbox = new QHBoxLayout; setUnifiedMargin(tab1hbox, 5); tab1hbox->addWidget(tableWidget); tab1->setLayout(tab1hbox); QWidget *tab2 = new QWidget; textEdit = new QTextEdit; textEdit->setPlainText(tr("Twinkle, twinkle, little star,\n" "How I wonder what you are.\n" "Up above the world so high,\n" "Like a diamond in the sky.\n" "Twinkle, twinkle, little star,\n" "How I wonder what you are!\n")); QHBoxLayout *tab2hbox = new QHBoxLayout; setUnifiedMargin(tab2hbox, 5); tab2hbox->addWidget(textEdit); tab2->setLayout(tab2hbox); bottomLeftTabWidget->addTab(tab1, tr("&Table")); bottomLeftTabWidget->addTab(tab2, tr("Text &Edit")); QWidget *pTreeViewWidget = new QWidget; QFileSystemModel *model = new QFileSystemModel(this); model->setRootPath(QDir::currentPath()); QHBoxLayout *pTabLayout = new QHBoxLayout; setUnifiedMargin(pTabLayout, 0); pTreeViewWidget->setLayout(pTabLayout); QTreeView *tree = new QTreeView; tree->setModel(model); pTabLayout->addWidget(tree); QWidget *pListViewWidget = new QWidget; QHBoxLayout *pListLayout = new QHBoxLayout; QStandardItemModel *listModel = new QStandardItemModel(this); setUnifiedMargin(pListLayout, 0); pListViewWidget->setLayout(pListLayout); QListView *lv = new QListView; lv->setDragEnabled(true); lv->setDragDropMode(QListView::DragDrop); lv->setDefaultDropAction(Qt::CopyAction); lv->setModel(listModel); pListLayout->addWidget(lv); for (uint8_t i = 0; i < 10; ++i) { QStandardItem *item = new QStandardItem; item->setIcon(this->style() ? this->style()->standardIcon(QStyle::StandardPixmap(QStyle::SP_DirIcon + i)) : QIcon()); item->setText(QStringLiteral("Row %1...............").arg(i + 1)); item->setEnabled(i % 2); item->setCheckable(true); item->setCheckState(Qt::Checked); item->setDragEnabled(true); listModel->appendRow(item); } QWidget *toolbtns = new QWidget; QVBoxLayout *tbVLayout = new QVBoxLayout(toolbtns); tbVLayout->addWidget(createToolButtons(nullptr, false)); tbVLayout->addWidget(createToolButtons(nullptr, true)); QScrollArea *toolArea = new QScrollArea; toolArea->setWidget(toolbtns); bottomLeftTabWidget->addTab(pTreeViewWidget, "&TreeView"); bottomLeftTabWidget->addTab(pListViewWidget, "&ListView"); bottomLeftTabWidget->addTab(toolArea, "toolbuttons"); bottomLeftTabWidget->addTab(new QWidget(), "tab 3"); bottomLeftTabWidget->addTab(new QWidget(), "tab 4"); } void WidgetGallery::createBottomRightGroupBox() { bottomRightGroupBox = new QGroupBox(tr("Group 3")); bottomRightGroupBox->setCheckable(true); bottomRightGroupBox->setChecked(true); lineEdit = new QLineEdit("s3cRe7"); lineEdit->setEchoMode(QLineEdit::Password); lineEdit->setClearButtonEnabled(true); lineEdit->setFrame(false); QMenu *menu = lineEdit->createStandardContextMenu(); menu->setParent(lineEdit); QAction *testActoin = new QAction("b"); testActoin->setCheckable(true); testActoin->setProperty("_d_menu_item_redpoint", true); QMenu *subMenu = new QMenu("just test red point sub menu", menu); subMenu->setProperty("_d_menu_item_redpoint", true); subMenu->setProperty("_d_menu_item_info", "new"); subMenu->addAction("111"); subMenu->addAction("222"); QAction *a3 = new QAction("a3"); a3->setProperty("_d_menu_item_redpoint", true); subMenu->addAction(a3); menu->addMenu(subMenu); testActoin->setProperty("_d_menu_item_info", "99+"); QObject::connect(testActoin, &QAction::triggered, testActoin, [testActoin](bool checked) { testActoin->setProperty("_d_menu_item_redpoint", checked); }); menu->addAction(testActoin); QObject::connect(lineEdit, &QLineEdit::textChanged, lineEdit, [menu]() { menu->popup(QCursor::pos()); }); spinBox = new QSpinBox(bottomRightGroupBox); spinBox->setValue(50); spinBox->setButtonSymbols(QAbstractSpinBox::PlusMinus); spinBox->setPrefix(" Prefix "); spinBox->setSuffix(" Suffix "); spinBox->setAlignment(Qt::AlignCenter); spinBox->setFrame(false); dateTimeEdit = new QDateTimeEdit(bottomRightGroupBox); dateTimeEdit->setDateTime(QDateTime::currentDateTime()); comboBoxEdit = new QComboBox(bottomRightGroupBox); comboBoxEdit->addItem(QIcon::fromTheme("dde-file-manager"), "dde-file-manager"); comboBoxEdit->addItem(QIcon::fromTheme("dde-introduction"), "dde-introduction"); comboBoxEdit->addItem(QIcon::fromTheme("deepin-deb-installer"), "deepin-deb-installer"); comboBoxEdit->setEditable(true); slider = new QSlider(Qt::Horizontal, bottomRightGroupBox); slider->setRange(0, 100); slider->setTickInterval(10); slider->setTickPosition(QSlider::TicksBelow); slider->setValue(40); scrollBar = new QScrollBar(Qt::Horizontal, bottomRightGroupBox); scrollBar->setValue(60); scrollBar->setProperty("_d_dtk_slider_always_show", true); dial = new QDial(bottomRightGroupBox); dial->setValue(30); dial->setNotchesVisible(true); QGridLayout *layout = new QGridLayout; layout->addWidget(lineEdit, 0, 0, 1, 2); layout->addWidget(spinBox, 1, 0, 1, 2); layout->addWidget(dateTimeEdit, 2, 0, 1, 2); layout->addWidget(comboBoxEdit, 3, 0, 1, 2); layout->addWidget(slider, 4, 0); layout->addWidget(scrollBar, 5, 0); layout->addWidget(dial, 4, 1, 2, 1); layout->setRowStretch(6, 1); bottomRightGroupBox->setLayout(layout); } //! [13] void WidgetGallery::createProgressBar() { progressBar = new QProgressBar; progressBar->setRange(0, 10000); progressBar->setValue(0); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(advanceProgressBar())); timer->start(1000); } //! [13] QToolButton* WidgetGallery::toolBtn(QToolButton::ToolButtonPopupMode mode, const QString &text, bool hasMenu, bool hasIcon, Qt::ToolButtonStyle style) { QToolButton *btn = new QToolButton; QMenu *menu = new QMenu; menu->addAction("action1"); menu->addAction("action2"); if (hasMenu) btn->setMenu(menu); if (hasIcon) btn->setIcon(QIcon::fromTheme("edit")); btn->setIconSize({16, 16}); btn->setPopupMode(mode); if (!text.isEmpty()) { btn->setText(text); btn->setToolButtonStyle(style); } return btn; } QWidget* WidgetGallery::createToolButtons(QWidget *parent, bool hasMenu) { QWidget *holder = new QWidget(parent); holder->resize(300, 500); QGridLayout *gridLayout = new QGridLayout(holder); gridLayout->addWidget(new QLabel(QString("ToolButtonPopupMode")), 0, 0); gridLayout->addWidget(new QLabel("IconOnly"), 0, 1); gridLayout->addWidget(new QLabel(" TextOnly"), 0, 2); gridLayout->addWidget(new QLabel("TextBesideIcon"), 0, 3); gridLayout->addWidget(new QLabel("TextUnderIcon"), 0, 4); gridLayout->addWidget(new QLabel("FollowStyle"), 0, 5); QString tmp = + hasMenu ? QString("(hasMenu)") : QString("(NoMenu)"); for (int i = 0; i < 3; ++i) { auto mode = static_cast(i); QMetaEnum metaEnum = QMetaEnum::fromType(); gridLayout->addWidget(new QLabel(metaEnum.valueToKey(mode) + tmp), i + 1, 0); if (hasMenu) { QToolButton *menuTextIconBtnUnderIconOnly = toolBtn(mode, "ToolButton", true, true, Qt::ToolButtonStyle::ToolButtonIconOnly); gridLayout->addWidget(menuTextIconBtnUnderIconOnly, i + 1, 1); QToolButton *menuTextIconBtnUnderTextOnly = toolBtn(mode, "ToolButton", true, true, Qt::ToolButtonStyle::ToolButtonTextOnly); gridLayout->addWidget(menuTextIconBtnUnderTextOnly, i + 1, 2); QToolButton *menuTextIconBtn = toolBtn(mode, "ToolButton", true, true, Qt::ToolButtonStyle::ToolButtonTextBesideIcon); gridLayout->addWidget(menuTextIconBtn, i + 1, 3); QToolButton *menuTextIconBtnUnder = toolBtn(mode, "ToolButton", true, true, Qt::ToolButtonStyle::ToolButtonTextUnderIcon); gridLayout->addWidget(menuTextIconBtnUnder, i + 1, 4); QToolButton *menuTextIconBtnUnderFollow = toolBtn(mode, "ToolButton", true, true, Qt::ToolButtonStyle::ToolButtonFollowStyle); gridLayout->addWidget(menuTextIconBtnUnderFollow, i + 1, 5); } else { QToolButton *noMenuTextIconBtnIconOnly = toolBtn(mode, "ToolButton", false, true, Qt::ToolButtonStyle::ToolButtonIconOnly); gridLayout->addWidget(noMenuTextIconBtnIconOnly, i + 1, 1); QToolButton *noMenuTextIconBtnTextOnly = toolBtn(mode, "ToolButton", false, true, Qt::ToolButtonStyle::ToolButtonTextOnly); gridLayout->addWidget(noMenuTextIconBtnTextOnly, i + 1, 2); QToolButton *noMenuTextIconBtn = toolBtn(mode, "ToolButton", false, true, Qt::ToolButtonStyle::ToolButtonTextBesideIcon); gridLayout->addWidget(noMenuTextIconBtn, i + 1, 3); QToolButton *noMenuTextIconBtnUnder = toolBtn(mode, "ToolButton", false, true, Qt::ToolButtonStyle::ToolButtonTextUnderIcon); gridLayout->addWidget(noMenuTextIconBtnUnder, i + 1, 4); QToolButton *noMenuTextIconBtnFollow = toolBtn(mode, "ToolButton", false, true, Qt::ToolButtonStyle::ToolButtonFollowStyle); gridLayout->addWidget(noMenuTextIconBtnFollow, i + 1, 5); } } return holder; } qt5integration-5.7.12/styles/widgetgallery.h000066400000000000000000000040711476226661600211440ustar00rootroot00000000000000// Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef WIDGETGALLERY_H #define WIDGETGALLERY_H #include #include QT_BEGIN_NAMESPACE class QCheckBox; class QComboBox; class QDateTimeEdit; class QDial; class QGroupBox; class QLabel; class QLineEdit; class QProgressBar; class QPushButton; class QRadioButton; class QScrollBar; class QSlider; class QSpinBox; class QTabWidget; class QTableWidget; class QTextEdit; QT_END_NAMESPACE //! [0] class WidgetGallery : public QMainWindow { Q_OBJECT public: WidgetGallery(QWidget *parent = 0); private slots: void changeStyle(int index); void changeStyle(const QString &styleName); void changePalette(); void advanceProgressBar(); private: void createTopLeftGroupBox(); void createTopRightGroupBox(); void createBottomLeftTabWidget(); void createBottomRightGroupBox(); void createProgressBar(); QToolButton* toolBtn(QToolButton::ToolButtonPopupMode mode, const QString &text = QString(), bool hasMenu = true, bool hasIcon = true, Qt::ToolButtonStyle style = Qt::ToolButtonStyle::ToolButtonTextBesideIcon); QWidget* createToolButtons(QWidget *parent = nullptr, bool hasMenu = true); QPalette originalPalette; QLabel *styleLabel; QComboBox *styleComboBox; QCheckBox *useStylePaletteCheckBox; QCheckBox *disableWidgetsCheckBox; //! [0] QGroupBox *topLeftGroupBox; QRadioButton *radioButton1; QRadioButton *radioButton2; QRadioButton *radioButton3; QCheckBox *checkBox; QGroupBox *topRightGroupBox; QPushButton *defaultPushButton; QPushButton *togglePushButton; QPushButton *flatPushButton; QTabWidget *bottomLeftTabWidget; QTableWidget *tableWidget; QTextEdit *textEdit; QGroupBox *bottomRightGroupBox; QLineEdit *lineEdit; QSpinBox *spinBox; QDateTimeEdit *dateTimeEdit; QComboBox *comboBoxEdit; QSlider *slider; QScrollBar *scrollBar; QDial *dial; QProgressBar *progressBar; //! [1] }; //! [1] #endif qt5integration-5.7.12/tests/000077500000000000000000000000001476226661600157455ustar00rootroot00000000000000qt5integration-5.7.12/tests/CMakeLists.txt000066400000000000000000000035121476226661600205060ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later add_executable(unit-tests iconengines/svgiconengine/ut_qsvgiconengine.cpp iconengines/svgiconengine/icons.qrc imageformats/dci/ut_qdciiohandler.cpp imageformats/dci/dci_test_files.qrc imageformats/svg/ut_qsvgiohandler.cpp styleplugins/chameleon/ut_chameleonstyle.cpp styleplugins/chameleon/icons/theme-icons.qrc platformtheme/ut_dthemesettings.cpp platformtheme/ut_qdeepintheme.cpp platformtheme/ut_qdeepinfiledialoghelper.cpp platformtheme/test-files.qrc platformtheme/filedialogservice.h platformtheme/filedialogservice.cpp platformtheme/filedialogmanagerservice.h platformtheme/filedialogmanagerservice.cpp ut_pluginloading.cpp main.cpp ) find_package(GTest REQUIRED) target_compile_options(unit-tests PRIVATE -g -fno-access-control -Wall -fsanitize=address -fsanitize-recover=address -O0 ) target_link_options(unit-tests PRIVATE -fsanitize=address -fsanitize-recover=address ) target_link_libraries(unit-tests PRIVATE GTest::GTest GTest::gmock dicon dsvgicon dci dsvg qdeepin chameleon asan ) target_compile_definitions(unit-tests PRIVATE DIALOG_SERVICE="org.deepin.fakefilemanager.filedialog" META_FILE_BASE_DIR="${CMAKE_SOURCE_DIR}" UT_PLATFORMPLUGIN_PATH="${PLUGIN_OUTPUT_BASE_DIR}" ) target_include_directories(unit-tests PRIVATE ${CMAKE_SOURCE_DIR}/iconengineplugins/builtinengine ${CMAKE_SOURCE_DIR}/iconengineplugins/dciiconengine ${CMAKE_SOURCE_DIR}/iconengineplugins/svgiconengine ${CMAKE_SOURCE_DIR}/imageformatplugins/svg ${CMAKE_SOURCE_DIR}/imageformatplugins/dci ${CMAKE_SOURCE_DIR}/styleplugins/chameleon ${CMAKE_SOURCE_DIR}/platformthemeplugin ) qt5integration-5.7.12/tests/iconengines/000077500000000000000000000000001476226661600202465ustar00rootroot00000000000000qt5integration-5.7.12/tests/iconengines/svgiconengine/000077500000000000000000000000001476226661600231045ustar00rootroot00000000000000qt5integration-5.7.12/tests/iconengines/svgiconengine/icon_window_16px.svg000066400000000000000000000016201476226661600270210ustar00rootroot00000000000000 icon_Window/normal qt5integration-5.7.12/tests/iconengines/svgiconengine/icons.qrc000066400000000000000000000001431476226661600247240ustar00rootroot00000000000000 icon_window_16px.svg qt5integration-5.7.12/tests/iconengines/svgiconengine/ut_qsvgiconengine.cpp000066400000000000000000000127711476226661600273470ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include #include #include #include #include #include "qsvgiconengine.h" #define ICONNAME ":/icon_window_16px.svg" DGUI_USE_NAMESPACE class ut_QSvgIconEngine : public testing::Test { protected: void SetUp() override; void TearDown() override; QSvgIconEngine *m_IconEngine = nullptr; bool canUseRender = true; }; void ut_QSvgIconEngine::SetUp() { // 排除没有rsvg环境时测试的干扰 DSvgRenderer render(QString(ICONNAME)); if (!render.isValid()) canUseRender = false; m_IconEngine = new QSvgIconEngine; QString fileName = ICONNAME; m_IconEngine->addFile(fileName, {}, QIcon::Normal, QIcon::Off); } void ut_QSvgIconEngine::TearDown() { delete m_IconEngine; } TEST_F(ut_QSvgIconEngine, QSvgIconEngine) { // 测试构造是否成功 ASSERT_TRUE(m_IconEngine); } TEST_F(ut_QSvgIconEngine, paint) { // 测试添加完原始数据后paint函数能够成功绘制数据 QImage svgImage(QSize(16, 16), QImage::Format_ARGB32); QPainter imgPainter(&svgImage); m_IconEngine->paint(&imgPainter, QRect(QPoint(0, 0), QSize(16, 16)), QIcon::Normal, QIcon::Off); ASSERT_FALSE(svgImage.isNull()); } TEST_F(ut_QSvgIconEngine, actualSize) { // 测试icon的大小是否存在 没有rsvg环境时忽略 QSize iconSize = m_IconEngine->actualSize(QSize(16, 16), QIcon::Normal, QIcon::Off); if (canUseRender) { ASSERT_FALSE(iconSize.isEmpty()); } else { ASSERT_TRUE(iconSize.isEmpty()); } } TEST_F(ut_QSvgIconEngine, pixmap) { // 测试添加完数据后pixmap函数能够成功拿到数据 QPixmap iconPixmap = m_IconEngine->pixmap(QSize(16, 16), QIcon::Normal, QIcon::Off); if (canUseRender) { ASSERT_FALSE(iconPixmap.isNull()); } else { ASSERT_TRUE(iconPixmap.isNull()); } } TEST_F(ut_QSvgIconEngine, key) { ASSERT_FALSE(m_IconEngine->key().isEmpty()); } TEST_F(ut_QSvgIconEngine, clone) { auto clone = m_IconEngine->clone(); ASSERT_TRUE(clone); delete clone; } TEST_F(ut_QSvgIconEngine, readAndWrite) { // 测试读写函数是否正常,读写会返回正常的数值 进行比较 QByteArray data; QDataStream inData(&data, QIODevice::WriteOnly); inData.setVersion(QDataStream::Qt_4_4); // 是否写入成功 ASSERT_TRUE(m_IconEngine->write(inData)); // 写入数据后 原始容器是否存在数据 ASSERT_FALSE(data.isEmpty()); QHash svgBuffers; QHash svgFiles; int isCompressed = -1; QDataStream out(&data, QIODevice::ReadOnly); out.setVersion(QDataStream::Qt_4_4); out >> svgFiles >> isCompressed >> svgBuffers; if (canUseRender) { // 获取写出的数据是否存在 ASSERT_FALSE(svgFiles.isEmpty()); ASSERT_NE(isCompressed, -1); ASSERT_FALSE(svgBuffers.isEmpty()); } svgFiles[-1] = QColor(Qt::red).name(); data.clear(); QDataStream inStream(&data, QIODevice::WriteOnly); inStream.setVersion(QDataStream::Qt_4_4); inStream << svgFiles << isCompressed << svgBuffers; QDataStream readSteam(&data, QIODevice::ReadOnly); readSteam.setVersion(QDataStream::Qt_4_4); // 测试读入数据是否成功 ASSERT_TRUE(m_IconEngine->read(readSteam)); } void testForAddFile(int *ret) { *ret = -1; #ifdef NDEBUG auto iconEngine = QSharedPointer(new QSvgIconEngine); QString fileName = ICONNAME; // 死亡测试 优先进行 测试是否存在崩溃等问题 ASSERT_DEBUG_DEATH(iconEngine->addFile(fileName, QSize(), QIcon::Normal, QIcon::Off), ""); #endif *ret = 0; } TEST(addFileDeathTest, addFile) { testing::FLAGS_gtest_death_test_style = "threadsafe"; int ret = -1; testForAddFile(&ret); // 如果函数崩溃 这里就不会等于0 ASSERT_EQ(ret, 0); } struct TestPixmapType_Param { TestPixmapType_Param(const QPixmap &p, QIcon::Mode m, QIcon::State s) : pixmap(p) , mode(m) , state(s) { } QPixmap pixmap; QIcon::Mode mode; QIcon::State state; }; class AddPixmapParamTest : public ::testing::TestWithParam { protected: void SetUp() override; void TearDown() override; QSvgIconEngine *engine; }; INSTANTIATE_TEST_SUITE_P(QSvgIconEngine, AddPixmapParamTest, ::testing::Values(TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Disabled, QIcon::On), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Active, QIcon::On), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Normal, QIcon::On), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Selected, QIcon::On), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Disabled, QIcon::Off), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Active, QIcon::Off), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Normal, QIcon::Off), TestPixmapType_Param(QPixmap(ICONNAME), QIcon::Selected, QIcon::Off))); TEST_P(AddPixmapParamTest, addPixmap) { // 参数设置 批量进行不同参数 判断返回数据是否一致 TestPixmapType_Param param = GetParam(); engine->addPixmap(param.pixmap, param.mode, param.state); ASSERT_EQ(param.pixmap.toImage(), engine->pixmap({16, 16}, param.mode, param.state).toImage()); } void AddPixmapParamTest::SetUp() { engine = new QSvgIconEngine; } void AddPixmapParamTest::TearDown() { delete engine; } qt5integration-5.7.12/tests/imageformats/000077500000000000000000000000001476226661600204235ustar00rootroot00000000000000qt5integration-5.7.12/tests/imageformats/dci/000077500000000000000000000000001476226661600211625ustar00rootroot00000000000000qt5integration-5.7.12/tests/imageformats/dci/dci_test_files.qrc000066400000000000000000000001401476226661600246440ustar00rootroot00000000000000 radio_checked.dci qt5integration-5.7.12/tests/imageformats/dci/radio_checked.dci000066400000000000000000000260171476226661600244150ustar00rootroot00000000000000DCI20+hover.dark3X1.1p.3.webpRIFFWEBPVP8L/A@'㠍$Grg?\xGr^;vuƝl{7iрv(-lү璈C * mI>_m)$Ix 8{a%]+!80|&6^$Iq2 7hL<Ȋ|yI?X~oO D J c /&lk /0 \JC,p"wd!8wAX"L1x5$J gB$VyYo-qٗ݃Hh&Q}xJȞ 7u6H4f z,Ec#;r^LIM&,9>l8̏ۼaZ$ă55yǶ.im=ץCmcf /^-۷-27q.u1 ck> wޟ Ϯ_˥T,|zrqѿZ2.1p.0.webpRIFFWEBPVP8L/A@o0?jHRc9>d' AbÁ0 Nm[mk0 `H#3ev#<n)2~lݎUi4y a./=wqq@?TRR/dB !2;R"s!ezA`F/H >L|?6hover.light\ 3 1.1p.webpRIFFWEBPVP8L/A@M0hH</]h|iLhII΍A1dkvp230CuUwfD gʒʒ$+$x/ sݯff>2ee{@?m<1wݵ5bAy30`;պW<70^{l3q,K "E ޼,p`iVj$j0MM2 {v`M<)͚d؝ܝ[L%A ɰh B:UYBQ"h: *X$g. Kh{*BRJMu&a0raә͡L." ff)jV)L?H洘]M'gfAњ;?Q~OY5]2#Akʇ> i%ZI)%# ]Zbο[z[s͵)`  b4%<n{]Ʌ0ni\/įf-H&b9B}Vm.t/mҭZZ2ٻo&ë|˥gB)gY**?4ER>ЇEI~kitOW>+PͺlDY)⒒@$NXUX|%uSUi55-bYd6> e>Sl>WCD` &]7y|_̋1xr釚뭾6:z y5f7N'n~#&a`|&KąL4CSXy]"II=]b0OFL ӻYcw"@nFXiXf 8o6Ѻ1 ,F@ 0D}[j38   s&>K"  㑃2 B{q1p_oC}]F0L@_o#dtiPBC8 "3\8y0^R4"B* B fH"aT#q ]Ƞi:"@1Ͽ@ӥd*Θ#pvtylmmh0K5 4(2.1p.3.webpRIFFWEBPVP8L/A@'6dW? rF7 ?#Vξ.=eobUw=oA_◼ą a@]<D!C1 >! Ov@ >?8  %ֈA,>P  \k rȥf$55)Fʠ-5CiB ]&h4e^(X&y$)+((~Ir֩gU^b ̐`TbLxʄ[*&|}1/~@I &@UbM+ iBHLf8Y*)^  z`D/.>`]k24xHp{FԚR8w&2&q&܍T$p͒#࣌#]fXy0_b&loA<vI;Qa>I?\Obg'{pN&[diOs͑Dcw M22[-Uꫳ_3.1p.0.webpRIFFWEBPVP8L/A@wj"IR~1c) 'ն=˿gf"pA p8$<~n?y?auU|"-/wX]\0 ԃK=%H́\H^f0b ҿb3b;qnormal.dark3F1.1p.3.png.alpha8PNG  IHDRBB?_4 pHYsaa?iIDATXk]Es}yi4VuӥT#!HܹJ蟐d'-$ AK|K53b#" [sf;DVߠoxe «LD" f1vfy=fl,v0257Y`z7>;`6Ta02!A fO/j;0=lٚ}v1$ !|Dd1$Qwbr {Ҟ)d@ޓ01\#]y9\?.'3b?b1g1#'':s,jO 03#q[?yF5OYB>B i o!6L@o!nkE @qgwQB_Nzy-ҫh0|sWU Pov qsߧ4#ޯ?&<^^fF%k;8x7vpppm| qz?~HIBD 0gl{/6\\ (K[ 6Kv}yysΕ*Q& 䛝A8qI⼖3"D*_c8_g6 c֚Wޙ-ns.0XkKgOxW1k/PWk,Pi DJPUoU^W"#bD8PzU @daaIBUP%ғs$(>'i8+rԭ|7Hb6$IENDB`2.1p.webpRIFFWEBPVP8L/A@o0?jHRc9>d' AbÁ0 Nm[mk0 `H#3ev#<n)2~lݎUi4y a./=wqq@?TRR/dB !2;R"s!ezA`F/H >L|?6normal.light31.1p.3.png.alpha8SPNG  IHDRBB?_4 pHYsaa?iIDATXk\U923 %BCeqaIH_QkA ]u]K]XQ6P"Vh`"&md7_-,f~ss=D+x'LD *^G$( &bba$dD,Vߜjw=0apJqtBj%/#gR4 ]lL㥉"̢t\4p;t?`Q:j] OZV2tZݵVհy~w:=ߌp*,*loU![Ͱ$իcX 0Jils $XZ?[MgJ t33O"=c=PX0R@sWY"JT@tYrHkb%2 ֨haf^%%Odbi0fu\qz{!NYXZ-aiGp+u\pa=a] E=DEoooCli/,:u{#]vwݩN贽([޻W#nr>#}"κ;{U {wu>(9۹Yqc؋4k>Fxz~"(3J}zz_BdEޯGe,\vz{m*8N-U;#~'Zߪ D޺؜@r#$j1xXoi &6X0ˣE {1/Q AD"{nK/$1Ρ(MJAa߿Li}6I$1:oQB3+A:Ъ[o,5[$Jy$c@AhT6scq' "5ZiQy5:hi)JT7ἳY*F' "J%̄Ps;?0 ED;!%#!̒M_2wOn ?+cIENDB`2.1p.webpRIFFWEBPVP8L/A@w0?j"IR~1@70> XPڶg @=AR/͓]Wgඑ"/'98J/Ppnkyz| ')9R ) S 62xAWl|fS7Y ~78pressed.darkl3$1.1p.webpRIFFWEBPVP8L/A@0$=wgꅇHy3_m$)k9Lq$۪rνeq"' @A)w6! 2OB N0mBf fU&`plbLjN"B<-4U5=ef 5)KM ZnC Ro RV3iJRĦ[aB 8# K% J  Y |>xޒrJ5n(0;|i{@#MDٶău'[F b$׾%mIr|~_q_#|܁)nΞܢ^)]>.@r9zzî{8Ͼ k 6%kR|oVZ_G;6-wՑPJbQ/|ծ1ٗD/cDZ&"K}FI/)/mXuUNCc[()Ӵ-hwV0׀E&xw:II nAOJ!ü1ϕTvlTD(ܠky*u8k݀wi u%}ݎ%=D(y:S>D4M|1)"r$ 12?+:'}¢eHW'3cLxPIO 0`NF)21%b0pt_Tqӧ_Ar.TTIvW)D Y'J\V1;U6Ĥ)BS8Xc);;l;"ފkLHBsٕCI*s4|pMϓ9I.bb-1nu8>0q#dP{KG#hڦ8>PMF>T%F!/h46xX/f?Қf3xԘVmݛSj1F 35茴40[!ZfKCs`L%-2.1p.3.webpRIFFWEBPVP8L/A@wm;ƟJLb\F iij#Im0EdՍT2 pG 0̊'0jFmNkm{8T @aQll#0;0Ch _Qgඑ"/'68\7ݏ+TaR)4pfSY+@]\2-(Y"S6xAW,|fUSY~78pressed.light*31.1p.webptRIFFlWEBPVP8L`/A@7mWQIac)Kxg+bH#)r߫/r6GdWQCbx`jV ;;۶ikp}ٮڶmx)o{8PTaL?-PQ "Hh( D "}2 UTaEu1iRVlXd H!Mz$16{ߑjq>}60'`$d!w֬6ל.c{Zi|-YY?{%eU X,ٲnPyu$98^l}èOAe"HϼoOGߚi) dzu8z/u|/m#ͤm63m۶m۶m۶SmmlKv3y;pƑ֖DԢ{nY~yeOkd~[y:Xl5Ggnzzc]GDh쟷qFn۸"!<88svPhlRhf\7{H̙b!#D "5n$5c2!=T-~.wkI\`Y*5k%+OnbX%q(}8Ezx <cq㸐lN"]ck,햴 Nߩv3I8/բ1M'oA ;atVKSJVҤM#2- d#tTbI0zݍ~nҴ*WZɂ!GY>Lg<> "|{ zJG&7 R ȣDyKۑ @SHT~!qZL=w'^ QQ(ӷ5Ȝ6]ߎ2.8ό |?6qt5integration-5.7.12/tests/imageformats/dci/ut_qdciiohandler.cpp000066400000000000000000000071341476226661600252110ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "qdciiohandler.h" #include #include #include #include #include #include #include #include DGUI_USE_NAMESPACE class ut_QDciIOHandler : public testing::Test { protected: void SetUp(); void TearDown(); }; void ut_QDciIOHandler::SetUp() { } void ut_QDciIOHandler::TearDown() { } TEST_F(ut_QDciIOHandler, testLoad) { QFile file(":/radio_checked.dci"); ASSERT_TRUE(file.open(QIODevice::ReadOnly)); QDciIOHandler handler; handler.setDevice(&file); handler.setFormat("dci"); ASSERT_TRUE(QDciIOHandler::canRead(&file)); file.seek(0); ASSERT_TRUE(handler.canRead()); ASSERT_TRUE(handler.option(QImageIOHandler::Size).toSize().isValid()); QImage image; ASSERT_TRUE(handler.read(&image)); ASSERT_FALSE(image.isNull()); } static bool imagePixelEQ(const QImage &image1, const QImage &image2) { if (image1.sizeInBytes() != image2.sizeInBytes()) return false; for (auto i = image1.sizeInBytes() - 1; i >= 0; --i) if (image1.constBits()[i] != image2.constBits()[i]) return false; return true; } TEST_F(ut_QDciIOHandler, testSetBackground) { QFile file(":/radio_checked.dci"); ASSERT_TRUE(file.open(QIODevice::ReadOnly)); QDciIOHandler handler; handler.setDevice(&file); handler.setFormat("dci"); QImage image; handler.setOption(QImageIOHandler::BackgroundColor, QColor(Qt::red)); ASSERT_TRUE(handler.read(&image)); ASSERT_FALSE(image.isNull()); const QSize size = handler.option(QImageIOHandler::Size).toSize(); DDciIcon dci(file.fileName()); ASSERT_FALSE(dci.isNull()); auto icon = dci.matchIcon(size.width(), DDciIcon::Light, DDciIcon::Normal, DDciIcon::DontFallbackMode); ASSERT_NE(icon, nullptr); ASSERT_TRUE(dci.isSupportedAttribute(icon, DDciIcon::HasPalette)); DDciIconPalette pa(QColor::Invalid, QColor(Qt::red)); QImage image2 = dci.pixmap(1.0, 0, icon, pa).toImage(); ASSERT_FALSE(image2.isNull()); ASSERT_TRUE(imagePixelEQ(image, image2)); } TEST_F(ut_QDciIOHandler, testSetFormat) { QFile file(":/radio_checked.dci"); ASSERT_TRUE(file.open(QIODevice::ReadOnly)); DDciIcon dci(file.fileName()); ASSERT_FALSE(dci.isNull()); { file.seek(0); QImage image; QDciIOHandler handler; handler.setDevice(&file); handler.setFormat("dci-light-hover"); ASSERT_TRUE(handler.read(&image)); ASSERT_FALSE(image.isNull()); const QSize size = handler.option(QImageIOHandler::Size).toSize(); auto icon = dci.matchIcon(size.width(), DDciIcon::Light, DDciIcon::Hover, DDciIcon::DontFallbackMode); ASSERT_NE(icon, nullptr); QImage image2 = dci.pixmap(1.0, 0, icon).toImage(); ASSERT_FALSE(image2.isNull()); ASSERT_TRUE(imagePixelEQ(image, image2)); } { file.seek(0); QImage image; QDciIOHandler handler; handler.setDevice(&file); handler.setFormat("dci-dark-pressed"); ASSERT_TRUE(handler.read(&image)); ASSERT_FALSE(image.isNull()); const QSize size = handler.option(QImageIOHandler::Size).toSize(); auto icon = dci.matchIcon(size.width(), DDciIcon::Dark, DDciIcon::Pressed, DDciIcon::DontFallbackMode); ASSERT_NE(icon, nullptr); QImage image2 = dci.pixmap(1.0, 0, icon).toImage(); ASSERT_FALSE(image2.isNull()); ASSERT_TRUE(imagePixelEQ(image, image2)); } } qt5integration-5.7.12/tests/imageformats/svg/000077500000000000000000000000001476226661600212225ustar00rootroot00000000000000qt5integration-5.7.12/tests/imageformats/svg/ut_qsvgiohandler.cpp000066400000000000000000000135121476226661600253060ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "qsvgiohandler.h" #include #include #include #include #include #include #include #include #ifndef UT_QSVGIOHANDLERPRIVATE #define UT_QSVGIOHANDLERPRIVATE DGUI_USE_NAMESPACE class QSvgIOHandlerPrivate { public: QSvgIOHandlerPrivate(QSvgIOHandler *qq); bool load(QIODevice *device); QSvgIOHandler *q; DSvgRenderer r; QSize defaultSize; QRect clipRect; QSize scaledSize; QRect scaledClipRect; bool loaded; bool readDone; QColor backColor; }; #endif class ut_QSvgIOHandler : public testing::Test { protected: void SetUp(); void TearDown(); QSvgIOHandler *handler; }; void ut_QSvgIOHandler::SetUp() { handler = new QSvgIOHandler(); } void ut_QSvgIOHandler::TearDown() { delete handler; } TEST_F(ut_QSvgIOHandler, testForPrivatePtr) { ASSERT_TRUE(handler->d); ASSERT_FALSE(handler->d->loaded); ASSERT_FALSE(handler->d->readDone); ASSERT_EQ(handler->d->backColor, Qt::transparent); } static const char *testTmpFile = "/tmp/tmpSvg.svg"; static const char *testSvgContent = "" "" "logo icon" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""; TEST_F(ut_QSvgIOHandler, testForLoad) { QImage image(QSize(20, 20), QImage::Format_RGB32); // 填充一个底色用于判断颜色是否被覆盖 image.fill(Qt::green); ASSERT_FALSE(handler->read(&image)); QFile tmpFile(testTmpFile); ASSERT_TRUE(tmpFile.open(QFile::WriteOnly)); tmpFile.write(testSvgContent); tmpFile.close(); ASSERT_TRUE(tmpFile.open(QFile::ReadWrite)); ASSERT_TRUE(handler->canRead(&tmpFile)); QRect clipRect(0, 0, 10, 10); handler->setOption(QSvgIOHandler::ClipRect, clipRect); ASSERT_EQ(handler->option(QSvgIOHandler::ClipRect), clipRect); QSize scaleSize(20, 20); handler->setOption(QSvgIOHandler::ScaledSize, scaleSize); ASSERT_EQ(handler->option(QSvgIOHandler::ScaledSize), scaleSize); QRect scaledClipRect(2, 2, 5, 5); handler->setOption(QSvgIOHandler::ScaledClipRect, scaledClipRect); ASSERT_EQ(handler->option(QSvgIOHandler::ScaledClipRect), scaledClipRect); QColor backgroundColor(Qt::blue); handler->setOption(QSvgIOHandler::BackgroundColor, backgroundColor); ASSERT_EQ(handler->option(QSvgIOHandler::BackgroundColor), backgroundColor); ASSERT_TRUE(handler->option(QSvgIOHandler::Size).isValid()); handler->setDevice(&tmpFile); handler->read(&image); tmpFile.close(); tmpFile.remove(); } TEST_F(ut_QSvgIOHandler, testFunction) { ASSERT_STREQ(handler->name(), "svg"); ASSERT_TRUE(handler->supportsOption(QSvgIOHandler::ImageFormat)); ASSERT_TRUE(handler->supportsOption(QSvgIOHandler::Size)); ASSERT_TRUE(handler->supportsOption(QSvgIOHandler::ClipRect)); ASSERT_TRUE(handler->supportsOption(QSvgIOHandler::ScaledSize)); ASSERT_TRUE(handler->supportsOption(QSvgIOHandler::ScaledClipRect)); ASSERT_TRUE(handler->supportsOption(QSvgIOHandler::BackgroundColor)); ASSERT_FALSE(handler->supportsOption(QSvgIOHandler::ImageTransformation)); } qt5integration-5.7.12/tests/main.cpp000066400000000000000000000020241476226661600173730ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #ifdef QT_DEBUG #include #endif int main(int argc, char *argv[]) { // gerrit编译时没有显示器,需要指定环境变量 qputenv("QT_QPA_PLATFORM", "offscreen"); // 风格插件需要添加平台主题,用于创建图标引擎 QByteArray platformThemePath; #ifdef UT_PLATFORMPLUGIN_PATH platformThemePath = UT_PLATFORMPLUGIN_PATH; QApplication::setLibraryPaths(QApplication::libraryPaths() << QString(UT_PLATFORMPLUGIN_PATH).append("../")); #endif if (!platformThemePath.isEmpty()) qputenv("QT_QPA_PLATFORM_PLUGIN_PATH", platformThemePath); qputenv("QT_QPA_PLATFORMTHEME", "deepin"); QApplication app(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); #ifdef QT_DEBUG __sanitizer_set_report_path("asan.log"); #endif return ret; } qt5integration-5.7.12/tests/platformtheme/000077500000000000000000000000001476226661600206145ustar00rootroot00000000000000qt5integration-5.7.12/tests/platformtheme/filedialogmanagerservice.cpp000066400000000000000000000042321476226661600263340ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "filedialogmanagerservice.h" #include #include FileDialogManagerService::FileDialogManagerService(const QString &service, const QString &path) : m_service{service}, m_path{path}, m_useFileChooserDialog{true}, m_errorMsg{} { registerAll(); } FileDialogManagerService::~FileDialogManagerService() { unregisterAll(); } bool FileDialogManagerService::registerAll() { QDBusConnection conn = QDBusConnection::sessionBus(); if (!conn.registerService(m_service)) { m_errorMsg = QString("Cannot register service %1").arg(m_service); return false; } if (!conn.registerObject(m_path, this, QDBusConnection::ExportAllContents)) { m_errorMsg = QString("Cannot register object %1").arg(m_path); return false; } return true; } bool FileDialogManagerService::unregisterAll() { QDBusConnection conn = QDBusConnection::sessionBus(); conn.unregisterObject(m_path); if (!conn.unregisterService(m_service)) { m_errorMsg = QString("Cannot unregister service %1").arg(m_service); return false; } return true; } QList FileDialogManagerService::dialogs() { return m_dialogMap.keys(); } QDBusObjectPath FileDialogManagerService::createDialog(const QString key) { QString path{"/com/deepin/filemanager/filedialog/"}; if (key.isEmpty()) { path.append(QUuid::createUuid().toRfc4122().toHex()); } else { path.append(key); } FileDialogService *dialogService = new FileDialogService(path); m_dialogMap.insert(QDBusObjectPath{path}, dialogService); return QDBusObjectPath{path}; } void FileDialogManagerService::destroyDialog(const QDBusObjectPath &path) { auto dialog = m_dialogMap.find(path); dialog.value()->deleteLater(); m_dialogMap.erase(dialog); } bool FileDialogManagerService::isUseFileChooserDialog() { return m_useFileChooserDialog; } QString FileDialogManagerService::errorString() { return m_errorMsg; } qt5integration-5.7.12/tests/platformtheme/filedialogmanagerservice.h000066400000000000000000000050421476226661600260010ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef FILEDIALOGMANAGERSERVICE_H #define FILEDIALOGMANAGERSERVICE_H #include #include #include "filedialogservice.h" #include class FileDialogManagerService : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.filedialogmanager") Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: FileDialogManagerService(const QString &service, const QString &path); ~FileDialogManagerService(); public Q_SLOTS: Q_SCRIPTABLE QDBusObjectPath createDialog(const QString key); void destroyDialog(const QDBusObjectPath &path); QList dialogs(); QString errorString(); bool isUseFileChooserDialog(); private: bool registerAll(); bool unregisterAll(); QMap m_dialogMap; QString m_service; QString m_path; bool m_useFileChooserDialog; QString m_errorMsg; }; #endif // FILEDIALOGMANAGERSERVICE_H qt5integration-5.7.12/tests/platformtheme/filedialogservice.cpp000066400000000000000000000067721476226661600250140ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include "filedialogservice.h" #include FileDialogService::FileDialogService(const QString &path) : m_objPath{path} , m_online{false} , m_accepted{false} , m_rejected{false} , m_visible{false} { QDBusConnection conn = QDBusConnection::sessionBus(); m_online = conn.registerObject(m_objPath, this, QDBusConnection::ExportAllContents); connect(this, &QObject::destroyed, this, &FileDialogService::destroyed); } FileDialogService::~FileDialogService() { QDBusConnection conn = QDBusConnection::sessionBus(); conn.unregisterObject(m_objPath); m_online = false; } void FileDialogService::accept() { m_accepted = true; Q_EMIT this->accepted(); } void FileDialogService::activateWindow() { } void FileDialogService::addCustomWidget(int type, const QString & data) { Q_UNUSED(type) Q_UNUSED(data) } void FileDialogService::addDisableUrlScheme(const QString & type) { Q_UNUSED(type) } QMap FileDialogService::allCustomWidgetsValue(int type) { Q_UNUSED(type) return QMap(); } void FileDialogService::beginAddCustomWidget() { } void FileDialogService::endAddCustomWidget() { } QDBusVariant FileDialogService::getCustomWidgetValue(int type, const QString & text) { Q_UNUSED(type) Q_UNUSED(text) return QDBusVariant(); } void FileDialogService::hide() { m_visible = false; } QString FileDialogService::labelText(int label) { Q_UNUSED(label) return QString(); } void FileDialogService::makeHeartbeat() { } void FileDialogService::open() { } int FileDialogService::options() { return 0; } void FileDialogService::reject() { m_rejected = true; Q_EMIT this->rejected(); } void FileDialogService::selectFile(const QString & filename) { Q_UNUSED(filename) } void FileDialogService::selectNameFilter(const QString & filter) { m_nameFilters.append(filter); } void FileDialogService::selectNameFilterByIndex(int index) { Q_UNUSED(index) } void FileDialogService::selectUrl(const QString & url) { m_selectedFiles.append(url); } QStringList FileDialogService::selectedFiles() { QStringList files; for (auto fileUrl : m_selectedFiles) { files.append(fileUrl.toString()); } return files; } QString FileDialogService::selectedNameFilter() { return m_nameFilters.join(';'); } int FileDialogService::selectedNameFilterIndex() { return 0; } QStringList FileDialogService::selectedUrls() { QStringList files; for (auto fileUrl : m_selectedFiles) { files.append(fileUrl.toString()); } return files; } void FileDialogService::setAllowMixedSelection(bool on) { Q_UNUSED(on) } void FileDialogService::setCurrentInputName(const QString & name) { Q_UNUSED(name) } void FileDialogService::setFileMode(int fileMode) { Q_UNUSED(fileMode) } void FileDialogService::setLabelText(int label, const QString & text) { Q_UNUSED(label) Q_UNUSED(text) } void FileDialogService::setOption(int option, bool on) { Q_UNUSED(option) Q_UNUSED(on) } void FileDialogService::setOptions(int options) { Q_UNUSED(options) } void FileDialogService::setWindowTitle(const QString & title) { Q_UNUSED(title) } void FileDialogService::show() { m_visible = true; } bool FileDialogService::testOption(int option) { Q_UNUSED(option) return false; } qulonglong FileDialogService::winId() { return qulonglong(); } qt5integration-5.7.12/tests/platformtheme/filedialogservice.h000066400000000000000000000343021476226661600244470ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #ifndef FILEDIALOGSERVICE_H #define FILEDIALOGSERVICE_H #include #include #include class FileDialogService : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.filedialog") Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") Q_PROPERTY(int acceptMode READ acceptMode WRITE setAcceptMode) Q_PROPERTY(QString directory READ directory WRITE setDirectory) Q_PROPERTY(QString directoryUrl READ directoryUrl WRITE setDirectoryUrl) Q_PROPERTY(int filter READ filter WRITE setFilter) Q_PROPERTY(int heartbeatInterval READ heartbeatInterval WRITE setHeartbeatInterval) Q_PROPERTY(bool hideOnAccept READ hideOnAccept WRITE setHideOnAccept) Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) Q_PROPERTY(int viewMode READ viewMode WRITE setViewMode) Q_PROPERTY(bool windowActive READ windowActive) Q_PROPERTY(uint windowFlags READ windowFlags WRITE setWindowFlags) public: inline int acceptMode() const { return m_acceptMode; } inline void setAcceptMode(int value) { m_acceptMode = value; } inline QString directory() const { return directoryUrl(); } inline void setDirectory(const QString &value) { setDirectoryUrl(value); Q_EMIT this->directoryChanged(); } inline QString directoryUrl() const { return m_directoryUrl; } inline void setDirectoryUrl(const QString &value) { m_directoryUrl = value; Q_EMIT this->directoryUrlChanged(); } inline int filter() const { return m_filter; } inline void setFilter(int value) { m_filter = value; } inline int heartbeatInterval() const { return m_heartbeatInterval; } inline void setHeartbeatInterval(int value) { m_heartbeatInterval = value; } inline bool hideOnAccept() const { return m_hideOnAccept; } inline void setHideOnAccept(bool value) { m_hideOnAccept = value; } inline QStringList nameFilters() const { return m_nameFilters; } inline void setNameFilters(const QStringList &value) { m_nameFilters = value; } inline int viewMode() const { return m_viewMode; } inline void setViewMode(int value) { m_viewMode = value; } inline bool windowActive() const { return m_windowActive; } inline uint windowFlags() const { return m_windowFlags; } inline void setWindowFlags(uint value) { m_windowFlags = value; } public Q_SLOTS: void accept(); void activateWindow(); void addCustomWidget(int type, const QString &data); void addDisableUrlScheme(const QString &type); QMap allCustomWidgetsValue(int type); void beginAddCustomWidget(); void endAddCustomWidget(); QDBusVariant getCustomWidgetValue(int type, const QString &text); void hide(); QString labelText(int label); void makeHeartbeat(); void open(); int options(); void reject(); void selectFile(const QString &filename); void selectNameFilter(const QString &filter); void selectNameFilterByIndex(int index); void selectUrl(const QString &url); QStringList selectedFiles(); QString selectedNameFilter(); int selectedNameFilterIndex(); QStringList selectedUrls(); void setAllowMixedSelection(bool on); void setCurrentInputName(const QString &name); void setFileMode(int fileMode); void setLabelText(int label, const QString &text); void setOption(int option, bool on); void setOptions(int options); void setWindowTitle(const QString &title); void show(); bool testOption(int option); qulonglong winId(); Q_SIGNALS: // SIGNALS void accepted(); void currentUrlChanged(); void destroyed(); void directoryChanged(); void directoryUrlChanged(); void finished(int result); void rejected(); void selectedNameFilterChanged(); void selectionFilesChanged(); void windowActiveChanged(); public: FileDialogService(const QString &path); ~FileDialogService(); QString m_objPath; bool m_online; bool m_accepted; bool m_rejected; bool m_visible; QList m_selectedFiles; int m_acceptMode; QString m_directoryUrl; int m_filter; int m_heartbeatInterval; bool m_hideOnAccept; QStringList m_nameFilters; int m_viewMode; bool m_windowActive; uint m_windowFlags; }; #endif // FILEDIALOGSERVICE_H qt5integration-5.7.12/tests/platformtheme/qt-theme.ini000066400000000000000000000002621476226661600230410ustar00rootroot00000000000000[Theme] Font=Noto Sans FontSize=11 IconThemeName=organic-glass FallBackIconThemeName=bloom StyleNames=chameleon MonoFont=Noto Mono ScaleLogicalDpi=96, 96 ScreenScaleFactors=1.25 qt5integration-5.7.12/tests/platformtheme/test-files.qrc000066400000000000000000000001331476226661600233770ustar00rootroot00000000000000 qt-theme.ini qt5integration-5.7.12/tests/platformtheme/ut_dthemesettings.cpp000066400000000000000000000062621476226661600250650ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include #endif #include "dthemesettings.h" class TestDThemeSettings : public testing::Test { public: static void SetUpTestSuite() { userConfigPath = new QTemporaryDir; userConfigPath->setAutoRemove(true); QDir path(userConfigPath->path()); path.mkdir("deepin"); QFile::copy(":/qt-theme.ini", userConfigPath->filePath("deepin/qt-theme.ini")); prevEnv = qgetenv("D_QT_THEME_CONFIG_PATH"); qputenv("D_QT_THEME_CONFIG_PATH", userConfigPath->path().toLocal8Bit()); themeSettings = new DThemeSettings(false); } static void TearDownTestSuite() { qputenv("D_Qt_THEME_CONFIG_PATH", prevEnv); delete themeSettings; delete userConfigPath; } static DThemeSettings *themeSettings; static QTemporaryDir *userConfigPath; static QByteArray prevEnv; }; DThemeSettings *TestDThemeSettings::themeSettings = nullptr; QTemporaryDir *TestDThemeSettings::userConfigPath = nullptr; QByteArray TestDThemeSettings::prevEnv = {}; // Test user settings load TEST_F(TestDThemeSettings, makeSettingsUserSpecified) { QSettings *settings = DThemeSettings::makeSettings(); ASSERT_NE(nullptr, settings); ASSERT_EQ(settings->status(), QSettings::NoError); QString name = settings->fileName(); EXPECT_EQ(name, userConfigPath->filePath("deepin/qt-theme.ini")); QStringList keys = settings->allKeys(); EXPECT_TRUE(keys.contains("Font")); EXPECT_TRUE(keys.contains("FontSize")); EXPECT_TRUE(keys.contains("IconThemeName")); EXPECT_TRUE(keys.contains("MonoFont")); EXPECT_TRUE(keys.contains("ScaleLogicalDpi")); EXPECT_TRUE(keys.contains("ScreenScaleFactors")); } // Make sure that ini file uses UTF-8 codec TEST_F(TestDThemeSettings, makeSettingsCodec) { QSettings *settings = DThemeSettings::makeSettings(); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec *iniCodec = settings->iniCodec(); EXPECT_EQ(codec->name(), iniCodec->name()); #else Q_UNUSED(settings) #endif } // Test properties using fake data TEST_F(TestDThemeSettings, properties) { EXPECT_EQ(themeSettings->isSetIconThemeName(), true); EXPECT_EQ(themeSettings->iconThemeName(), "organic-glass"); EXPECT_EQ(themeSettings->isSetFallbackIconThemeName(), true); EXPECT_EQ(themeSettings->fallbackIconThemeName(), "bloom"); EXPECT_EQ(themeSettings->isSetStyleNames(), true); EXPECT_EQ(themeSettings->styleNames(), QStringList{"chameleon"}); EXPECT_EQ(themeSettings->isSetSystemFont(), true); EXPECT_EQ(themeSettings->systemFont(), "Noto Sans"); EXPECT_EQ(themeSettings->isSetSystemFixedFont(), true); EXPECT_EQ(themeSettings->systemFixedFont(), "Noto Mono"); EXPECT_EQ(themeSettings->screenScaleFactors(), "1.25"); DDpi dpi = themeSettings->scaleLogicalDpi(); EXPECT_DOUBLE_EQ(dpi.first, 96.0); EXPECT_DOUBLE_EQ(dpi.second, 96.0); } qt5integration-5.7.12/tests/platformtheme/ut_qdeepinfiledialoghelper.cpp000066400000000000000000000111111476226661600266700ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include #include "filedialogmanagerservice.h" #include "filedialog_interface.h" #include "qdeepinfiledialoghelper.h" #include #include class TestQDeepinFileDialogHelper : public testing::Test { public: static void SetUpTestSuite() { qputenv("_d_fileDialogServiceName", DIALOG_SERVICE); manager = new FileDialogManagerService(DIALOG_SERVICE, "/com/deepin/filemanager/filedialogmanager"); QDeepinFileDialogHelper::initDBusFileDialogManager(); } static void TearDownTestSuite() { qunsetenv("_d_fileDialogServiceName"); delete manager; } void SetUp() override { helper = new QDeepinFileDialogHelper; nativedlg = new QFileDialog; } void TearDown() override { delete helper; delete nativedlg; } void ensureDialog() { if (filedlg) return; if (helper) { helper->ensureDialog(); if (helper->filedlgInterface) { auto dialogPath = helper->filedlgInterface->path(); filedlg = manager->m_dialogMap[QDBusObjectPath{dialogPath}]; } } } private: QDeepinFileDialogHelper *helper{nullptr}; FileDialogService *filedlg{nullptr}; QFileDialog *nativedlg{nullptr}; static FileDialogManagerService *manager; }; FileDialogManagerService *TestQDeepinFileDialogHelper::manager = nullptr; TEST_F(TestQDeepinFileDialogHelper, ensureDialog) { EXPECT_EQ(nullptr, filedlg); EXPECT_NE(nullptr, helper); ensureDialog(); EXPECT_NE(nullptr, filedlg); } TEST_F(TestQDeepinFileDialogHelper, show) { helper->setOptions(QFileDialogOptions::create()); bool success = helper->show(Qt::Dialog, Qt::ApplicationModal, nativedlg->windowHandle()); ASSERT_TRUE(success); EXPECT_TRUE(QGuiApplicationPrivate::self->modalWindowList.contains(helper->auxiliaryWindow)); EXPECT_EQ(helper->auxiliaryWindow, qApp->modalWindow()); } TEST_F(TestQDeepinFileDialogHelper, exec) { ensureDialog(); QTimer::singleShot(1, filedlg, &FileDialogService::accept); helper->exec(); EXPECT_TRUE(filedlg->m_visible); // Ensure that auxiliary window is non-modal after exec ASSERT_NE(nullptr, helper->auxiliaryWindow); EXPECT_FALSE(QGuiApplicationPrivate::self->modalWindowList.contains(helper->auxiliaryWindow)); } TEST_F(TestQDeepinFileDialogHelper, hide) { ensureDialog(); QTimer::singleShot(1, helper, &QDeepinFileDialogHelper::hide); helper->exec(); EXPECT_FALSE(filedlg->m_visible); ASSERT_NE(nullptr, helper->auxiliaryWindow); EXPECT_FALSE(QGuiApplicationPrivate::self->modalWindowList.contains(helper->auxiliaryWindow)); } TEST_F(TestQDeepinFileDialogHelper, setDirectory) { ensureDialog(); filedlg->setDirectory("/test"); helper->setDirectory(QUrl("/dtk")); EXPECT_EQ("/dtk", filedlg->m_directoryUrl); } TEST_F(TestQDeepinFileDialogHelper, directory) { ensureDialog(); filedlg->m_directoryUrl = "/test"; EXPECT_EQ(filedlg->directory(), "/test"); } TEST_F(TestQDeepinFileDialogHelper, selectFile) { ensureDialog(); filedlg->m_selectedFiles.clear(); helper->selectFile(QUrl{"/test"}); ASSERT_EQ(1, filedlg->m_selectedFiles.size()); EXPECT_EQ(QUrl{"/test"}, filedlg->m_selectedFiles[0]); } TEST_F(TestQDeepinFileDialogHelper, selectedFiles) { ensureDialog(); filedlg->m_selectedFiles = { QUrl{"/test1"}, QUrl{"/test2"}, QUrl{"/test3"} };; auto result = helper->selectedFiles(); ASSERT_EQ(3, result.size()); EXPECT_EQ("/test1", result[0].toString()); EXPECT_EQ("/test2", result[1].toString()); EXPECT_EQ("/test3", result[2].toString()); } TEST_F(TestQDeepinFileDialogHelper, setFilter) { ensureDialog(); filedlg->m_filter = 0; EXPECT_EQ(0, filedlg->filter()); // TODO Add test for setFilter. Now not sure why options are empty when helper created. } TEST_F(TestQDeepinFileDialogHelper, selectNameFilter) { ensureDialog(); filedlg->m_nameFilters.clear(); helper->selectNameFilter("*.cpp"); EXPECT_EQ(1, filedlg->m_nameFilters.size()); EXPECT_EQ("*.cpp", filedlg->m_nameFilters[0]); } TEST_F(TestQDeepinFileDialogHelper, selectedNameFilters) { ensureDialog(); filedlg->m_nameFilters = QStringList{ "*.cpp", "*.h" }; auto result = helper->selectedNameFilter(); EXPECT_EQ("*.cpp;*.h", result); } qt5integration-5.7.12/tests/platformtheme/ut_qdeepintheme.cpp000066400000000000000000000050231476226661600245000ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include "qdeepintheme.h" #include "filedialogmanagerservice.h" #ifndef DIALOG_SERVICE #define DIALOG_SERVICE "org.deepin.fakefilemanager.filedialog" #endif class EnvGuard { public: EnvGuard(const char *name, const QByteArray &value) : m_name{name} { m_prev = qgetenv(name); qputenv(name, value); } ~EnvGuard() { qputenv(qPrintable(m_name), m_prev); } private: QString m_name; QByteArray m_prev; }; class TestQDeepinTheme : public testing::Test { public: static void SetUpTestSuite() { qputenv("_d_fileDialogServiceName", DIALOG_SERVICE); theme = new QDeepinTheme; managerService = new FileDialogManagerService(DIALOG_SERVICE, "/com/deepin/filemanager/filedialogmanager"); } static void TearDownTestSuite() { qunsetenv("_d_fileDialogServiceName"); delete theme; delete managerService; } static QDeepinTheme *theme; static FileDialogManagerService *managerService; }; QDeepinTheme *TestQDeepinTheme::theme = nullptr; FileDialogManagerService *TestQDeepinTheme::managerService = nullptr; TEST_F(TestQDeepinTheme, usePlatformNativeDialog) { managerService->m_useFileChooserDialog = true; { // Test if environment variable take effect EnvGuard guard{"_d_disableDBusFileDialog", "false"}; EXPECT_TRUE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); } { EnvGuard guard{"_d_disableDBusFileDialog", "true"}; EXPECT_FALSE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); } managerService->m_useFileChooserDialog = false; { EnvGuard guard{"_d_disableDBusFileDialog", "false"}; EXPECT_FALSE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); } { EnvGuard guard{"_d_disableDBusFileDialog", "true"}; EXPECT_FALSE(theme->usePlatformNativeDialog(QDeepinTheme::FileDialog)); } } TEST_F(TestQDeepinTheme, createPlatformDialogHelper) { managerService->m_useFileChooserDialog = true; auto helper = theme->createPlatformDialogHelper(QPlatformTheme::FileDialog); EXPECT_NE(nullptr, helper); } // Test if right icon engine is choosed TEST_F(TestQDeepinTheme, createIconEngine) { auto engine = theme->createIconEngine("icon_Layout"); ASSERT_NE(nullptr, engine); } TEST_F(TestQDeepinTheme, settings) { ASSERT_NE(nullptr, theme->settings()); } qt5integration-5.7.12/tests/styleplugins/000077500000000000000000000000001476226661600205075ustar00rootroot00000000000000qt5integration-5.7.12/tests/styleplugins/chameleon/000077500000000000000000000000001476226661600224425ustar00rootroot00000000000000qt5integration-5.7.12/tests/styleplugins/chameleon/icons/000077500000000000000000000000001476226661600235555ustar00rootroot00000000000000qt5integration-5.7.12/tests/styleplugins/chameleon/icons/actions/000077500000000000000000000000001476226661600252155ustar00rootroot00000000000000qt5integration-5.7.12/tests/styleplugins/chameleon/icons/actions/icon_Layout_16px.svg000066400000000000000000000024241476226661600311030ustar00rootroot00000000000000 icon_Layout/normal qt5integration-5.7.12/tests/styleplugins/chameleon/icons/theme-icons.qrc000066400000000000000000000001771476226661600265040ustar00rootroot00000000000000 actions/icon_Layout_16px.svg qt5integration-5.7.12/tests/styleplugins/chameleon/ut_chameleonstyle.cpp000066400000000000000000002424441476226661600267040ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2021 - 2022 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "chameleonstyle.h" DWIDGET_USE_NAMESPACE; using namespace chameleon; class TestForStyleHintParam : public ::testing::TestWithParam { protected: void SetUp() override; void TearDown() override; ChameleonStyle *style; QWidget *testWidget; }; void TestForStyleHintParam::SetUp() { style = new ChameleonStyle; testWidget = new QWidget; } void TestForStyleHintParam::TearDown() { delete style; delete testWidget; } INSTANTIATE_TEST_SUITE_P(ChameleonStyle, TestForStyleHintParam, ::testing::Range(int(ChameleonStyle::SH_EtchDisabledText), int(ChameleonStyle::SH_SpinBox_ButtonsInsideFrame))); TEST_P(TestForStyleHintParam, styleHint) { QStyleOption opt; opt.initFrom(testWidget); testWidget->setStyle(style); int param = GetParam(); // 测试在调用默认参数时是否会崩溃 style->styleHint(ChameleonStyle::StyleHint(param)); // 测试调用有参时是否会崩溃 style->styleHint(ChameleonStyle::StyleHint(param), &opt, testWidget); } class TestForPixelMetricParam : public ::testing::TestWithParam { protected: void SetUp() override; void TearDown() override; ChameleonStyle *style; QWidget *testWidget; }; void TestForPixelMetricParam::SetUp() { style = new ChameleonStyle; testWidget = new QWidget; } void TestForPixelMetricParam::TearDown() { delete style; delete testWidget; } INSTANTIATE_TEST_SUITE_P(ChameleonStyle, TestForPixelMetricParam, ::testing::Range(quint64(ChameleonStyle::PM_FocusBorderWidth), quint64(ChameleonStyle::PM_ButtonMinimizedSize))); TEST_P(TestForPixelMetricParam, pixelMetric) { QStyleOption opt; opt.initFrom(testWidget); testWidget->setStyle(style); quint64 param = GetParam(); // 测试在调用默认参数时是否有潜在崩溃风险 style->pixelMetric(QStyle::PixelMetric(param)); // 测试调用有参时是否有潜在崩溃风险 style->pixelMetric(QStyle::PixelMetric(param), &opt, testWidget); } class TestForQtDrawControlParam : public ::testing::TestWithParam { protected: void SetUp() override; void TearDown() override; ChameleonStyle *style; QWidget *testWidget; }; INSTANTIATE_TEST_SUITE_P(ChameleonStyle, TestForQtDrawControlParam, ::testing::Range(int(QStyle::CE_PushButton), int(QStyle::CE_ShapedFrame))); TEST_P(TestForQtDrawControlParam, drawControl) { QStyleOption opt; opt.initFrom(testWidget); // 测试Qt原生drawControl参数调用时是否有潜在崩溃风险 QPixmap surface(QSize(200, 200)); QPainter painter(&surface); int param = GetParam(); // DStyle中存在的元素值在DTKWIDGET中使用 这里不再测试调用 style->drawControl(QStyle::ControlElement(param), &opt, &painter); } void TestForQtDrawControlParam::SetUp() { style = new ChameleonStyle; testWidget = new QWidget; } void TestForQtDrawControlParam::TearDown() { delete style; delete testWidget; } struct DrawComplexControl_Param { explicit DrawComplexControl_Param(QStyle::ComplexControl cc, QStyleOptionComplex *opt) : cc(cc) , opt(opt) { } void releaseOption() { switch (cc) { case QStyle::CC_SpinBox: delete qstyleoption_cast(opt); break; case QStyle::CC_ToolButton: delete qstyleoption_cast(opt); break; case QStyle::CC_Slider: delete qstyleoption_cast(opt); break; case QStyle::CC_ComboBox: delete qstyleoption_cast(opt); break; default: delete opt; } opt = nullptr; } QStyle::ComplexControl cc; QStyleOptionComplex *opt; }; class TestForQtDrawComplexControlParam : public ::testing::TestWithParam { protected: void SetUp() override; void TearDown() override; ChameleonStyle *style; QWidget *testWidget; }; INSTANTIATE_TEST_SUITE_P(ChameleonStyle, TestForQtDrawComplexControlParam, ::testing::Values(DrawComplexControl_Param(QStyle::CC_SpinBox, new QStyleOptionSpinBox), DrawComplexControl_Param(QStyle::CC_ToolButton, new QStyleOptionToolButton), DrawComplexControl_Param(QStyle::CC_Slider, new QStyleOptionSlider), DrawComplexControl_Param(QStyle::CC_ComboBox, new QStyleOptionComboBox))); TEST_P(TestForQtDrawComplexControlParam, drawComplexControl) { DrawComplexControl_Param param = GetParam(); QPixmap surface(QSize(200, 200)); QPainter p(&surface); param.opt->initFrom(testWidget); // 测试调用默认参数时函数是否会崩溃 style->drawComplexControl(param.cc, param.opt, &p); param.releaseOption(); } void TestForQtDrawComplexControlParam::SetUp() { style = new ChameleonStyle; testWidget = new QWidget; } void TestForQtDrawComplexControlParam::TearDown() { delete style; delete testWidget; } class TestForQtStandardPixmapParam : public ::testing::TestWithParam { }; INSTANTIATE_TEST_SUITE_P(ChameleonStyle, TestForQtStandardPixmapParam, ::testing::Range(int(QStyle::SP_TitleBarMenuButton), int(QStyle::SP_LineEditClearButton))); TEST_P(TestForQtStandardPixmapParam, StandardPixmap) { ChameleonStyle *style = new ChameleonStyle; int param = GetParam(); qDebug() << "QStyle::standardIcon:" << param << " isNull: " << (style->standardIcon(QStyle::StandardPixmap(param)).isNull()); qDebug() << "QStyle::standardPixmap:" << param << " isNull: " << (style->standardPixmap(QStyle::StandardPixmap(param)).isNull()); if (param < int(QStyle::CC_MdiControls)) qDebug() << "DStyle::hitTestComplexControl" << param << style->hitTestComplexControl(QStyle::ComplexControl(param), nullptr, {0, 0}); delete style; } #define ASSERT_DrawFuncHasData(DrawFunc) \ painter->begin(&pixmap); \ DrawFunc(); \ painter->end(); \ ASSERT_FALSE(pixmap.isNull()); \ ASSERT_TRUE(testPixmapHasData()); \ pixmap.fill(Qt::green) #define ASSERT_DrawFuncNoData(DrawFunc) \ painter->begin(&pixmap); \ DrawFunc(); \ painter->end(); \ ASSERT_FALSE(pixmap.isNull()); \ ASSERT_FALSE(testPixmapHasData()); \ pixmap.fill(Qt::green) #define INIT_TESTWIDGET(ClassName) \ if (testWidget) \ delete testWidget; \ testWidget = new ClassName; \ testWidget->setGeometry(0, 0, 100, 100) class TestDrawUtilIntegration; class TestForDrawUtil : public ::testing::Test { friend TestDrawUtilIntegration; protected: void SetUp(); void TearDown(); bool testPixmapHasData(); ChameleonStyle *style; QWidget *testWidget = nullptr; QPixmap pixmap; QPainter *painter; }; class TestDrawUtilIntegration { public: TestDrawUtilIntegration(TestForDrawUtil *parent) : m_parent(parent) { } protected: inline QPainter *painter() const { return m_parent->painter; } inline QWidget *testWidget() const { return m_parent->testWidget; } inline ChameleonStyle *style() const { return m_parent->style; } TestForDrawUtil *m_parent; }; void TestForDrawUtil::SetUp() { style = new ChameleonStyle; pixmap = QPixmap(QSize(200, 200)); painter = new QPainter; // 以异色作为初始颜色防止默认随机颜色的干扰 pixmap.fill(Qt::green); } void TestForDrawUtil::TearDown() { delete style; delete painter; delete testWidget; } bool TestForDrawUtil::testPixmapHasData() { QImage image = pixmap.toImage(); image.reinterpretAsFormat(QImage::Format_RGB32); const QRgb *bits = reinterpret_cast(image.constBits()); const QRgb *end = bits + image.sizeInBytes() / sizeof(QRgb); return !std::all_of(bits, end, [](QRgb r) { return r == QColor(Qt::green).rgb(); }); } TEST_F(TestForDrawUtil, drawShadow) { auto drawShaowFunc = [&]() { style->drawShadow(painter, QRect(0, 0, 20, 20), Qt::black); }; ASSERT_DrawFuncHasData(drawShaowFunc); } TEST_F(TestForDrawUtil, drawBorder) { auto drawBorderFunc = [&]() { QStyleOption opt; opt.initFrom(testWidget); // 测试调用是否存在异常崩溃并且测试函数的绘制操作是否有效 style->drawBorder(painter, &opt, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawBorderFunc); } TEST_F(TestForDrawUtil, drawCalenderEllipse) { auto drawCalenderEllipseFunc = [&]() { // 测试绘制操作是否存在数据 style->drawCalenderEllipse(painter, QRect(0, 0, 50, 50), 5); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawCalenderEllipseFunc); } TEST_F(TestForDrawUtil, drawButtonBoxButton) { class TestButtonBoxButtonDrawFunc : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawButtonBoxButonBeginning() { DStyleOptionButtonBoxButton button; button.init(testWidget()); button.orientation = Qt::Horizontal; button.position = DStyleOptionButtonBoxButton::Beginning; style()->drawButtonBoxButton(&button, painter(), m_DefaultRect, m_radius); } void testDrawButtonBoxButtonMiddle() { DStyleOptionButtonBoxButton button; button.init(testWidget()); button.orientation = Qt::Horizontal; button.position = DStyleOptionButtonBoxButton::Middle; style()->drawButtonBoxButton(&button, painter(), m_DefaultRect, m_radius); } void testDrawButtonBoxButtonEnd() { DStyleOptionButtonBoxButton button; button.init(testWidget()); button.orientation = Qt::Horizontal; button.position = DStyleOptionButtonBoxButton::End; style()->drawButtonBoxButton(&button, painter(), m_DefaultRect, m_radius); } void testDrawButtonBoxButtonOnlyOne() { DStyleOptionButtonBoxButton button; button.init(testWidget()); button.orientation = Qt::Horizontal; button.position = DStyleOptionButtonBoxButton::OnlyOne; style()->drawButtonBoxButton(&button, painter(), m_DefaultRect, m_radius); } void testDrawButtonBoxButtonVerticalBeginning() { DStyleOptionButtonBoxButton button; button.init(testWidget()); button.orientation = Qt::Vertical; button.position = DStyleOptionButtonBoxButton::Beginning; style()->drawButtonBoxButton(&button, painter(), m_DefaultRect, m_radius); } private: QRect m_DefaultRect = {0, 0, 50, 50}; int m_radius = 5; }; INIT_TESTWIDGET(QWidget); TestButtonBoxButtonDrawFunc drawFuncInstance(this); // 多场景触发绘制 测试数据是否存在 并 异于初始数据 ASSERT_DrawFuncHasData(drawFuncInstance.testDrawButtonBoxButonBeginning); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawButtonBoxButtonMiddle); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawButtonBoxButtonEnd); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawButtonBoxButtonOnlyOne); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawButtonBoxButtonVerticalBeginning); } TEST_F(TestForDrawUtil, drawButtonDownArrow) { auto drawButtonDownArrowFunc = [&]() { QStyleOptionButton opt; opt.initFrom(testWidget); style->drawButtonDownArrow(&opt, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawButtonDownArrowFunc); } TEST_F(TestForDrawUtil, drawSpinBox) { auto drawSpinBoxPlusMinusFunc = [&]() { QStyleOptionSpinBox opt; opt.initFrom(testWidget); opt.buttonSymbols = QAbstractSpinBox::PlusMinus; style->drawSpinBox(&opt, painter, testWidget); }; auto drawSpinBoxUpDownArrows = [&]() { QStyleOptionSpinBox opt; opt.initFrom(testWidget); opt.buttonSymbols = QAbstractSpinBox::UpDownArrows; style->drawSpinBox(&opt, painter, testWidget); }; INIT_TESTWIDGET(QWidget); testWidget->setProperty("_d_dtk_spinBox", true); ASSERT_DrawFuncHasData(drawSpinBoxPlusMinusFunc); ASSERT_DrawFuncHasData(drawSpinBoxUpDownArrows); } TEST_F(TestForDrawUtil, drawMenuBarItem) { auto drawMenuBarItemMarginAndExclusive = [&]() { QStyleOptionMenuItem opt; opt.initFrom(testWidget); opt.menuItemType = QStyleOptionMenuItem::Margin; opt.checkType = QStyleOptionMenuItem::Exclusive; opt.text = "测试1"; opt.icon = style->standardIcon(QStyle::SP_DirIcon); opt.menuRect = QRect(20, 20, 60, 40); opt.maxIconWidth = 20; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) opt.reservedShortcutWidth = 2; #else opt.tabWidth = 2; #endif QRect ret; style->drawMenuBarItem(&opt, ret, painter, testWidget); }; auto drawMenuBarItemNormalAndExclusive = [&]() { QStyleOptionMenuItem opt; opt.initFrom(testWidget); opt.menuItemType = QStyleOptionMenuItem::Normal; opt.checkType = QStyleOptionMenuItem::Exclusive; opt.text = "测试2"; opt.icon = style->standardIcon(QStyle::SP_DirIcon); opt.menuRect = QRect(20, 20, 60, 40); opt.maxIconWidth = 20; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) opt.reservedShortcutWidth = 2; #else opt.tabWidth = 2; #endif opt.state |= QStyle::State_MouseOver; QRect ret; style->drawMenuBarItem(&opt, ret, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawMenuBarItemMarginAndExclusive); ASSERT_DrawFuncHasData(drawMenuBarItemNormalAndExclusive); } TEST_F(TestForDrawUtil, drawMenuItemBackground) { class TestMenuItemBackgroundDrawFunc : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNormalBackground() { QStyleOption opt; opt.initFrom(testWidget()); opt.state |= QStyle::State_Selected; style()->drawMenuItemBackground(&opt, painter(), QStyleOptionMenuItem::Normal); } void testDrawDefaultItemBackground() { QStyleOption opt; opt.initFrom(testWidget()); opt.state |= QStyle::State_MouseOver; style()->drawMenuItemBackground(&opt, painter(), QStyleOptionMenuItem::DefaultItem); } void testDrawSunMenuBackground() { QStyleOption opt; opt.initFrom(testWidget()); opt.state |= QStyle::State_Sunken; style()->drawMenuItemBackground(&opt, painter(), QStyleOptionMenuItem::SubMenu); } }; INIT_TESTWIDGET(QWidget); TestMenuItemBackgroundDrawFunc drawFuncInstance(this); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawNormalBackground); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawDefaultItemBackground); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawSunMenuBackground); } TEST_F(TestForDrawUtil, drawMenuItem) { class TestMenuItemDrawFunc : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNorMenuItem() { QStyleOptionMenuItem opt; opt.initFrom(testWidget()); opt.menuItemType = QStyleOptionMenuItem::Normal; style()->drawMenuItem(&opt, painter(), testWidget()); } void testDrawSeparatorMenuItem() { QStyleOptionMenuItem opt; opt.initFrom(testWidget()); opt.menuItemType = QStyleOptionMenuItem::Separator; style()->drawMenuItem(&opt, painter(), testWidget()); } void testDrawSubMenuItem() { QStyleOptionMenuItem opt2; opt2.initFrom(testWidget()); opt2.menuItemType = QStyleOptionMenuItem::SubMenu; style()->drawMenuItem(&opt2, painter(), testWidget()); } }; INIT_TESTWIDGET(QWidget); TestMenuItemDrawFunc drawFuncInstance(this); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawNorMenuItem); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawSeparatorMenuItem); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawSubMenuItem); } TEST_F(TestForDrawUtil, drawTabBar) { class TestTabBarDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawRoundedEstOnlyOneTab() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::RoundedEast; tab.position = QStyleOptionTab::OnlyOneTab; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 1"; style()->drawTabBar(painter(), &tab, testWidget()); } void testDrawTriangularNorthMiddleTab() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= QStyle::State_Enabled; tab.shape = QTabBar::TriangularNorth; tab.position = QStyleOptionTab::Middle; tab.selectedPosition = QStyleOptionTab::NextIsSelected; tab.cornerWidgets = QStyleOptionTab::RightCornerWidget; tab.text = "test 2"; tab.icon = QIcon::fromTheme("icon_Layout"); tab.iconSize = QSize(16, 16); style()->drawTabBar(painter(), &tab, testWidget()); } void testDrawRoundedWestBeginningTab() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= QStyle::State_Enabled; tab.shape = QTabBar::RoundedWest; tab.position = QStyleOptionTab::Beginning; tab.selectedPosition = QStyleOptionTab::PreviousIsSelected; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 3"; tab.icon = style()->standardIcon(QStyle::SP_DirIcon); tab.iconSize = QSize(16, 16); style()->drawTabBar(painter(), &tab, testWidget()); } }; INIT_TESTWIDGET(QTabBar); TestTabBarDrawUtil tabbarDrawInstance(this); ASSERT_DrawFuncHasData(tabbarDrawInstance.testDrawRoundedEstOnlyOneTab); ASSERT_DrawFuncHasData(tabbarDrawInstance.testDrawTriangularNorthMiddleTab); ASSERT_DrawFuncHasData(tabbarDrawInstance.testDrawRoundedWestBeginningTab); } TEST_F(TestForDrawUtil, drawTabBarLabel) { class TestTabBarLabelDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawRoundedEastOnlyOneTabLabel() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::RoundedEast; tab.position = QStyleOptionTab::OnlyOneTab; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 1"; style()->drawTabBarLabel(painter(), &tab, testWidget()); } void testDrawTriangularNorthTabLabel() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= QStyle::State_Enabled; tab.shape = QTabBar::TriangularNorth; tab.text = "test 2"; style()->drawTabBarLabel(painter(), &tab, testWidget()); } void testDrawTriangularNorthOnlyOneTabLabel() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::TriangularNorth; tab.position = QStyleOptionTab::OnlyOneTab; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 3"; style()->drawTabBarLabel(painter(), &tab, testWidget()); } void testDrawTriangularWestOnlyOneTabLabel() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::TriangularWest; tab.position = QStyleOptionTab::OnlyOneTab; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 4"; style()->drawTabBarLabel(painter(), &tab, testWidget()); } }; INIT_TESTWIDGET(DTabBar); TestTabBarLabelDrawUtil drawFuncInstance(this); testWidget->setProperty("_d_dtk_tabbartab_type", true); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawRoundedEastOnlyOneTabLabel); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawTriangularNorthTabLabel); testWidget->setProperty("_d_dtk_tabbar_alignment", 0); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawTriangularNorthOnlyOneTabLabel); testWidget->setProperty("_d_dtk_tabbar_alignment", 1); ASSERT_DrawFuncHasData(drawFuncInstance.testDrawTriangularWestOnlyOneTabLabel); } TEST_F(TestForDrawUtil, drawTabBarCloseButton) { INIT_TESTWIDGET(QTabBar); QTabBar *tabbar = qobject_cast(testWidget); ASSERT_TRUE(tabbar); tabbar->addTab("测试1"); tabbar->addTab("测试2"); tabbar->addTab("测试3"); auto drawEnableAndSelectedCloseButton = [&]() { QWidget *btn1 = new QWidget(tabbar); btn1->resize(20, 20); tabbar->setTabButton(0, QTabBar::LeftSide, btn1); QStyleOption opt; opt.initFrom (btn1); opt.state = QStyle::State_Enabled | QStyle::State_Selected; style->drawTabBarCloseButton(painter, &opt, btn1); }; auto drawNormalCloseButton = [&]() { QWidget *btn2 = new QWidget(tabbar); btn2->resize(20, 20); tabbar->setTabButton(1, QTabBar::RightSide, btn2); QStyleOption opt; opt.initFrom(btn2); style->drawTabBarCloseButton(painter, &opt, btn2); }; ASSERT_DrawFuncHasData(drawEnableAndSelectedCloseButton); ASSERT_DrawFuncHasData(drawNormalCloseButton); } TEST_F(TestForDrawUtil, drawTabBarScrollButton) { class TestTabBarScrollButtonDrawUtil : public TestDrawUtilIntegration { public: TestTabBarScrollButtonDrawUtil(TestForDrawUtil *parent) : TestDrawUtilIntegration(parent) { tabbar = qobject_cast(testWidget()); toolButton = new QToolButton(tabbar); } void testDownArrowDrawUtil() { toolButton->setArrowType(Qt::DownArrow); QStyleOptionToolButton opt; opt.initFrom(toolButton); opt.text = "test 1"; opt.arrowType = Qt::DownArrow; style()->drawTabBarScrollButton(painter(), &opt, toolButton); } void testUpArrowDrawUtil() { toolButton->setArrowType(Qt::UpArrow); QStyleOptionToolButton opt; opt.initFrom(toolButton); opt.text = "test 2"; opt.arrowType = Qt::UpArrow; ASSERT_TRUE(tabbar); tabbar->setShape(QTabBar::TriangularEast); style()->drawTabBarScrollButton(painter(), &opt, toolButton); } void testLeftArrowDrawUtil() { toolButton->setArrowType(Qt::LeftArrow); QStyleOptionToolButton opt; opt.initFrom(toolButton); opt.text = "test 3"; opt.arrowType = Qt::LeftArrow; ASSERT_TRUE(tabbar); tabbar->setShape(QTabBar::TriangularEast); style()->drawTabBarScrollButton(painter(), &opt, toolButton); } void testRightArrowDrawUtil() { toolButton->setArrowType(Qt::RightArrow); QStyleOptionToolButton opt; opt.initFrom(toolButton); opt.text = "test 4"; opt.arrowType = Qt::RightArrow; tabbar->setShape(QTabBar::TriangularEast); style()->drawTabBarScrollButton(painter(), &opt, toolButton); } private: QToolButton *toolButton; QTabBar *tabbar; }; INIT_TESTWIDGET(QTabBar); TestTabBarScrollButtonDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDownArrowDrawUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testUpArrowDrawUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testLeftArrowDrawUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testRightArrowDrawUtil); } TEST_F(TestForDrawUtil, drawComboBox) { class TestComboBoxDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNormalComboBox() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.editable = true; opt.popupRect = QRect(0, 0, 30, 30); opt.frame = true; opt.currentText = "test 1"; opt.currentIcon = style()->standardIcon(QStyle::SP_DirIcon); opt.iconSize = QSize(16, 16); opt.state = QStyle::State_Enabled | QStyle::State_MouseOver; style()->drawComboBox(painter(), &opt, testWidget()); } void testDrawArrowFrameEditAndPopupComboBox() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.editable = false; opt.frame = false; opt.currentText = "test 2"; opt.currentIcon = style()->standardIcon(QStyle::SP_DirIcon); opt.iconSize = QSize(16, 16); opt.subControls |= QStyle::SC_ComboBoxArrow | QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField | QStyle::SC_ComboBoxListBoxPopup; style()->drawComboBox(painter(), &opt, testWidget()); } void testDrawArrowFrameComboBox() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.editable = false; opt.frame = false; opt.currentText = "test 3"; opt.currentIcon = style()->standardIcon(QStyle::SP_DirIcon); opt.iconSize = QSize(16, 16); opt.subControls |= QStyle::SC_ComboBoxArrow | QStyle::SC_ComboBoxFrame; style()->drawComboBox(painter(), &opt, testWidget()); } void testDrawEditPopupFocusComboBox() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.currentText = "test 4"; opt.currentIcon = style()->standardIcon(QStyle::SP_DirIcon); opt.iconSize = QSize(16, 16); opt.state = QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_HasFocus; opt.subControls |= QStyle::SC_ComboBoxEditField | QStyle::SC_ComboBoxListBoxPopup; style()->drawComboBox(painter(), &opt, testWidget()); } }; INIT_TESTWIDGET(QWidget); TestComboBoxDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNormalComboBox); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawArrowFrameEditAndPopupComboBox); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawArrowFrameComboBox); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawEditPopupFocusComboBox); } TEST_F(TestForDrawUtil, drawComboBoxLabel) { class TestComboBoxLabelDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawEnableAndHoverComboBoxLabel() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.editable = true; opt.popupRect = QRect(0, 0, 30, 30); opt.frame = true; opt.currentText = "test 1"; opt.currentIcon = QIcon::fromTheme("icon_Layout"); opt.iconSize = QSize(16, 16); opt.state = QStyle::State_Enabled | QStyle::State_MouseOver; style()->drawComboBoxLabel(painter(), &opt, testWidget()); } void testDrawArrowFrameEditComboBoxLabel() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.editable = false; opt.popupRect = QRect(0, 0, 30, 30); opt.frame = false; opt.currentText = "test 2"; opt.currentIcon = QIcon::fromTheme("icon_Layout"); opt.iconSize = QSize(16, 16); opt.subControls |= QStyle::SC_ComboBoxArrow | QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField | QStyle::SC_ComboBoxListBoxPopup; style()->drawComboBoxLabel(painter(), &opt, testWidget()); } void testDrawArrowFrameSunkenComboBoxLabel() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.rect = QRect(20, 20, 100, 50); opt.currentText = "test 3"; opt.currentIcon = {}; opt.iconSize = {}; opt.subControls |= QStyle::SC_ComboBoxArrow | QStyle::SC_ComboBoxFrame; opt.state = QStyle::State_Enabled | QStyle::State_Sunken; style()->drawComboBoxLabel(painter(), &opt, testWidget()); } void testDrawFocusAndSelectComboBoxLabel() { QStyleOptionComboBox opt; opt.initFrom(testWidget()); opt.currentText = "测试3"; opt.currentIcon = QIcon::fromTheme("icon_Layout"); opt.iconSize = QSize(16, 16); opt.state = QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_HasFocus; opt.subControls |= QStyle::SC_ComboBoxEditField | QStyle::SC_ComboBoxListBoxPopup; style()->drawComboBoxLabel(painter(), &opt, testWidget()); } }; INIT_TESTWIDGET(QWidget); TestComboBoxLabelDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawEnableAndHoverComboBoxLabel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawArrowFrameEditComboBoxLabel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawArrowFrameSunkenComboBoxLabel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawFocusAndSelectComboBoxLabel); } TEST_F(TestForDrawUtil, drawSliderHandle) { class TestSliderHandleDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNoTicksSliderHandle() { QStyleOptionSlider slider; slider.initFrom(testWidget()); slider.tickPosition = QSlider::NoTicks; style()->drawSliderHandle(&slider, defaultRect, painter(), testWidget()); } void testDrawHorizontalLeftTicksSliderHandle() { QStyleOptionSlider slider; slider.initFrom(testWidget()); slider.orientation = Qt::Horizontal; slider.tickPosition = QSlider::TicksLeft; style()->drawSliderHandle(&slider, defaultRect, painter(), testWidget()); } void testDrawHorizontalRightTicksSliderHandle() { QStyleOptionSlider slider; slider.initFrom(testWidget()); slider.orientation = Qt::Horizontal; slider.tickPosition = QSlider::TicksRight; style()->drawSliderHandle(&slider, defaultRect, painter(), testWidget()); } void testDrawVerticalLeftTicksSliderHandle() { QStyleOptionSlider slider; slider.initFrom(testWidget()); slider.orientation = Qt::Vertical; slider.tickPosition = QSlider::TicksLeft; style()->drawSliderHandle(&slider, defaultRect, painter(), testWidget()); } void testDrawVerticalRightTicksSliderHandle() { QStyleOptionSlider slider; slider.initFrom(testWidget()); slider.orientation = Qt::Vertical; slider.tickPosition = QSlider::TicksRight; style()->drawSliderHandle(&slider, defaultRect, painter(), testWidget()); } private: QRectF defaultRect = QRectF(0, 0, 50, 50); }; INIT_TESTWIDGET(QWidget); TestSliderHandleDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNoTicksSliderHandle); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalLeftTicksSliderHandle); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalRightTicksSliderHandle); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawVerticalLeftTicksSliderHandle); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawVerticalRightTicksSliderHandle); } TEST_F(TestForDrawUtil, drawSliderHandleFocus) { class TestSliderHandleFocusDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawHorizontalNoticksSliderHandleFocus() { QStyleOptionSlider opt; opt.initFrom(testWidget()); opt.orientation = Qt::Horizontal; opt.tickPosition = QSlider::NoTicks; opt.minimum = 0; opt.maximum = 100; style()->drawSliderHandleFocus(&opt, defaultRect, painter(), nullptr); } void testDrawHorizontalLeftTicksSliderHandleFocus() { QStyleOptionSlider opt; opt.initFrom(testWidget()); opt.orientation = Qt::Horizontal; opt.tickPosition = QSlider::TicksLeft; opt.minimum = 0; opt.maximum = 100; style()->drawSliderHandleFocus(&opt, defaultRect, painter(), nullptr); } void testDrawHorizontalRightTicksSliderHandleFocus() { QStyleOptionSlider opt; opt.initFrom(testWidget()); opt.orientation = Qt::Horizontal; opt.tickPosition = QSlider::TicksRight; opt.minimum = 0; opt.maximum = 100; style()->drawSliderHandleFocus(&opt, defaultRect, painter(), nullptr); } void testDrawVerticalLeftTicksSliderHandleFocus() { QStyleOptionSlider opt; opt.initFrom(testWidget()); opt.orientation = Qt::Vertical; opt.tickPosition = QSlider::TicksLeft; opt.minimum = 0; opt.maximum = 100; style()->drawSliderHandleFocus(&opt, defaultRect, painter(), nullptr); } void testDrawVerticalRightTicksSliderHandleFocus() { QStyleOptionSlider opt; opt.initFrom(testWidget()); opt.orientation = Qt::Vertical; opt.tickPosition = QSlider::TicksRight; opt.minimum = 0; opt.maximum = 100; style()->drawSliderHandleFocus(&opt, defaultRect, painter(), nullptr); } private: QRectF defaultRect = QRect(0, 0, 20, 20); }; INIT_TESTWIDGET(QWidget); TestSliderHandleFocusDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalNoticksSliderHandleFocus); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalLeftTicksSliderHandleFocus); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalRightTicksSliderHandleFocus); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawVerticalLeftTicksSliderHandleFocus); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawVerticalRightTicksSliderHandleFocus); } TEST_F(TestForDrawUtil, drawIcon) { auto drawIconUtil = [&]() { QStyleOption opt; opt.state |= QStyle::State_Enabled; opt.state |= QStyle::State_Selected; QRect rect(0, 0, 10, 10); style->drawIcon(&opt, painter, rect, QIcon::fromTheme("icon_Layout"), true); }; ASSERT_DrawFuncHasData(drawIconUtil); } TEST_F(TestForDrawUtil, tabLayout) { INIT_TESTWIDGET(QWidget); QStyleOptionTab tab; tab.initFrom(testWidget); tab.iconSize = QSize(32, 32); tab.shape = QTabBar::RoundedEast; tab.icon = QIcon::fromTheme("icon_Layout"); QRect textRect, iconRect; style->tabLayout(&tab, testWidget, &textRect, &iconRect); ASSERT_TRUE(textRect.isValid()); ASSERT_TRUE(iconRect.isValid()); } TEST_F(TestForDrawUtil, drawTableViewItem) { auto drawNormalTableViewItem = [&]() { QStyleOptionViewItem opt; opt.initFrom(testWidget); opt.backgroundBrush = Qt::darkCyan; style->drawTableViewItem(QStyle::PE_PanelItemViewItem, &opt, painter, testWidget); }; auto drawEnableItemRadiusTableView = [&]() { QStyleOptionViewItem opt; opt.initFrom(testWidget); opt.backgroundBrush = Qt::darkCyan; opt.state |= QStyle::State_Selected; opt.showDecorationSelected = true; testWidget->setProperty("_d_dtk_enable_tableviewitem_radius", true); style->drawTableViewItem(QStyle::PE_PanelItemViewItem, &opt, painter, testWidget); }; INIT_TESTWIDGET(QTableView); ASSERT_DrawFuncHasData(drawNormalTableViewItem); ASSERT_DrawFuncHasData(drawEnableItemRadiusTableView); } TEST_F(TestForDrawUtil, drawMenuItemRedPoint) { INIT_TESTWIDGET(QMenu); QMenu *menu = qobject_cast(testWidget); ASSERT_TRUE(menu); auto drawNormalMenuItemRedPoint = [&]() { QAction *action = new QAction(menu); action->setText("test 1"); action->setProperty("_d_menu_item_redpoint", true); menu->addAction(action); QStyleOptionMenuItem opt; opt.initFrom(menu); opt.menuItemType = QStyleOptionMenuItem::Normal; opt.rect = menu->actionGeometry(action); style->drawMenuItemRedPoint(&opt, painter, menu); }; auto drawSubMenuRedPoint = [&]() { QAction *actionMenu = new QAction(menu); QMenu *submenu = new QMenu("test menu"); submenu->setProperty("_d_menu_item_redpoint", true); actionMenu->setMenu(submenu); menu->addAction(actionMenu); QStyleOptionMenuItem opt; opt.initFrom(menu); opt.menuItemType = QStyleOptionMenuItem::Normal; opt.menuItemType = QStyleOptionMenuItem::SubMenu; opt.rect = menu->actionGeometry(actionMenu); style->drawMenuItemRedPoint(&opt, painter, menu); }; ASSERT_DrawFuncHasData(drawNormalMenuItemRedPoint); ASSERT_DrawFuncHasData(drawSubMenuRedPoint); } TEST_F(TestForDrawUtil, drawPrimitivePanelItemViewItem) { class TestPanelItemPrimitiveDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawSelectedViewItemPanel() { QStyleOption opt; opt.initFrom(testWidget()); opt.state |= QStyle::State_Selected; style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter(), testWidget()->findChild("qt_calendar_calendarview")); } void testDrawHoverAndSelectedViewItemBeginningPanel() { QStyleOptionViewItem tableviewOption; tableviewOption.initFrom(testWidget()); tableviewOption.showDecorationSelected = true; tableviewOption.state |= (QStyle::State_Selected | QStyle::State_MouseOver); tableviewOption.viewItemPosition = QStyleOptionViewItem::Beginning; style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &tableviewOption, painter(), testWidget()); } void testDrawEndItemViewPanel() { QStyleOptionViewItem tableviewOption; tableviewOption.initFrom(testWidget()); tableviewOption.showDecorationSelected = true; tableviewOption.state |= (QStyle::State_Selected | QStyle::State_MouseOver); tableviewOption.viewItemPosition = QStyleOptionViewItem::End; style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &tableviewOption, painter(), testWidget()); } void testDrawNoDecorationViemItemPanel() { QStyleOptionViewItem tableviewOption; tableviewOption.initFrom(testWidget()); tableviewOption.state |= (QStyle::State_Selected | QStyle::State_MouseOver); tableviewOption.viewItemPosition = QStyleOptionViewItem::End; tableviewOption.showDecorationSelected = false; tableviewOption.backgroundBrush = Qt::darkRed; style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &tableviewOption, painter(), testWidget()); } void testDrawSelectedDecorationListViewItemPanel() { QStyleOptionViewItem listViewOption; listViewOption.initFrom(testWidget()); listViewOption.state |= QStyle::State_Selected; listViewOption.showDecorationSelected = true; style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &listViewOption, painter(), testWidget()); } }; INIT_TESTWIDGET(QCalendarWidget); TestPanelItemPrimitiveDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawSelectedViewItemPanel); INIT_TESTWIDGET(QTreeView); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHoverAndSelectedViewItemBeginningPanel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawEndItemViewPanel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNoDecorationViemItemPanel); INIT_TESTWIDGET(QListView); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawSelectedDecorationListViewItemPanel); } TEST_F(TestForDrawUtil, drawPrimitivePanelLineEdit) { class TestPanelLineEditDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawFlatFocusLineEdit() { QStyleOptionFrame frameOption; frameOption.initFrom(testWidget()); frameOption.features |= QStyleOptionFrame::Flat; frameOption.state |= QStyle::State_HasFocus; style()->drawPrimitive(QStyle::PE_PanelLineEdit, &frameOption, painter(), testWidget()); } void testDrawRoundedLineEdit() { QStyleOptionFrame frameOption; frameOption.initFrom(testWidget()); frameOption.state |= QStyle::State_HasFocus; frameOption.features |= QStyleOptionFrame::Rounded; frameOption.lineWidth = 5; style()->drawPrimitive(QStyle::PE_PanelLineEdit, &frameOption, painter(), testWidget()); } void testDrawHasOpacityLineEdit() { QStyleOption option; option.initFrom(testWidget()); testWidget()->setProperty("_d_dtk_lineedit_opacity", true); style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, painter(), testWidget()); } void testDrawHasParentAndOpacityLineEdit() { DSpinBox spinbox; spinbox.resize(200, 200); spinbox.setProperty("_d_dtk_lineedit_opacity", true); testWidget()->setParent(&spinbox); QStyleOption option; option.initFrom(testWidget()); style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, painter(), testWidget()); testWidget()->setParent(nullptr); } }; INIT_TESTWIDGET(QLineEdit); TestPanelLineEditDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawFlatFocusLineEdit); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawRoundedLineEdit); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHasOpacityLineEdit); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHasParentAndOpacityLineEdit); } TEST_F(TestForDrawUtil, drawPrimitiveIndicatorRadioButton) { auto drawNormalRadioButton = [&]() { QStyleOption radioButtonOption; radioButtonOption.initFrom(testWidget); radioButtonOption.state |= QStyle::State_On; style->drawPrimitive(QStyle::PE_IndicatorRadioButton, &radioButtonOption, painter, testWidget); }; auto drawOffStateRadioButton = [&]() { QStyleOption radioButtonOption; radioButtonOption.initFrom(testWidget); radioButtonOption.state |= QStyle::State_Off; style->drawPrimitive(QStyle::PE_IndicatorRadioButton, &radioButtonOption, painter, testWidget); }; INIT_TESTWIDGET(QRadioButton); ASSERT_DrawFuncHasData(drawNormalRadioButton); ASSERT_DrawFuncHasData(drawOffStateRadioButton); } TEST_F(TestForDrawUtil, drawPrimitiveIndicatorCheckBox) { class TestIndicatorCheckBoxDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNoChangeStateIndicatorCheckBox() { QStyleOption checkBoxOption; checkBoxOption.initFrom(testWidget()); checkBoxOption.state |= QStyle::State_NoChange; style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxOption, painter(), testWidget()); } void testDrawStateOnIndicatorCheckBox() { QStyleOption checkBoxOption; checkBoxOption.initFrom(testWidget()); checkBoxOption.state |= QStyle::State_On; style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxOption, painter(), testWidget()); } void testDrawNormalIndicatorCheckBox() { QStyleOption checkBoxOption; checkBoxOption.initFrom(testWidget()); style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &checkBoxOption, painter(), testWidget()); } }; INIT_TESTWIDGET(QCheckBox); TestIndicatorCheckBoxDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNoChangeStateIndicatorCheckBox); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawStateOnIndicatorCheckBox); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNormalIndicatorCheckBox); } TEST_F(TestForDrawUtil, drawPrimitiveIndicatorTabClose) { auto drawIndicatorTabClose = [&]() { QStyleOption opt; opt.initFrom(testWidget); style->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawIndicatorTabClose); } TEST_F(TestForDrawUtil, drawPrimitiveFrameTabWidget) { auto drawFrameTabWidget = [&]() { QStyleOption opt; opt.initFrom(testWidget); style->drawPrimitive(QStyle::PE_FrameTabWidget, &opt, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawFrameTabWidget); } TEST_F(TestForDrawUtil, drawPrimitiveIndicatorItemViewItemCheck) { class TestIndicatorItemViewItemCheckDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNoChangeStateItemViewItemCheck() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_NoChange; style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter(), testWidget()); } void testDrawOnStateItemViewItemCheck() { QStyleOption option; option.initFrom(testWidget()); option.state |= (QStyle::State_On | QStyle::State_Enabled); style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter(), testWidget()); } void testDrawOffStateAndNoUncheckedItemViewItemCheck() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_Off; option.state &= ~QStyle::State_On; style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter(), testWidget()); } void testDrawOffStateAndHasUncheckedItemViewItemCheck() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_Off; option.state &= ~QStyle::State_On; testWidget()->setProperty("_d_dtk_UncheckedItemIndicator", true); style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QWidget); TestIndicatorItemViewItemCheckDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNoChangeStateItemViewItemCheck); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawOnStateItemViewItemCheck); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawOffStateAndNoUncheckedItemViewItemCheck); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawOffStateAndHasUncheckedItemViewItemCheck); } TEST_F(TestForDrawUtil, drawPrimitivePanelMenu) { auto drawPanelMenuUtilWithValidWindowColor = [&]() { QStyleOption option; option.initFrom(testWidget); ASSERT_TRUE(option.palette.window().color().isValid()); style->drawPrimitive(QStyle::PE_PanelMenu, &option, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawPanelMenuUtilWithValidWindowColor); } TEST_F(TestForDrawUtil, drawPrimitiveFrame) { auto drawFrameUtil = [&]() { QStyleOptionFrame option; option.initFrom(testWidget); option.features |= QStyleOptionFrame::Rounded; option.lineWidth = 1; style->drawPrimitive(QStyle::PE_Frame, &option, painter, testWidget); }; auto drawFrameUtilWithNoLine = [&]() { QStyleOptionFrame option; option.initFrom(testWidget); option.features |= QStyleOptionFrame::Rounded; option.lineWidth = 0; painter->setBackground(option.palette.window()); style->drawPrimitive(QStyle::PE_Frame, &option, painter, testWidget); }; INIT_TESTWIDGET(QFrame); ASSERT_DrawFuncHasData(drawFrameUtil); ASSERT_DrawFuncHasData(drawFrameUtilWithNoLine); } TEST_F(TestForDrawUtil, drawPrimitivePanelTipLabel) { // PE_PanelTipLabel return directly. auto drawPanelTipLabel = [&]() { style->drawPrimitive(QStyle::PE_PanelTipLabel, nullptr, nullptr, nullptr); }; ASSERT_DrawFuncNoData(drawPanelTipLabel); } TEST_F(TestForDrawUtil, drawPrimitiveFrameGroupBox) { auto drawFrameGroupBoxFlatFeature = [&]() { QStyleOptionFrame option; option.initFrom(testWidget); option.features |= QStyleOptionFrame::Flat; // Flat feature return directly. style->drawPrimitive(QStyle::PE_FrameGroupBox, &option, painter, testWidget); }; auto drawFrameNormalFrameGroupBox = [&]() { QStyleOption option; option.initFrom(testWidget); style->drawPrimitive(QStyle::PE_FrameGroupBox, &option, painter, testWidget); }; INIT_TESTWIDGET(QFrame); ASSERT_DrawFuncNoData(drawFrameGroupBoxFlatFeature); INIT_TESTWIDGET(QGroupBox); ASSERT_DrawFuncHasData(drawFrameNormalFrameGroupBox); } TEST_F(TestForDrawUtil, drawPrimitiveIndicatorArrowRightAndLeft) { auto drawIndicatorArrowRightUtil = [&]() { QStyleOption option; option.initFrom(testWidget); style->drawPrimitive(QStyle::PE_IndicatorArrowRight, &option, painter, testWidget); }; auto drawIndicatorArrowLeftUtil = [&]() { QStyleOption option; option.initFrom(testWidget); style->drawPrimitive(QStyle::PE_IndicatorArrowLeft, &option, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawIndicatorArrowRightUtil); ASSERT_DrawFuncHasData(drawIndicatorArrowLeftUtil); } TEST_F(TestForDrawUtil, drawPrimitiveFrameTabBarBase) { auto drawFrameTabBarBaseUtil = [&]() { // Only return directly. style->drawPrimitive(QStyle::PE_FrameTabBarBase, nullptr, nullptr, nullptr); }; ASSERT_DrawFuncNoData(drawFrameTabBarBaseUtil); } TEST_F(TestForDrawUtil, drawPrimitiveIndicatorBranch) { class TestIndicatorBranchDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawChildrenSelectedStateUtil() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_Children | QStyle::State_Selected; option.state &= ~QStyle::State_Open; style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter(), testWidget()); } void testDrawChildrenStateUtil() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_Children; option.state &= ~QStyle::State_Open; style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter(), testWidget()); } void testDrawChildrenOpenSelectedStateUtil() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_Children | QStyle::State_Open | QStyle::State_Selected; style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter(), testWidget()); } void testDrawChildrenOpenStateUtil() { QStyleOption option; option.initFrom(testWidget()); option.state |= QStyle::State_Children | QStyle::State_Open; style()->drawPrimitive(QStyle::PE_IndicatorBranch, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QTreeView); TestIndicatorBranchDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawChildrenSelectedStateUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawChildrenStateUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawChildrenOpenSelectedStateUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawChildrenOpenStateUtil); } TEST_F(TestForDrawUtil, drawPrimitivePanelItemViewRow) { class TestPanelItemViewRowDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawPanelItemViewInQCalendarWidget() { QWidget *tableView = testWidget()->findChild("qt_calendar_calendarview"); ASSERT_TRUE(tableView); QStyleOption option; option.initFrom(tableView); style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter(), tableView); } void testDrawPanelItemViewActiveQTreeView() { QTreeView *treeView = qobject_cast(testWidget()); ASSERT_TRUE(treeView); QStyleOptionViewItem option; option.initFrom(treeView); option.state |= QStyle::State_Enabled | QStyle::State_Active; style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter(), treeView); } void testDrawPanelItemViewInactiveEndQTreeView() { QTreeView *treeView = qobject_cast(testWidget()); ASSERT_TRUE(treeView); QStyleOptionViewItem option; option.initFrom(treeView); option.state |= (QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_MouseOver); option.state &= ~QStyle::State_Active; option.viewItemPosition = QStyleOptionViewItem::End; style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter(), treeView); } void testDrawPanelItemViewInactiveValidQTreeView() { QTreeView *treeView = qobject_cast(testWidget()); ASSERT_TRUE(treeView); QStyleOptionViewItem option; option.initFrom(treeView); option.state |= (QStyle::State_Enabled | QStyle::State_Selected | QStyle::State_MouseOver); option.state &= ~QStyle::State_Active; option.viewItemPosition = QStyleOptionViewItem::Middle; style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter(), treeView); } void testDrawPanelItemViewInactiveAlternateQTreeView() { QTreeView *treeView = qobject_cast(testWidget()); ASSERT_TRUE(treeView); QStyleOptionViewItem option; option.initFrom(treeView); option.state |= QStyle::State_Enabled; option.state &= ~QStyle::State_Active; option.features |= QStyleOptionViewItem::Alternate; option.viewItemPosition = QStyleOptionViewItem::Middle; style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter(), treeView); } void testDrawQListViewPanelItemRow() { QListView *listView = qobject_cast(testWidget()); ASSERT_TRUE(listView); QStyleOptionViewItem option; option.initFrom(listView); option.state |= QStyle::State_Enabled; option.features |= QStyleOptionViewItem::Alternate; option.viewItemPosition = QStyleOptionViewItem::Middle; style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter(), listView); } }; INIT_TESTWIDGET(QCalendarWidget); TestPanelItemViewRowDrawUtil drawUtilInstance(this); ASSERT_DrawFuncNoData(drawUtilInstance.testDrawPanelItemViewInQCalendarWidget); INIT_TESTWIDGET(QTreeView); ASSERT_DrawFuncNoData(drawUtilInstance.testDrawPanelItemViewActiveQTreeView); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawPanelItemViewInactiveEndQTreeView); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawPanelItemViewInactiveValidQTreeView); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawPanelItemViewInactiveAlternateQTreeView); INIT_TESTWIDGET(QListView); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawQListViewPanelItemRow); } TEST_F(TestForDrawUtil, drawPrimitiveFrameStatusBarItem) { auto drawStatusbarItemUtil = [&]() { // return directly style->drawPrimitive(QStyle::PE_FrameStatusBarItem, nullptr, nullptr, nullptr); }; ASSERT_DrawFuncNoData(drawStatusbarItemUtil); } TEST_F(TestForDrawUtil, drawPrimitivePanelStatusBar) { auto drawPanelStatusBarUtil = [&]() { QStyleOption option; option.initFrom(testWidget); style->drawPrimitive(QStyle::PE_PanelStatusBar, &option, painter, testWidget); }; INIT_TESTWIDGET(QStatusBar); ASSERT_DrawFuncHasData(drawPanelStatusBarUtil); } TEST_F(TestForDrawUtil, drawControlCheckBoxAndRadioButton) { class TestCheckBoxAndRadioButtonDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawCheckBoxUtil() { QStyleOptionButton option; option.initFrom(testWidget()); option.state |= QStyle::State_HasFocus; option.text = "test 1"; option.features |= QStyleOptionButton::DefaultButton; style()->drawControl(QStyle::CE_CheckBox, &option, painter(), testWidget()); } void testDrawRadioButtonUtil() { QStyleOptionButton option; option.initFrom(testWidget()); option.state |= QStyle::State_HasFocus; option.text = "test 1"; style()->drawControl(QStyle::CE_RadioButton, &option, painter(), testWidget()); } }; TestCheckBoxAndRadioButtonDrawUtil drawUtilInstance(this); INIT_TESTWIDGET(QCheckBox); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawCheckBoxUtil); INIT_TESTWIDGET(QRadioButton); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawRadioButtonUtil); } TEST_F(TestForDrawUtil, drawControlScrollBarSlider) { class TestScrollBarSliderDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawNormalScrollBarSlider() { QStyleOptionSlider option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal | QStyle::State_MouseOver; option.state |= QStyle::QStyle::State_MouseOver; style()->drawControl(QStyle::CE_ScrollBarSlider, &option, painter(), testWidget()); } void testDrawNormalVerticalScrollBarSlider() { QStyleOptionSlider option; option.initFrom(testWidget()); option.state |= QStyle::QStyle::State_MouseOver; style()->drawControl(QStyle::CE_ScrollBarSlider, &option, painter(), testWidget()); } void testDrawHorizontalSliderWithSpaceProperty() { QStyleOptionSlider option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.state |= QStyle::QStyle::State_MouseOver; testWidget()->setProperty("_d_slider_spaceLeft", 10); testWidget()->setProperty("_d_slider_spaceRight", 10); testWidget()->setProperty("_d_slider_spaceUp", 10); testWidget()->setProperty("_d_slider_spaceDown", 10); style()->drawControl(QStyle::CE_ScrollBarSlider, &option, painter(), testWidget()); } void testDrawVerticalSliderWithSpaceProperty() { QStyleOptionSlider option; option.initFrom(testWidget()); option.state |= (QStyle::State_MouseOver | QStyle::State_Sunken); style()->drawControl(QStyle::CE_ScrollBarSlider, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QScrollBar); TestScrollBarSliderDrawUtil drawUtilInstance(this); QScrollBar *bar = qobject_cast (drawUtilInstance.testWidget()); bar->setProperty("_d_dtk_slider_always_show", true); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNormalScrollBarSlider); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawNormalVerticalScrollBarSlider); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalSliderWithSpaceProperty); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawVerticalSliderWithSpaceProperty); } TEST_F(TestForDrawUtil, drawControlMenuBarItem) { auto drawMenuBarItemUtil = [&]() { QStyleOptionMenuItem option; option.initFrom(testWidget); option.menuItemType = QStyleOptionMenuItem::Margin; option.checkType = QStyleOptionMenuItem::Exclusive; option.text = "test 1"; option.icon = style->standardIcon(QStyle::SP_DirIcon); option.menuRect = QRect(20, 20, 60, 40); option.maxIconWidth = 20; #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) option.reservedShortcutWidth = 2; #else option.tabWidth = 2; #endif style->drawControl(QStyle::CE_MenuBarItem, &option, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawMenuBarItemUtil); } TEST_F(TestForDrawUtil, drawControlMenuItem) { auto drawNormalMenuItemUtil = [&]() { QStyleOptionMenuItem opt; opt.initFrom(testWidget); opt.menuItemType = QStyleOptionMenuItem::Normal; style->drawControl(QStyle::CE_MenuItem, &opt, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawNormalMenuItemUtil); } TEST_F(TestForDrawUtil, drawControlPushButtonAndBevel) { class TestPushButtonAndBevelUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawFocusPushButtonUtil() { QStyleOptionButton option; option.initFrom(testWidget()); option.state |= QStyle::State_HasFocus; option.text = "test 1"; style()->drawControl(QStyle::CE_PushButton, &option, painter(), testWidget()); } void testDrawPushButtonBevelDefaultButton() { QStyleOptionButton option; option.initFrom(testWidget()); option.features |= QStyleOptionButton::DefaultButton; option.text = "test 2"; style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter(), testWidget()); } void testDrawPushButtonBevelAutoDefaultButton() { QStyleOptionButton option; option.initFrom(testWidget()); option.features |= QStyleOptionButton::AutoDefaultButton; option.text = "test 3"; style()->drawControl(QStyle::CE_PushButtonBevel, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QPushButton); TestPushButtonAndBevelUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawFocusPushButtonUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawPushButtonBevelDefaultButton); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawPushButtonBevelAutoDefaultButton); } TEST_F(TestForDrawUtil, drawControlTabBarTab) { class TestTabBarTabDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawTabBarTabShapeUtil() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::RoundedEast; tab.position = QStyleOptionTab::OnlyOneTab; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 1"; style()->drawControl(QStyle::CE_TabBarTabShape, &tab, painter(), testWidget()); } void testDrawTabBarTabLabelUtil() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::RoundedEast; tab.position = QStyleOptionTab::Beginning; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 2"; style()->drawControl(QStyle::CE_TabBarTabLabel, &tab, painter(), testWidget()); } void testDrawTabBarTabHorizontalSelectedUtil() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::RoundedNorth; tab.position = QStyleOptionTab::Middle; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 3"; style()->drawControl(QStyle::CE_TabBarTab, &tab, painter(), testWidget()); } void testDrawTabBarTabVerticalCheckedUtil() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= (QStyle::State_Selected | QStyle::State_Enabled); tab.shape = QTabBar::TriangularWest; tab.position = QStyleOptionTab::Beginning; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 4"; testWidget()->setProperty("_d_dtk_tabbartab_type", true); style()->drawControl(QStyle::CE_TabBarTab, &tab, painter(), testWidget()); } void testDrawTabBarTabVerticalCheckedAndOffStateUtil() { QStyleOptionTab tab; tab.initFrom(testWidget()); tab.state |= QStyle::State_Enabled; tab.shape = QTabBar::RoundedSouth; tab.position = QStyleOptionTab::Beginning; tab.selectedPosition = QStyleOptionTab::NotAdjacent; tab.cornerWidgets = QStyleOptionTab::NoCornerWidgets; tab.text = "test 4"; testWidget()->setProperty("_d_dtk_tabbartab_type", true); style()->drawControl(QStyle::CE_TabBarTab, &tab, painter(), testWidget()); } }; INIT_TESTWIDGET(QTabBar); TestTabBarTabDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawTabBarTabShapeUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawTabBarTabLabelUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawTabBarTabHorizontalSelectedUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawTabBarTabVerticalCheckedUtil); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawTabBarTabVerticalCheckedAndOffStateUtil); } TEST_F(TestForDrawUtil, drawControlRubberBand) { auto drawRunnerBandUtil = [&]() { QStyleOptionRubberBand option; option.initFrom(testWidget); style->drawControl(QStyle::CE_RubberBand, &option, painter, testWidget); }; INIT_TESTWIDGET(QWidget); ASSERT_DrawFuncHasData(drawRunnerBandUtil); } TEST_F(TestForDrawUtil, drawControlHeader) { auto drawHeaderUtil = [&]() { QStyleOptionHeader header; header.initFrom(testWidget); header.sortIndicator = QStyleOptionHeader::SortUp; style->drawControl(QStyle::CE_Header, &header, painter, testWidget); }; INIT_TESTWIDGET(QHeaderView(Qt::Horizontal)); ASSERT_DrawFuncHasData(drawHeaderUtil); } TEST_F(TestForDrawUtil, drawShapedFrameUtil) { class TestShapedFrameDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testBoxPlainShapedFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.frameShape = QFrame::Box; option.lineWidth = 3; option.midLineWidth = 2; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testBoxSunkenShapedFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.state = QStyle::State_Sunken; option.frameShape = QFrame::Box; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testBoxRaisedShapedFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.state = QStyle::State_Raised; option.frameShape = QFrame::Box; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testStyledPanelShapedFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.frameShape = QFrame::StyledPanel; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testStyledPanelSunkenFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.state = QStyle::State_Sunken; option.frameShape = QFrame::StyledPanel; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), nullptr); } void testPanelPlainFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.frameShape = QFrame::Panel; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testPanelSunkenFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.state = QStyle::State_Sunken; option.frameShape = QFrame::Panel; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testWinPanelSunkenFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.state = QStyle::State_Sunken; option.frameShape = QFrame::WinPanel; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testWinPanelPlainFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.frameShape = QFrame::WinPanel; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testHLinePlainFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.frameShape = QFrame::HLine; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } void testVLineSunkenFrame() { QStyleOptionFrame option; option.initFrom(testWidget()); option.state = QStyle::State_Sunken; option.frameShape = QFrame::VLine; option.lineWidth = 2; option.midLineWidth = 3; style()->drawControl(QStyle::CE_ShapedFrame, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QFrame); TestShapedFrameDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testBoxPlainShapedFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testBoxSunkenShapedFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testBoxRaisedShapedFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testStyledPanelShapedFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testStyledPanelSunkenFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testPanelPlainFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testPanelSunkenFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testWinPanelSunkenFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testWinPanelPlainFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testHLinePlainFrame); ASSERT_DrawFuncHasData(drawUtilInstance.testVLineSunkenFrame); } TEST_F(TestForDrawUtil, drawControlComboBoxLabel) { auto drawComboBoxLabelUtil = [&]() { QStyleOptionComboBox option; option.initFrom(testWidget); option.currentText = "test 1"; style->drawControl(QStyle::CE_ComboBoxLabel, &option, painter, testWidget); }; INIT_TESTWIDGET(QComboBox); ASSERT_DrawFuncHasData(drawComboBoxLabelUtil); } TEST_F(TestForDrawUtil, drawControlPushButtonLabel) { class TestPushButtonLabelDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawWarningButtonLabel() { QStyleOptionButton option; option.initFrom(testWidget()); option.features |= QStyleOptionButton::ButtonFeature(DStyleOptionButton::WarningButton); option.text = "test 1"; option.icon = style()->standardIcon(QStyle::SP_FileIcon); option.direction = Qt::RightToLeft; option.state |= QStyle::State_On | QStyle::State_Sunken; option.features |= QStyleOptionButton::HasMenu; style()->drawControl(QStyle::CE_PushButtonLabel, &option, painter(), testWidget()); } void testDrawSuggestButtonLabel() { QStyleOptionButton option; option.initFrom(testWidget()); option.features |= QStyleOptionButton::ButtonFeature(DStyleOptionButton::SuggestButton); option.text = "test 1"; option.icon = style()->standardIcon(QStyle::SP_FileIcon); option.direction = Qt::LeftToRight; option.state |= QStyle::State_On | QStyle::State_Sunken; option.features |= QStyleOptionButton::HasMenu; style()->drawControl(QStyle::CE_PushButtonLabel, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QPushButton); TestPushButtonLabelDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawWarningButtonLabel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawSuggestButtonLabel); } TEST_F(TestForDrawUtil, drawControlProgressBar) { class TestProgressBarDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawHorizontalProgressBar() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 80; option.minimum = 0; option.maximum = 100; style()->drawControl(QStyle::CE_ProgressBar, &option, painter(), testWidget()); } void testVerticalProgressBar() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state &= ~QStyle::State_Horizontal; option.progress = 50; option.minimum = 0; option.maximum = 100; style()->drawControl(QStyle::CE_ProgressBar, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QProgressBar); TestProgressBarDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawHorizontalProgressBar); ASSERT_DrawFuncHasData(drawUtilInstance.testVerticalProgressBar); } TEST_F(TestForDrawUtil, drawControlProgressBarGroove) { class TestProgressBarGrooveDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testProgressBarGrooveUtil() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 50; option.minimum = 0; option.maximum = 100; style()->drawControl(QStyle::CE_ProgressBarGroove, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QProgressBar); TestProgressBarGrooveDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testProgressBarGrooveUtil); } TEST_F(TestForDrawUtil, drawControlProgressBarContents) { class TestProgressBarContentsDrawUtil : public TestDrawUtilIntegration { public: using TestDrawUtilIntegration::TestDrawUtilIntegration; void testDrawProgressBarTextVisibleUtl() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 50; option.minimum = 0; option.maximum = 100; option.textVisible = true; option.text = "test 1"; style()->drawControl(QStyle::CE_ProgressBarContents, &option, painter(), testWidget()); } void testDrawProgressBarUtl() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 100; option.minimum = 0; option.maximum = 100; option.rect = QRect(0, 0, 6, 4); style()->drawControl(QStyle::CE_ProgressBarContents, &option, painter(), testWidget()); } void testDrawCenterProgressBarLabel() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 50; option.minimum = 0; option.maximum = 100; option.rect = QRect(0, 0, 80, 40); option.text = "test 2"; option.fontMetrics = testWidget()->fontMetrics(); option.textAlignment = Qt::AlignCenter; style()->drawControl(QStyle::CE_ProgressBarLabel, &option, painter(), testWidget()); } void testDrawRightProgressBarLabel() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 10; option.minimum = 0; option.maximum = 100; option.rect = QRect(0, 0, 80, 40); option.text = "test 3"; option.textAlignment = Qt::AlignRight; style()->drawControl(QStyle::CE_ProgressBarLabel, &option, painter(), testWidget()); } void testDrawLeftProgressBarLabel() { QStyleOptionProgressBar option; option.initFrom(testWidget()); option.state |= QStyle::State_Horizontal; option.progress = 90; option.minimum = 0; option.maximum = 100; option.rect = QRect(0, 0, 80, 40); option.text = "test 4"; option.textAlignment = Qt::AlignLeft; style()->drawControl(QStyle::CE_ProgressBarLabel, &option, painter(), testWidget()); } }; INIT_TESTWIDGET(QProgressBar); TestProgressBarContentsDrawUtil drawUtilInstance(this); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawProgressBarTextVisibleUtl); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawProgressBarUtl); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawCenterProgressBarLabel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawRightProgressBarLabel); ASSERT_DrawFuncHasData(drawUtilInstance.testDrawLeftProgressBarLabel); } qt5integration-5.7.12/tests/test-coverage.sh000077500000000000000000000013761476226661600210630ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. # # SPDX-License-Identifier: LGPL-3.0-or-later SCRIPT_PATH=$(dirname $0) cd $SCRIPT_PATH && cd .. BUILD_DIR=$PWD/build HTML_DIR=${BUILD_DIR}/html XML_DIR=${BUILD_DIR}/report export ASAN_OPTIONS="halt_on_error=0" cmake -B${BUILD_DIR} -DCMAKE_BUILD_TYPE=Debug -DENABLE_COV=ON cmake --build ${BUILD_DIR} --target unit-tests -j$(nproc) cd $BUILD_DIR tests/unit-tests --gtest_output=xml:${XML_DIR}/report_qtintegration.xml lcov -d ./ -c -o coverage_all.info lcov --remove coverage_all.info "*/tests/*" "*/usr/include*" "*build/*" --output-file coverage.info genhtml -o $HTML_DIR $BUILD_DIR/coverage.info && mv ${BUILD_DIR}/html/index.html ${BUILD_DIR}/html/cov_qtintegration.html qt5integration-5.7.12/tests/ut_pluginloading.cpp000066400000000000000000000053261476226661600220230ustar00rootroot00000000000000/* * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. * SPDX-License-Identifier: LGPL-3.0-or-later */ #include #include #include #include #include #include struct PluginInfo { QString path; QString metaFilePath; }; class TestPluginLoading : public testing::Test, public testing::WithParamInterface { public: static void SetUpTestSuite() { // Assume build directory is in project root directory #ifdef UT_PLATFORMPLUGIN_PATH pluginBaseDir = UT_PLATFORMPLUGIN_PATH; #else pluginBaseDir = "../plugins"; #endif #ifdef META_FILE_BASE_DIR metaFileBaseDir = META_FILE_BASE_DIR; #else metaFileBaseDir = "../.."; #endif } private: static QString pluginBaseDir; static QString metaFileBaseDir; }; QString TestPluginLoading::pluginBaseDir = ""; QString TestPluginLoading::metaFileBaseDir = ""; TEST_P(TestPluginLoading, load) { auto info = GetParam(); QPluginLoader loader(info.path); loader.load(); // Test if loaded successfully EXPECT_TRUE(loader.isLoaded()); EXPECT_NE(nullptr, loader.instance()); // Test if the meta data match, especially key QFile metaFile{QDir(metaFileBaseDir).filePath(info.metaFilePath)}; auto success = metaFile.open(QFile::ReadOnly); ASSERT_TRUE(success); QJsonParseError err; auto doc = QJsonDocument::fromJson(metaFile.readAll(), &err); ASSERT_EQ(err.error, QJsonParseError::NoError); ASSERT_FALSE(doc.isNull()); ASSERT_FALSE(doc.isEmpty()); ASSERT_TRUE(doc.isObject()); auto root = doc.object(); auto meta = loader.metaData(); // meta info must include Keys field auto fileKeys = root.value("Keys").toArray(); auto metaKeys = meta.value("MetaData").toObject().value("Keys").toArray(); ASSERT_FALSE(fileKeys.isEmpty()); ASSERT_FALSE(metaKeys.isEmpty()); ASSERT_EQ(fileKeys.count(), metaKeys.count()); for (int i = 0; i < fileKeys.count(); ++i) { EXPECT_EQ(fileKeys.at(i).toString(), metaKeys.at(i).toString()); } loader.unload(); } INSTANTIATE_TEST_SUITE_P(Default, TestPluginLoading, testing::Values( PluginInfo{"iconengines/libdicon.so", "iconengineplugins/diconengine/diconengine.json"}, PluginInfo{"iconengines/libdsvgicon.so", "iconengineplugins/svgiconengine/qsvgiconengine.json"}, PluginInfo{"imageformats/libdci.so", "imageformatplugins/dci/dci.json"}, PluginInfo{"imageformats/libdsvg.so", "imageformatplugins/svg/svg.json"}, PluginInfo{"platformthemes/libqdeepin.so", "platformthemeplugin/deepin.json"}, PluginInfo{"styles/libchameleon.so", "styleplugins/chameleon/chameleon.json"} ) ); qt5integration-5.7.12/toolGenerate/000077500000000000000000000000001476226661600172335ustar00rootroot00000000000000qt5integration-5.7.12/toolGenerate/qdbusxml2cpp/000077500000000000000000000000001476226661600216575ustar00rootroot00000000000000qt5integration-5.7.12/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogAdaptor.cpp000066400000000000000000000265171476226661600323010ustar00rootroot00000000000000/* * This file was generated by qdbusxml2cpp version 0.8 * Command line was: qdbusxml2cpp ./qt5integration/platformthemeplugin/xmls/com.deepin.filemanager.filedialog.xml -a ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogAdaptor -i ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialog.h * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * * This is an auto-generated file. * Do not edit! All changes made to it will be lost. */ #include "./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogAdaptor.h" #include #include #include #include #include #include #include /* * Implementation of adaptor class FiledialogAdaptor */ FiledialogAdaptor::FiledialogAdaptor(QObject *parent) : QDBusAbstractAdaptor(parent) { // constructor setAutoRelaySignals(true); } FiledialogAdaptor::~FiledialogAdaptor() { // destructor } int FiledialogAdaptor::acceptMode() const { // get the value of property acceptMode return qvariant_cast< int >(parent()->property("acceptMode")); } void FiledialogAdaptor::setAcceptMode(int value) { // set the value of property acceptMode parent()->setProperty("acceptMode", QVariant::fromValue(value)); } QString FiledialogAdaptor::directory() const { // get the value of property directory return qvariant_cast< QString >(parent()->property("directory")); } void FiledialogAdaptor::setDirectory(const QString &value) { // set the value of property directory parent()->setProperty("directory", QVariant::fromValue(value)); } QString FiledialogAdaptor::directoryUrl() const { // get the value of property directoryUrl return qvariant_cast< QString >(parent()->property("directoryUrl")); } void FiledialogAdaptor::setDirectoryUrl(const QString &value) { // set the value of property directoryUrl parent()->setProperty("directoryUrl", QVariant::fromValue(value)); } int FiledialogAdaptor::filter() const { // get the value of property filter return qvariant_cast< int >(parent()->property("filter")); } void FiledialogAdaptor::setFilter(int value) { // set the value of property filter parent()->setProperty("filter", QVariant::fromValue(value)); } int FiledialogAdaptor::heartbeatInterval() const { // get the value of property heartbeatInterval return qvariant_cast< int >(parent()->property("heartbeatInterval")); } void FiledialogAdaptor::setHeartbeatInterval(int value) { // set the value of property heartbeatInterval parent()->setProperty("heartbeatInterval", QVariant::fromValue(value)); } bool FiledialogAdaptor::hideOnAccept() const { // get the value of property hideOnAccept return qvariant_cast< bool >(parent()->property("hideOnAccept")); } void FiledialogAdaptor::setHideOnAccept(bool value) { // set the value of property hideOnAccept parent()->setProperty("hideOnAccept", QVariant::fromValue(value)); } QStringList FiledialogAdaptor::nameFilters() const { // get the value of property nameFilters return qvariant_cast< QStringList >(parent()->property("nameFilters")); } void FiledialogAdaptor::setNameFilters(const QStringList &value) { // set the value of property nameFilters parent()->setProperty("nameFilters", QVariant::fromValue(value)); } int FiledialogAdaptor::viewMode() const { // get the value of property viewMode return qvariant_cast< int >(parent()->property("viewMode")); } void FiledialogAdaptor::setViewMode(int value) { // set the value of property viewMode parent()->setProperty("viewMode", QVariant::fromValue(value)); } bool FiledialogAdaptor::windowActive() const { // get the value of property windowActive return qvariant_cast< bool >(parent()->property("windowActive")); } uint FiledialogAdaptor::windowFlags() const { // get the value of property windowFlags return qvariant_cast< uint >(parent()->property("windowFlags")); } void FiledialogAdaptor::setWindowFlags(uint value) { // set the value of property windowFlags parent()->setProperty("windowFlags", QVariant::fromValue(value)); } void FiledialogAdaptor::accept() { // handle method call com.deepin.filemanager.filedialog.accept QMetaObject::invokeMethod(parent(), "accept"); } void FiledialogAdaptor::activateWindow() { // handle method call com.deepin.filemanager.filedialog.activateWindow QMetaObject::invokeMethod(parent(), "activateWindow"); } void FiledialogAdaptor::addCustomWidget(int type, const QString &data) { // handle method call com.deepin.filemanager.filedialog.addCustomWidget QMetaObject::invokeMethod(parent(), "addCustomWidget", Q_ARG(int, type), Q_ARG(QString, data)); } void FiledialogAdaptor::addDisableUrlScheme(const QString &type) { // handle method call com.deepin.filemanager.filedialog.addDisableUrlScheme QMetaObject::invokeMethod(parent(), "addDisableUrlScheme", Q_ARG(QString, type)); } QMap FiledialogAdaptor::allCustomWidgetsValue(int type) { // handle method call com.deepin.filemanager.filedialog.allCustomWidgetsValue QMap values; QMetaObject::invokeMethod(parent(), "allCustomWidgetsValue", Q_RETURN_ARG(QMap, values), Q_ARG(int, type)); return values; } void FiledialogAdaptor::beginAddCustomWidget() { // handle method call com.deepin.filemanager.filedialog.beginAddCustomWidget QMetaObject::invokeMethod(parent(), "beginAddCustomWidget"); } void FiledialogAdaptor::deleteLater() { // handle method call com.deepin.filemanager.filedialog.deleteLater QMetaObject::invokeMethod(parent(), "deleteLater"); } void FiledialogAdaptor::endAddCustomWidget() { // handle method call com.deepin.filemanager.filedialog.endAddCustomWidget QMetaObject::invokeMethod(parent(), "endAddCustomWidget"); } QDBusVariant FiledialogAdaptor::getCustomWidgetValue(int type, const QString &text) { // handle method call com.deepin.filemanager.filedialog.getCustomWidgetValue QDBusVariant value; QMetaObject::invokeMethod(parent(), "getCustomWidgetValue", Q_RETURN_ARG(QDBusVariant, value), Q_ARG(int, type), Q_ARG(QString, text)); return value; } void FiledialogAdaptor::hide() { // handle method call com.deepin.filemanager.filedialog.hide QMetaObject::invokeMethod(parent(), "hide"); } QString FiledialogAdaptor::labelText(int label) { // handle method call com.deepin.filemanager.filedialog.labelText QString text; QMetaObject::invokeMethod(parent(), "labelText", Q_RETURN_ARG(QString, text), Q_ARG(int, label)); return text; } void FiledialogAdaptor::makeHeartbeat() { // handle method call com.deepin.filemanager.filedialog.makeHeartbeat QMetaObject::invokeMethod(parent(), "makeHeartbeat"); } void FiledialogAdaptor::open() { // handle method call com.deepin.filemanager.filedialog.open QMetaObject::invokeMethod(parent(), "open"); } int FiledialogAdaptor::options() { // handle method call com.deepin.filemanager.filedialog.options int options; QMetaObject::invokeMethod(parent(), "options", Q_RETURN_ARG(int, options)); return options; } void FiledialogAdaptor::reject() { // handle method call com.deepin.filemanager.filedialog.reject QMetaObject::invokeMethod(parent(), "reject"); } void FiledialogAdaptor::selectFile(const QString &filename) { // handle method call com.deepin.filemanager.filedialog.selectFile QMetaObject::invokeMethod(parent(), "selectFile", Q_ARG(QString, filename)); } void FiledialogAdaptor::selectNameFilter(const QString &filter) { // handle method call com.deepin.filemanager.filedialog.selectNameFilter QMetaObject::invokeMethod(parent(), "selectNameFilter", Q_ARG(QString, filter)); } void FiledialogAdaptor::selectNameFilterByIndex(int index) { // handle method call com.deepin.filemanager.filedialog.selectNameFilterByIndex QMetaObject::invokeMethod(parent(), "selectNameFilterByIndex", Q_ARG(int, index)); } void FiledialogAdaptor::selectUrl(const QString &url) { // handle method call com.deepin.filemanager.filedialog.selectUrl QMetaObject::invokeMethod(parent(), "selectUrl", Q_ARG(QString, url)); } QStringList FiledialogAdaptor::selectedFiles() { // handle method call com.deepin.filemanager.filedialog.selectedFiles QStringList filelist; QMetaObject::invokeMethod(parent(), "selectedFiles", Q_RETURN_ARG(QStringList, filelist)); return filelist; } QString FiledialogAdaptor::selectedNameFilter() { // handle method call com.deepin.filemanager.filedialog.selectedNameFilter QString filter; QMetaObject::invokeMethod(parent(), "selectedNameFilter", Q_RETURN_ARG(QString, filter)); return filter; } int FiledialogAdaptor::selectedNameFilterIndex() { // handle method call com.deepin.filemanager.filedialog.selectedNameFilterIndex int index; QMetaObject::invokeMethod(parent(), "selectedNameFilterIndex", Q_RETURN_ARG(int, index)); return index; } QStringList FiledialogAdaptor::selectedUrls() { // handle method call com.deepin.filemanager.filedialog.selectedUrls QStringList urllist; QMetaObject::invokeMethod(parent(), "selectedUrls", Q_RETURN_ARG(QStringList, urllist)); return urllist; } void FiledialogAdaptor::setAllowMixedSelection(bool on) { // handle method call com.deepin.filemanager.filedialog.setAllowMixedSelection QMetaObject::invokeMethod(parent(), "setAllowMixedSelection", Q_ARG(bool, on)); } void FiledialogAdaptor::setCurrentInputName(const QString &name) { // handle method call com.deepin.filemanager.filedialog.setCurrentInputName QMetaObject::invokeMethod(parent(), "setCurrentInputName", Q_ARG(QString, name)); } void FiledialogAdaptor::setFileMode(int fileMode) { // handle method call com.deepin.filemanager.filedialog.setFileMode QMetaObject::invokeMethod(parent(), "setFileMode", Q_ARG(int, fileMode)); } void FiledialogAdaptor::setLabelText(int label, const QString &text) { // handle method call com.deepin.filemanager.filedialog.setLabelText QMetaObject::invokeMethod(parent(), "setLabelText", Q_ARG(int, label), Q_ARG(QString, text)); } void FiledialogAdaptor::setOption(int option, bool on) { // handle method call com.deepin.filemanager.filedialog.setOption QMetaObject::invokeMethod(parent(), "setOption", Q_ARG(int, option), Q_ARG(bool, on)); } void FiledialogAdaptor::setOptions(int options) { // handle method call com.deepin.filemanager.filedialog.setOptions QMetaObject::invokeMethod(parent(), "setOptions", Q_ARG(int, options)); } void FiledialogAdaptor::setWindowTitle(const QString &title) { // handle method call com.deepin.filemanager.filedialog.setWindowTitle QMetaObject::invokeMethod(parent(), "setWindowTitle", Q_ARG(QString, title)); } void FiledialogAdaptor::show() { // handle method call com.deepin.filemanager.filedialog.show QMetaObject::invokeMethod(parent(), "show"); } bool FiledialogAdaptor::testOption(int option) { // handle method call com.deepin.filemanager.filedialog.testOption bool on; QMetaObject::invokeMethod(parent(), "testOption", Q_RETURN_ARG(bool, on), Q_ARG(int, option)); return on; } qulonglong FiledialogAdaptor::winId() { // handle method call com.deepin.filemanager.filedialog.winId qulonglong windowId; QMetaObject::invokeMethod(parent(), "winId", Q_RETURN_ARG(qulonglong, windowId)); return windowId; } qt5integration-5.7.12/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogAdaptor.h000066400000000000000000000225631476226661600317430ustar00rootroot00000000000000/* * This file was generated by qdbusxml2cpp version 0.8 * Command line was: qdbusxml2cpp ./qt5integration/platformthemeplugin/xmls/com.deepin.filemanager.filedialog.xml -a ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogAdaptor -i ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialog.h * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * * This is an auto-generated file. * This file may have been hand-edited. Look for HAND-EDIT comments * before re-generating it. */ #ifndef COM_DEEPIN_FILEMANAGER_FILEDIALOGADAPTOR_H #define COM_DEEPIN_FILEMANAGER_FILEDIALOGADAPTOR_H #include #include #include "./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialog.h" QT_BEGIN_NAMESPACE class QByteArray; template class QList; template class QMap; class QString; class QStringList; class QVariant; QT_END_NAMESPACE /* * Adaptor class for interface com.deepin.filemanager.filedialog */ class FiledialogAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.filedialog") Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: FiledialogAdaptor(QObject *parent); virtual ~FiledialogAdaptor(); public: // PROPERTIES Q_PROPERTY(int acceptMode READ acceptMode WRITE setAcceptMode) int acceptMode() const; void setAcceptMode(int value); Q_PROPERTY(QString directory READ directory WRITE setDirectory) QString directory() const; void setDirectory(const QString &value); Q_PROPERTY(QString directoryUrl READ directoryUrl WRITE setDirectoryUrl) QString directoryUrl() const; void setDirectoryUrl(const QString &value); Q_PROPERTY(int filter READ filter WRITE setFilter) int filter() const; void setFilter(int value); Q_PROPERTY(int heartbeatInterval READ heartbeatInterval WRITE setHeartbeatInterval) int heartbeatInterval() const; void setHeartbeatInterval(int value); Q_PROPERTY(bool hideOnAccept READ hideOnAccept WRITE setHideOnAccept) bool hideOnAccept() const; void setHideOnAccept(bool value); Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters) QStringList nameFilters() const; void setNameFilters(const QStringList &value); Q_PROPERTY(int viewMode READ viewMode WRITE setViewMode) int viewMode() const; void setViewMode(int value); Q_PROPERTY(bool windowActive READ windowActive) bool windowActive() const; Q_PROPERTY(uint windowFlags READ windowFlags WRITE setWindowFlags) uint windowFlags() const; void setWindowFlags(uint value); public Q_SLOTS: // METHODS void accept(); void activateWindow(); void addCustomWidget(int type, const QString &data); void addDisableUrlScheme(const QString &type); QMap allCustomWidgetsValue(int type); void beginAddCustomWidget(); void deleteLater(); void endAddCustomWidget(); QDBusVariant getCustomWidgetValue(int type, const QString &text); void hide(); QString labelText(int label); void makeHeartbeat(); void open(); int options(); void reject(); void selectFile(const QString &filename); void selectNameFilter(const QString &filter); void selectNameFilterByIndex(int index); void selectUrl(const QString &url); QStringList selectedFiles(); QString selectedNameFilter(); int selectedNameFilterIndex(); QStringList selectedUrls(); void setAllowMixedSelection(bool on); void setCurrentInputName(const QString &name); void setFileMode(int fileMode); void setLabelText(int label, const QString &text); void setOption(int option, bool on); void setOptions(int options); void setWindowTitle(const QString &title); void show(); bool testOption(int option); qulonglong winId(); Q_SIGNALS: // SIGNALS void accepted(); void currentUrlChanged(); void destroyed(); void directoryChanged(); void directoryUrlChanged(); void finished(int result); void rejected(); void selectedNameFilterChanged(); void selectionFilesChanged(); void windowActiveChanged(); }; #endif qt5integration-5.7.12/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanagerAdaptor.cpp000066400000000000000000000047401476226661600336260ustar00rootroot00000000000000/* * This file was generated by qdbusxml2cpp version 0.8 * Command line was: qdbusxml2cpp ./qt5integration/platformthemeplugin/xmls/com.deepin.filemanager.filedialogmanager.xml -a ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanagerAdaptor -i ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanager.h * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * * This is an auto-generated file. * Do not edit! All changes made to it will be lost. */ #include "./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanagerAdaptor.h" #include #include #include #include #include #include #include /* * Implementation of adaptor class FiledialogmanagerAdaptor */ FiledialogmanagerAdaptor::FiledialogmanagerAdaptor(QObject *parent) : QDBusAbstractAdaptor(parent) { // constructor setAutoRelaySignals(true); } FiledialogmanagerAdaptor::~FiledialogmanagerAdaptor() { // destructor } QDBusObjectPath FiledialogmanagerAdaptor::createDialog(const QString &key) { // handle method call com.deepin.filemanager.filedialogmanager.createDialog QDBusObjectPath path; QMetaObject::invokeMethod(parent(), "createDialog", Q_RETURN_ARG(QDBusObjectPath, path), Q_ARG(QString, key)); return path; } void FiledialogmanagerAdaptor::destroyDialog(const QDBusObjectPath &path) { // handle method call com.deepin.filemanager.filedialogmanager.destroyDialog QMetaObject::invokeMethod(parent(), "destroyDialog", Q_ARG(QDBusObjectPath, path)); } QList FiledialogmanagerAdaptor::dialogs() { // handle method call com.deepin.filemanager.filedialogmanager.dialogs QList dialogObjectList; QMetaObject::invokeMethod(parent(), "dialogs", Q_RETURN_ARG(QList, dialogObjectList)); return dialogObjectList; } QString FiledialogmanagerAdaptor::errorString() { // handle method call com.deepin.filemanager.filedialogmanager.errorString QString error; QMetaObject::invokeMethod(parent(), "errorString", Q_RETURN_ARG(QString, error)); return error; } bool FiledialogmanagerAdaptor::isUseFileChooserDialog() { // handle method call com.deepin.filemanager.filedialogmanager.isUseFileChooserDialog bool ok; QMetaObject::invokeMethod(parent(), "isUseFileChooserDialog", Q_RETURN_ARG(bool, ok)); return ok; } qt5integration-5.7.12/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanagerAdaptor.h000066400000000000000000000045731476226661600332770ustar00rootroot00000000000000/* * This file was generated by qdbusxml2cpp version 0.8 * Command line was: qdbusxml2cpp ./qt5integration/platformthemeplugin/xmls/com.deepin.filemanager.filedialogmanager.xml -a ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanagerAdaptor -i ./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanager.h * * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. * * This is an auto-generated file. * This file may have been hand-edited. Look for HAND-EDIT comments * before re-generating it. */ #ifndef COM_DEEPIN_FILEMANAGER_FILEDIALOGMANAGERADAPTOR_H #define COM_DEEPIN_FILEMANAGER_FILEDIALOGMANAGERADAPTOR_H #include #include #include "./qt5integration/toolGenerate/qdbusxml2cpp/com.deepin.filemanager.filedialogmanager.h" QT_BEGIN_NAMESPACE class QByteArray; template class QList; template class QMap; class QString; class QStringList; class QVariant; QT_END_NAMESPACE /* * Adaptor class for interface com.deepin.filemanager.filedialogmanager */ class FiledialogmanagerAdaptor: public QDBusAbstractAdaptor { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "com.deepin.filemanager.filedialogmanager") Q_CLASSINFO("D-Bus Introspection", "" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "") public: FiledialogmanagerAdaptor(QObject *parent); virtual ~FiledialogmanagerAdaptor(); public: // PROPERTIES public Q_SLOTS: // METHODS QDBusObjectPath createDialog(const QString &key); void destroyDialog(const QDBusObjectPath &path); QList dialogs(); QString errorString(); bool isUseFileChooserDialog(); Q_SIGNALS: // SIGNALS }; #endif