diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt index ddf3ba1..9ab55c2 100644 --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -1,88 +1,90 @@ include(ECMMarkAsTest) include(ECMMarkNonGuiExecutable) find_package(Qt5Test ${REQUIRED_QT_VERSION} CONFIG QUIET) find_package(Qt5Qml ${REQUIRED_QT_VERSION} CONFIG QUIET) if(NOT Qt5Test_FOUND) message(STATUS "Qt5Test not found, autotests will not be built.") return() endif() if(NOT Qt5Qml_FOUND) message(STATUS "Qt5Qml not found, QML autotests will not be built.") endif() include_directories( ${Qt5Gui_PRIVATE_INCLUDE_DIRS} ${Qt5PlatformSupport_PRIVATE_INCLUDE_DIRS} ${CMAKE_BINARY_DIR}/src/platformtheme ) set(CONFIGFILE "${CMAKE_CURRENT_SOURCE_DIR}/kdeplatformtheme_kdeglobals") set(CHANGED_CONFIGFILE "${CMAKE_CURRENT_SOURCE_DIR}/kdeplatformtheme_changed_kdeglobals") configure_file(kdeplatformtheme_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/kdeplatformtheme_config.h) remove_definitions(-DQT_NO_CAST_FROM_ASCII) # qdbusmenubar uses them remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS) macro(FRAMEWORKINTEGRATION_TESTS _testname) add_executable(${_testname} ${_testname}.cpp ${ARGN}) set_target_properties(${_testname} PROPERTIES COMPILE_FLAGS "-DUNIT_TEST") add_test(frameworkintegration-${_testname} ${_testname}) ecm_mark_as_test(${_testname}) ecm_mark_nongui_executable(${_testname}) target_link_libraries(${_testname} Qt5::Test Qt5::DBus Qt5::X11Extras ${QT5PLATFORMSUPPORT_LIBS} KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets KF5::I18n KF5::Notifications KF5::WindowSystem KF5::WaylandClient XCB::XCB) endmacro() set(platformThemeSRCS ../src/platformtheme/kdeplatformtheme.cpp ../src/platformtheme/kfontsettingsdata.cpp ../src/platformtheme/khintssettings.cpp ../src/platformtheme/kdeplatformfiledialoghelper.cpp ../src/platformtheme/kdeplatformfiledialogbase.cpp ../src/platformtheme/kdeplatformsystemtrayicon.cpp ../src/platformtheme/kdirselectdialog.cpp ../src/platformtheme/kfiletreeview.cpp ../src/platformtheme/kwaylandintegration.cpp ../src/platformtheme/x11integration.cpp ) if(Qt5Core_VERSION VERSION_EQUAL "5.7.0" OR Qt5Core_VERSION VERSION_GREATER "5.7.0") set(platformThemeSRCS ../src/platformtheme/qdbusmenubar.cpp # fork of Qt's qdbusmenubar with some added setters for our convenience ${platformThemeSRCS} ) endif() frameworkintegration_tests( kdeplatformtheme_unittest ${platformThemeSRCS} ) frameworkintegration_tests( kfontsettingsdata_unittest ../src/platformtheme/kfontsettingsdata.cpp ) frameworkintegration_tests( kfiledialog_unittest ) frameworkintegration_tests( ksni_unittest ) frameworkintegration_tests( kdirselectdialog_unittest ../src/platformtheme/kdeplatformfiledialogbase.cpp ../src/platformtheme/kdirselectdialog.cpp ../src/platformtheme/kfiletreeview.cpp ) frameworkintegration_tests( khintssettings_unittest ../src/platformtheme/khintssettings.cpp ) if(Qt5Qml_FOUND) + add_test(NAME qmltests COMMAND qmltestrunner WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + frameworkintegration_tests(kfiledialogqml_unittest) target_link_libraries(kfiledialogqml_unittest Qt5::Qml) endif() diff --git a/autotests/tst_filedialog.qml b/autotests/tst_filedialog.qml new file mode 100644 index 0000000..27c4edf --- /dev/null +++ b/autotests/tst_filedialog.qml @@ -0,0 +1,24 @@ +import QtQuick 2.2 +import QtTest 1.0 +import QtQuick.Dialogs 1.2 +TestCase { + id: testCase + width: 400 + height: 400 + visible: true + when: windowShown + name: "FileDialogTest" + + FileDialog { + id: fileDialog + folder: shortcuts.home + } + + function test_filedialog() { + //At the moment it just makes sure that something opens and doesn't crash. + //Since this is a QGuiApplication (and not a QApplication) + fileDialog.visible = true + testCase.wait(200) + fileDialog.visible = false + } +} diff --git a/src/platformtheme/CMakeLists.txt b/src/platformtheme/CMakeLists.txt index 04acb13..96a22c0 100644 --- a/src/platformtheme/CMakeLists.txt +++ b/src/platformtheme/CMakeLists.txt @@ -1,74 +1,72 @@ find_package(X11) set_package_properties(X11 PROPERTIES DESCRIPTION "Required for updating the Cursor theme on X11" URL "http://www.x.org" TYPE REQUIRED ) set(HAVE_X11 ${X11_FOUND}) if(HAVE_X11) find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED X11Extras) find_package(XCB COMPONENTS XCB) - set_package_properties(XCB PROPERTIES DESCRIPTION "Required for exposing the global menu on X11" - TYPE REQUIRED - ) + set_package_properties(XCB PROPERTIES TYPE REQUIRED) endif() configure_file(config-platformtheme.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-platformtheme.h ) # qdbusmenubar uses them remove_definitions(-DQT_NO_SIGNALS_SLOTS_KEYWORDS) include_directories(${Qt5Core_PRIVATE_INCLUDE_DIRS}) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) set(platformtheme_SRCS kdeplatformtheme.cpp kfontsettingsdata.cpp khintssettings.cpp kdeplatformfiledialoghelper.cpp kdeplatformfiledialogbase.cpp kdeplatformsystemtrayicon.cpp kfiletreeview.cpp kdirselectdialog.cpp kwaylandintegration.cpp x11integration.cpp main.cpp ) if(Qt5Core_VERSION VERSION_EQUAL "5.7.0" OR Qt5Core_VERSION VERSION_GREATER "5.7.0") set(platformtheme_SRCS qdbusmenubar.cpp # fork of Qt's qdbusmenubar with some added setters for our convenience ${platformtheme_SRCS} ) endif() add_library(KDEPlasmaPlatformTheme MODULE ${platformtheme_SRCS}) target_link_libraries(KDEPlasmaPlatformTheme PRIVATE Qt5::DBus Qt5::X11Extras KF5::ConfigWidgets KF5::ConfigCore KF5::IconThemes KF5::KIOFileWidgets # KFileFilterCombo, KDirSortFilterProxyModel, KRecentDirs KF5::KIOWidgets KF5::XmlGui KF5::I18n KF5::Notifications KF5::WindowSystem KF5::WaylandClient XCB::XCB ${QT5PLATFORMSUPPORT_LIBS} ) if(HAVE_X11) target_link_libraries(KDEPlasmaPlatformTheme PRIVATE Qt5::X11Extras ${X11_Xcursor_LIB} ${XCB_XCB_LIBRARY}) endif() install(TARGETS KDEPlasmaPlatformTheme DESTINATION ${KDE_INSTALL_QTPLUGINDIR}/platformthemes) install(FILES fonts_global.upd fonts_akregator.upd fonts_kate.upd DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) install(PROGRAMS fonts_global.pl fonts_akregator.pl fonts_kate.pl DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR}) diff --git a/src/platformtheme/kdeplatformtheme.cpp b/src/platformtheme/kdeplatformtheme.cpp index c19d85b..704f176 100644 --- a/src/platformtheme/kdeplatformtheme.cpp +++ b/src/platformtheme/kdeplatformtheme.cpp @@ -1,371 +1,371 @@ /* This file is part of the KDE libraries * Copyright 2013 Kevin Ottens * Copyright 2013 Aleix Pol Gonzalez * Copyright 2014 Lukáš Tinkl * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License or ( at * your option ) version 3 or, at the discretion of KDE e.V. ( which shall * act as a proxy as in section 14 of the GPLv3 ), any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include "kdeplatformtheme.h" #include "kfontsettingsdata.h" #include "khintssettings.h" #include "kdeplatformfiledialoghelper.h" #include "kdeplatformsystemtrayicon.h" #include "kwaylandintegration.h" #include "x11integration.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(5,7,0) #include "qdbusmenubar_p.h" #endif static const QByteArray s_x11AppMenuServiceNamePropertyName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_SERVICE_NAME"); static const QByteArray s_x11AppMenuObjectPathPropertyName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_OBJECT_PATH"); static const QByteArray s_waylandAppMenuServiceNamePropertyName = QByteArrayLiteral("KDE_APPMENU_SERVICE_NAME"); static const QByteArray s_waylandAppMenuObjectPathPropertyName = QByteArrayLiteral("KDE_APPMENU_OBJECT_PATH"); static bool checkDBusGlobalMenuAvailable() { QDBusConnection connection = QDBusConnection::sessionBus(); QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar"); return connection.interface()->isServiceRegistered(registrarService); } static bool isDBusGlobalMenuAvailable() { static bool dbusGlobalMenuAvailable = checkDBusGlobalMenuAvailable(); return dbusGlobalMenuAvailable; } KdePlatformTheme::KdePlatformTheme() { loadSettings(); if (KWindowSystem::isPlatformWayland()) { m_kwaylandIntegration.reset(new KWaylandIntegration()); m_kwaylandIntegration->init(); } #if HAVE_X11 if (KWindowSystem::isPlatformX11()) { m_x11Integration.reset(new X11Integration()); m_x11Integration->init(); } #endif QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, false); } KdePlatformTheme::~KdePlatformTheme() { delete m_fontsData; delete m_hints; } QVariant KdePlatformTheme::themeHint(QPlatformTheme::ThemeHint hintType) const { QVariant hint = m_hints->hint(hintType); if (hint.isValid()) { return hint; } else { return QPlatformTheme::themeHint(hintType); } } const QPalette *KdePlatformTheme::palette(Palette type) const { QPalette *palette = m_hints->palette(type); if (palette) { return palette; } else { return QPlatformTheme::palette(type); } } const QFont *KdePlatformTheme::font(Font type) const { KFontSettingsData::FontTypes fdtype; switch (type) { case SystemFont: fdtype = KFontSettingsData::GeneralFont; break; case MenuFont: case MenuBarFont: case MenuItemFont: fdtype = KFontSettingsData::MenuFont; break; case MessageBoxFont: case LabelFont: case TipLabelFont: case StatusBarFont: case PushButtonFont: case ToolButtonFont: case ItemViewFont: case ListViewFont: case HeaderViewFont: case ListBoxFont: case ComboMenuItemFont: case ComboLineEditFont: fdtype = KFontSettingsData::GeneralFont; break; case TitleBarFont: case MdiSubWindowTitleFont: case DockWidgetTitleFont: fdtype = KFontSettingsData::WindowTitleFont; break; case SmallFont: case MiniFont: fdtype = KFontSettingsData::SmallestReadableFont; break; case FixedFont: fdtype = KFontSettingsData::FixedFont; break; default: fdtype = KFontSettingsData::GeneralFont; break; } return m_fontsData->font(fdtype); } QIconEngine *KdePlatformTheme::createIconEngine(const QString &iconName) const { return new KIconEngine(iconName, KIconLoader::global()); } void KdePlatformTheme::loadSettings() { m_fontsData = new KFontSettingsData; m_hints = new KHintsSettings; } QList KdePlatformTheme::keyBindings(QKeySequence::StandardKey key) const { switch (key) { case QKeySequence::HelpContents: return KStandardShortcut::shortcut(KStandardShortcut::Help); case QKeySequence::WhatsThis: return KStandardShortcut::shortcut(KStandardShortcut::WhatsThis); case QKeySequence::Open: return KStandardShortcut::shortcut(KStandardShortcut::Open); case QKeySequence::Close: return KStandardShortcut::shortcut(KStandardShortcut::Close); case QKeySequence::Save: return KStandardShortcut::shortcut(KStandardShortcut::Save); case QKeySequence::New: return KStandardShortcut::shortcut(KStandardShortcut::New); case QKeySequence::Cut: return KStandardShortcut::shortcut(KStandardShortcut::Cut); case QKeySequence::Copy: return KStandardShortcut::shortcut(KStandardShortcut::Copy); case QKeySequence::Paste: return KStandardShortcut::shortcut(KStandardShortcut::Paste); case QKeySequence::Undo: return KStandardShortcut::shortcut(KStandardShortcut::Undo); case QKeySequence::Redo: return KStandardShortcut::shortcut(KStandardShortcut::Redo); case QKeySequence::Back: return KStandardShortcut::shortcut(KStandardShortcut::Back); case QKeySequence::Forward: return KStandardShortcut::shortcut(KStandardShortcut::Forward); case QKeySequence::Refresh: return KStandardShortcut::shortcut(KStandardShortcut::Reload); case QKeySequence::ZoomIn: return KStandardShortcut::shortcut(KStandardShortcut::ZoomIn); case QKeySequence::ZoomOut: return KStandardShortcut::shortcut(KStandardShortcut::ZoomOut); case QKeySequence::Print: return KStandardShortcut::shortcut(KStandardShortcut::Print); case QKeySequence::Find: return KStandardShortcut::shortcut(KStandardShortcut::Find); case QKeySequence::FindNext: return KStandardShortcut::shortcut(KStandardShortcut::FindNext); case QKeySequence::FindPrevious: return KStandardShortcut::shortcut(KStandardShortcut::FindPrev); case QKeySequence::Replace: return KStandardShortcut::shortcut(KStandardShortcut::Replace); case QKeySequence::SelectAll: return KStandardShortcut::shortcut(KStandardShortcut::SelectAll); case QKeySequence::MoveToNextWord: return KStandardShortcut::shortcut(KStandardShortcut::ForwardWord); case QKeySequence::MoveToPreviousWord: return KStandardShortcut::shortcut(KStandardShortcut::BackwardWord); case QKeySequence::MoveToNextPage: return KStandardShortcut::shortcut(KStandardShortcut::Next); case QKeySequence::MoveToPreviousPage: return KStandardShortcut::shortcut(KStandardShortcut::Prior); case QKeySequence::MoveToStartOfLine: return KStandardShortcut::shortcut(KStandardShortcut::BeginningOfLine); case QKeySequence::MoveToEndOfLine: return KStandardShortcut::shortcut(KStandardShortcut::EndOfLine); case QKeySequence::MoveToStartOfDocument: return KStandardShortcut::shortcut(KStandardShortcut::Begin); case QKeySequence::MoveToEndOfDocument: return KStandardShortcut::shortcut(KStandardShortcut::End); case QKeySequence::SaveAs: return KStandardShortcut::shortcut(KStandardShortcut::SaveAs); case QKeySequence::Preferences: return KStandardShortcut::shortcut(KStandardShortcut::Preferences); case QKeySequence::Quit: return KStandardShortcut::shortcut(KStandardShortcut::Quit); case QKeySequence::FullScreen: return KStandardShortcut::shortcut(KStandardShortcut::FullScreen); case QKeySequence::Deselect: return KStandardShortcut::shortcut(KStandardShortcut::Deselect); case QKeySequence::DeleteStartOfWord: return KStandardShortcut::shortcut(KStandardShortcut::DeleteWordBack); case QKeySequence::DeleteEndOfWord: return KStandardShortcut::shortcut(KStandardShortcut::DeleteWordForward); case QKeySequence::NextChild: return KStandardShortcut::shortcut(KStandardShortcut::TabNext); case QKeySequence::PreviousChild: return KStandardShortcut::shortcut(KStandardShortcut::TabPrev); default: return QPlatformTheme::keyBindings(key); } } bool KdePlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const { - return type == QPlatformTheme::FileDialog; + return type == QPlatformTheme::FileDialog && qobject_cast(QCoreApplication::instance()); } QString KdePlatformTheme::standardButtonText(int button) const { switch (static_cast(button)) { case QPlatformDialogHelper::NoButton: qWarning() << Q_FUNC_INFO << "Unsupported standard button:" << button; return QString(); case QPlatformDialogHelper::Ok: return KStandardGuiItem::ok().text(); case QPlatformDialogHelper::Save: return KStandardGuiItem::save().text(); case QPlatformDialogHelper::SaveAll: return i18nc("@action:button", "Save All"); case QPlatformDialogHelper::Open: return KStandardGuiItem::open().text(); case QPlatformDialogHelper::Yes: return KStandardGuiItem::yes().text(); case QPlatformDialogHelper::YesToAll: return i18nc("@action:button", "Yes to All"); case QPlatformDialogHelper::No: return KStandardGuiItem::no().text(); case QPlatformDialogHelper::NoToAll: return i18nc("@action:button", "No to All"); case QPlatformDialogHelper::Abort: // FIXME KStandardGuiItem::stop() doesn't seem right here return i18nc("@action:button", "Abort"); case QPlatformDialogHelper::Retry: return i18nc("@action:button", "Retry"); case QPlatformDialogHelper::Ignore: return i18nc("@action:button", "Ignore"); case QPlatformDialogHelper::Close: return KStandardGuiItem::close().text(); case QPlatformDialogHelper::Cancel: return KStandardGuiItem::cancel().text(); case QPlatformDialogHelper::Discard: return KStandardGuiItem::discard().text(); case QPlatformDialogHelper::Help: return KStandardGuiItem::help().text(); case QPlatformDialogHelper::Apply: return KStandardGuiItem::apply().text(); case QPlatformDialogHelper::Reset: return KStandardGuiItem::reset().text(); case QPlatformDialogHelper::RestoreDefaults: return KStandardGuiItem::defaults().text(); default: return QPlatformTheme::defaultStandardButtonText(button); } } QPlatformDialogHelper *KdePlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const { switch (type) { case QPlatformTheme::FileDialog: return new KDEPlatformFileDialogHelper; case QPlatformTheme::FontDialog: case QPlatformTheme::ColorDialog: case QPlatformTheme::MessageDialog: default: return 0; } } QPlatformSystemTrayIcon *KdePlatformTheme::createPlatformSystemTrayIcon() const { return new KDEPlatformSystemTrayIcon; } #if QT_VERSION >= QT_VERSION_CHECK(5,7,0) QPlatformMenuBar *KdePlatformTheme::createPlatformMenuBar() const { if (isDBusGlobalMenuAvailable()) { auto *menu = new QDBusMenuBar(); QObject::connect(menu, &QDBusMenuBar::windowChanged, menu, [this, menu](QWindow *newWindow, QWindow *oldWindow) { const QString &serviceName = QDBusConnection::sessionBus().baseService(); const QString &objectPath = menu->objectPath(); if (m_x11Integration) { if (oldWindow) { m_x11Integration->setWindowProperty(oldWindow, s_x11AppMenuServiceNamePropertyName, {}); m_x11Integration->setWindowProperty(oldWindow, s_x11AppMenuObjectPathPropertyName, {}); } if (newWindow) { m_x11Integration->setWindowProperty(newWindow, s_x11AppMenuServiceNamePropertyName, serviceName.toUtf8()); m_x11Integration->setWindowProperty(newWindow, s_x11AppMenuObjectPathPropertyName, objectPath.toUtf8()); } } if (m_kwaylandIntegration) { if (oldWindow) { m_kwaylandIntegration->setWindowProperty(oldWindow, s_waylandAppMenuServiceNamePropertyName, {}); m_kwaylandIntegration->setWindowProperty(oldWindow, s_waylandAppMenuObjectPathPropertyName, {}); } if (newWindow) { m_kwaylandIntegration->setWindowProperty(newWindow, s_waylandAppMenuServiceNamePropertyName, serviceName.toUtf8()); m_kwaylandIntegration->setWindowProperty(newWindow, s_waylandAppMenuObjectPathPropertyName, objectPath.toUtf8()); } } }); return menu; } return nullptr; } #endif #include "kdeplatformtheme.moc"