├── .git-blame-ignore-revs ├── .gitignore ├── .gitlab-ci.yml ├── .kde-ci.yml ├── CMakeLists.txt ├── KF6XmlGuiConfig.cmake.in ├── LICENSES ├── BSD-2-Clause.txt ├── CC0-1.0.txt ├── LGPL-2.0-only.txt ├── LGPL-2.0-or-later.txt ├── LGPL-2.1-only.txt ├── LGPL-2.1-or-later.txt ├── LGPL-3.0-only.txt └── LicenseRef-KDE-Accepted-LGPL.txt ├── README.md ├── TODO.xmlgui ├── autotests ├── CMakeLists.txt ├── icons │ └── hicolor │ │ ├── 16x16 │ │ └── actions │ │ │ └── go-up.png │ │ ├── 22x22 │ │ └── actions │ │ │ └── go-up.png │ │ ├── 32x32 │ │ └── actions │ │ │ └── go-up.png │ │ ├── 48x48 │ │ └── actions │ │ │ └── go-up.png │ │ ├── 64x64 │ │ └── actions │ │ │ └── go-up.png │ │ └── index.theme ├── kactioncategorytest.cpp ├── kactioncategorytest.h ├── kactioncollectiontest.cpp ├── kactioncollectiontest.h ├── kmainwindow_unittest.cpp ├── kmainwindow_unittest.h ├── ktoolbar_unittest.cpp ├── ktooltiphelper_unittest.cpp ├── ktooltiphelper_unittest.h ├── kxmlgui_unittest.cpp ├── kxmlgui_unittest.h ├── testguiclient.h └── testxmlguiwindow.h ├── docs └── pics │ ├── kaboutapplicationdialog.png │ ├── kbugreport.png │ ├── kedittoolbar.png │ ├── khelpmenu.png │ ├── kkeysequencewidget.png │ ├── kshortcutsdialog.png │ └── kshortcutwidget.png ├── make_kdepackages_updated.py ├── metainfo.yaml ├── po ├── af │ └── kxmlgui6.po ├── ar │ └── kxmlgui6.po ├── as │ └── kxmlgui6.po ├── ast │ └── kxmlgui6.po ├── az │ └── kxmlgui6.po ├── be │ └── kxmlgui6.po ├── be@latin │ └── kxmlgui6.po ├── bg │ └── kxmlgui6.po ├── bn │ └── kxmlgui6.po ├── bn_IN │ └── kxmlgui6.po ├── br │ └── kxmlgui6.po ├── bs │ └── kxmlgui6.po ├── ca │ └── kxmlgui6.po ├── ca@valencia │ └── kxmlgui6.po ├── crh │ └── kxmlgui6.po ├── cs │ └── kxmlgui6.po ├── csb │ └── kxmlgui6.po ├── cy │ └── kxmlgui6.po ├── da │ └── kxmlgui6.po ├── de │ └── kxmlgui6.po ├── el │ └── kxmlgui6.po ├── en_GB │ └── kxmlgui6.po ├── eo │ └── kxmlgui6.po ├── es │ └── kxmlgui6.po ├── et │ └── kxmlgui6.po ├── eu │ └── kxmlgui6.po ├── fa │ └── kxmlgui6.po ├── fi │ └── kxmlgui6.po ├── fr │ └── kxmlgui6.po ├── fy │ └── kxmlgui6.po ├── ga │ └── kxmlgui6.po ├── gd │ └── kxmlgui6.po ├── gl │ └── kxmlgui6.po ├── gu │ └── kxmlgui6.po ├── ha │ └── kxmlgui6.po ├── he │ └── kxmlgui6.po ├── hi │ └── kxmlgui6.po ├── hne │ └── kxmlgui6.po ├── hr │ └── kxmlgui6.po ├── hsb │ └── kxmlgui6.po ├── hu │ └── kxmlgui6.po ├── hy │ └── kxmlgui6.po ├── ia │ └── kxmlgui6.po ├── id │ └── kxmlgui6.po ├── ie │ └── kxmlgui6.po ├── is │ └── kxmlgui6.po ├── it │ └── kxmlgui6.po ├── ja │ └── kxmlgui6.po ├── ka │ └── kxmlgui6.po ├── kab │ └── kxmlgui6.po ├── kk │ └── kxmlgui6.po ├── km │ └── kxmlgui6.po ├── kn │ └── kxmlgui6.po ├── ko │ └── kxmlgui6.po ├── ku │ └── kxmlgui6.po ├── lb │ └── kxmlgui6.po ├── lg │ └── kxmlgui6.po ├── lt │ └── kxmlgui6.po ├── lv │ └── kxmlgui6.po ├── mai │ └── kxmlgui6.po ├── mk │ └── kxmlgui6.po ├── ml │ └── kxmlgui6.po ├── mr │ └── kxmlgui6.po ├── ms │ └── kxmlgui6.po ├── my │ └── kxmlgui6.po ├── nb │ └── kxmlgui6.po ├── nds │ └── kxmlgui6.po ├── ne │ └── kxmlgui6.po ├── nl │ └── kxmlgui6.po ├── nn │ └── kxmlgui6.po ├── oc │ └── kxmlgui6.po ├── or │ └── kxmlgui6.po ├── pa │ └── kxmlgui6.po ├── pl │ └── kxmlgui6.po ├── ps │ └── kxmlgui6.po ├── pt │ └── kxmlgui6.po ├── pt_BR │ └── kxmlgui6.po ├── ro │ └── kxmlgui6.po ├── ru │ └── kxmlgui6.po ├── sa │ └── kxmlgui6.po ├── se │ └── kxmlgui6.po ├── si │ └── kxmlgui6.po ├── sk │ └── kxmlgui6.po ├── sl │ └── kxmlgui6.po ├── sq │ └── kxmlgui6.po ├── sr │ └── kxmlgui6.po ├── sr@ijekavian │ └── kxmlgui6.po ├── sr@ijekavianlatin │ └── kxmlgui6.po ├── sr@latin │ └── kxmlgui6.po ├── sv │ └── kxmlgui6.po ├── ta │ └── kxmlgui6.po ├── te │ └── kxmlgui6.po ├── tg │ └── kxmlgui6.po ├── th │ └── kxmlgui6.po ├── tok │ └── kxmlgui6.po ├── tr │ └── kxmlgui6.po ├── tt │ └── kxmlgui6.po ├── ug │ └── kxmlgui6.po ├── uk │ └── kxmlgui6.po ├── uz │ └── kxmlgui6.po ├── uz@cyrillic │ └── kxmlgui6.po ├── vi │ └── kxmlgui6.po ├── wa │ └── kxmlgui6.po ├── xh │ └── kxmlgui6.po ├── zh_CN │ └── kxmlgui6.po ├── zh_HK │ └── kxmlgui6.po └── zh_TW │ └── kxmlgui6.po ├── python ├── CMakeLists.txt ├── bindings.h └── bindings.xml ├── src ├── CMakeLists.txt ├── Messages.sh ├── TODO ├── aboutkde.svg ├── config-xmlgui.h.cmake ├── designer │ └── CMakeLists.txt ├── kaboutapplicationdialog.cpp ├── kaboutapplicationdialog.h ├── kaboutkdedialog_p.cpp ├── kaboutkdedialog_p.h ├── kaboutplugindialog.cpp ├── kaboutplugindialog.h ├── kabstractaboutdialog_p.cpp ├── kabstractaboutdialog_p.h ├── kactioncategory.cpp ├── kactioncategory.h ├── kactioncollection.cpp ├── kactioncollection.h ├── kactionconflictdetector_p.h ├── kbugreport.cpp ├── kbugreport.h ├── kcheckaccelerators.cpp ├── kcheckaccelerators.h ├── kedittoolbar.cpp ├── kedittoolbar.h ├── kedittoolbar_p.h ├── khelpmenu.cpp ├── khelpmenu.h ├── kkeysequencewidget.cpp ├── kkeysequencewidget.h ├── klicensedialog_p.cpp ├── klicensedialog_p.h ├── kmainwindow.cpp ├── kmainwindow.h ├── kmainwindow_p.h ├── kmainwindowiface.cpp ├── kmainwindowiface_p.h ├── kmenumenuhandler_p.cpp ├── kmenumenuhandler_p.h ├── kpartgui.dtd ├── kshortcuteditwidget.cpp ├── kshortcutschemeseditor.cpp ├── kshortcutschemeshelper.cpp ├── kshortcutschemeshelper_p.h ├── kshortcutsdialog.cpp ├── kshortcutsdialog.h ├── kshortcutsdialog.ui ├── kshortcutsdialog_p.h ├── kshortcutseditor.cpp ├── kshortcutseditor.h ├── kshortcutseditordelegate.cpp ├── kshortcutseditoritem.cpp ├── kshortcutwidget.cpp ├── kshortcutwidget.h ├── kshortcutwidget.ui ├── kswitchlanguagedialog_p.cpp ├── kswitchlanguagedialog_p.h ├── ktoggletoolbaraction.cpp ├── ktoggletoolbaraction.h ├── ktoolbar.cpp ├── ktoolbar.h ├── ktoolbarhandler.cpp ├── ktoolbarhandler_p.h ├── ktoolbarhelper.cpp ├── ktoolbarhelper_p.h ├── ktooltiphelper.cpp ├── ktooltiphelper.h ├── ktooltiphelper_p.h ├── kundoactions.cpp ├── kundoactions.h ├── kxmlgui-index.qdoc ├── kxmlgui.qdoc ├── kxmlgui.qdocconf ├── kxmlgui.qrc ├── kxmlgui.xsd ├── kxmlguibuilder.cpp ├── kxmlguibuilder.h ├── kxmlguiclient.cpp ├── kxmlguiclient.h ├── kxmlguifactory.cpp ├── kxmlguifactory.h ├── kxmlguifactory_p.cpp ├── kxmlguifactory_p.h ├── kxmlguiversionhandler.cpp ├── kxmlguiversionhandler_p.h ├── kxmlguiwindow.cpp ├── kxmlguiwindow.h ├── systeminformation_p.h ├── thumb_frame.png └── ui_standards.rc └── tests ├── CMakeLists.txt ├── kbugreporttest.cpp ├── kmainwindowrestoretest.cpp ├── kmainwindowrestoretest.h ├── kmainwindowtest.cpp ├── kmainwindowtest.h ├── krichtexteditor ├── CMakeLists.txt ├── krichtexteditor.cpp ├── krichtexteditor.h ├── krichtexteditorui.rc └── main.cpp ├── krulertest.cpp ├── krulertest.h ├── ktoolbartest.cpp ├── kwindowtest.cpp ├── kwindowtest.h ├── kwindowtest.rc ├── kxmlguitest.cpp ├── kxmlguitest.h ├── kxmlguitest_part.rc ├── kxmlguitest_shell.rc ├── kxmlguiwindowtest.cpp └── kxmlguiwindowtestui.rc /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # clang-format 2 | fa555b3c75a9f1b9940f0abac7729679c35173af 3 | 43bc90ba2ae813d9e0d5cf3e6e50570da1c87caa 4 | 5 | #clang-tidy 6 | fb6ba49bf944bab53123cc8011898af15b1c7c17 7 | 8 | #astyle 9 | 0b8696343af10941c962f054c5dd7c8fe501182b 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the following files 2 | *~ 3 | *.[oa] 4 | *.diff 5 | *.kate-swp 6 | *.kdev4 7 | .kdev_include_paths 8 | *.kdevelop.pcs 9 | *.moc 10 | *.moc.cpp 11 | *.orig 12 | *.user 13 | .*.swp 14 | .swp.* 15 | Doxyfile 16 | Makefile 17 | avail 18 | random_seed 19 | /build*/ 20 | CMakeLists.txt.user* 21 | *.unc-backup* 22 | .cmake/ 23 | /.clang-format 24 | /compile_commands.json 25 | .clangd 26 | .idea 27 | .vscode 28 | /cmake-build* 29 | .cache 30 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Volker Krause 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | include: 5 | - project: sysadmin/ci-utilities 6 | file: 7 | - /gitlab-templates/linux-qt6.yml 8 | - /gitlab-templates/linux-qt6-next.yml 9 | - /gitlab-templates/linux-qt6-static.yml 10 | - /gitlab-templates/android-qt6.yml 11 | - /gitlab-templates/freebsd-qt6.yml 12 | - /gitlab-templates/windows-qt6.yml 13 | - /gitlab-templates/xml-lint.yml 14 | - /gitlab-templates/yaml-lint.yml 15 | -------------------------------------------------------------------------------- /.kde-ci.yml: -------------------------------------------------------------------------------- 1 | Dependencies: 2 | - 'on': ['@all'] 3 | 'require': 4 | 'frameworks/extra-cmake-modules': '@same' 5 | 'frameworks/kitemviews': '@same' 6 | 'frameworks/kconfig': '@same' 7 | 'frameworks/kconfigwidgets': '@same' 8 | 'frameworks/ki18n': '@same' 9 | 'frameworks/kiconthemes': '@same' 10 | 'frameworks/ktextwidgets': '@same' 11 | 'frameworks/kwidgetsaddons': '@same' 12 | 13 | - 'on': ['Linux', 'FreeBSD'] 14 | 'require': 15 | 'frameworks/kglobalaccel': '@same' 16 | 17 | Options: 18 | test-before-installing: True 19 | require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows'] 20 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | set(KF_VERSION "6.16.0") # handled by release scripts 4 | set(KF_DEP_VERSION "6.15.0") # handled by release scripts 5 | project(KXmlGui VERSION ${KF_VERSION}) 6 | 7 | # ECM setup 8 | include(FeatureSummary) 9 | find_package(ECM 6.15.0 NO_MODULE) 10 | set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") 11 | feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) 12 | 13 | 14 | set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) 15 | 16 | include(ECMMarkNonGuiExecutable) 17 | include(ECMSetupVersion) 18 | include(ECMGenerateHeaders) 19 | include(ECMGenerateExportHeader) 20 | 21 | include(KDEInstallDirs) 22 | include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) 23 | include(KDECMakeSettings) 24 | include(KDEGitCommitHooks) 25 | include(ECMQtDeclareLoggingCategory) 26 | include(ECMDeprecationSettings) 27 | include(ECMGenerateQDoc) 28 | include(CMakeDependentOption) 29 | 30 | set(kxmlgui_version_header "${CMAKE_CURRENT_BINARY_DIR}/src/kxmlgui_version.h") 31 | ecm_setup_version(PROJECT 32 | VARIABLE_PREFIX KXMLGUI 33 | VERSION_HEADER "${kxmlgui_version_header}" 34 | PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF6XmlGuiConfigVersion.cmake" 35 | SOVERSION 6) 36 | 37 | set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].") 38 | 39 | option(FORCE_DISABLE_KGLOBALACCEL "Force building KXmlGui without KGlobalAccel. Doing this will break global shortcut support. [default=OFF]" OFF) 40 | 41 | cmake_dependent_option(BUILD_DESIGNERPLUGIN "Build plugin for Qt Designer" ON "NOT CMAKE_CROSSCOMPILING" OFF) 42 | add_feature_info(DESIGNERPLUGIN ${BUILD_DESIGNERPLUGIN} "Build plugin for Qt Designer") 43 | 44 | # Dependencies 45 | set(REQUIRED_QT_VERSION 6.7.0) 46 | find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets Xml Network PrintSupport) 47 | if(Qt6Core_VERSION VERSION_GREATER_EQUAL "6.9.0") 48 | find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED CorePrivate) 49 | endif() 50 | 51 | # shall we use DBus? 52 | # enabled per default on Linux & BSD systems 53 | set(USE_DBUS_DEFAULT OFF) 54 | if(UNIX AND NOT APPLE AND NOT ANDROID AND NOT HAIKU) 55 | set(USE_DBUS_DEFAULT ON) 56 | endif() 57 | option(USE_DBUS "Build components using DBus" ${USE_DBUS_DEFAULT}) 58 | if(USE_DBUS) 59 | find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED DBus) 60 | set(HAVE_QTDBUS ${Qt6DBus_FOUND}) 61 | 62 | # needs DBus + is only available on Linux & BSD 63 | if (NOT FORCE_DISABLE_KGLOBALACCEL AND NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT HAIKU) 64 | find_package(KF6GlobalAccel ${KF_DEP_VERSION} REQUIRED) 65 | set (HAVE_GLOBALACCEL ${KF6GlobalAccel_FOUND}) 66 | endif() 67 | endif() 68 | 69 | find_package(KF6CoreAddons ${KF_DEP_VERSION} REQUIRED) 70 | find_package(KF6ItemViews ${KF_DEP_VERSION} REQUIRED) 71 | find_package(KF6Config ${KF_DEP_VERSION} REQUIRED) 72 | find_package(KF6ConfigWidgets ${KF_DEP_VERSION} REQUIRED) 73 | find_package(KF6GuiAddons ${KF_DEP_VERSION} REQUIRED) 74 | find_package(KF6I18n ${KF_DEP_VERSION} REQUIRED) 75 | find_package(KF6IconThemes ${KF_DEP_VERSION} REQUIRED) 76 | find_package(KF6WidgetsAddons ${KF_DEP_VERSION} REQUIRED) 77 | 78 | option(BUILD_PYTHON_BINDINGS "Build Python bindings" ON) 79 | 80 | # Only Linux and FreeBSD CI has the relevant packages 81 | if (ANDROID OR APPLE OR WIN32 OR HAIKU OR NOT BUILD_SHARED_LIBS) 82 | set(BUILD_PYTHON_BINDINGS OFF) 83 | endif() 84 | 85 | if (BUILD_PYTHON_BINDINGS) 86 | find_package(Python3 3.9 REQUIRED COMPONENTS Interpreter Development) 87 | find_package(Shiboken6 REQUIRED) 88 | find_package(PySide6 REQUIRED) 89 | endif() 90 | 91 | ecm_set_disabled_deprecation_versions( 92 | QT 6.9 93 | KF 6.14 94 | ) 95 | 96 | add_definitions(-DTRANSLATION_DOMAIN=\"kxmlgui6\") 97 | ki18n_install(po) 98 | 99 | add_feature_info(PYTHON_BINDINGS ${BUILD_PYTHON_BINDINGS} "Python bindings") 100 | 101 | # Subdirectories 102 | add_subdirectory(src) 103 | if (BUILD_TESTING) 104 | add_subdirectory(tests) 105 | add_subdirectory(autotests) 106 | endif() 107 | 108 | if (BUILD_PYTHON_BINDINGS) 109 | include(ECMGeneratePythonBindings) 110 | add_subdirectory(python) 111 | endif() 112 | 113 | # create a Config.cmake and a ConfigVersion.cmake file and install them 114 | set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF6XmlGui") 115 | 116 | include(CMakePackageConfigHelpers) 117 | 118 | configure_package_config_file( 119 | "${CMAKE_CURRENT_SOURCE_DIR}/KF6XmlGuiConfig.cmake.in" 120 | "${CMAKE_CURRENT_BINARY_DIR}/KF6XmlGuiConfig.cmake" 121 | INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} 122 | ) 123 | 124 | install(FILES 125 | "${CMAKE_CURRENT_BINARY_DIR}/KF6XmlGuiConfig.cmake" 126 | "${CMAKE_CURRENT_BINARY_DIR}/KF6XmlGuiConfigVersion.cmake" 127 | DESTINATION "${CMAKECONFIG_INSTALL_DIR}" 128 | COMPONENT Devel 129 | ) 130 | 131 | install(EXPORT KF6XmlGuiTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF6XmlGuiTargets.cmake NAMESPACE KF6:: ) 132 | 133 | install(FILES 134 | ${kxmlgui_version_header} 135 | DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KXmlGui COMPONENT Devel 136 | ) 137 | 138 | include(ECMFeatureSummary) 139 | ecm_feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) 140 | 141 | kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT) 142 | -------------------------------------------------------------------------------- /KF6XmlGuiConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include(CMakeFindDependencyMacro) 4 | if (@HAVE_QTDBUS@) 5 | find_dependency(Qt6DBus @REQUIRED_QT_VERSION@) 6 | endif() 7 | find_dependency(Qt6Widgets @REQUIRED_QT_VERSION@) 8 | find_dependency(Qt6Xml @REQUIRED_QT_VERSION@) 9 | 10 | find_dependency(KF6Config "@KF_DEP_VERSION@") 11 | find_dependency(KF6ConfigWidgets "@KF_DEP_VERSION@") 12 | find_dependency(KF6GuiAddons "@KF_DEP_VERSION@") 13 | 14 | if (NOT @BUILD_SHARED_LIBS@) 15 | find_dependency(Qt6Network "@REQUIRED_QT_VERSION@") 16 | find_dependency(Qt6PrintSupport "@REQUIRED_QT_VERSION@") 17 | 18 | if (@KF6GlobalAccel_FOUND@) 19 | find_dependency(KF6GlobalAccel "@KF_DEP_VERSION@") 20 | endif() 21 | 22 | find_dependency(KF6CoreAddons "@KF_DEP_VERSION@") 23 | find_dependency(KF6WidgetsAddons "@KF_DEP_VERSION@") 24 | find_dependency(KF6ItemViews "@KF_DEP_VERSION@") 25 | find_dependency(KF6I18n "@KF_DEP_VERSION@") 26 | find_dependency(KF6IconThemes "@KF_DEP_VERSION@") 27 | endif() 28 | 29 | include("${CMAKE_CURRENT_LIST_DIR}/KF6XmlGuiTargets.cmake") 30 | -------------------------------------------------------------------------------- /LICENSES/BSD-2-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-KDE-Accepted-LGPL.txt: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the GNU Lesser General Public 3 | License as published by the Free Software Foundation; either 4 | version 3 of the license or (at your option) any later version 5 | that is accepted by the membership of KDE e.V. (or its successor 6 | approved by the membership of KDE e.V.), which shall act as a 7 | proxy as defined in Section 6 of version 3 of the license. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KXMLGUI 2 | 3 | Framework for managing menu and toolbar actions 4 | 5 | ## Introduction 6 | 7 | KXMLGUI provides a framework for managing menu and toolbar actions in an 8 | abstract way. The actions are configured through a XML description and hooks 9 | in the application code. The framework supports merging of multiple 10 | description for example for integrating actions from plugins. 11 | 12 | ## Kiosk 13 | 14 | KXMLGui makes use of the Kiosk authorization functionality of KConfig (see the 15 | KAuthorized namespace in that framework). Notably, QAction instances added to a 16 | KActionCollection are disabled if KAuthorized::authorizeAction() reports that 17 | they are not authorized. The items on the standard help menu (KHelpMenu) can 18 | likewise be disabled based on Kiosk settings, and toolbar editing can be 19 | restricted. 20 | 21 | See KActionCollection, KHelpMenu and KToolBar documentation for more 22 | information. 23 | 24 | 25 | -------------------------------------------------------------------------------- /TODO.xmlgui: -------------------------------------------------------------------------------- 1 | Bug with toolbars: a->saveState(); delete a; b->saveState(); delete b; 2 | will store wrong positions (index, offset and newline). 3 | When removing an xmlgui-client involves destroying toolbars, we need to save the 4 | whole set of toolbar positions of the mainwindow, into the xmlgui-client. 5 | 6 | Data structure: 7 | struct KToolBarPos { 8 | short int index; 9 | short int offset; 10 | bool newLine; 11 | }; 12 | typedef QValueVector KToolBarPosList; 13 | 14 | API: 15 | KToolBarPosList KMainWindow::toolBarPositionList() const; 16 | 17 | The remaining problem is to know when to call it: 18 | * when we know in advance that we'll be able to remove toolbars? 19 | (when creating the client we could remember if we created a toolbar and store 20 | that bit of information, to re-use it when removing the client again) 21 | * when removing the first toolbar (of a given client); then we need 22 | to differentiate between first and following toolbars 23 | * always, if fast enough? With tons of plugins that might not be a good idea. 24 | 25 | ========== More long term 26 | 27 | Problems: 28 | * No ui_standards.rc merging for parts 29 | * Confusing tag names (MergeLocal vs DefineGroup) for similar features 30 | * Two different merging codes (DOM-tree merging for ui_standards, xmlguifactory merging 31 | between xmlguiclients). 32 | 33 | Solution: 34 | * Get rid of the custom DOM-tree merging code from kxmlguiclient (for ui_standards.rc), 35 | use the existing merging code from kxmlguifactory instead 36 | * MergeLocal and DefineGroup are renamed MergeGroup, and append= becomes equivalent to group=. 37 | * Action is renamed MergeAction, and uses a new kind of place holder 38 | (one that matches actions by name during merging) 39 | So ui_standards.rc needs to be turned into s and s only. 40 | * This also means that it will be possible to have only merge tags (and custom items 41 | like separators and tearoffhandle etc.) in a container, in which case it should 42 | not appear in the GUI. For that, ContainerNode must be improved so that it supports 43 | having no real GUI container attached to it. 44 | Big problem here. This means not building a container until we find that it 45 | really has an action (and the other way round: deleting a container when 46 | removing its last action, as we do, but still keeping a ContainerNode around...) 47 | (A ContainerNode is destroyed when its owner guiclient is removed from the factory, 48 | no change here). 49 | 50 | * A new XMLGUIClient provides the ui_standards.rc XML. It has the same instance 51 | as the mainwindow's guiclient. It provides no actions. No problems, since it 52 | only has tags. 53 | 54 | But that new xmlguiclient will 'own' the containers, so KEditToolbar will 55 | give wrong information. 56 | 57 | =====> 58 | This means the following KEditToolbar improvement is necessary: 59 | (it's an almost unrelated and necessary change there anyway, usability-wise) 60 | 61 | It would use merging, to present a merged view of the toolbars 62 | When the user inserts an action to a toolbar, we know which client the action 63 | belongs to, so we know which XML file to modify. 64 | BUT if the user adds actions in non-contiguous positions, we need to 65 | create groups, so that the merging actually does 66 | what the user asked for (!!) 67 | 68 | This allows to get rid of the "toolbar " combobox stuff, and just have 69 | a list of toolbars there. 70 | 71 | Implementation: it can do this by providing its own KXMLGUIBuilder, to a 72 | new factory. The guiclients would be wrapped in a KXMLGUIClientProxy, 73 | which would forward the action() and domElement() calls - because a client 74 | can be in only one factory at a time. 75 | 76 | This custom builder needs to know about action plugging too, we don't really want 77 | to call KAction::plug here. So this would be 'virtualized' (new virtual, in a new 78 | interface to keep BC, that by default calls plug, but does something else in 79 | kedittoolbar's builder). 80 | 81 | 82 | ====== 83 | 84 | Additional benefits: 85 | * Any XML file can use the new feature to modify the way a 86 | child client (e.g. a part) is getting merged, without adding group attributes 87 | to the child client (useful for a binary-only one, e.g.) 88 | 89 | -- 90 | David Faure 91 | Simon Hausmann 92 | -------------------------------------------------------------------------------- /autotests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Xml Test) 3 | 4 | include(ECMAddTests) 5 | 6 | if (HAVE_QTDBUS) 7 | add_definitions(-DWITH_QTDBUS) 8 | endif() 9 | 10 | ecm_add_tests( 11 | kactioncategorytest.cpp 12 | kactioncollectiontest.cpp 13 | LINK_LIBRARIES Qt6::Test KF6::XmlGui 14 | ) 15 | ecm_add_tests( 16 | kmainwindow_unittest.cpp 17 | ktoolbar_unittest.cpp 18 | ktooltiphelper_unittest.cpp 19 | kxmlgui_unittest.cpp 20 | GUI 21 | LINK_LIBRARIES Qt6::Test KF6::IconThemes KF6::XmlGui 22 | ) 23 | 24 | set_tests_properties(ktoolbar_unittest PROPERTIES RUN_SERIAL TRUE) # it wipes out ~/.qttest/share 25 | -------------------------------------------------------------------------------- /autotests/icons/hicolor/16x16/actions/go-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/autotests/icons/hicolor/16x16/actions/go-up.png -------------------------------------------------------------------------------- /autotests/icons/hicolor/22x22/actions/go-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/autotests/icons/hicolor/22x22/actions/go-up.png -------------------------------------------------------------------------------- /autotests/icons/hicolor/32x32/actions/go-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/autotests/icons/hicolor/32x32/actions/go-up.png -------------------------------------------------------------------------------- /autotests/icons/hicolor/48x48/actions/go-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/autotests/icons/hicolor/48x48/actions/go-up.png -------------------------------------------------------------------------------- /autotests/icons/hicolor/64x64/actions/go-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/autotests/icons/hicolor/64x64/actions/go-up.png -------------------------------------------------------------------------------- /autotests/kactioncategorytest.cpp: -------------------------------------------------------------------------------- 1 | #include "kactioncategorytest.h" 2 | 3 | #include 4 | 5 | #include "kactioncategory.h" 6 | #include "kactioncollection.h" 7 | #include 8 | #include 9 | 10 | void tst_KActionCategory::tstCreation() 11 | { 12 | KActionCollection collection((QObject *)nullptr); 13 | KActionCategory category1(QStringLiteral("category1"), &collection); 14 | KActionCategory category2(QStringLiteral("category2"), &collection); 15 | 16 | // Check that the name is correct 17 | QCOMPARE(category1.text(), QStringLiteral("category1")); 18 | QCOMPARE(category2.text(), QStringLiteral("category2")); 19 | 20 | // Check that the parent is correct 21 | QCOMPARE(category1.collection(), &collection); 22 | QCOMPARE(category2.collection(), &collection); 23 | 24 | // Check that the category is available as a child of the collection 25 | QList categories = collection.findChildren(); 26 | QCOMPARE(categories.size(), 2); 27 | QCOMPARE(categories.count(&category1), 1); 28 | QCOMPARE(categories.count(&category2), 1); 29 | 30 | // Change the text 31 | category1.setText(QStringLiteral("Other Text")); 32 | QCOMPARE(category1.text(), QStringLiteral("Other Text")); 33 | } 34 | 35 | void tst_KActionCategory::tstSynchronization() 36 | { 37 | KActionCollection collection((QObject *)nullptr); 38 | KActionCategory category1(QStringLiteral("category1"), &collection); 39 | KActionCategory category2(QStringLiteral("category2"), &collection); 40 | 41 | // The collection is empty 42 | QCOMPARE(collection.count(), 0); 43 | 44 | // Now add a action to category1 45 | QAction *action1 = category1.addAction(QStringLiteral("action1")); 46 | // Check it was added to the category. 47 | QCOMPARE(category1.actions().count(), 1); 48 | QCOMPARE(category1.actions().count(action1), 1); 49 | // Check it was added to the collection 50 | QCOMPARE(collection.actions().count(), 1); 51 | QCOMPARE(collection.actions().count(action1), 1); 52 | 53 | // Short intermezzo. Add the action a second time 54 | category1.addAction(QStringLiteral("action1_new"), action1); 55 | QCOMPARE(category1.actions().count(), 1); 56 | QCOMPARE(category1.actions().count(action1), 1); 57 | QCOMPARE(collection.actions().count(), 1); 58 | QCOMPARE(collection.actions().count(action1), 1); 59 | 60 | // Now add a action to category2 61 | QAction *action2 = category2.addAction(QStringLiteral("action2")); 62 | // Check it was added to the category. 63 | QCOMPARE(category2.actions().count(), 1); 64 | QCOMPARE(category2.actions().count(action2), 1); 65 | // Check it was added to the collection 66 | QCOMPARE(collection.actions().count(), 2); 67 | QCOMPARE(collection.actions().count(action2), 1); 68 | 69 | // Delete action1 70 | delete action1; 71 | // Check it was removed from the collection 72 | QCOMPARE(collection.actions().count(), 1); 73 | QCOMPARE(collection.actions().count(action1), 0); 74 | // Check it was removed from the category. 75 | QCOMPARE(category1.actions().count(), 0); 76 | QCOMPARE(category1.actions().count(action1), 0); 77 | 78 | // Remove action2 from the collection 79 | collection.removeAction(action2); 80 | // Check it was removed from the collection 81 | QCOMPARE(collection.actions().count(), 0); 82 | QCOMPARE(collection.actions().count(action2), 0); 83 | // Check it was removed from the category. 84 | QCOMPARE(category2.actions().count(), 0); 85 | QCOMPARE(category2.actions().count(action2), 0); 86 | 87 | // Create another category, add a action, delete the category and check 88 | // if the action is still part of the collection. 89 | KActionCategory *category3 = new KActionCategory(QStringLiteral("category3"), &collection); 90 | QAction *action3 = category3->addAction(QStringLiteral("action3")); 91 | // Check it was added to the collection 92 | QCOMPARE(collection.actions().count(action3), 1); 93 | // delete the category 94 | delete category3; 95 | // Make sure the action is still there. 96 | QCOMPARE(collection.actions().count(action3), 1); 97 | } 98 | 99 | void tst_KActionCategory::tstActionCreation() 100 | { 101 | KActionCollection collection((QObject *)nullptr); 102 | KActionCategory category(QStringLiteral("category"), &collection); 103 | 104 | // QAction * addAction(const QString &name, QAction *action); 105 | QAction *action1 = new QAction(nullptr); 106 | category.addAction(QStringLiteral("action1"), action1); 107 | QCOMPARE(category.actions().count(action1), 1); 108 | QCOMPARE(collection.actions().count(action1), 1); 109 | 110 | // QAction * addAction(const QString &name, QAction *action); 111 | QAction *action2 = new QAction(nullptr); 112 | category.addAction(QStringLiteral("action2"), action2); 113 | QCOMPARE(category.actions().count(action2), 1); 114 | QCOMPARE(collection.actions().count(action2), 1); 115 | 116 | // QAction * addAction( 117 | // KStandardAction::StandardAction actionType, 118 | // const QObject *receiver = NULL, 119 | // const char *member = NULL); 120 | QAction *action3 = category.addAction(KStandardActions::Revert); 121 | QCOMPARE(category.actions().count(action3), 1); 122 | QCOMPARE(collection.actions().count(action3), 1); 123 | 124 | // QAction * addAction( 125 | // KStandardAction::StandardAction actionType, 126 | // const QString &name, 127 | // const QObject *receiver = NULL, 128 | // const char *member = NULL); 129 | QAction *action4 = category.addAction(KStandardActions::Quit, QStringLiteral("myownname")); 130 | QCOMPARE(action4->objectName(), QStringLiteral("myownname")); 131 | QCOMPARE(category.actions().count(action4), 1); 132 | QCOMPARE(collection.actions().count(action4), 1); 133 | 134 | // QAction *addAction( 135 | // const QString &name, 136 | // const QObject *receiver = NULL, 137 | // const char *member = NULL); 138 | QAction *action5 = category.addAction(QStringLiteral("action5")); 139 | QCOMPARE(category.actions().count(action5), 1); 140 | QCOMPARE(collection.actions().count(action5), 1); 141 | 142 | // template 143 | // ActionType *add( 144 | // const QString &name, 145 | // const QObject *receiver = NULL, 146 | // const char *member = NULL) 147 | KSelectAction *action6 = category.add(QStringLiteral("action6")); 148 | QCOMPARE(category.actions().count(action6), 1); 149 | QCOMPARE(collection.actions().count(action6), 1); 150 | 151 | // There should be 6 actions inside the collection and category 152 | QCOMPARE(category.actions().count(), 6); 153 | QCOMPARE(collection.actions().count(), 6); 154 | delete action1; 155 | delete action2; 156 | } 157 | 158 | QTEST_MAIN(tst_KActionCategory) 159 | 160 | #include "moc_kactioncategorytest.cpp" 161 | -------------------------------------------------------------------------------- /autotests/kactioncategorytest.h: -------------------------------------------------------------------------------- 1 | #ifndef KACTIONCATEGORYTEST_H 2 | #define KACTIONCATEGORYTEST_H 3 | 4 | #include 5 | 6 | class tst_KActionCategory : public QObject 7 | { 8 | Q_OBJECT 9 | 10 | private Q_SLOTS: 11 | 12 | // Test the creation of action categories, 13 | void tstCreation(); 14 | 15 | // Check the synchronization between the action category and the 16 | // collection 17 | void tstSynchronization(); 18 | 19 | // Test the creation of actions 20 | void tstActionCreation(); 21 | 22 | }; // class tst_KActionCategory 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /autotests/kactioncollectiontest.h: -------------------------------------------------------------------------------- 1 | #ifndef KACTIONCOLLECTIONTEST_H 2 | #define KACTIONCOLLECTIONTEST_H 3 | 4 | #include "kactioncollection.h" 5 | #include 6 | 7 | class tst_KActionCollection : public QObject 8 | { 9 | Q_OBJECT 10 | 11 | public Q_SLOTS: 12 | void init(); 13 | void cleanup(); 14 | 15 | private Q_SLOTS: 16 | void clear(); 17 | void deleted(); 18 | void take(); 19 | void writeSettings(); 20 | void readSettings(); 21 | void insertReplaces1(); 22 | void insertReplaces2(); 23 | void testSetShortcuts(); 24 | void implicitStandardActionInsertionUsingCreate(); 25 | void implicitStandardActionInsertionUsingCut(); 26 | void shouldEmitSignals(); 27 | void addStandardActionFunctorSignal(); 28 | void testActionsAreInInsertionOrder(); 29 | void testActionForName(); 30 | 31 | private: 32 | KConfigGroup clearConfig(); 33 | 34 | KActionCollection *collection; 35 | }; 36 | 37 | #endif // KACTIONCOLLECTIONTEST_H 38 | -------------------------------------------------------------------------------- /autotests/kmainwindow_unittest.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2006 David Faure 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef KMAINWINDOW_UNITTEST_H 9 | #define KMAINWINDOW_UNITTEST_H 10 | 11 | #include 12 | 13 | class KMainWindow_UnitTest : public QObject 14 | { 15 | Q_OBJECT 16 | 17 | private Q_SLOTS: 18 | void initTestCase(); 19 | void cleanupTestCase(); 20 | void testDefaultName(); 21 | void testFixedName(); 22 | void testNameWithSpecialChars(); 23 | void testNameWithHash(); 24 | void testSaveWindowSize(); 25 | void testSaveWindowSizeInStateConfig(); 26 | void testAutoSaveSettings(); 27 | void testNoAutoSave(); 28 | void testWidgetWithStatusBar(); 29 | 30 | void testDeleteOnClose(); 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /autotests/ktooltiphelper_unittest.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2021 Felix Ernst 4 | 5 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 6 | */ 7 | 8 | #ifndef KTOOLTIPHELPER_UNITTEST_H 9 | #define KTOOLTIPHELPER_UNITTEST_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | class QFrame; 16 | class QToolButton; 17 | class QWidget; 18 | 19 | class KToolTipHelper_UnitTest : public QObject 20 | { 21 | Q_OBJECT 22 | 23 | private: 24 | QString shownToolTip(QWidget *widget); 25 | 26 | private Q_SLOTS: 27 | void initTestCase(); 28 | void testGeneralWidget(); 29 | void testInvokingWhatsThis(); 30 | void testQToolButton(); 31 | void testQMenu(); 32 | void cleanupTestCase(); 33 | 34 | private: 35 | std::unique_ptr m_window; 36 | QWidget *m_centralWidget; 37 | QFrame *m_frame; 38 | QFrame *m_frameWithoutToolTip; 39 | QToolButton *m_toolButton; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /autotests/kxmlgui_unittest.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 David Faure 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef KXMLGUI_UNITTEST_H 9 | #define KXMLGUI_UNITTEST_H 10 | 11 | #include 12 | 13 | class KXmlGui_UnitTest : public QObject 14 | { 15 | Q_OBJECT 16 | 17 | private Q_SLOTS: 18 | void initTestCase(); 19 | void testFindVersionNumber_data(); 20 | void testFindVersionNumber(); 21 | void testVersionHandlerSameVersion(); 22 | void testVersionHandlerNewVersionNothingKept(); 23 | void testVersionHandlerNewVersionUserChanges(); 24 | void testPartMerging(); 25 | void testPartMergingSettings(); 26 | void testShortcutSchemeMerging(); 27 | void testUiStandardsMerging_data(); 28 | void testUiStandardsMerging(); 29 | void testActionListAndSeparator(); 30 | void testHiddenToolBar(); 31 | void testCustomPlaceToolBar(); 32 | void testDeletedContainers(); 33 | void testAutoSaveSettings(); 34 | void testXMLFileReplacement(); 35 | void testTopLevelSeparator(); 36 | void testMenuNames(); 37 | void testClientDestruction(); 38 | void testMenusNoXmlFile(); 39 | void testShortcuts(); 40 | void testPopupMenuParent(); 41 | void testSpecificApplicationLanguageQLocale(); 42 | void testSingleModifierQKeySequenceEndsWithPlus(); 43 | void testSaveShortcutsAndRefresh(); 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /autotests/testguiclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2009 David Faure 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 6 | */ 7 | 8 | #ifndef TESTGUICLIENT_H 9 | #define TESTGUICLIENT_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | // because setDOMDocument and setXML are protected 19 | class TestGuiClient : public KXMLGUIClient 20 | { 21 | public: 22 | explicit TestGuiClient(const QByteArray &xml = QByteArray()) 23 | : KXMLGUIClient() 24 | { 25 | if (!xml.isNull()) { 26 | setXML(QString::fromLatin1(xml)); 27 | } 28 | } 29 | void setXMLFilePublic(const QString &file, bool merge = false, bool setXMLDoc = true) 30 | { 31 | setXMLFile(file, merge, setXMLDoc); 32 | } 33 | void setLocalXMLFilePublic(const QString &file) 34 | { 35 | setLocalXMLFile(file); 36 | } 37 | void createGUI(const QByteArray &xml, bool withUiStandards = false) 38 | { 39 | if (withUiStandards) { 40 | setXMLFile(KXMLGUIClient::standardsXmlFileLocation()); 41 | } 42 | 43 | setXML(QString::fromLatin1(xml), true); 44 | } 45 | void mergeXML(const QByteArray &xml) 46 | { 47 | setXML(QString::fromLatin1(xml), true); 48 | } 49 | void createActions(const QStringList &actionNames) 50 | { 51 | KActionCollection *coll = actionCollection(); 52 | for (const QString &actionName : actionNames) { 53 | coll->addAction(actionName)->setText(QStringLiteral("Action")); 54 | } 55 | } 56 | 57 | // Find a toolbar (created by this guiclient) 58 | KToolBar *toolBarByName(const QString &name) 59 | { 60 | // qDebug() << "containers:" << factory()->containers("ToolBar"); 61 | QWidget *toolBarW = factory()->container(name, this); 62 | if (!toolBarW) { 63 | qWarning() << "No toolbar found with name" << name; 64 | } 65 | Q_ASSERT(toolBarW); 66 | KToolBar *toolBar = qobject_cast(toolBarW); 67 | Q_ASSERT(toolBar); 68 | return toolBar; 69 | } 70 | }; 71 | 72 | #endif /* TESTGUICLIENT_H */ 73 | -------------------------------------------------------------------------------- /autotests/testxmlguiwindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2009 David Faure 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 6 | */ 7 | 8 | #ifndef TESTXMLGUIWINDOW_H 9 | #define TESTXMLGUIWINDOW_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | class TestXmlGuiWindow : public KXmlGuiWindow 25 | { 26 | public: 27 | TestXmlGuiWindow(const QByteArray &xml, const char *localXmlFileName) 28 | : KXmlGuiWindow() 29 | { 30 | QVERIFY(m_userFile.open()); 31 | m_userFile.write(xml); 32 | m_fileName = m_userFile.fileName(); // remember filename 33 | Q_ASSERT(!m_fileName.isEmpty()); 34 | m_userFile.close(); // write to disk 35 | // just so that we can use kedittoolbar (because m_fileName is absolute) 36 | setLocalXMLFile(QString::fromLatin1(localXmlFileName)); 37 | } 38 | void createGUI() 39 | { 40 | // This merges in ui_standards.rc, too. 41 | KXmlGuiWindow::createGUI(m_fileName); 42 | } 43 | void createGUIBad() 44 | { 45 | KXmlGuiWindow::createGUI(QStringLiteral("dontexist.rc")); 46 | } 47 | 48 | // Same as in KMainWindow_UnitTest 49 | void reallyResize(int width, int height) 50 | { 51 | const QSize oldSize = size(); 52 | resize(width, height); 53 | // Send the pending resize event (resize() only sets Qt::WA_PendingResizeEvent) 54 | QResizeEvent e(size(), oldSize); 55 | QApplication::sendEvent(this, &e); 56 | } 57 | 58 | // KMainWindow::toolBar(name) creates it if not found, and we don't want that. 59 | // Also this way we test container() rather than just doing a findChild. 60 | KToolBar *toolBarByName(const QString &name) 61 | { 62 | KXMLGUIFactory *factory = guiFactory(); 63 | // qDebug() << "containers:" << factory->containers("ToolBar"); 64 | QWidget *toolBarW = factory->container(name, this); 65 | if (!toolBarW) { 66 | qWarning() << "No toolbar found with name" << name; 67 | } 68 | Q_ASSERT(toolBarW); 69 | KToolBar *toolBar = qobject_cast(toolBarW); 70 | Q_ASSERT(toolBar); 71 | return toolBar; 72 | } 73 | QMenu *menuByName(const QString &name) 74 | { 75 | KXMLGUIFactory *factory = guiFactory(); 76 | QWidget *menuW = factory->container(name, this); 77 | Q_ASSERT(menuW); 78 | QMenu *menu = qobject_cast(menuW); 79 | Q_ASSERT(menu); 80 | return menu; 81 | } 82 | 83 | void createActions(const QStringList &actionNames) 84 | { 85 | KActionCollection *coll = actionCollection(); 86 | for (const QString &actionName : actionNames) { 87 | coll->addAction(actionName)->setText(QStringLiteral("Action")); 88 | } 89 | } 90 | 91 | private: 92 | QTemporaryFile m_userFile; 93 | QString m_fileName; 94 | }; 95 | 96 | #endif /* TESTXMLGUIWINDOW_H */ 97 | -------------------------------------------------------------------------------- /docs/pics/kaboutapplicationdialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/kaboutapplicationdialog.png -------------------------------------------------------------------------------- /docs/pics/kbugreport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/kbugreport.png -------------------------------------------------------------------------------- /docs/pics/kedittoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/kedittoolbar.png -------------------------------------------------------------------------------- /docs/pics/khelpmenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/khelpmenu.png -------------------------------------------------------------------------------- /docs/pics/kkeysequencewidget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/kkeysequencewidget.png -------------------------------------------------------------------------------- /docs/pics/kshortcutsdialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/kshortcutsdialog.png -------------------------------------------------------------------------------- /docs/pics/kshortcutwidget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/docs/pics/kshortcutwidget.png -------------------------------------------------------------------------------- /make_kdepackages_updated.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Script to automatically update the "kdepackages.h" file 5 | # FIXME - This is a slow script. Rewrite me using a smart logic. Thanks! 6 | # 7 | import string 8 | import urllib 9 | import re 10 | 11 | def unescape(text): 12 | text = text.replace(" "," ") 13 | text = text.replace("‑","-") 14 | text = text.replace("&","&") 15 | return text 16 | 17 | 18 | print "Fetching products and components from bugs.kde.org..." 19 | 20 | pkg = open("src/kdepackages.h","w") 21 | pkg.write("// DO NOT EDIT - EDIT products in bugs.kde.org and run ./make_kdepackages_updated.py in kxmlgui to update\n") 22 | pkg.write("const char * const packages[] = {\n") 23 | 24 | data = urllib.urlopen('https://bugs.kde.org/describecomponents.cgi').read() 25 | 26 | for line in string.split(data,'\n'): 27 | print "====parsing:" 28 | #print line 29 | match = re.search('(describecomponents.cgi\?product=.*)">(.*)', line) 30 | if match: 31 | product = match.group(2) 32 | link = match.group(1) 33 | 34 | link = 'https://bugs.kde.org/' + link 35 | data2 = urllib.urlopen(link).read() 36 | 37 | productname = unescape(product) 38 | print productname 39 | pkg.write(" \"" + productname + "\",\n") 40 | data2 = string.split(data2,'\n') 41 | iter = 0 42 | end = len(data2) 43 | print "link: " + link 44 | while( iter < end-1 ): 45 | iter = iter+1 46 | line = data2[iter] 47 | match = re.search('amp;resolution=---">(.*)', line) 48 | if match: 49 | product = match.group(1) 50 | product = unescape(product) 51 | print "found component: " + product 52 | if product!="general": 53 | pkg.write(" \"" + productname + "/" + product + "\",\n") 54 | print productname + "/" + product 55 | 56 | pkg.write("0 };\n") 57 | pkg.close() 58 | -------------------------------------------------------------------------------- /metainfo.yaml: -------------------------------------------------------------------------------- 1 | maintainer: 2 | description: User configurable main windows 3 | tier: 3 4 | type: integration 5 | platforms: 6 | - name: Linux 7 | - name: FreeBSD 8 | - name: Windows 9 | - name: macOS 10 | - name: Android 11 | portingAid: false 12 | deprecated: false 13 | release: true 14 | libraries: 15 | - cmake: "KF6::XmlGui" 16 | cmakename: KF6XmlGui 17 | 18 | public_lib: true 19 | group: Frameworks 20 | subgroup: Tier 3 21 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Manuel Alcaraz Zambrano 2 | # SPDX-License-Identifier: BSD-2-Clause 3 | 4 | set(bindings_library "KXmlGui") 5 | 6 | set(wrapped_header ${CMAKE_CURRENT_SOURCE_DIR}/bindings.h) 7 | set(typesystem_file ${CMAKE_CURRENT_SOURCE_DIR}/bindings.xml) 8 | 9 | set(generated_sources 10 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kxmlgui_module_wrapper.cpp 11 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kaboutapplicationdialog_wrapper.cpp 12 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kaboutplugindialog_wrapper.cpp 13 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kactioncategory_wrapper.cpp 14 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kactioncollection_wrapper.cpp 15 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kbugreport_wrapper.cpp 16 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kedittoolbar_wrapper.cpp 17 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/khelpmenu_wrapper.cpp 18 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kkeysequencewidget_wrapper.cpp 19 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kmainwindow_wrapper.cpp 20 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kshortcutsdialog_wrapper.cpp 21 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kshortcutseditor_wrapper.cpp 22 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kshortcutwidget_wrapper.cpp 23 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/ktoggletoolbaraction_wrapper.cpp 24 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/ktoolbar_wrapper.cpp 25 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/ktooltiphelper_wrapper.cpp 26 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kundoactions_wrapper.cpp 27 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kxmlguibuilder_wrapper.cpp 28 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kxmlguiclient_wrapper.cpp 29 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kxmlguifactory_wrapper.cpp 30 | ${CMAKE_CURRENT_BINARY_DIR}/KXmlGui/kxmlguiwindow_wrapper.cpp) 31 | 32 | ecm_generate_python_bindings( 33 | PACKAGE_NAME ${bindings_library} 34 | VERSION ${KF_VERSION} 35 | WRAPPED_HEADER ${wrapped_header} 36 | TYPESYSTEM ${typesystem_file} 37 | GENERATED_SOURCES ${generated_sources} 38 | DEPENDENCIES KF6::XmlGui 39 | QT_VERSION ${REQUIRED_QT_VERSION} 40 | HOMEPAGE_URL "https://invent.kde.org/frameworks/kxmlgui" 41 | ISSUES_URL "https://bugs.kde.org/describecomponents.cgi?product=frameworks-kxmlgui" 42 | AUTHOR "The KDE Community" 43 | README ../README.md 44 | ) 45 | 46 | target_link_libraries(${bindings_library} PRIVATE KF6::XmlGui) 47 | 48 | execute_process(COMMAND ${Python_EXECUTABLE} -Esc "import sysconfig; print(sysconfig.get_path('platlib', vars={'platbase': '${CMAKE_INSTALL_PREFIX}', 'base': '${CMAKE_INSTALL_PREFIX}'}))" OUTPUT_VARIABLE sysconfig_output) 49 | 50 | string(STRIP ${sysconfig_output} PYTHON_INSTALL_DIR) 51 | 52 | install(TARGETS ${bindings_library} LIBRARY DESTINATION "${PYTHON_INSTALL_DIR}") 53 | 54 | -------------------------------------------------------------------------------- /python/bindings.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: 2024 Manuel Alcaraz Zambrano 2 | // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | -------------------------------------------------------------------------------- /python/bindings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(KF6XmlGui) 2 | add_library(KF6::XmlGui ALIAS KF6XmlGui) 3 | 4 | set_target_properties(KF6XmlGui PROPERTIES 5 | VERSION ${KXMLGUI_VERSION} 6 | SOVERSION ${KXMLGUI_SOVERSION} 7 | EXPORT_NAME XmlGui 8 | ) 9 | 10 | if (HAVE_GLOBALACCEL) 11 | target_link_libraries(KF6XmlGui PRIVATE KF6::GlobalAccel) 12 | endif () 13 | if(WIN32) 14 | target_link_libraries(KF6XmlGui PRIVATE secur32) # GetUserNameEx() 15 | endif() 16 | 17 | configure_file(config-xmlgui.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-xmlgui.h ) 18 | 19 | target_sources(KF6XmlGui PRIVATE 20 | kaboutapplicationdialog.cpp 21 | kaboutkdedialog_p.cpp 22 | kaboutplugindialog.cpp 23 | kabstractaboutdialog_p.cpp 24 | kactioncategory.cpp 25 | kactioncollection.cpp 26 | kactionconflictdetector_p.h 27 | kbugreport.cpp 28 | kedittoolbar.cpp 29 | khelpmenu.cpp 30 | kkeysequencewidget.cpp 31 | klicensedialog_p.cpp 32 | kmainwindow.cpp 33 | kmenumenuhandler_p.cpp 34 | kshortcuteditwidget.cpp 35 | kshortcutschemeseditor.cpp 36 | kshortcutschemeshelper.cpp 37 | kshortcutsdialog.cpp 38 | kshortcutseditor.cpp 39 | kshortcutseditordelegate.cpp 40 | kshortcutseditoritem.cpp 41 | kshortcutwidget.cpp 42 | kswitchlanguagedialog_p.cpp 43 | ktoggletoolbaraction.cpp 44 | ktoolbar.cpp 45 | ktoolbarhandler.cpp 46 | ktoolbarhelper.cpp 47 | ktooltiphelper.cpp 48 | kxmlguibuilder.cpp 49 | kxmlguiclient.cpp 50 | kxmlguifactory.cpp 51 | kxmlguifactory_p.cpp 52 | kxmlguiversionhandler.cpp 53 | kxmlguiwindow.cpp 54 | kundoactions.cpp 55 | kcheckaccelerators.cpp 56 | ) 57 | if (HAVE_QTDBUS) 58 | target_sources(KF6XmlGui PRIVATE kmainwindowiface.cpp) 59 | target_compile_definitions(KF6XmlGui PRIVATE WITH_QTDBUS) 60 | endif() 61 | 62 | # add the resource file 63 | target_sources(KF6XmlGui PRIVATE 64 | kxmlgui.qrc 65 | ) 66 | 67 | ecm_qt_declare_logging_category(KF6XmlGui 68 | HEADER debug.h 69 | IDENTIFIER DEBUG_KXMLGUI 70 | CATEGORY_NAME kf.xmlgui 71 | OLD_CATEGORY_NAMES kf5.kxmlgui 72 | DESCRIPTION "KXmlGui" 73 | EXPORT KXMLGUI 74 | ) 75 | 76 | ki18n_wrap_ui(KF6XmlGui 77 | kshortcutsdialog.ui 78 | kshortcutwidget.ui 79 | ) 80 | 81 | ecm_generate_export_header(KF6XmlGui 82 | BASE_NAME KXmlGui 83 | GROUP_BASE_NAME KF 84 | VERSION ${KF_VERSION} 85 | USE_VERSION_HEADER 86 | DEPRECATED_BASE_VERSION 0 87 | DEPRECATION_VERSIONS 6.9 6.12 6.15 88 | EXCLUDE_DEPRECATED_BEFORE_AND_AT ${EXCLUDE_DEPRECATED_BEFORE_AND_AT} 89 | ) 90 | 91 | target_include_directories(KF6XmlGui INTERFACE "$") 92 | 93 | target_include_directories(KF6XmlGui PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) 94 | 95 | target_link_libraries(KF6XmlGui 96 | PUBLIC 97 | Qt6::Xml #To parse the configuration (QDomDocument etc) 98 | Qt6::Widgets #QWidget is used everywhere 99 | KF6::ConfigCore #Reading config for ToolbarIcons, Shortcut Schemes... 100 | KF6::ConfigWidgets #KStandardAction 101 | KF6::GuiAddons #KKeySequenceWidget 102 | PRIVATE 103 | Qt6::Network #QNetworkAccessManager in kaboutapplicationpersonmodel_p 104 | Qt6::PrintSupport #QPrinter in kshortcutseditor 105 | Qt6::CorePrivate #QSystemLocale in initializeLanguages 106 | KF6::CoreAddons #KAboutData 107 | KF6::WidgetsAddons #KToggleAction 108 | KF6::ItemViews #KWidgetItemDelegate in KAboutApplicationPersonListDelegate 109 | KF6::I18n #i18n and i18nc in many places 110 | KF6::IconThemes #KIconLoader and KIconThemes in KToolBar 111 | KF6::IconWidgets #KIconDialog 112 | ) 113 | if (HAVE_QTDBUS) 114 | target_link_libraries(KF6XmlGui PUBLIC Qt6::DBus) #QDBus connect to signal in KToolBar 115 | endif() 116 | 117 | ecm_generate_headers(KXmlGui_HEADERS 118 | HEADER_NAMES 119 | KAboutApplicationDialog 120 | KAboutPluginDialog 121 | KActionCategory 122 | KActionCollection 123 | KBugReport 124 | KEditToolBar 125 | KHelpMenu 126 | KKeySequenceWidget 127 | KMainWindow 128 | KShortcutsDialog 129 | KShortcutsEditor 130 | KShortcutWidget 131 | KToggleToolBarAction 132 | KToolBar 133 | KToolTipHelper 134 | KXMLGUIBuilder 135 | KXMLGUIClient 136 | KXMLGUIFactory 137 | KXmlGuiWindow 138 | KUndoActions 139 | 140 | REQUIRED_HEADERS KXmlGui_HEADERS 141 | ) 142 | 143 | ecm_generate_qdoc(KF6XmlGui kxmlgui.qdocconf) 144 | 145 | install(TARGETS KF6XmlGui EXPORT KF6XmlGuiTargets ${KF_INSTALL_TARGETS_DEFAULT_ARGS}) 146 | 147 | install(FILES 148 | ${CMAKE_CURRENT_BINARY_DIR}/kxmlgui_export.h 149 | ${KXmlGui_HEADERS} 150 | DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF}/KXmlGui COMPONENT Devel 151 | ) 152 | 153 | if(BUILD_DESIGNERPLUGIN) 154 | add_subdirectory(designer) 155 | endif() 156 | 157 | ecm_qt_install_logging_categories( 158 | EXPORT KXMLGUI 159 | FILE kxmlgui.categories 160 | DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR} 161 | ) 162 | -------------------------------------------------------------------------------- /src/Messages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Invoke the extractrc script on all .ui, .rc, and .kcfg files in the sources. 4 | # The results are stored in a pseudo .cpp file to be picked up by xgettext. 5 | lst=`find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` 6 | if [ -n "$lst" ] ; then 7 | $EXTRACTRC $lst >> rc.cpp 8 | fi 9 | 10 | # Extract strings from all source files. 11 | # If your framework depends on KI18n, use $XGETTEXT. If it uses Qt translation 12 | # system, use $EXTRACT_TR_STRINGS. 13 | $XGETTEXT `find . -name \*.cpp -o -name \*.h -o -name \*.qml` -o $podir/kxmlgui6.pot 14 | -------------------------------------------------------------------------------- /src/TODO: -------------------------------------------------------------------------------- 1 | - KActionCollection::addAction with a previously added action should replace the old one. For consistency with 2 | the Qt associative containers (and remember to add an autotest :) 3 | -------------------------------------------------------------------------------- /src/config-xmlgui.h.cmake: -------------------------------------------------------------------------------- 1 | /* KF6GlobalAccel available */ 2 | #cmakedefine01 HAVE_GLOBALACCEL 3 | -------------------------------------------------------------------------------- /src/designer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(ECMAddQtDesignerPlugin) 2 | 3 | ecm_qtdesignerplugin_widget(KKeySequenceWidget 4 | TOOLTIP "QKeySequence picker widget. (KF6)" 5 | WHATSTHIS "A widget to pick a QKeySequence." 6 | GROUP "Buttons (KF6)" 7 | ) 8 | ecm_qtdesignerplugin_widget(KShortcutsEditor 9 | TOOLTIP "Shortcuts editor widget. (KF6)" 10 | WHATSTHIS "A widget to edit a list of shortcuts." 11 | GROUP "Input (KF6)" 12 | ) 13 | ecm_qtdesignerplugin_widget(KShortcutWidget 14 | TOOLTIP "Shortcut picker widget. (KF6)" 15 | WHATSTHIS "A widget to pick a KShortcut." 16 | GROUP "Buttons (KF6)" 17 | ) 18 | 19 | ecm_add_qtdesignerplugin(kxmlguiwidgets 20 | NAME KXmlGuiWidgets 21 | OUTPUT_NAME kxmlgui6widgets 22 | WIDGETS 23 | KKeySequenceWidget 24 | KShortcutsEditor 25 | KShortcutWidget 26 | LINK_LIBRARIES 27 | KF6::XmlGui 28 | INSTALL_DESTINATION "${KDE_INSTALL_QTPLUGINDIR}/designer" 29 | COMPONENT Devel 30 | ) 31 | -------------------------------------------------------------------------------- /src/kaboutapplicationdialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Urs Wolfer 4 | SPDX-FileCopyrightText: 2008 Friedrich W. H. Kossebau 5 | SPDX-FileCopyrightText: 2010 Teo Mrnjavac 6 | SPDX-FileCopyrightText: 2021 Julius Künzel 7 | 8 | Parts of this class have been take from the KAboutApplication class, which was: 9 | SPDX-FileCopyrightText: 2000 Waldo Bastian 10 | SPDX-FileCopyrightText: 2000 Espen Sand 11 | 12 | SPDX-License-Identifier: LGPL-2.0-only 13 | */ 14 | 15 | #include "kaboutapplicationdialog.h" 16 | 17 | #include "kabstractaboutdialog_p.h" 18 | #include "klicensedialog_p.h" 19 | // KF 20 | #include 21 | #include 22 | #include 23 | // Qt 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | class KAboutApplicationDialogPrivate : public KAbstractAboutDialogPrivate 30 | { 31 | public: 32 | KAboutApplicationDialogPrivate(const KAboutData &aboutData, KAboutApplicationDialog *parent) 33 | : q(parent) 34 | , aboutData(aboutData) 35 | { 36 | } 37 | 38 | void init(KAboutApplicationDialog::Options opt); 39 | 40 | private: 41 | KAboutApplicationDialog *const q; 42 | 43 | const KAboutData aboutData; 44 | }; 45 | 46 | KAboutApplicationDialog::KAboutApplicationDialog(const KAboutData &aboutData, QWidget *parent) 47 | : KAboutApplicationDialog(aboutData, NoOptions, parent) 48 | { 49 | } 50 | 51 | KAboutApplicationDialog::KAboutApplicationDialog(const KAboutData &aboutData, Options opt, QWidget *parent) 52 | : QDialog(parent) 53 | , d(new KAboutApplicationDialogPrivate(aboutData, this)) 54 | { 55 | d->init(opt); 56 | } 57 | 58 | void KAboutApplicationDialogPrivate::init(KAboutApplicationDialog::Options opt) 59 | { 60 | q->setWindowTitle(i18nc("@title:window", "About %1", aboutData.displayName())); 61 | 62 | // Set up the title widget... 63 | QIcon titleIcon; 64 | if (aboutData.programLogo().canConvert()) { 65 | titleIcon = QIcon(aboutData.programLogo().value()); 66 | } else if (aboutData.programLogo().canConvert()) { 67 | titleIcon = QIcon(QPixmap::fromImage(aboutData.programLogo().value())); 68 | } else if (aboutData.programLogo().canConvert()) { 69 | titleIcon = aboutData.programLogo().value(); 70 | } else { 71 | titleIcon = qApp->windowIcon(); 72 | } 73 | 74 | QWidget *titleWidget = createTitleWidget(titleIcon, aboutData.displayName(), aboutData.version(), q); 75 | 76 | // Then the tab bar... 77 | QTabWidget *tabWidget = new QTabWidget; 78 | tabWidget->setUsesScrollButtons(false); 79 | 80 | // Set up the first page... 81 | QWidget *aboutWidget = createAboutWidget(aboutData.shortDescription(), // 82 | aboutData.otherText(), 83 | aboutData.copyrightStatement(), 84 | aboutData.homepage(), 85 | aboutData.licenses(), 86 | q); 87 | 88 | tabWidget->addTab(aboutWidget, i18nc("@title:tab", "About")); 89 | 90 | // Components page 91 | if (!(opt & KAboutApplicationDialog::HideLibraries)) { 92 | QWidget *componentWidget = createComponentWidget(aboutData.components(), q); 93 | 94 | const QString componentPageTitle = i18nc("@title:tab", "Components"); 95 | tabWidget->addTab(componentWidget, componentPageTitle); 96 | } 97 | 98 | // And here we go, authors page... 99 | const int authorCount = aboutData.authors().count(); 100 | if (authorCount) { 101 | QWidget *authorWidget = 102 | createAuthorsWidget(aboutData.authors(), aboutData.customAuthorTextEnabled(), aboutData.customAuthorRichText(), aboutData.bugAddress(), q); 103 | 104 | const QString authorPageTitle = i18ncp("@title:tab", "Author", "Authors", authorCount); 105 | tabWidget->addTab(authorWidget, authorPageTitle); 106 | } 107 | 108 | // And credits page... 109 | if (!aboutData.credits().isEmpty()) { 110 | QWidget *creditWidget = createCreditWidget(aboutData.credits(), q); 111 | tabWidget->addTab(creditWidget, i18nc("@title:tab", "Thanks To")); 112 | } 113 | 114 | // Finally, the optional translators page... 115 | if (!(opt & KAboutApplicationDialog::HideTranslators) && !aboutData.translators().isEmpty()) { 116 | QWidget *translatorWidget = createTranslatorsWidget(aboutData.translators(), q); 117 | 118 | tabWidget->addTab(translatorWidget, i18nc("@title:tab", "Translation")); 119 | } 120 | 121 | createForm(titleWidget, tabWidget, q); 122 | } 123 | 124 | KAboutApplicationDialog::~KAboutApplicationDialog() 125 | { 126 | // The delegate wants to be deleted before the items it created, otherwise 127 | // complains bitterly about it 128 | qDeleteAll(findChildren()); 129 | } 130 | 131 | #include "moc_kaboutapplicationdialog.cpp" 132 | -------------------------------------------------------------------------------- /src/kaboutapplicationdialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Urs Wolfer 4 | 5 | Parts of this class have been take from the KAboutApplication class, which was: 6 | SPDX-FileCopyrightText: 2000 Waldo Bastian 7 | SPDX-FileCopyrightText: 2000 Espen Sand 8 | 9 | SPDX-License-Identifier: LGPL-2.0-only 10 | */ 11 | 12 | #ifndef KABOUT_APPLICATION_DIALOG_H 13 | #define KABOUT_APPLICATION_DIALOG_H 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | class KAboutData; 21 | 22 | /*! 23 | * \class KAboutApplicationDialog 24 | * \inmodule KXmlGui 25 | * 26 | * \brief Standard "About Application" dialog box. 27 | * 28 | * This class provides the standard "About Application" dialog box 29 | * that is used by KHelpMenu. It uses the information of the global 30 | * KAboutData that is specified at the start of your program in 31 | * main(). Normally you should not use this class directly but rather 32 | * the KHelpMenu class or even better just subclass your toplevel 33 | * window from KMainWindow. If you do the latter, the help menu and 34 | * thereby this dialog box is available through the 35 | * KMainWindow::helpMenu() function. 36 | * 37 | * \image kaboutapplicationdialog.png "KAboutApplicationDialog" 38 | */ 39 | 40 | class KXMLGUI_EXPORT KAboutApplicationDialog : public QDialog 41 | { 42 | Q_OBJECT 43 | public: 44 | /*! 45 | * \enum KAboutApplicationDialog::Option 46 | * 47 | * Defines some options that can be applied to the about dialog. 48 | * 49 | * \value NoOptions 50 | * Shows the standard about dialog. 51 | * \value HideTranslators 52 | * Hides the translators tab. 53 | * \value HideLibraries 54 | * Since 5.77, hides the libraries tab. 55 | * Since 5.87, hides the components tab (which replaces the libraries tab). 56 | * \since 4.4 57 | */ 58 | enum Option { 59 | NoOptions = 0x0, 60 | HideTranslators = 0x1, 61 | HideLibraries = 0x2, 62 | }; 63 | Q_DECLARE_FLAGS(Options, Option) 64 | Q_FLAG(Options) 65 | 66 | /*! 67 | * Constructs a fully featured "About Application" dialog box 68 | * using existing \a aboutData and the specified \a opts. 69 | * 70 | * You should set the toplevel window as the parent 71 | * so that the dialog becomes centered. 72 | * 73 | * \sa Options 74 | * 75 | * \since 4.4 76 | */ 77 | explicit KAboutApplicationDialog(const KAboutData &aboutData, Options opts, QWidget *parent = nullptr); 78 | 79 | /*! 80 | * \brief Constructs a fully featured "About Application" dialog box 81 | * using existing \a aboutData. 82 | * 83 | * You should set the toplevel window as the \a parent 84 | * so that the dialog becomes centered. 85 | */ 86 | explicit KAboutApplicationDialog(const KAboutData &aboutData, QWidget *parent = nullptr); 87 | 88 | ~KAboutApplicationDialog() override; 89 | 90 | private: 91 | std::unique_ptr const d; 92 | 93 | Q_DISABLE_COPY(KAboutApplicationDialog) 94 | }; 95 | 96 | Q_DECLARE_OPERATORS_FOR_FLAGS(KAboutApplicationDialog::Options) 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/kaboutkdedialog_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Urs Wolfer 4 | 5 | Parts of this class have been take from the KAboutKDE class, which was 6 | SPDX-FileCopyrightText: 2000 Espen Sand 7 | 8 | SPDX-License-Identifier: LGPL-2.0-only 9 | */ 10 | 11 | #ifndef KABOUT_KDE_DIALOG_H 12 | #define KABOUT_KDE_DIALOG_H 13 | 14 | #include 15 | 16 | namespace KDEPrivate 17 | { 18 | /*! 19 | * \brief Standard "About KDE" dialog box 20 | * 21 | * This class provides the standard "About KDE" dialog box that is used 22 | * in KHelpMenu. Normally you should not use this class directly, but 23 | * rather the KHelpMenu class or even better just subclass your 24 | * toplevel window from KMainWindow. If you do the latter, the help 25 | * menu and thereby this dialog box is available through the 26 | * KMainWindow::helpMenu() function. 27 | * 28 | * \internal 29 | */ 30 | 31 | class KAboutKdeDialog : public QDialog 32 | { 33 | Q_OBJECT 34 | 35 | public: 36 | /*! 37 | * Constructor. Creates a fully featured "About KDE" dialog box. 38 | * Note that this dialog is made modeless in the KHelpMenu class so 39 | * the users may expect a modeless dialog. 40 | * 41 | * \a parent The parent of the dialog box. You should use the 42 | * toplevel window so that the dialog becomes centered. 43 | */ 44 | explicit KAboutKdeDialog(QWidget *parent = nullptr); 45 | 46 | private: 47 | class Private; 48 | Private *const d; 49 | Q_DISABLE_COPY(KAboutKdeDialog) 50 | }; 51 | 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/kaboutplugindialog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Urs Wolfer 4 | SPDX-FileCopyrightText: 2008, 2019 Friedrich W. H. Kossebau 5 | SPDX-FileCopyrightText: 2010 Teo Mrnjavac 6 | 7 | Parts of this class have been take from the KAboutApplication class, which was 8 | SPDX-FileCopyrightText: 2000 Waldo Bastian 9 | SPDX-FileCopyrightText: 2000 Espen Sand 10 | 11 | SPDX-License-Identifier: LGPL-2.0-only 12 | */ 13 | 14 | #include "kaboutplugindialog.h" 15 | 16 | #include "kabstractaboutdialog_p.h" 17 | // KF 18 | #include 19 | #include 20 | #include 21 | #include 22 | // Qt 23 | #include 24 | #include 25 | 26 | class KAboutPluginDialogPrivate : public KAbstractAboutDialogPrivate 27 | { 28 | public: 29 | KAboutPluginDialogPrivate(const KPluginMetaData &pluginMetaData, KAboutPluginDialog *parent) 30 | : q(parent) 31 | , pluginMetaData(pluginMetaData) 32 | , pluginLicense(KAboutLicense::byKeyword(pluginMetaData.license())) 33 | { 34 | } 35 | 36 | void init(KAboutPluginDialog::Options opt); 37 | 38 | public: 39 | KAboutPluginDialog *const q; 40 | 41 | const KPluginMetaData pluginMetaData; 42 | const KAboutLicense pluginLicense; 43 | }; 44 | 45 | KAboutPluginDialog::KAboutPluginDialog(const KPluginMetaData &pluginMetaData, QWidget *parent) 46 | : KAboutPluginDialog(pluginMetaData, NoOptions, parent) 47 | { 48 | } 49 | 50 | KAboutPluginDialog::KAboutPluginDialog(const KPluginMetaData &pluginMetaData, Options opt, QWidget *parent) 51 | : QDialog(parent) 52 | , d(new KAboutPluginDialogPrivate(pluginMetaData, this)) 53 | { 54 | d->init(opt); 55 | } 56 | 57 | KAboutPluginDialog::~KAboutPluginDialog() 58 | { 59 | // The delegates want to be deleted before the items it created 60 | qDeleteAll(findChildren()); 61 | } 62 | 63 | void KAboutPluginDialogPrivate::init(KAboutPluginDialog::Options opt) 64 | { 65 | q->setWindowTitle(i18nc("@title:window", "About %1", pluginMetaData.name())); 66 | 67 | // Set up the title widget... 68 | const QIcon pluginIcon = !pluginMetaData.iconName().isEmpty() ? QIcon::fromTheme(pluginMetaData.iconName()) : qApp->windowIcon(); 69 | QWidget *titleWidget = createTitleWidget(pluginIcon, pluginMetaData.name(), pluginMetaData.version(), q); 70 | 71 | // Then the tab bar... 72 | QTabWidget *tabWidget = new QTabWidget; 73 | tabWidget->setUsesScrollButtons(false); 74 | 75 | QString extraInformation; 76 | // Set up the first page... 77 | QWidget *aboutWidget = createAboutWidget(pluginMetaData.description(), // 78 | extraInformation, 79 | pluginMetaData.copyrightText(), 80 | pluginMetaData.website(), 81 | {pluginLicense}, 82 | q); 83 | 84 | tabWidget->addTab(aboutWidget, i18nc("@title:tab", "About")); 85 | 86 | // And here we go, authors page... 87 | const int authorCount = pluginMetaData.authors().count(); 88 | if (authorCount) { 89 | // TODO: add bug report address to plugin metadata 90 | QWidget *authorWidget = createAuthorsWidget(pluginMetaData.authors(), false, QString(), QString(), q); 91 | 92 | const QString authorPageTitle = i18ncp("@title:tab", "Author", "Authors", authorCount); 93 | tabWidget->addTab(authorWidget, authorPageTitle); 94 | } 95 | 96 | // And credits page... 97 | if (!pluginMetaData.otherContributors().isEmpty()) { 98 | QWidget *creditWidget = createCreditWidget(pluginMetaData.otherContributors(), q); 99 | tabWidget->addTab(creditWidget, i18nc("@title:tab", "Thanks To")); 100 | } 101 | 102 | // Finally, the optional translators page... 103 | if (!(opt & KAboutPluginDialog::HideTranslators) && !pluginMetaData.translators().isEmpty()) { 104 | QWidget *translatorWidget = createTranslatorsWidget(pluginMetaData.translators(), q); 105 | tabWidget->addTab(translatorWidget, i18nc("@title:tab", "Translation")); 106 | } 107 | 108 | createForm(titleWidget, tabWidget, q); 109 | } 110 | 111 | #include "moc_kaboutplugindialog.cpp" 112 | -------------------------------------------------------------------------------- /src/kaboutplugindialog.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only 6 | */ 7 | 8 | #ifndef KABOUT_PLUGIN_DIALOG_H 9 | #define KABOUT_PLUGIN_DIALOG_H 10 | 11 | #include 12 | // Qt 13 | #include 14 | #include 15 | 16 | class KPluginMetaData; 17 | class KAboutPluginDialogPrivate; 18 | 19 | /*! 20 | * \class KAboutPluginDialog 21 | * \inmodule KXMLGui 22 | * 23 | * \brief This class provides a standard "About Plugin" dialog box. 24 | * 25 | * \since 5.65 26 | */ 27 | class KXMLGUI_EXPORT KAboutPluginDialog : public QDialog 28 | { 29 | Q_OBJECT 30 | 31 | public: 32 | /*! 33 | * \enum KAboutPluginDialog::Option 34 | * 35 | * Defines some options which can be applied to the about dialog. 36 | * 37 | * \value NoOptions 38 | * Show the standard about dialog. 39 | * \value HideTranslators 40 | * Don't show the translators tab. 41 | */ 42 | enum Option { 43 | NoOptions = 0x0, 44 | HideTranslators = 0x1, 45 | }; 46 | Q_DECLARE_FLAGS(Options, Option) 47 | Q_FLAG(Options) 48 | 49 | /*! 50 | * \brief Constructs a fully featured "About Plugin" dialog box 51 | * using the provided \a pluginMetaData and extra \a options. 52 | * 53 | * \a pluginMetaData The data about the plugin to show in the dialog. 54 | * 55 | * \a options Options to apply, such as hiding the translators tab. 56 | * 57 | * \a parent The parent of the dialog box. 58 | * Use the toplevel window so that the dialog becomes centered. 59 | */ 60 | explicit KAboutPluginDialog(const KPluginMetaData &pluginMetaData, Options options, QWidget *parent = nullptr); 61 | 62 | /*! 63 | * Constructs a default "About Plugin" dialog box 64 | * using the provided \a pluginMetaData. 65 | * 66 | * \a pluginMetaData The data about the plugin to show in the dialog. 67 | * 68 | * \a parent The parent of the dialog box. 69 | * Use the toplevel window so that the dialog becomes centered. 70 | */ 71 | explicit KAboutPluginDialog(const KPluginMetaData &pluginMetaData, QWidget *parent = nullptr); 72 | 73 | ~KAboutPluginDialog() override; 74 | 75 | private: 76 | std::unique_ptr const d; 77 | 78 | Q_DISABLE_COPY(KAboutPluginDialog) 79 | }; 80 | 81 | Q_DECLARE_OPERATORS_FOR_FLAGS(KAboutPluginDialog::Options) 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/kabstractaboutdialog_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only 6 | */ 7 | 8 | #ifndef KABSTRACTABOUTDIALOG_P_H 9 | #define KABSTRACTABOUTDIALOG_P_H 10 | 11 | #include 12 | 13 | class QDialog; 14 | class QWidget; 15 | class QIcon; 16 | 17 | /*! 18 | * \internal 19 | * 20 | * Private base class implementing util methods for assembling an About dialog. 21 | */ 22 | class KAbstractAboutDialogPrivate 23 | { 24 | public: 25 | KAbstractAboutDialogPrivate() = default; 26 | ~KAbstractAboutDialogPrivate() = default; 27 | 28 | public: 29 | QWidget *createTitleWidget(const QIcon &icon, const QString &displayName, const QString &version, QWidget *parent); 30 | QWidget *createAboutWidget(const QString &shortDescription, 31 | const QString &otherText, 32 | const QString ©rightStatement, 33 | const QString &homepage, 34 | const QList &licenses, 35 | QWidget *parent); 36 | QWidget *createComponentWidget(const QList &components, QWidget *parent); 37 | QWidget *createAuthorsWidget(const QList &authors, 38 | bool customAuthorTextEnabled, 39 | const QString &customAuthorRichText, 40 | const QString &bugAddress, 41 | QWidget *parent); 42 | QWidget *createCreditWidget(const QList &credits, QWidget *parent); 43 | QWidget *createTranslatorsWidget(const QList &translators, QWidget *parent); 44 | void createForm(QWidget *titleWidget, QWidget *tabWidget, QDialog *dialog); 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/kactioncategory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2008 Michael Jansen 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "kactioncategory.h" 8 | 9 | #include 10 | 11 | struct KActionCategoryPrivate { 12 | KActionCategoryPrivate(KActionCategory *host); 13 | 14 | //! Our host 15 | KActionCategory *q; 16 | 17 | //! The text for this category 18 | QString text; 19 | 20 | //! List of actions 21 | QList actions; 22 | 23 | }; // class KActionCategoryPrivate 24 | 25 | KActionCategory::KActionCategory(const QString &text, KActionCollection *parent) 26 | : QObject(parent) 27 | , d(new KActionCategoryPrivate(this)) 28 | { 29 | d->text = text; 30 | } 31 | 32 | KActionCategory::~KActionCategory() = default; 33 | 34 | const QList KActionCategory::actions() const 35 | { 36 | return d->actions; 37 | } 38 | 39 | QAction *KActionCategory::addAction(const QString &name, QAction *action) 40 | { 41 | collection()->addAction(name, action); 42 | addAction(action); 43 | return action; 44 | } 45 | 46 | #if KXMLGUI_BUILD_DEPRECATED_SINCE(6, 9) 47 | QAction *KActionCategory::addAction(KStandardAction::StandardAction actionType, const QObject *receiver, const char *member) 48 | { 49 | QAction *action = collection()->addAction(actionType, receiver, member); 50 | addAction(action); 51 | return action; 52 | } 53 | #endif 54 | 55 | #if KXMLGUI_BUILD_DEPRECATED_SINCE(6, 9) 56 | QAction *KActionCategory::addAction(KStandardAction::StandardAction actionType, const QString &name, const QObject *receiver, const char *member) 57 | { 58 | QAction *action = collection()->addAction(actionType, name, receiver, member); 59 | addAction(action); 60 | return action; 61 | } 62 | #endif 63 | 64 | #if KXMLGUI_ENABLE_DEPRECATED_SINCE(6, 9) 65 | QAction *KActionCategory::addAction(const QString &name, const QObject *receiver, const char *member) 66 | { 67 | QAction *action = collection()->addAction(name, receiver, member); 68 | addAction(action); 69 | return action; 70 | } 71 | #endif 72 | 73 | QAction *KActionCategory::addAction(KStandardActions::StandardAction actionType) 74 | { 75 | QAction *action = collection()->addAction(actionType); 76 | addAction(action); 77 | return action; 78 | } 79 | 80 | QAction *KActionCategory::addAction(KStandardActions::StandardAction actionType, const QString &name) 81 | { 82 | QAction *action = collection()->addAction(actionType, name); 83 | addAction(action); 84 | return action; 85 | } 86 | 87 | void KActionCategory::addAction(QAction *action) 88 | { 89 | // Only add the action if wasn't added earlier. 90 | if (!d->actions.contains(action)) { 91 | d->actions.append(action); 92 | } 93 | } 94 | 95 | KActionCollection *KActionCategory::collection() const 96 | { 97 | return qobject_cast(parent()); 98 | } 99 | 100 | QString KActionCategory::text() const 101 | { 102 | return d->text; 103 | } 104 | 105 | void KActionCategory::setText(const QString &text) 106 | { 107 | d->text = text; 108 | } 109 | 110 | void KActionCategory::unlistAction(QAction *action) 111 | { 112 | // ATTENTION: 113 | // This method is called from KActionCollection with an QObject formerly 114 | // known as a QAction during _k_actionDestroyed(). So don't do fancy stuff 115 | // here that needs a real QAction! 116 | d->actions.erase(std::remove(d->actions.begin(), d->actions.end(), action), d->actions.end()); 117 | } 118 | 119 | KActionCategoryPrivate::KActionCategoryPrivate(KActionCategory *host) 120 | : q(host) 121 | { 122 | } 123 | 124 | #include "moc_kactioncategory.cpp" 125 | -------------------------------------------------------------------------------- /src/kactionconflictdetector_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 1999 Reginald Stadlbauer 4 | SPDX-FileCopyrightText: 1999 Simon Hausmann 5 | SPDX-FileCopyrightText: 2000 Nicolas Hadacek 6 | SPDX-FileCopyrightText: 2000 Kurt Granroth 7 | SPDX-FileCopyrightText: 2000 Michael Koch 8 | SPDX-FileCopyrightText: 2001 Holger Freyther 9 | SPDX-FileCopyrightText: 2002 Ellis Whitehead 10 | SPDX-FileCopyrightText: 2002 Joseph Wenninger 11 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda 12 | 13 | SPDX-License-Identifier: LGPL-2.0-only 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | class KActionConflictDetector : public QObject 23 | { 24 | Q_OBJECT 25 | public: 26 | explicit KActionConflictDetector(QObject *parent = nullptr) 27 | : QObject(parent) 28 | { 29 | } 30 | 31 | bool eventFilter(QObject *watched, QEvent *event) override 32 | { 33 | if (event->type() == QEvent::Shortcut && qobject_cast(watched)) { 34 | QShortcutEvent *se = static_cast(event); 35 | if (se->isAmbiguous()) { 36 | KMessageBox::information(nullptr, // No widget to be seen around here 37 | i18n("The key sequence '%1' is ambiguous. Use 'Configure Keyboard Shortcuts'\n" 38 | "from the 'Settings' menu to solve the ambiguity.\n" 39 | "No action will be triggered.", 40 | se->key().toString(QKeySequence::NativeText)), 41 | i18nc("@title:window", "Ambiguous shortcut detected")); 42 | return true; 43 | } 44 | } 45 | 46 | return QObject::eventFilter(watched, event); 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /src/kbugreport.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 1999 David Faure 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef KBUGREPORT_H 9 | #define KBUGREPORT_H 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | class KAboutData; 16 | class KBugReportPrivate; 17 | 18 | /*! 19 | * \class KBugReport 20 | * \inmodule KXmlGui 21 | * 22 | * \brief A dialog box for sending bug reports. 23 | * 24 | * All the information needed by the dialog box 25 | * (program name, version, bug-report address, etc.) 26 | * comes from the KAboutData class. 27 | * Make sure you create an instance of KAboutData and call 28 | * KAboutData::setApplicationData(). 29 | * 30 | * \image kbugreport.png "KBugReport" 31 | */ 32 | class KXMLGUI_EXPORT KBugReport : public QDialog 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | /*! 38 | * \brief Creates a bug-report dialog using information derived from 39 | * \a aboutData as a child of \a parent. 40 | * 41 | * Note that you shouldn't have to do this manually, 42 | * since KHelpMenu takes care of the menu item 43 | * for "Report Bug..." and of creating a KBugReport dialog. 44 | */ 45 | explicit KBugReport(const KAboutData &aboutData, QWidget *parent = nullptr); 46 | 47 | /*! 48 | * \brief Destructor. 49 | */ 50 | ~KBugReport() override; 51 | 52 | /*! 53 | * \brief OK has been clicked. 54 | */ 55 | void accept() override; 56 | 57 | protected: 58 | /*! 59 | * \brief Attempt to e-mail the bug report. 60 | * 61 | * Returns true on success. 62 | */ 63 | bool sendBugReport(); 64 | 65 | private: 66 | friend class KBugReportPrivate; 67 | std::unique_ptr const d; 68 | 69 | Q_DISABLE_COPY(KBugReport) 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/kcheckaccelerators.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer 4 | SPDX-FileCopyrightText: 1998, 1999, 2000 KDE Team 5 | SPDX-FileCopyrightText: 2008 Nick Shaforostoff 6 | 7 | SPDX-License-Identifier: LGPL-2.0-or-later 8 | */ 9 | 10 | #include "kcheckaccelerators.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | KCheckAccelerators::KCheckAccelerators(QObject *parent, int key_, bool autoCheck_) 39 | : QObject(parent) 40 | , key(key_) 41 | , block(false) 42 | , autoCheck(autoCheck_) 43 | , drklash(nullptr) 44 | { 45 | setObjectName(QStringLiteral("kapp_accel_filter")); 46 | 47 | KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Development")); 48 | alwaysShow = cg.readEntry("AlwaysShowCheckAccelerators", false); 49 | 50 | parent->installEventFilter(this); 51 | connect(&autoCheckTimer, &QTimer::timeout, this, &KCheckAccelerators::autoCheckSlot); 52 | } 53 | 54 | bool KCheckAccelerators::eventFilter(QObject * /*obj*/, QEvent *e) 55 | { 56 | if (block) { 57 | return false; 58 | } 59 | 60 | switch (e->type()) { // just simplify debuggin 61 | case QEvent::ShortcutOverride: 62 | if (key && (static_cast(e)->key() == key)) { 63 | block = true; 64 | checkAccelerators(false); 65 | block = false; 66 | e->accept(); 67 | return true; 68 | } 69 | break; 70 | case QEvent::ChildAdded: 71 | case QEvent::ChildRemoved: 72 | // Only care about widgets; this also avoids starting the timer in other 73 | // threads 74 | if (!static_cast(e)->child()->isWidgetType()) { 75 | break; 76 | } 77 | Q_FALLTHROUGH(); 78 | // fall-through 79 | case QEvent::Resize: 80 | case QEvent::LayoutRequest: 81 | case QEvent::WindowActivate: 82 | case QEvent::WindowDeactivate: 83 | if (autoCheck) { 84 | autoCheckTimer.setSingleShot(true); 85 | autoCheckTimer.start(20); // 20 ms 86 | } 87 | return false; 88 | case QEvent::Timer: 89 | case QEvent::MouseMove: 90 | case QEvent::Paint: 91 | return false; 92 | default: 93 | // qCDebug(DEBUG_KXMLGUI) << "KCheckAccelerators::eventFilter " << e->type() 94 | // << " " << autoCheck; 95 | break; 96 | } 97 | return false; 98 | } 99 | 100 | void KCheckAccelerators::autoCheckSlot() 101 | { 102 | if (block) { 103 | autoCheckTimer.setSingleShot(true); 104 | autoCheckTimer.start(20); 105 | return; 106 | } 107 | block = true; 108 | checkAccelerators(!alwaysShow); 109 | block = false; 110 | } 111 | 112 | void KCheckAccelerators::createDialog(QWidget *actWin, bool automatic) 113 | { 114 | if (drklash) { 115 | return; 116 | } 117 | 118 | drklash = new QDialog(actWin); 119 | drklash->setAttribute(Qt::WA_DeleteOnClose); 120 | drklash->setObjectName(QStringLiteral("kapp_accel_check_dlg")); 121 | drklash->setWindowTitle(i18nc("@title:window", "Dr. Klash' Accelerator Diagnosis")); 122 | drklash->resize(500, 460); 123 | QVBoxLayout *layout = new QVBoxLayout(drklash); 124 | drklash_view = new QTextBrowser(drklash); 125 | layout->addWidget(drklash_view); 126 | QCheckBox *disableAutoCheck = nullptr; 127 | if (automatic) { 128 | disableAutoCheck = new QCheckBox(i18nc("@option:check", "Disable automatic checking"), drklash); 129 | connect(disableAutoCheck, &QCheckBox::toggled, this, &KCheckAccelerators::slotDisableCheck); 130 | layout->addWidget(disableAutoCheck); 131 | } 132 | QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, drklash); 133 | layout->addWidget(buttonBox); 134 | connect(buttonBox, &QDialogButtonBox::rejected, drklash, &QDialog::close); 135 | if (disableAutoCheck) { 136 | disableAutoCheck->setFocus(); 137 | } else { 138 | drklash_view->setFocus(); 139 | } 140 | } 141 | 142 | void KCheckAccelerators::slotDisableCheck(bool on) 143 | { 144 | autoCheck = !on; 145 | if (!on) { 146 | autoCheckSlot(); 147 | } 148 | } 149 | 150 | void KCheckAccelerators::checkAccelerators(bool automatic) 151 | { 152 | QWidget *actWin = qApp->activeWindow(); 153 | if (!actWin) { 154 | return; 155 | } 156 | 157 | KAcceleratorManager::manage(actWin); 158 | QString a; 159 | QString c; 160 | QString r; 161 | KAcceleratorManager::last_manage(a, c, r); 162 | 163 | if (automatic) { // for now we only show dialogs on F12 checks 164 | return; 165 | } 166 | 167 | if (c.isEmpty() && r.isEmpty() && (automatic || a.isEmpty())) { 168 | return; 169 | } 170 | 171 | QString s; 172 | 173 | if (!c.isEmpty()) { 174 | s += i18n("

Accelerators changed

") 175 | + QLatin1String( 176 | "%3
%1%2
") 178 | .arg(i18n("Old Text"), i18n("New Text"), c); 179 | } 180 | 181 | if (!r.isEmpty()) { 182 | s += i18n("

Accelerators removed

") + QLatin1String("%2
%1
").arg(i18n("Old Text"), r); 183 | } 184 | 185 | if (!a.isEmpty()) { 186 | s += i18n("

Accelerators added (just for your info)

") 187 | + QLatin1String("%2
%1
").arg(i18n("New Text"), a); 188 | } 189 | 190 | createDialog(actWin, automatic); 191 | drklash_view->setHtml(s); 192 | drklash->show(); 193 | drklash->raise(); 194 | 195 | // dlg will be destroyed before returning 196 | } 197 | 198 | void KCheckAccelerators::initiateIfNeeded() 199 | { 200 | static QPointer checker; 201 | if (checker) { 202 | return; 203 | } 204 | 205 | KConfigGroup cg(KSharedConfig::openConfig(), QStringLiteral("Development")); 206 | QString sKey = cg.readEntry("CheckAccelerators").trimmed(); 207 | int key = 0; 208 | if (!sKey.isEmpty()) { 209 | QList cuts = QKeySequence::listFromString(sKey); 210 | if (!cuts.isEmpty()) { 211 | key = cuts.first()[0].toCombined(); 212 | } 213 | } 214 | const bool autoCheck = cg.readEntry("AutoCheckAccelerators", true); 215 | if (key == 0 && !autoCheck) { 216 | return; 217 | } 218 | 219 | checker = new KCheckAccelerators(qApp, key, autoCheck); 220 | } 221 | 222 | #include "moc_kcheckaccelerators.cpp" 223 | -------------------------------------------------------------------------------- /src/kcheckaccelerators.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 1997 Matthias Kalle Dalheimer 4 | SPDX-FileCopyrightText: 1998, 1999, 2000 KDE Team 5 | SPDX-FileCopyrightText: 2008 Nick Shaforostoff 6 | 7 | SPDX-License-Identifier: LGPL-2.0-or-later 8 | */ 9 | 10 | #ifndef KCHECKACCELERATORS_H_ 11 | #define KCHECKACCELERATORS_H_ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | class QDialog; 19 | class QTextBrowser; 20 | 21 | /*! 22 | \internal 23 | This class allows translators (and application developers) to check for accelerator 24 | conflicts in menu and widgets. Put the following in your kdeglobals (or the config 25 | file for the application you're testing): 26 | 27 | \code 28 | [Development] 29 | CheckAccelerators=F12 30 | AutoCheckAccelerators=false 31 | AlwaysShowCheckAccelerators=false 32 | \endcode 33 | 34 | The checking can be either manual or automatic. To perform manual check, press 35 | the keyboard shortcut set to 'CheckAccelerators' (here F12). If automatic checking 36 | is enabled by setting 'AutoCheckAccelerators' to true, check will be performed every 37 | time the GUI changes. It's possible that in certain cases the check will be 38 | done also when no visible changes in the GUI happen or the check won't be done 39 | even if the GUI changed (in the latter case, use manual check ). Automatic 40 | checks can be anytime disabled by the checkbox in the dialog presenting 41 | the results of the check. If you set 'AlwaysShowCheckAccelerators' to true, 42 | the dialog will be shown even if the automatic check didn't find any conflicts, 43 | and all submenus will be shown, even those without conflicts. 44 | 45 | The dialog first lists the name of the window, then all results for all menus 46 | (if the window has a menubar) and then result for all controls in the active 47 | window (if there are any checkboxes etc.). For every submenu and all controls 48 | there are shown all conflicts grouped by accelerator, and a list of all used 49 | accelerators. 50 | */ 51 | 52 | class KCheckAccelerators : public QObject 53 | { 54 | Q_OBJECT 55 | public: 56 | static void initiateIfNeeded(); 57 | 58 | private: 59 | KCheckAccelerators(QObject *parent, int key, bool autoCheck); 60 | /*! 61 | * Re-implemented to filter the parent's events. 62 | * \internal 63 | */ 64 | bool eventFilter(QObject *, QEvent *e) override; 65 | 66 | private: 67 | void checkAccelerators(bool automatic); 68 | int key; 69 | bool block; 70 | bool alwaysShow; 71 | bool autoCheck; 72 | 73 | QTimer autoCheckTimer; 74 | void createDialog(QWidget *parent, bool automatic); 75 | QPointer drklash; 76 | QTextBrowser *drklash_view; 77 | 78 | private Q_SLOTS: 79 | void autoCheckSlot(); 80 | void slotDisableCheck(bool); 81 | }; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/kedittoolbar.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2000 Kurt Granroth 4 | SPDX-FileCopyrightText: 2006 Hamish Rodda 5 | 6 | SPDX-License-Identifier: LGPL-2.0-only 7 | */ 8 | 9 | #ifndef KEDITTOOLBAR_H 10 | #define KEDITTOOLBAR_H 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | class KActionCollection; 18 | 19 | class KEditToolBarPrivate; 20 | class KXMLGUIFactory; 21 | /*! 22 | * \class KEditToolBar 23 | * \inmodule KXmlGui 24 | * 25 | * \brief A dialog used to customize or configure toolbars. 26 | * 27 | * This dialog only works if your application uses the XML UI 28 | * framework for creating menus and toolbars. It depends on the XML 29 | * files to describe the toolbar layouts and it requires the actions 30 | * to determine which buttons are active. 31 | * 32 | * Typically you do not need to use it directly as KXmlGuiWindow::setupGUI 33 | * takes care of it. 34 | * 35 | * If you use KXMLGUIClient::plugActionList() you need to overload 36 | * KXmlGuiWindow::saveNewToolbarConfig() to plug actions again: 37 | * 38 | * \code 39 | * void MyClass::saveNewToolbarConfig() 40 | * { 41 | * KXmlGuiWindow::saveNewToolbarConfig(); 42 | * plugActionList( "list1", list1Actions ); 43 | * plugActionList( "list2", list2Actions ); 44 | * } 45 | * \endcode 46 | * 47 | * When created, KEditToolBar takes a KXMLGUIFactory object, and uses it to 48 | * find all of the action collections and XML files (there is one of each for the 49 | * mainwindow, but there could be more, when adding other XMLGUI clients like 50 | * KParts or plugins). The editor aims to be semi-intelligent about where it 51 | * assigns any modifications. In other words, it will not write out part specific 52 | * changes to your application's main XML file. 53 | * 54 | * KXmlGuiWindow and KParts::MainWindow take care of creating KEditToolBar correctly 55 | * and connecting to its newToolBarConfig slot, but if you really really want to do it 56 | * yourself, see the KXmlGuiWindow::configureToolbars() and 57 | * KXmlGuiWindow::saveNewToolbarConfig() code. 58 | * 59 | * \image kedittoolbar.png "KEditToolBar (example: usage in KWrite)" 60 | * 61 | */ 62 | class KXMLGUI_EXPORT KEditToolBar : public QDialog 63 | { 64 | Q_OBJECT 65 | public: 66 | /*! 67 | * \brief Old constructor for apps that do not use components. 68 | * 69 | * This constructor is somewhat deprecated, since it doesn't work 70 | * with any KXMLGuiClient being added to the mainwindow. 71 | * You really want to use the other constructor. 72 | * 73 | * You \b must pass along your collection of actions (some of which appear in your toolbars). 74 | * 75 | * \a collection The collection of actions to work on. 76 | * 77 | * \a parent The parent of the dialog. 78 | */ 79 | explicit KEditToolBar(KActionCollection *collection, QWidget *parent = nullptr); 80 | 81 | /*! 82 | * \brief Main constructor. 83 | * 84 | * The main parameter, \a factory, is a pointer to the 85 | * XML GUI factory object for your application. It contains a list 86 | * of all of the GUI clients (along with the action collections and 87 | * xml files) and the toolbar editor uses that. 88 | * 89 | * Use this like so: 90 | * \code 91 | * KEditToolBar edit(factory()); 92 | * if (edit.exec()) 93 | * // ... 94 | * \endcode 95 | * 96 | * \a factory Your application's factory object. 97 | * 98 | * \a parent The usual parent for the dialog. 99 | */ 100 | explicit KEditToolBar(KXMLGUIFactory *factory, QWidget *parent = nullptr); 101 | 102 | /*! 103 | * \brief Destructor. 104 | */ 105 | ~KEditToolBar() override; 106 | 107 | /*! 108 | * \brief Sets \a toolBarName as the default toolbar 109 | * that will be selected when the dialog is shown. 110 | * 111 | * If not set, or QString() is passed in, the global default tool bar name 112 | * will be used. 113 | * 114 | * \sa setGlobalDefaultToolBar 115 | */ 116 | void setDefaultToolBar(const QString &toolBarName); 117 | 118 | /*! 119 | * \brief Sets a new resource \a file and whether the global resource file 120 | * should be used. 121 | * 122 | * The name (absolute or relative) of your application's UI resource \a file 123 | * is assumed to be share/apps/appname/appnameui.rc, but it can be 124 | * overridden by calling this method. 125 | * 126 | * The \a global parameter controls whether or not the 127 | * global resource file is used. If this is \c true, then you may 128 | * edit all of the actions in your toolbars -- global ones and 129 | * local one. If it is \c false, then you may edit only your 130 | * application's entries. The only time you should set this to 131 | * false is if your application does not use the global resource 132 | * file at all (very rare). 133 | * 134 | * \a file The application's local resource file. 135 | * 136 | * \a global If \c true, then the global resource file will also be parsed. 137 | */ 138 | void setResourceFile(const QString &file, bool global = true); 139 | 140 | /*! 141 | * \brief Sets \a toolBarName as the default toolbar 142 | * which will be auto-selected for all KEditToolBar instances. 143 | * 144 | * Can be overridden on a per-dialog basis 145 | * by calling setDefaultToolBar( const QString& ) on the dialog. 146 | * 147 | * \since 6.0 148 | */ 149 | static void setGlobalDefaultToolBar(const QString &toolBarName); 150 | 151 | Q_SIGNALS: 152 | /*! 153 | * \brief Emitted when 'Apply' or 'Ok' is clicked or toolbars were reset. 154 | * 155 | * Connect to it to plug action lists and to call applyMainWindowSettings 156 | * (see sample code in the documentation for this class). 157 | */ 158 | void newToolBarConfig(); 159 | 160 | protected: 161 | void showEvent(QShowEvent *event) override; 162 | void hideEvent(QHideEvent *event) override; 163 | 164 | private: 165 | friend class KEditToolBarPrivate; 166 | std::unique_ptr const d; 167 | 168 | Q_DISABLE_COPY(KEditToolBar) 169 | }; 170 | 171 | #endif // _KEDITTOOLBAR_H 172 | -------------------------------------------------------------------------------- /src/klicensedialog_p.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Urs Wolfer 4 | SPDX-FileCopyrightText: 2008 Friedrich W. H. Kossebau 5 | SPDX-FileCopyrightText: 2010 Teo Mrnjavac 6 | 7 | Parts of this class have been take from the KAboutApplication class, which was 8 | SPDX-FileCopyrightText: 2000 Waldo Bastian 9 | SPDX-FileCopyrightText: 2000 Espen Sand 10 | 11 | SPDX-License-Identifier: LGPL-2.0-only 12 | */ 13 | 14 | #include "klicensedialog_p.h" 15 | 16 | // KF 17 | #include 18 | #include 19 | // Qt 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | KLicenseDialog::KLicenseDialog(const KAboutLicense &license, QWidget *parent) 28 | : QDialog(parent) 29 | { 30 | setAttribute(Qt::WA_DeleteOnClose); 31 | QVBoxLayout *layout = new QVBoxLayout(this); 32 | 33 | setWindowTitle(i18nc("@title:window", "License Agreement")); 34 | 35 | const QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont); 36 | 37 | const QString licenseText = license.text(); 38 | 39 | QTextBrowser *licenseBrowser = new QTextBrowser(this); 40 | licenseBrowser->setFont(font); 41 | licenseBrowser->setLineWrapMode(QTextEdit::NoWrap); 42 | licenseBrowser->setText(licenseText); 43 | layout->addWidget(licenseBrowser); 44 | 45 | QDialogButtonBox *buttonBox = new QDialogButtonBox(this); 46 | buttonBox->setStandardButtons(QDialogButtonBox::Close); 47 | connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); 48 | connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); 49 | layout->addWidget(buttonBox); 50 | 51 | // try to set up the dialog such that the full width of the 52 | // document is visible without horizontal scroll-bars being required 53 | auto *style = this->style(); 54 | const int leftMarginHint = style->pixelMetric(QStyle::PM_LayoutLeftMargin); 55 | const int rightMarginHint = style->pixelMetric(QStyle::PM_LayoutRightMargin); 56 | const qreal idealWidth = licenseBrowser->document()->idealWidth() + leftMarginHint + rightMarginHint + licenseBrowser->verticalScrollBar()->width() * 2; 57 | 58 | // try to allow enough height for a reasonable number of lines to be shown 59 | QFontMetrics metrics(font); 60 | const int idealHeight = metrics.height() * 30; 61 | 62 | resize(sizeHint().expandedTo(QSize(qRound(idealWidth), idealHeight))); 63 | } 64 | 65 | KLicenseDialog::~KLicenseDialog() = default; 66 | 67 | #include "moc_klicensedialog_p.cpp" 68 | -------------------------------------------------------------------------------- /src/klicensedialog_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2019 Friedrich W. H. Kossebau 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only 6 | */ 7 | 8 | #ifndef KLICENSEDIALOG_P_H 9 | #define KLICENSEDIALOG_P_H 10 | 11 | // Qt 12 | #include 13 | 14 | class KAboutLicense; 15 | 16 | /*! 17 | * \internal 18 | * \brief A dialog to display a license. 19 | * \inmodule KXmlGui 20 | */ 21 | class KLicenseDialog : public QDialog 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | explicit KLicenseDialog(const KAboutLicense &license, QWidget *parent = nullptr); 27 | ~KLicenseDialog() override; 28 | 29 | private: 30 | Q_DISABLE_COPY(KLicenseDialog) 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/kmainwindow_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2000 Reginald Stadlbauer 4 | SPDX-FileCopyrightText: 1997 Stephan Kulow 5 | SPDX-FileCopyrightText: 1997-2000 Sven Radej 6 | SPDX-FileCopyrightText: 1997-2000 Matthias Ettrich 7 | SPDX-FileCopyrightText: 1999 Chris Schlaeger 8 | SPDX-FileCopyrightText: 2002 Joseph Wenninger 9 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda 10 | 11 | SPDX-License-Identifier: LGPL-2.0-only 12 | */ 13 | 14 | #ifndef KMAINWINDOW_P_H 15 | #define KMAINWINDOW_P_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | class QObject; 23 | class QSessionManager; 24 | class QTimer; 25 | class KHelpMenu; 26 | class KMainWindow; 27 | 28 | class KMainWindowPrivate 29 | { 30 | public: 31 | virtual ~KMainWindowPrivate() = default; 32 | 33 | bool autoSaveSettings : 1; 34 | bool settingsDirty : 1; 35 | bool autoSaveWindowSize : 1; 36 | bool sizeApplied : 1; 37 | bool suppressCloseEvent : 1; 38 | 39 | KConfigGroup autoSaveGroup; 40 | mutable KConfigGroup m_stateConfigGroup; 41 | inline KConfigGroup &getStateConfig() const 42 | { 43 | if (!m_stateConfigGroup.isValid()) { 44 | // Always use a separate state config here, consumers may override this with a custom/window-specific group 45 | m_stateConfigGroup = KSharedConfig::openStateConfig()->group(QStringLiteral("MainWindow")); 46 | } 47 | return m_stateConfigGroup; 48 | } 49 | inline void migrateStateDataIfNeeded(KConfigGroup &cg) 50 | { 51 | if (m_stateConfigGroup.isValid()) { 52 | // The window sizes are written in KWindowSystem and RestorePositionForNextInstance is only temporarily written until 53 | // all instances of the app are closed 54 | cg.moveValuesTo({"State"}, m_stateConfigGroup); 55 | } 56 | } 57 | 58 | QTimer *settingsTimer; 59 | QTimer *sizeTimer; 60 | QRect defaultWindowSize; 61 | KHelpMenu *helpMenu; 62 | KMainWindow *q; 63 | QPointer dockResizeListener; 64 | QString dbusName; 65 | bool letDirtySettings; 66 | QEventLoopLocker locker; 67 | 68 | // This slot will be called when the style KCM changes settings that need 69 | // to be set on the already running applications. 70 | void _k_slotSettingsChanged(int category); 71 | void _k_slotSaveAutoSaveSize(); 72 | void _k_slotSaveAutoSavePosition(); 73 | 74 | void init(KMainWindow *_q); 75 | void polish(KMainWindow *q); 76 | enum CallCompression { 77 | NoCompressCalls = 0, 78 | CompressCalls, 79 | }; 80 | void setSettingsDirty(CallCompression callCompression = NoCompressCalls); 81 | void setSizeDirty(); 82 | }; 83 | 84 | class KMWSessionManager : public QObject 85 | { 86 | Q_OBJECT 87 | public: 88 | KMWSessionManager(); 89 | ~KMWSessionManager() override; 90 | 91 | private: 92 | void saveState(QSessionManager &); 93 | void commitData(QSessionManager &); 94 | }; 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /src/kmainwindowiface.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2001 Ian Reinhart Geiser 4 | SPDX-FileCopyrightText: 2006 Thiago Macieira 5 | 6 | SPDX-License-Identifier: LGPL-2.0-or-later 7 | */ 8 | 9 | #include "kmainwindowiface_p.h" 10 | 11 | #include "kactioncollection.h" 12 | #include "kxmlguiwindow.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | KMainWindowInterface::KMainWindowInterface(KXmlGuiWindow *mainWindow) 21 | : QDBusAbstractAdaptor(mainWindow) 22 | , m_MainWindow(mainWindow) 23 | { 24 | } 25 | 26 | KMainWindowInterface::~KMainWindowInterface() 27 | { 28 | } 29 | 30 | QStringList KMainWindowInterface::actions() 31 | { 32 | QStringList tmp_actions; 33 | const QList lst = m_MainWindow->actionCollection()->actions(); 34 | for (QAction *it : lst) { 35 | const QList associatedObjects = it->associatedObjects(); 36 | const bool hasAssociatedWidgets = std::any_of(associatedObjects.cbegin(), associatedObjects.cend(), [](QObject *object) { 37 | return (qobject_cast(object) != nullptr); 38 | }); 39 | if (hasAssociatedWidgets) { 40 | tmp_actions.append(it->objectName()); 41 | } 42 | } 43 | return tmp_actions; 44 | } 45 | 46 | bool KMainWindowInterface::activateAction(const QString &action) 47 | { 48 | QAction *tmp_Action = m_MainWindow->actionCollection()->action(action); 49 | if (tmp_Action) { 50 | tmp_Action->trigger(); 51 | return true; 52 | } else { 53 | return false; 54 | } 55 | } 56 | 57 | bool KMainWindowInterface::disableAction(const QString &action) 58 | { 59 | QAction *tmp_Action = m_MainWindow->actionCollection()->action(action); 60 | if (tmp_Action) { 61 | tmp_Action->setEnabled(false); 62 | return true; 63 | } else { 64 | return false; 65 | } 66 | } 67 | 68 | bool KMainWindowInterface::enableAction(const QString &action) 69 | { 70 | QAction *tmp_Action = m_MainWindow->actionCollection()->action(action); 71 | if (tmp_Action) { 72 | tmp_Action->setEnabled(true); 73 | return true; 74 | } else { 75 | return false; 76 | } 77 | } 78 | 79 | bool KMainWindowInterface::actionIsEnabled(const QString &action) 80 | { 81 | QAction *tmp_Action = m_MainWindow->actionCollection()->action(action); 82 | if (tmp_Action) { 83 | return tmp_Action->isEnabled(); 84 | } else { 85 | return false; 86 | } 87 | } 88 | 89 | QString KMainWindowInterface::actionToolTip(const QString &action) 90 | { 91 | QAction *tmp_Action = m_MainWindow->actionCollection()->action(action); 92 | if (tmp_Action) { 93 | return tmp_Action->toolTip(); 94 | } else { 95 | return QStringLiteral("Error no such object!"); 96 | } 97 | } 98 | 99 | qlonglong KMainWindowInterface::winId() 100 | { 101 | return qlonglong(m_MainWindow->winId()); 102 | } 103 | 104 | void KMainWindowInterface::grabWindowToClipBoard() 105 | { 106 | QClipboard *clipboard = QApplication::clipboard(); 107 | clipboard->setPixmap(m_MainWindow->grab()); 108 | } 109 | 110 | #include "moc_kmainwindowiface_p.cpp" 111 | -------------------------------------------------------------------------------- /src/kmainwindowiface_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2001 Ian Reinhart Geiser 4 | SPDX-FileCopyrightText: 2006 Thiago Macieira 5 | 6 | SPDX-License-Identifier: LGPL-2.0-or-later 7 | */ 8 | 9 | #ifndef KMAINWINDOWIFACE_P_H 10 | #define KMAINWINDOWIFACE_P_H 11 | 12 | #include 13 | 14 | class KXmlGuiWindow; 15 | 16 | /*! 17 | * \brief D-Bus interface to KMainWindow. 18 | * \inmodule KXmlGui 19 | * 20 | * This is the main interface to the KMainWindow. This provides a consistent 21 | * D-Bus interface to all KDE applications that use it. 22 | */ 23 | class KMainWindowInterface : public QDBusAbstractAdaptor 24 | { 25 | Q_OBJECT 26 | Q_CLASSINFO("D-Bus Interface", "org.kde.KMainWindow") 27 | 28 | public: 29 | /*! 30 | \brief Constructs a new interface object. 31 | 32 | \a mainWindow - The parent KMainWindow object 33 | that will provide us with the QAction objects. 34 | */ 35 | explicit KMainWindowInterface(KXmlGuiWindow *mainWindow); 36 | 37 | /*! 38 | \brief Destructor. 39 | 40 | Cleans up the dcop action proxy object. 41 | */ 42 | ~KMainWindowInterface() override; 43 | 44 | public Q_SLOTS: 45 | /*! 46 | \brief Returns a list of actions available to the application's window. 47 | */ 48 | QStringList actions(); 49 | 50 | /*! 51 | \brief Activates the requested \a action. 52 | 53 | The names of valid actions can be found by calling actions(). 54 | 55 | Returns the success of the operation. 56 | */ 57 | bool activateAction(const QString &action); 58 | 59 | /*! 60 | \brief Disables the requested \a action. 61 | 62 | The names of valid actions can be found by calling actions(). 63 | 64 | Returns the success of the operation. 65 | */ 66 | bool disableAction(const QString &action); 67 | 68 | /*! 69 | \brief Enables the requested \a action. 70 | 71 | The names of valid actions can be found by calling actions(). 72 | 73 | Returns the success of the operation. 74 | */ 75 | bool enableAction(const QString &action); 76 | 77 | /*! 78 | \brief Returns the status of the requested \a action. 79 | 80 | The names of valid actions can be found by calling actions(). 81 | */ 82 | bool actionIsEnabled(const QString &action); 83 | 84 | /*! 85 | \brief Returns the tool tip text of the requested \a action. 86 | The names of valid actions can be found by calling actions(). 87 | */ 88 | QString actionToolTip(const QString &action); 89 | 90 | /*! 91 | \brief Returns the ID of the current main window. 92 | 93 | This is useful for automated screen captures or other evil 94 | widget fun. 95 | 96 | Returns A integer value of the main window's ID. 97 | **/ 98 | qlonglong winId(); 99 | 100 | /*! 101 | \brief Copies a pixmap representation of the current main window to 102 | the clipboard. 103 | **/ 104 | void grabWindowToClipBoard(); 105 | 106 | private: 107 | KXmlGuiWindow *m_MainWindow; 108 | }; 109 | 110 | #endif // KMAINWINDOWIFACE_P_H 111 | -------------------------------------------------------------------------------- /src/kmenumenuhandler_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2006 Olivier Goffart 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef kmenumenuhandler_p_h 9 | #define kmenumenuhandler_p_h 10 | 11 | #include 12 | 13 | class QAction; 14 | class QMenu; 15 | 16 | class KXMLGUIBuilder; 17 | class KSelectAction; 18 | 19 | namespace KDEPrivate 20 | { 21 | /*! 22 | * \internal 23 | * \brief This class handles the context menu of QMenu. 24 | * 25 | * Used by KXmlGuiBuilder. 26 | */ 27 | class KMenuMenuHandler : public QObject 28 | { 29 | Q_OBJECT 30 | public: 31 | explicit KMenuMenuHandler(KXMLGUIBuilder *b); 32 | ~KMenuMenuHandler() override 33 | { 34 | } 35 | void insertMenu(QMenu *menu); 36 | bool eventFilter(QObject *watched, QEvent *event) override; 37 | 38 | private Q_SLOTS: 39 | void slotSetShortcut(); 40 | void buildToolbarAction(); 41 | void slotAddToToolBar(int); 42 | 43 | private: 44 | void showContextMenu(QMenu *menu, const QPoint &pos); 45 | 46 | KXMLGUIBuilder *m_builder = nullptr; 47 | KSelectAction *m_toolbarAction = nullptr; 48 | QMenu *m_popupMenu = nullptr; 49 | QAction *m_popupAction = nullptr; 50 | QMenu *m_contextMenu = nullptr; 51 | }; 52 | 53 | } // END namespace KDEPrivate 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /src/kshortcuteditwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 1998 Mark Donohoe 4 | SPDX-FileCopyrightText: 1997 Nicolas Hadacek 5 | SPDX-FileCopyrightText: 1998 Matthias Ettrich 6 | SPDX-FileCopyrightText: 2001 Ellis Whitehead 7 | SPDX-FileCopyrightText: 2006 Hamish Rodda 8 | SPDX-FileCopyrightText: 2007 Roberto Raggi 9 | SPDX-FileCopyrightText: 2007 Andreas Hartmetz 10 | 11 | SPDX-License-Identifier: LGPL-2.0-or-later 12 | */ 13 | 14 | #include "config-xmlgui.h" 15 | #include "kshortcutsdialog_p.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #if HAVE_GLOBALACCEL 26 | #include 27 | #endif 28 | 29 | #include "kkeysequencewidget.h" 30 | 31 | void TabConnectedWidget::paintEvent(QPaintEvent *e) 32 | { 33 | QWidget::paintEvent(e); 34 | QPainter p(this); 35 | QPen pen(QPalette().highlight().color()); 36 | pen.setWidth(6); 37 | p.setPen(pen); 38 | p.drawLine(0, 0, width(), 0); 39 | if (qApp->isLeftToRight()) { 40 | p.drawLine(0, 0, 0, height()); 41 | } else { 42 | p.drawLine(width(), 0, width(), height()); 43 | } 44 | } 45 | 46 | ShortcutEditWidget::ShortcutEditWidget(QWidget *viewport, const QKeySequence &defaultSeq, const QKeySequence &activeSeq, bool allowLetterShortcuts) 47 | : TabConnectedWidget(viewport) 48 | , m_defaultKeySequence(defaultSeq) 49 | , m_isUpdating(false) 50 | , m_action(nullptr) 51 | , m_noneText(i18nc("No shortcut defined", "None")) 52 | { 53 | QGridLayout *layout = new QGridLayout(this); 54 | 55 | m_defaultRadio = new QRadioButton(i18nc("@option:radio", "Default:"), this); 56 | m_defaultLabel = new QLabel(m_noneText, this); 57 | const QString defaultText = defaultSeq.toString(QKeySequence::NativeText); 58 | if (!defaultText.isEmpty()) { 59 | m_defaultLabel->setText(defaultText); 60 | } 61 | 62 | m_customRadio = new QRadioButton(i18nc("@option:radio", "Custom:"), this); 63 | m_customEditor = new KKeySequenceWidget(this); 64 | m_customEditor->setModifierlessAllowed(allowLetterShortcuts); 65 | 66 | layout->addWidget(m_defaultRadio, 0, 0); 67 | layout->addWidget(m_defaultLabel, 0, 1); 68 | layout->addWidget(m_customRadio, 1, 0); 69 | layout->addWidget(m_customEditor, 1, 1); 70 | layout->setColumnStretch(2, 1); 71 | 72 | setKeySequence(activeSeq); 73 | 74 | connect(m_defaultRadio, &QRadioButton::toggled, this, &ShortcutEditWidget::defaultToggled); 75 | connect(m_customEditor, &KKeySequenceWidget::keySequenceChanged, this, &ShortcutEditWidget::setCustom); 76 | connect(m_customEditor, &KKeySequenceWidget::stealShortcut, this, &ShortcutEditWidget::stealShortcut); 77 | #if HAVE_GLOBALACCEL 78 | connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, [this](QAction *action, const QKeySequence &seq) { 79 | if (action != m_action) { 80 | return; 81 | } 82 | setKeySequence(seq); 83 | }); 84 | #endif 85 | } 86 | 87 | KKeySequenceWidget::ShortcutTypes ShortcutEditWidget::checkForConflictsAgainst() const 88 | { 89 | return m_customEditor->checkForConflictsAgainst(); 90 | } 91 | 92 | // slot 93 | void ShortcutEditWidget::defaultToggled(bool checked) 94 | { 95 | if (m_isUpdating) { 96 | return; 97 | } 98 | 99 | m_isUpdating = true; 100 | if (checked) { 101 | // The default key sequence should be activated. We check first if this is 102 | // possible. 103 | if (m_customEditor->isKeySequenceAvailable(m_defaultKeySequence)) { 104 | // Clear the customs widget 105 | m_customEditor->clearKeySequence(); 106 | Q_EMIT keySequenceChanged(m_defaultKeySequence); 107 | } else { 108 | // We tried to switch to the default key sequence and failed. Go 109 | // back. 110 | m_customRadio->setChecked(true); 111 | } 112 | } else { 113 | // The empty key sequence is always valid 114 | Q_EMIT keySequenceChanged(QKeySequence()); 115 | } 116 | m_isUpdating = false; 117 | } 118 | 119 | void ShortcutEditWidget::setCheckActionCollections(const QList &checkActionCollections) 120 | { 121 | // We just forward them to out KKeySequenceWidget. 122 | m_customEditor->setCheckActionCollections(checkActionCollections); 123 | } 124 | 125 | void ShortcutEditWidget::setCheckForConflictsAgainst(KKeySequenceWidget::ShortcutTypes types) 126 | { 127 | m_customEditor->setCheckForConflictsAgainst(types); 128 | } 129 | 130 | void ShortcutEditWidget::setComponentName(const QString &componentName) 131 | { 132 | m_customEditor->setComponentName(componentName); 133 | } 134 | 135 | void ShortcutEditWidget::setMultiKeyShortcutsAllowed(bool allowed) 136 | { 137 | // We just forward them to out KKeySequenceWidget. 138 | m_customEditor->setMultiKeyShortcutsAllowed(allowed); 139 | } 140 | 141 | bool ShortcutEditWidget::multiKeyShortcutsAllowed() const 142 | { 143 | return m_customEditor->multiKeyShortcutsAllowed(); 144 | } 145 | 146 | void ShortcutEditWidget::setAction(QObject *action) 147 | { 148 | m_action = action; 149 | } 150 | 151 | // slot 152 | void ShortcutEditWidget::setCustom(const QKeySequence &seq) 153 | { 154 | if (m_isUpdating) { 155 | return; 156 | } 157 | 158 | // seq is a const reference to a private variable of KKeySequenceWidget. 159 | // Somewhere below we possible change that one. But we want to emit seq 160 | // whatever happens. So we make a copy. 161 | QKeySequence original = seq; 162 | 163 | m_isUpdating = true; 164 | 165 | // Check if the user typed in the default sequence into the custom field. 166 | // We do this by calling setKeySequence which will do the right thing. 167 | setKeySequence(original); 168 | 169 | Q_EMIT keySequenceChanged(original); 170 | m_isUpdating = false; 171 | } 172 | 173 | void ShortcutEditWidget::setKeySequence(const QKeySequence &activeSeq) 174 | { 175 | const QString seqString = activeSeq.isEmpty() ? m_noneText : activeSeq.toString(QKeySequence::NativeText); 176 | if (seqString == m_defaultLabel->text()) { 177 | m_defaultRadio->setChecked(true); 178 | m_customEditor->clearKeySequence(); 179 | } else { 180 | m_customRadio->setChecked(true); 181 | // m_customEditor->setKeySequence does some stuff we only want to 182 | // execute when the sequence really changes. 183 | if (activeSeq != m_customEditor->keySequence()) { 184 | m_customEditor->setKeySequence(activeSeq); 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/kshortcutschemeshelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2008 Alexander Dymo 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #include "kshortcutschemeshelper_p.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "debug.h" 22 | #include "kactioncollection.h" 23 | #include "kxmlguiclient.h" 24 | 25 | bool KShortcutSchemesHelper::saveShortcutScheme(const QList &collections, const QString &schemeName) 26 | { 27 | // Every action collection is associated with a KXMLGUIClient 28 | // (at least if it was added by KXMLGUIFactory::configureShortcuts() 29 | // or KXMLGUIFactory::showConfigureShortcutsDialog()) 30 | 31 | // Some GUI clients have the same name (e.g. the child client for a mainwindow 32 | // holding the actions for hiding/showing toolbars), so we need to save them 33 | // together, otherwise they will overwrite each other's files on disk. 34 | 35 | // For cases like kdevelop (many guiclients not reused in other apps) it's simpler 36 | // to even save all shortcuts to a single shortcuts file -> set the boolean below to true 37 | // to create an all-in-one scheme. 38 | // Maybe we need a checkbox for this? Or an env var for contributors to set, rather? End users don't care. 39 | const bool saveToApplicationFile = false; 40 | 41 | QMultiMap collectionsByClientName; 42 | for (KActionCollection *coll : collections) { 43 | const KXMLGUIClient *client = coll->parentGUIClient(); 44 | if (client) { 45 | const QString key = saveToApplicationFile ? QCoreApplication::applicationName() : client->componentName(); 46 | collectionsByClientName.insert(key, coll); 47 | } 48 | } 49 | const auto componentNames = collectionsByClientName.uniqueKeys(); 50 | for (const QString &componentName : componentNames) { 51 | qCDebug(DEBUG_KXMLGUI) << "Considering component" << componentName; 52 | QDomDocument doc; 53 | QDomElement docElem = doc.createElement(QStringLiteral("gui")); 54 | docElem.setAttribute(QStringLiteral("version"), QStringLiteral("1")); 55 | docElem.setAttribute(QStringLiteral("name"), componentName); 56 | doc.appendChild(docElem); 57 | QDomElement elem = doc.createElement(QStringLiteral("ActionProperties")); 58 | docElem.appendChild(elem); 59 | 60 | const auto componentCollections = collectionsByClientName.values(componentName); 61 | for (KActionCollection *collection : componentCollections) { 62 | qCDebug(DEBUG_KXMLGUI) << "Saving shortcut scheme for action collection with" << collection->actions().count() << "actions"; 63 | 64 | const auto collectionActions = collection->actions(); 65 | for (QAction *action : collectionActions) { 66 | if (!action) { 67 | continue; 68 | } 69 | 70 | const QString actionName = action->objectName(); 71 | const QString shortcut = QKeySequence::listToString(action->shortcuts()); 72 | // qCDebug(DEBUG_KXMLGUI) << "action" << actionName << "has shortcut" << shortcut; 73 | if (!shortcut.isEmpty()) { 74 | QDomElement act_elem = doc.createElement(QStringLiteral("Action")); 75 | act_elem.setAttribute(QStringLiteral("name"), actionName); 76 | act_elem.setAttribute(QStringLiteral("shortcut"), shortcut); 77 | elem.appendChild(act_elem); 78 | } 79 | } 80 | } 81 | 82 | const QString schemeFileName = writableShortcutSchemeFileName(componentName, schemeName); 83 | if (elem.childNodes().isEmpty()) { 84 | QFile::remove(schemeFileName); 85 | } else { 86 | qCDebug(DEBUG_KXMLGUI) << "saving to" << schemeFileName; 87 | QDir().mkpath(QFileInfo(schemeFileName).absolutePath()); 88 | QFile schemeFile(schemeFileName); 89 | if (!schemeFile.open(QFile::WriteOnly | QFile::Truncate)) { 90 | qCDebug(DEBUG_KXMLGUI) << "COULD NOT WRITE" << schemeFileName; 91 | return false; 92 | } 93 | 94 | QTextStream out(&schemeFile); 95 | out << doc.toString(2); 96 | } 97 | } 98 | return true; 99 | } 100 | 101 | QString KShortcutSchemesHelper::currentShortcutSchemeName() 102 | { 103 | return KSharedConfig::openConfig()->group(QStringLiteral("Shortcut Schemes")).readEntry("Current Scheme", "Default"); 104 | } 105 | 106 | QString KShortcutSchemesHelper::writableShortcutSchemeFileName(const QString &componentName, const QString &schemeName) 107 | { 108 | return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/%1/shortcuts/%2").arg(componentName, schemeName); 109 | } 110 | 111 | QString KShortcutSchemesHelper::writableApplicationShortcutSchemeFileName(const QString &schemeName) 112 | { 113 | return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) 114 | + QLatin1String("/%1/shortcuts/%2").arg(QCoreApplication::applicationName(), schemeName); 115 | } 116 | 117 | QString KShortcutSchemesHelper::shortcutSchemeFileName(const QString &componentName, const QString &schemeName) 118 | { 119 | return QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("%1/shortcuts/%2").arg(componentName, schemeName)); 120 | } 121 | 122 | QString KShortcutSchemesHelper::applicationShortcutSchemeFileName(const QString &schemeName) 123 | { 124 | return QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("%1/shortcuts/%2").arg(QCoreApplication::applicationName(), schemeName)); 125 | } 126 | -------------------------------------------------------------------------------- /src/kshortcutschemeshelper_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2008 Alexander Dymo 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef KSHORTCUTSCHEMESHELPER_P_H 9 | #define KSHORTCUTSCHEMESHELPER_P_H 10 | 11 | #include 12 | 13 | class KActionCollection; 14 | class KXMLGUIClient; 15 | 16 | class KShortcutSchemesHelper 17 | { 18 | public: 19 | /*! 20 | * Saves actions from these collections to the shortcut scheme file. 21 | * 22 | * This doesn't save anything for action collections without a parent xmlgui client. 23 | * 24 | * Returns \c true if the shortcut scheme was successfully saved. 25 | */ 26 | static bool saveShortcutScheme(const QList &collections, const QString &schemeName); 27 | 28 | /*! 29 | * Returns the current shortcut scheme name for the application. 30 | */ 31 | static QString currentShortcutSchemeName(); 32 | 33 | /*! 34 | * Returns the name of the (writable) file to save the shortcut scheme to. 35 | */ 36 | static QString writableShortcutSchemeFileName(const QString &componentName, const QString &schemeName); 37 | 38 | /*! 39 | * Returns the name of the scheme file for application itself. 40 | */ 41 | static QString writableApplicationShortcutSchemeFileName(const QString &schemeName); 42 | 43 | /*! 44 | * Returns the name of the file to read the shortcut scheme from. 45 | */ 46 | static QString shortcutSchemeFileName(const QString &componentName, const QString &schemeName); 47 | 48 | /*! 49 | * Returns the name of the scheme file for application itself, for reading. 50 | */ 51 | static QString applicationShortcutSchemeFileName(const QString &schemeName); 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/kshortcutsdialog.ui: -------------------------------------------------------------------------------- 1 | 2 | KShortcutsDialog 3 | 4 | 5 | 6 | 0 7 | 0 8 | 761 9 | 549 10 | 11 | 12 | 13 | 14 | 15 | 16 | Search interactively for shortcut names (e.g. Copy) or combination of keys (e.g. Ctrl+C) by typing them here. 17 | 18 | 19 | 20 | 21 | 22 | 23 | Here you can see a list of key bindings, i.e. associations between actions (e.g. 'Copy') shown in the left column and keys or combination of keys (e.g. Ctrl+V) shown in the right column. 24 | 25 | 26 | true 27 | 28 | 29 | true 30 | 31 | 32 | 33 | Action 34 | 35 | 36 | 37 | 38 | Shortcut 39 | 40 | 41 | 42 | 43 | Alternate 44 | 45 | 46 | 47 | 48 | Global 49 | 50 | 51 | 52 | 53 | Global Alternate 54 | 55 | 56 | 57 | 58 | Mouse Button Gesture 59 | 60 | 61 | 62 | 63 | Mouse Shape Gesture 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | KTreeWidgetSearchLineWidget 73 | QWidget 74 |
ktreewidgetsearchlinewidget.h
75 |
76 |
77 | 78 | 79 |
80 | -------------------------------------------------------------------------------- /src/kshortcutwidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Andreas Hartmetz 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #include "kshortcutwidget.h" 9 | #include "ui_kshortcutwidget.h" 10 | 11 | class KShortcutWidgetPrivate 12 | { 13 | public: 14 | KShortcutWidgetPrivate(KShortcutWidget *qq) 15 | : q(qq) 16 | { 17 | } 18 | 19 | // private slots 20 | void priKeySequenceChanged(const QKeySequence &); 21 | void altKeySequenceChanged(const QKeySequence &); 22 | 23 | // members 24 | KShortcutWidget *const q; 25 | Ui::KShortcutWidget ui; 26 | QList cut; 27 | bool holdChangedSignal; 28 | }; 29 | 30 | KShortcutWidget::KShortcutWidget(QWidget *parent) 31 | : QWidget(parent) 32 | , d(new KShortcutWidgetPrivate(this)) 33 | { 34 | d->holdChangedSignal = false; 35 | d->ui.setupUi(this); 36 | connect(d->ui.priEditor, &KKeySequenceWidget::keySequenceChanged, this, [this](const QKeySequence &keyseq) { 37 | d->priKeySequenceChanged(keyseq); 38 | }); 39 | connect(d->ui.altEditor, &KKeySequenceWidget::keySequenceChanged, this, [this](const QKeySequence &keyseq) { 40 | d->altKeySequenceChanged(keyseq); 41 | }); 42 | } 43 | 44 | KShortcutWidget::~KShortcutWidget() = default; 45 | 46 | void KShortcutWidget::setModifierlessAllowed(bool allow) 47 | { 48 | d->ui.priEditor->setModifierlessAllowed(allow); 49 | d->ui.altEditor->setModifierlessAllowed(allow); 50 | } 51 | 52 | bool KShortcutWidget::isModifierlessAllowed() 53 | { 54 | return d->ui.priEditor->isModifierlessAllowed(); 55 | } 56 | 57 | void KShortcutWidget::setClearButtonsShown(bool show) 58 | { 59 | d->ui.priEditor->setClearButtonShown(show); 60 | d->ui.altEditor->setClearButtonShown(show); 61 | } 62 | 63 | QList KShortcutWidget::shortcut() const 64 | { 65 | QList ret; 66 | ret << d->ui.priEditor->keySequence() << d->ui.altEditor->keySequence(); 67 | return ret; 68 | } 69 | 70 | void KShortcutWidget::setCheckActionCollections(const QList &actionCollections) 71 | { 72 | d->ui.priEditor->setCheckActionCollections(actionCollections); 73 | d->ui.altEditor->setCheckActionCollections(actionCollections); 74 | } 75 | 76 | // slot 77 | void KShortcutWidget::applyStealShortcut() 78 | { 79 | d->ui.priEditor->applyStealShortcut(); 80 | d->ui.altEditor->applyStealShortcut(); 81 | } 82 | 83 | // slot 84 | void KShortcutWidget::setShortcut(const QList &newSc) 85 | { 86 | if (newSc == d->cut) { 87 | return; 88 | } 89 | 90 | d->holdChangedSignal = true; 91 | 92 | if (!newSc.isEmpty()) { 93 | d->ui.priEditor->setKeySequence(newSc.first()); 94 | } 95 | 96 | if (newSc.size() > 1) { 97 | d->ui.altEditor->setKeySequence(newSc.at(1)); 98 | } 99 | 100 | d->holdChangedSignal = false; 101 | 102 | Q_EMIT shortcutChanged(d->cut); 103 | } 104 | 105 | // slot 106 | void KShortcutWidget::clearShortcut() 107 | { 108 | setShortcut(QList()); 109 | } 110 | 111 | // private slot 112 | void KShortcutWidgetPrivate::priKeySequenceChanged(const QKeySequence &seq) 113 | { 114 | if (cut.isEmpty()) { 115 | cut << seq; 116 | } else { 117 | cut[0] = seq; 118 | } 119 | 120 | if (!holdChangedSignal) { 121 | Q_EMIT q->shortcutChanged(cut); 122 | } 123 | } 124 | 125 | // private slot 126 | void KShortcutWidgetPrivate::altKeySequenceChanged(const QKeySequence &seq) 127 | { 128 | if (cut.size() <= 1) { 129 | cut << seq; 130 | } else { 131 | cut[1] = seq; 132 | } 133 | 134 | if (!holdChangedSignal) { 135 | Q_EMIT q->shortcutChanged(cut); 136 | } 137 | } 138 | 139 | #include "moc_kshortcutwidget.cpp" 140 | -------------------------------------------------------------------------------- /src/kshortcutwidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2007 Andreas Hartmetz 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | #ifndef KSHORTCUTWIDGET_H 8 | #define KSHORTCUTWIDGET_H 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | class KActionCollection; 18 | class KShortcutWidgetPrivate; 19 | 20 | /*! 21 | * \class KShortcutWidget 22 | * \inmodule KXmlGui 23 | * 24 | * Provides a widget that lets the user assign a main shortcut 25 | * and an alternate shortcut for a certain action. 26 | * 27 | * \image kshortcutwidget.png "KShortcutWidget" 28 | */ 29 | class KXMLGUI_EXPORT KShortcutWidget : public QWidget 30 | { 31 | Q_OBJECT 32 | 33 | /*! 34 | * \property KShortcutWidget::modifierlessAllowed 35 | */ 36 | Q_PROPERTY(bool modifierlessAllowed READ isModifierlessAllowed WRITE setModifierlessAllowed) 37 | public: 38 | /*! 39 | * \brief Creates a new shortcut widget as a child of \a parent. 40 | */ 41 | explicit KShortcutWidget(QWidget *parent = nullptr); 42 | /*! 43 | * \brief Destructs the shortcut widget. 44 | */ 45 | ~KShortcutWidget() override; 46 | 47 | /*! 48 | * \brief Sets whether to \a allow a shortcut 49 | * that doesn't include a modifier key. 50 | */ 51 | void setModifierlessAllowed(bool allow); 52 | 53 | /*! 54 | * \brief Returns whether the set widget shortcut 55 | * can be set without including a modifier key. 56 | */ 57 | bool isModifierlessAllowed(); 58 | 59 | /*! 60 | * \brief Sets whether to \a show the clear buttons next to the 61 | * main and alternate shortcuts of the widget. 62 | */ 63 | void setClearButtonsShown(bool show); 64 | 65 | /*! 66 | * \brief Returns the set shortcut. 67 | */ 68 | QList shortcut() const; 69 | 70 | /*! 71 | * \brief Sets a list of \a actionCollections to check against 72 | * for a conflictuous shortcut. 73 | * 74 | * If there is a conflictuous shortcut with a QAction, 75 | * and that this shortcut can be configured 76 | * (that is, KActionCollection::isShortcutConfigurable() returns \c true) 77 | * the user will be prompted to eventually steal the shortcut from this action. 78 | * 79 | * Global shortcuts are automatically checked for conflicts. 80 | * 81 | * Don't forget to call applyStealShortcut() to actually steal the shortcut. 82 | * 83 | * \since 4.1 84 | */ 85 | void setCheckActionCollections(const QList &actionCollections); 86 | 87 | Q_SIGNALS: 88 | /*! 89 | * \brief Emitted when the given shortcut \a cut has changed. 90 | */ 91 | void shortcutChanged(const QList &cut); 92 | 93 | public Q_SLOTS: 94 | /*! 95 | * \brief Sets the given shortcut \a cut to the widget. 96 | */ 97 | void setShortcut(const QList &cut); 98 | /*! 99 | * \brief Unassigns the widget's shortcut. 100 | */ 101 | void clearShortcut(); 102 | 103 | /*! 104 | * \brief Actually remove the shortcut that the user wanted to steal, 105 | * from the action that was using it. 106 | * 107 | * To be called before you apply your changes. 108 | * No shortcuts are stolen until this function is called. 109 | */ 110 | void applyStealShortcut(); 111 | 112 | private: 113 | friend class KShortcutWidgetPrivate; 114 | std::unique_ptr const d; 115 | }; 116 | 117 | #endif // KSHORTCUTWIDGET_H 118 | -------------------------------------------------------------------------------- /src/kshortcutwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | KShortcutWidget 3 | 4 | 5 | 6 | 0 7 | 0 8 | 180 9 | 49 10 | 11 | 12 | 13 | 14 | 9 15 | 16 | 17 | 6 18 | 19 | 20 | 21 | 22 | Main: 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 0 31 | 0 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Qt::Horizontal 40 | 41 | 42 | 43 | 50 44 | 31 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Alternate: 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | KKeySequenceWidget 71 | QWidget 72 |
kkeysequencewidget.h
73 |
74 |
75 | 76 | 77 |
78 | -------------------------------------------------------------------------------- /src/kswitchlanguagedialog_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE Libraries 3 | SPDX-FileCopyrightText: 2007 Krzysztof Lichota 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef _KSWITCHLANGUAGEDIALOG_H_ 9 | #define _KSWITCHLANGUAGEDIALOG_H_ 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace KDEPrivate 16 | { 17 | KXMLGUI_EXPORT void setApplicationSpecificLanguage(const QByteArray &languageCode); 18 | KXMLGUI_EXPORT void initializeLanguages(); 19 | 20 | class KSwitchLanguageDialogPrivate; 21 | 22 | /*! 23 | * \brief Standard "switch application language" dialog box. 24 | * 25 | * This class provides "switch application language" dialog box that is used 26 | * in KHelpMenu. 27 | * \internal 28 | */ 29 | 30 | class KSwitchLanguageDialog : public QDialog 31 | { 32 | Q_OBJECT 33 | 34 | public: 35 | /*! 36 | * \brief Constructs a fully featured "Switch application language" dialog box. 37 | * 38 | * Note that this dialog is made modeless in the KHelpMenu class so 39 | * the users may expect a modeless dialog. 40 | * 41 | * \a parent The parent of the dialog box. You should use the 42 | * toplevel window so that the dialog becomes centered. 43 | * 44 | * \a name Internal name of the widget. This name in not used in the 45 | * caption. 46 | * 47 | * \a modal If false, this widget will be modeless and must be 48 | * made visible using QWidget::show(). Otherwise it will be 49 | * modal and must be made visible using QWidget::exec(). 50 | */ 51 | explicit KSwitchLanguageDialog(QWidget *parent = nullptr); 52 | 53 | ~KSwitchLanguageDialog() override; 54 | 55 | protected Q_SLOTS: 56 | /*! 57 | * \brief Activated when the Ok button has been clicked. 58 | */ 59 | virtual void slotOk(); 60 | void slotDefault(); 61 | 62 | /*! 63 | \brief Called when one of the language buttons changes state. 64 | */ 65 | virtual void languageOnButtonChanged(const QString &); 66 | 67 | /*! 68 | \brief Called to add one language button to dialog. 69 | */ 70 | virtual void slotAddLanguageButton(); 71 | 72 | /*! 73 | \brief Called when "Remove" language button is clicked. 74 | */ 75 | virtual void removeButtonClicked(); 76 | 77 | private: 78 | KSwitchLanguageDialogPrivate *const d; 79 | 80 | friend class KSwitchLanguageDialogPrivate; 81 | }; 82 | 83 | } 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/ktoggletoolbaraction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 1999 Reginald Stadlbauer 4 | SPDX-FileCopyrightText: 1999 Simon Hausmann 5 | SPDX-FileCopyrightText: 2000 Nicolas Hadacek 6 | SPDX-FileCopyrightText: 2000 Kurt Granroth 7 | SPDX-FileCopyrightText: 2000 Michael Koch 8 | SPDX-FileCopyrightText: 2001 Holger Freyther 9 | SPDX-FileCopyrightText: 2002 Ellis Whitehead 10 | SPDX-FileCopyrightText: 2002 Joseph Wenninger 11 | SPDX-FileCopyrightText: 2003 Andras Mantia 12 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda 13 | 14 | SPDX-License-Identifier: LGPL-2.0-only 15 | */ 16 | 17 | #include "ktoggletoolbaraction.h" 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include "kmainwindow.h" 26 | #include "ktoolbar.h" 27 | 28 | class KToggleToolBarActionPrivate 29 | { 30 | public: 31 | KToggleToolBarActionPrivate(KToggleToolBarAction *q) 32 | : toolBar(nullptr) 33 | , beingToggled(false) 34 | { 35 | const bool authorized = KAuthorized::authorizeAction(QStringLiteral("options_show_toolbar")); 36 | q->setEnabled(authorized); 37 | q->setVisible(authorized); 38 | } 39 | 40 | QPointer toolBar; 41 | bool beingToggled; 42 | }; 43 | 44 | KToggleToolBarAction::KToggleToolBarAction(KToolBar *toolBar, const QString &text, QObject *parent) 45 | : KToggleAction(text, parent) 46 | , d(new KToggleToolBarActionPrivate(this)) 47 | { 48 | d->toolBar = toolBar; 49 | d->toolBar->installEventFilter(this); 50 | 51 | d->beingToggled = true; 52 | setChecked(d->toolBar->isVisible()); 53 | d->beingToggled = false; 54 | } 55 | 56 | KToggleToolBarAction::~KToggleToolBarAction() = default; 57 | 58 | bool KToggleToolBarAction::eventFilter(QObject *watched, QEvent *event) 59 | { 60 | if (d->beingToggled) { 61 | return false; 62 | } 63 | 64 | d->beingToggled = true; 65 | 66 | if (watched == d->toolBar) { 67 | switch (event->type()) { 68 | case QEvent::Hide: 69 | if (isChecked()) { 70 | setChecked(false); 71 | } 72 | break; 73 | 74 | case QEvent::Show: 75 | if (!isChecked()) { 76 | setChecked(true); 77 | } 78 | break; 79 | 80 | default: 81 | break; 82 | } 83 | } 84 | 85 | d->beingToggled = false; 86 | 87 | return false; 88 | } 89 | 90 | KToolBar *KToggleToolBarAction::toolBar() 91 | { 92 | return d->toolBar; 93 | } 94 | 95 | void KToggleToolBarAction::slotToggled(bool checked) 96 | { 97 | if (!d->beingToggled && d->toolBar && checked != d->toolBar->isVisible()) { 98 | d->beingToggled = true; 99 | d->toolBar->setVisible(checked); 100 | d->beingToggled = false; 101 | 102 | QMainWindow *mw = d->toolBar->mainWindow(); 103 | if (mw && qobject_cast(mw)) { 104 | static_cast(mw)->setSettingsDirty(); 105 | } 106 | } 107 | 108 | KToggleAction::slotToggled(checked); 109 | } 110 | 111 | #include "moc_ktoggletoolbaraction.cpp" 112 | -------------------------------------------------------------------------------- /src/ktoggletoolbaraction.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 1999 Reginald Stadlbauer 4 | SPDX-FileCopyrightText: 1999 Simon Hausmann 5 | SPDX-FileCopyrightText: 2000 Nicolas Hadacek 6 | SPDX-FileCopyrightText: 2000 Kurt Granroth 7 | SPDX-FileCopyrightText: 2000 Michael Koch 8 | SPDX-FileCopyrightText: 2001 Holger Freyther 9 | SPDX-FileCopyrightText: 2002 Ellis Whitehead 10 | SPDX-FileCopyrightText: 2003 Andras Mantia 11 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda 12 | 13 | SPDX-License-Identifier: LGPL-2.0-only 14 | */ 15 | 16 | #ifndef KTOGGLETOOLBARACTION_H 17 | #define KTOGGLETOOLBARACTION_H 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | class KToolBar; 24 | 25 | /*! 26 | * \class KToggleToolBarAction 27 | * \inmodule KXmlGui 28 | * 29 | * An action that takes care of everything associated with 30 | * showing or hiding a toolbar by a menu action. It will 31 | * show or hide the toolbar with the given name when 32 | * activated, and check or uncheck itself if the toolbar 33 | * is manually shown or hidden. 34 | * 35 | * If you need to perform some additional action when the 36 | * toolbar is shown or hidden, connect to the toggled(bool) 37 | * signal. It will be emitted after the toolbar's 38 | * visibility has changed, whenever it changes. 39 | */ 40 | class KXMLGUI_EXPORT KToggleToolBarAction : public KToggleAction 41 | { 42 | Q_OBJECT 43 | 44 | public: 45 | /*! 46 | * \brief Creates a KToggleToolBarAction that manages the \a toolBar 47 | * with \a text in its label, as a child of \a parent. 48 | */ 49 | KToggleToolBarAction(KToolBar *toolBar, const QString &text, QObject *parent); 50 | 51 | /*! 52 | * \brief Destroys the toggle toolbar action. 53 | */ 54 | ~KToggleToolBarAction() override; 55 | 56 | /*! 57 | * \brief Returns a pointer to the tool bar it manages. 58 | */ 59 | KToolBar *toolBar(); 60 | 61 | /*! 62 | * \brief Filters then returns the specified \a event 63 | * for a given \a watched object. 64 | * 65 | * Reimplemented from QObject. 66 | */ 67 | bool eventFilter(QObject *watched, QEvent *event) override; 68 | 69 | private Q_SLOTS: 70 | void slotToggled(bool checked) override; 71 | 72 | private: 73 | std::unique_ptr const d; 74 | }; 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /src/ktoolbarhandler_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2002 Simon Hausmann 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only 6 | */ 7 | 8 | #ifndef KTOOLBARHANDLER_H 9 | #define KTOOLBARHANDLER_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | class KXmlGuiWindow; 16 | 17 | namespace KDEPrivate 18 | { 19 | class ToolBarHandler : public QObject, public KXMLGUIClient 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | /*! 25 | * Creates a new tool bar handler for the supplied 26 | * \a mainWindow. 27 | */ 28 | explicit ToolBarHandler(KXmlGuiWindow *mainWindow); 29 | 30 | /*! 31 | * Creates a new tool bar handler for the supplied 32 | * \a mainWindow and with the supplied parent. 33 | */ 34 | ToolBarHandler(KXmlGuiWindow *mainWindow, QObject *parent); 35 | 36 | /*! 37 | * Destroys the tool bar handler. 38 | */ 39 | ~ToolBarHandler() override; 40 | 41 | /*! 42 | * Returns the action which is responsible for the tool bar menu. 43 | */ 44 | QAction *toolBarMenuAction(); 45 | 46 | public Q_SLOTS: 47 | void setupActions(); 48 | 49 | private Q_SLOTS: 50 | void clientAdded(KXMLGUIClient *client); 51 | 52 | private: 53 | class Private; 54 | Private *const d; 55 | }; 56 | 57 | } // namespace KDEPrivate 58 | 59 | #endif // KTOOLBARHANDLER_H 60 | -------------------------------------------------------------------------------- /src/ktoolbarhelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2017 Alexander Potashev 3 | 4 | SPDX-License-Identifier: LGPL-2.1-or-later 5 | */ 6 | 7 | #include "ktoolbarhelper_p.h" 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace KToolbarHelper 14 | { 15 | QString i18nToolBarName(const QDomElement &element) 16 | { 17 | QDomElement textElement; 18 | bool textElementFound = false; 19 | const QList textKeys = {QStringLiteral("text"), QStringLiteral("Text")}; 20 | for (const QString &key : textKeys) { 21 | QDomNode textNode = element.namedItem(key); 22 | if (textNode.isElement()) { 23 | textElement = textNode.toElement(); 24 | textElementFound = true; 25 | break; 26 | } 27 | } 28 | 29 | if (!textElementFound) { 30 | return element.attribute(QStringLiteral("name")); 31 | } 32 | 33 | QByteArray domain = textElement.attribute(QStringLiteral("translationDomain")).toUtf8(); 34 | QByteArray text = textElement.text().toUtf8(); 35 | QByteArray context = textElement.attribute(QStringLiteral("context")).toUtf8(); 36 | 37 | if (domain.isEmpty()) { 38 | domain = element.ownerDocument().documentElement().attribute(QStringLiteral("translationDomain")).toUtf8(); 39 | if (domain.isEmpty()) { 40 | domain = KLocalizedString::applicationDomain(); 41 | } 42 | } 43 | QString i18nText; 44 | if (!text.isEmpty() && !context.isEmpty()) { 45 | i18nText = i18ndc(domain.constData(), context.constData(), text.constData()); 46 | } else if (!text.isEmpty()) { 47 | i18nText = i18nd(domain.constData(), text.constData()); 48 | } 49 | return i18nText; 50 | } 51 | 52 | } // namespace KToolbarHelper 53 | -------------------------------------------------------------------------------- /src/ktoolbarhelper_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2017 Alexander Potashev 3 | 4 | SPDX-License-Identifier: LGPL-2.1-or-later 5 | */ 6 | 7 | #ifndef KTOOLBARHELPER_P_H 8 | #define KTOOLBARHELPER_P_H 9 | 10 | #include 11 | 12 | namespace KToolbarHelper 13 | { 14 | QString i18nToolBarName(const QDomElement &element); 15 | 16 | } 17 | 18 | #endif // KTOOLBARHELPER_P_H 19 | -------------------------------------------------------------------------------- /src/ktooltiphelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2021 Felix Ernst 4 | 5 | SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-2-Clause 6 | */ 7 | 8 | #ifndef KTOOLTIPHELPER_H 9 | #define KTOOLTIPHELPER_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | class KToolTipHelperPrivate; 18 | 19 | /*! 20 | * \class KToolTipHelper 21 | * \inmodule KXmlGui 22 | * 23 | * \brief An event filter used to enhance tooltips. 24 | * 25 | * Example: 26 | * Without this class, a tooltip of a QToolButton of a "New" action will read something like 27 | * "New File". Using this class, the tooltip can be enhanced to read something like 28 | * "New File (Ctrl+N)" and in the next line smaller "Press Shift for help.". 29 | * Pressing Shift will open the "What's This" context help for that widget. If a hyperlink in 30 | * that help is clicked, the corresponding event will also be filtered by this class and open 31 | * the linked location. 32 | * 33 | * The extra text added to tooltips is only shown when available and where it makes sense. If a 34 | * QToolButton has no associated shortcut and an empty QWidget::whatsThis(), this class won't 35 | * tamper with the requested tooltip at all. 36 | * 37 | * This class also activates tooltips for actions in QMenus but only when it makes sense like when 38 | * the tooltip isn't equal to the already displayed text. 39 | * 40 | * If you want the "Press Shift for help." line to be displayed for a widget that has whatsThis() 41 | * but no toolTip() take a look at KToolTipHelper::whatsThisHintOnly(). 42 | * 43 | * The enhanced tooltips can be enabled at any time after the QApplication was constructed with: 44 | * 45 | * \code 46 | * qApp->installEventFilter(KToolTipHelper::instance()); 47 | * \endcode 48 | * 49 | * Therefore, to de-activate them you can call the following any time later: 50 | * 51 | * \code 52 | * qApp->removeEventFilter(KToolTipHelper::instance()); 53 | * \endcode 54 | * 55 | * If you want KToolTipHelper to not tamper with certain QEvents, e.g. you want to handle some 56 | * tooltips differently or you want to change what happens when a QWhatsThisClickedEvent is 57 | * processed, first remove KToolTipHelper as an event filter just like in the line of code above. 58 | * Then create your own custom EventFilter that handles those QEvents differently and, for all 59 | * cases that you don't want to handle differently, call: 60 | * \code 61 | * return KToolTipHelper::instance()->eventFilter(watched, event); 62 | * \endcode 63 | * 64 | * Since 5.84, KMainWindow installs this EventFilter by default. 65 | * If you want to opt out of that, remove the EventFilter 66 | * in the constructor of your MainWindow class inheriting from KMainWindow. 67 | * 68 | * \sa QToolTip 69 | * \since 5.84 70 | */ 71 | class KXMLGUI_EXPORT KToolTipHelper : public QObject 72 | { 73 | Q_OBJECT 74 | Q_DISABLE_COPY(KToolTipHelper) 75 | 76 | public: 77 | static KToolTipHelper *instance(); 78 | 79 | /*! 80 | * \brief Filters the given \a event for a given \a watched object. 81 | * 82 | * Filters QEvent::ToolTip if an enhanced tooltip is available for the widget. 83 | * Filters the QEvent::KeyPress that is used to expand an expandable tooltip. 84 | * Filters QEvent::WhatsThisClicked so hyperlinks in whatsThis() texts work. 85 | * 86 | * \sa QObject::eventFilter() 87 | * \sa QHelpEvent 88 | */ 89 | bool eventFilter(QObject *watched, QEvent *event) override; 90 | 91 | /*! 92 | * \brief Use this to have a widget show "Press Shift for help." as its tooltip. 93 | * 94 | * Example usage: 95 | * \code 96 | * widget->setToolTip(KToolTipHelper::whatsThisHintOnly()); 97 | * \endcode 98 | * 99 | * KToolTipHelper won't show that tooltip if the widget's whatsThis() is empty. 100 | * 101 | * Returns a QString that is interpreted by this class to show the expected tooltip. 102 | */ 103 | static const QString whatsThisHintOnly(); 104 | 105 | private: 106 | KXMLGUI_NO_EXPORT explicit KToolTipHelper(QObject *parent); 107 | 108 | KXMLGUI_NO_EXPORT ~KToolTipHelper() override; 109 | 110 | private: 111 | std::unique_ptr const d; 112 | 113 | friend class KToolTipHelperPrivate; 114 | }; 115 | 116 | #endif // KTOOLTIPHELPER_H 117 | -------------------------------------------------------------------------------- /src/ktooltiphelper_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2021 Felix Ernst 4 | 5 | SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-2-Clause 6 | */ 7 | 8 | #ifndef KTOOLTIPHELPER_P_H 9 | #define KTOOLTIPHELPER_P_H 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | class KToolTipHelper; 18 | 19 | class QAction; 20 | class QHelpEvent; 21 | class QMenu; 22 | 23 | /*! 24 | * \brief The private class of KToolTipHelper used for the PIMPL idiom. 25 | * \inmodule KXmlGui 26 | * \internal 27 | */ 28 | class KToolTipHelperPrivate : public QObject 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | /*! 34 | * \brief Singleton implementation for KToolTipHelper and 35 | * NOT of this class (KToolTipHelperPrivate). 36 | */ 37 | static KToolTipHelper *instance(); 38 | 39 | explicit KToolTipHelperPrivate(KToolTipHelper *qq); 40 | 41 | ~KToolTipHelperPrivate() override; 42 | 43 | /*! \sa KToolTipHelper::eventFilter() */ 44 | bool eventFilter(QObject *watched, QEvent *event) override; 45 | 46 | /*! \sa KToolTipHelper::whatsThisHintOnly() */ 47 | static const QString whatsThisHintOnly(); 48 | 49 | /*! 50 | * \brief Makes sure submenus that show up do not mess with tooltips appearing in menus. 51 | * 52 | * This is somewhat of a workaround for Qt not posting QEvent::ToolTips when the 53 | * cursor wasn't moved *after* a submenu hides. 54 | * 55 | * Returns false. 56 | */ 57 | bool handleHideEvent(QObject *watched, QEvent *event); 58 | 59 | /*! 60 | * \brief Returns \c true if the key press is used to 61 | * expand a tooltip, \c false otherwise. 62 | */ 63 | bool handleKeyPressEvent(QEvent *event); 64 | 65 | /*! 66 | * Is called from handleToolTipEvent() to handle a QEvent::ToolTip in a menu. 67 | * This method will show the tooltip of the action that is hovered at a nice 68 | * position. 69 | * 70 | * \a menu The menu that a tooltip is requested for. 71 | * 72 | * \a helpEvent The QEvent::ToolTip that was cast to a QHelpEvent. 73 | */ 74 | bool handleMenuToolTipEvent(QMenu *menu, QHelpEvent *helpEvent); 75 | 76 | /*! 77 | * \brief Returns \c false if no special handling of the tooltip event 78 | * seems necessary, \c true otherwise. 79 | * 80 | * \a watched The object that is receiving the QHelpEvent. 81 | * 82 | * \a helpEvent The QEvent::ToolTip that was cast to a QHelpEvent. 83 | */ 84 | bool handleToolTipEvent(QObject *watched, QHelpEvent *helpEvent); 85 | 86 | /*! 87 | * \brief Handles links being clicked in whatsThis. 88 | * 89 | * Returns true. 90 | */ 91 | bool handleWhatsThisClickedEvent(QEvent *event); 92 | 93 | /*! 94 | * \brief The name is slightly misleading because it will only post events for QMenus. 95 | * \sa handleHideEvent() 96 | */ 97 | void postToolTipEventIfCursorDidntMove() const; 98 | 99 | /*! 100 | * \brief Shows a tooltip that contains a whatsThisHint 101 | * at the location \a globalPos. 102 | * 103 | * If \a tooltip is empty, only a whatsThisHint is shown. 104 | * 105 | * The parameter usage is identical to that of QToolTip::showText. The only difference 106 | * is that this method doesn't need a QWidget *w parameter because that one is already 107 | * retrieved in handleToolTipEvent() prior to calling this method. 108 | * 109 | * \sa QToolTip::showText() 110 | */ 111 | void showExpandableToolTip(const QPoint &globalPos, const QString &toolTip = QString(), const QRect &rect = QRect()); 112 | 113 | public: 114 | KToolTipHelper *const q; 115 | 116 | private: 117 | /*! \brief An action in a menu a tooltip was requested for. */ 118 | QPointer m_action; 119 | /*! 120 | * \brief The global position where the last tooltip 121 | * that had a whatsThisHint was displayed. 122 | */ 123 | QPoint m_lastExpandableToolTipGlobalPos; 124 | /*! \brief The last widget a QEvent::tooltip was sent for. */ 125 | QPointer m_widget; 126 | /*! \brief Whether or not the last tooltip was expandable. */ 127 | bool m_lastToolTipWasExpandable = false; 128 | 129 | /*! 130 | * \brief The global position of where the cursor was when the last 131 | * QEvent::HideEvent for a menu occurred. 132 | * 133 | * \sa handleHideEvent() */ 134 | QPoint m_cursorGlobalPosWhenLastMenuHid; 135 | /*! 136 | * \brief Calls postToolTipEventIfCursorDidntMove(). 137 | * \sa handleHideEvent() 138 | */ 139 | QTimer m_toolTipTimeout; 140 | 141 | static KToolTipHelper *s_instance; 142 | }; 143 | 144 | /* 145 | * This method checks if string "a" is sufficiently different 146 | * from string "b", barring characters like periods, ampersands 147 | * and other characters. 148 | * 149 | * Used for determining if tooltips are different from their icon name counterparts. 150 | * 151 | * Returns true if the string "a" is similar to "b" and false otherwise. 152 | */ 153 | bool isTextSimilar(const QString &a, const QString &b); 154 | 155 | #endif // KTOOLTIPHELPER_P_H 156 | -------------------------------------------------------------------------------- /src/kundoactions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2006 Peter Simonsson 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #include "kundoactions.h" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | QAction *KUndoActions::createRedoAction(QUndoStack *undoStack, KActionCollection *actionCollection, const QString &actionName) 20 | { 21 | QAction *action = undoStack->createRedoAction(actionCollection); 22 | 23 | if (actionName.isEmpty()) { 24 | action->setObjectName(KStandardActions::name(KStandardActions::Redo)); 25 | } else { 26 | action->setObjectName(actionName); 27 | } 28 | 29 | action->setIcon(QIcon::fromTheme(QStringLiteral("edit-redo"))); 30 | action->setIconText(i18n("Redo")); 31 | KActionCollection::setDefaultShortcuts(action, KStandardShortcut::redo()); 32 | 33 | actionCollection->addAction(action->objectName(), action); 34 | 35 | return action; 36 | } 37 | 38 | QAction *KUndoActions::createUndoAction(QUndoStack *undoStack, KActionCollection *actionCollection, const QString &actionName) 39 | { 40 | QAction *action = undoStack->createUndoAction(actionCollection); 41 | 42 | if (actionName.isEmpty()) { 43 | action->setObjectName(KStandardActions::name(KStandardActions::Undo)); 44 | } else { 45 | action->setObjectName(actionName); 46 | } 47 | 48 | action->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo"))); 49 | action->setIconText(i18n("Undo")); 50 | KActionCollection::setDefaultShortcuts(action, KStandardShortcut::undo()); 51 | 52 | actionCollection->addAction(action->objectName(), action); 53 | 54 | return action; 55 | } 56 | -------------------------------------------------------------------------------- /src/kundoactions.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2006 Peter Simonsson 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #ifndef KUNDOACTIONS_H 9 | #define KUNDOACTIONS_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | class KActionCollection; 16 | class QAction; 17 | class QUndoStack; 18 | 19 | /*! 20 | * \brief Provides functions that creates undo/redo actions for a QUndoStack with KDE's default icons and shortcuts. 21 | * 22 | * \namespace KUndoActions 23 | * \inmodule KXmlGui 24 | * 25 | * See QUndoStack for more information. 26 | * 27 | * \since 5.0 28 | */ 29 | namespace KUndoActions 30 | { 31 | /*! 32 | * \brief Creates an redo action with the default shortcut and icon 33 | * and adds it to \a actionCollection. 34 | * 35 | * \a undoStack the QUndoStack the action triggers the redo on 36 | * 37 | * \a actionCollection the KActionCollection that should be the parent of the action 38 | * 39 | * \a actionName the created action's object name, empty string will set it to the KDE default 40 | * 41 | * Returns the created action. 42 | */ 43 | KXMLGUI_EXPORT QAction *createRedoAction(QUndoStack *undoStack, KActionCollection *actionCollection, const QString &actionName = QString()); 44 | 45 | /*! 46 | * \brief Creates an undo action with the default KDE shortcut and icon 47 | * and adds it to \a actionCollection. 48 | * 49 | * Returns the created action. 50 | * 51 | * \a undoStack The QUndoStack the action triggers the undo on. 52 | * 53 | * \a actionCollection The KActionCollection that should be the parent of the action. 54 | * 55 | * \a actionName The created action's object name, empty string 56 | * will set it to the KDE default. 57 | */ 58 | KXMLGUI_EXPORT QAction *createUndoAction(QUndoStack *undoStack, KActionCollection *actionCollection, const QString &actionName = QString()); 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/kxmlgui-index.qdoc: -------------------------------------------------------------------------------- 1 | /*! 2 | \page kxmlgui-index.html 3 | \title KXmlGui 4 | 5 | KXmlGui is a collection of convenience classes and widgets to manage your app's main window. 6 | 7 | \section1 Using the Module 8 | 9 | \include {module-use.qdocinc} {using the c++ api} 10 | 11 | \section2 Building with CMake 12 | 13 | \include {module-use.qdocinc} {building with cmake} {KF6} {XmlGui} {KF6::XmlGui} 14 | 15 | \section1 API Reference 16 | 17 | \list 18 | \li \l{KXmlGui C++ Classes} 19 | \endlist 20 | */ 21 | -------------------------------------------------------------------------------- /src/kxmlgui.qdoc: -------------------------------------------------------------------------------- 1 | /*! 2 | \module KXmlGui 3 | \title KXmlGui C++ Classes 4 | \ingroup modules 5 | \cmakepackage KF6 6 | \cmakecomponent XmlGui 7 | 8 | \brief KXmlGui is a collection of convenience classes and widgets to manage your own main QtWidgets window. 9 | 10 | A window can be created using \l KXmlGuiWindow and \l KMainWindow. 11 | 12 | Shortcuts can be centrally managed using \l KActionCollection. 13 | 14 | The actions are configured through a XML description and hooks in the application code. The framework supports merging of multiple description for example for integrating actions from plugins. 15 | 16 | KXMLGui makes use of the Kiosk authorization functionality of KConfig (see the \l KAuthorized namespace in that framework). Notably, \l QAction instances added to a \l KActionCollection are disabled if \l KAuthorized::authorizeAction() reports that they are not authorized. The items on the standard help menu (\l KHelpMenu) can likewise be disabled based on Kiosk settings, and toolbar editing can be restricted. 17 | 18 | See \l KActionCollection, \l KHelpMenu and \l KToolBar documentation for more information. 19 | */ 20 | -------------------------------------------------------------------------------- /src/kxmlgui.qdocconf: -------------------------------------------------------------------------------- 1 | include($KDE_DOCS/global/qt-module-defaults.qdocconf) 2 | 3 | project = KXmlGui 4 | description = Collection of convenience classes and widgets to manage your own main QtWidgets window 5 | 6 | documentationinheaders = true 7 | 8 | headerdirs += . 9 | sourcedirs += . 10 | 11 | imagedirs = ../docs/pics 12 | 13 | outputformats = HTML 14 | 15 | navigation.landingpage = "KXmlGui" 16 | 17 | depends += qtcore qtgui qtwidgets qtxml kcoreaddons kconfigcore kconfiggui kglobalaccel kconfigwidgets 18 | 19 | qhp.projects = KXmlGui 20 | 21 | qhp.KXmlGui.file = kxmlgui.qhp 22 | qhp.KXmlGui.namespace = org.kde.kxmlgui.$QT_VERSION_TAG 23 | qhp.KXmlGui.virtualFolder = kxmlgui 24 | qhp.KXmlGui.indexTitle = KXmlGui 25 | qhp.KXmlGui.indexRoot = 26 | 27 | qhp.KXmlGui.subprojects = classes 28 | qhp.KXmlGui.subprojects.classes.title = C++ Classes 29 | qhp.KXmlGui.subprojects.classes.indexTitle = KXmlGui C++ Classes 30 | qhp.KXmlGui.subprojects.classes.selectors = class fake:headerfile 31 | qhp.KXmlGui.subprojects.classes.sortPages = true 32 | 33 | tagfile = kxmlgui.tags 34 | -------------------------------------------------------------------------------- /src/kxmlgui.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ui_standards.rc 5 | aboutkde.svg 6 | thumb_frame.png 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/kxmlguibuilder.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE project 3 | SPDX-FileCopyrightText: 2000 Simon Hausmann 4 | SPDX-FileCopyrightText: 2000 David Faure 5 | 6 | SPDX-License-Identifier: LGPL-2.0-or-later 7 | */ 8 | 9 | #ifndef kxmlguibuilder_h 10 | #define kxmlguibuilder_h 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | class KXMLGUIBuilderPrivate; 18 | class KXMLGUIClient; 19 | 20 | class QAction; 21 | class QDomElement; 22 | class QWidget; 23 | 24 | /*! 25 | * \class KXMLGUIBuilder 26 | * \inmodule KXmlGui 27 | * 28 | * Implements the creation of the GUI (menubar, menus and toolbars) 29 | * as requested by the GUI factory. 30 | * 31 | * The virtual methods are mostly for historical reasons, there isn't really 32 | * a need to derive from KXMLGUIBuilder anymore. 33 | */ 34 | class KXMLGUI_EXPORT KXMLGUIBuilder 35 | { 36 | public: 37 | /*! 38 | * \brief Constructs a new KXMLGUIBuilder object from \a widget. 39 | */ 40 | explicit KXMLGUIBuilder(QWidget *widget); 41 | /*! 42 | * \brief Destructor. 43 | */ 44 | virtual ~KXMLGUIBuilder(); 45 | 46 | /* \internal */ 47 | KXMLGUIClient *builderClient() const; 48 | /* \internal */ 49 | void setBuilderClient(KXMLGUIClient *client); 50 | /* \internal */ 51 | QWidget *widget(); 52 | 53 | virtual QStringList containerTags() const; 54 | 55 | /*! 56 | * \brief Creates a container (menubar/menu/toolbar/statusbar/separator/...) 57 | * from an \a element at \a index in the XML file. 58 | * 59 | * \a parent The parent for the container. 60 | * 61 | * \a index The index where the container should be inserted 62 | * into the parent container/widget. 63 | * 64 | * \a element The element from the DOM tree describing the 65 | * container (use it to access container specified attributes 66 | * or child elements). 67 | * 68 | * \a containerAction The action created for this container; 69 | * used for e.g. passing to removeContainer. 70 | */ 71 | virtual QWidget *createContainer(QWidget *parent, int index, const QDomElement &element, QAction *&containerAction); 72 | 73 | /*! 74 | * \brief Removes the given \a container. 75 | * 76 | * \a parent The parent for the container. 77 | * 78 | * \a element The element from the DOM tree describing the container 79 | * (use it to access container specified attributes or child elements). 80 | * 81 | * \a containerAction The action created for this container. 82 | */ 83 | virtual void removeContainer(QWidget *container, QWidget *parent, QDomElement &element, QAction *containerAction); 84 | 85 | virtual QStringList customTags() const; 86 | 87 | virtual QAction *createCustomElement(QWidget *parent, int index, const QDomElement &element); 88 | 89 | virtual void finalizeGUI(KXMLGUIClient *client); 90 | 91 | protected: 92 | virtual void virtual_hook(int id, void *data); 93 | 94 | private: 95 | std::unique_ptr const d; 96 | }; 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /src/kxmlguiversionhandler_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2000 Simon Hausmann 4 | SPDX-FileCopyrightText: 2000 Kurt Granroth 5 | SPDX-FileCopyrightText: 2007 David Faure 6 | 7 | SPDX-License-Identifier: LGPL-2.0-or-later 8 | */ 9 | 10 | #ifndef KXMLGUIVERSIONHANDLER_P_H 11 | #define KXMLGUIVERSIONHANDLER_P_H 12 | 13 | #include 14 | 15 | /*! 16 | * \internal 17 | * \inmodule KXmlGui 18 | * \brief Helper class for KXMLGUIClient::setXMLFile. 19 | * 20 | * Finds the xml file with the largest version number and takes 21 | * care of keeping user settings (from the most local file) 22 | * like action shortcuts or toolbar customizations. 23 | * 24 | * This is about handling upgrades (a new version of the application 25 | * has been installed, with a new xmlgui file, and the user might have 26 | * a local modified version of an older xmlgui file). 27 | */ 28 | class KXmlGuiVersionHandler 29 | { 30 | public: 31 | explicit KXmlGuiVersionHandler(const QStringList &files); 32 | 33 | QString finalFile() const 34 | { 35 | return m_file; 36 | } 37 | QString finalDocument() const 38 | { 39 | return m_doc; 40 | } 41 | 42 | private: 43 | QString m_file; 44 | QString m_doc; 45 | }; 46 | 47 | #endif /* KXMLGUIVERSIONHANDLER_P_H */ 48 | -------------------------------------------------------------------------------- /src/systeminformation_p.h: -------------------------------------------------------------------------------- 1 | /* This file is part of the KDE project 2 | SPDX-FileCopyrightText: 1999 David Faure 3 | SPDX-FileCopyrightText: 2014 Alex Richardson 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | #ifndef SYSTEMINFORMATION_P_H 8 | #define SYSTEMINFORMATION_P_H 9 | 10 | #include 11 | 12 | namespace SystemInformation 13 | { 14 | QString userName(); 15 | } 16 | 17 | #if !defined(Q_OS_WIN) 18 | #include 19 | #include 20 | #include 21 | inline QString SystemInformation::userName() 22 | { 23 | struct passwd *p = getpwuid(getuid()); 24 | return QString::fromLatin1(p->pw_name); 25 | } 26 | 27 | #else 28 | #include 29 | #include 30 | #define SECURITY_WIN32 31 | #include 32 | // #include // GetUserNameEx 33 | 34 | inline QString SystemInformation::userName() 35 | { 36 | WCHAR nameBuffer[256]; 37 | DWORD bufsize = 256; 38 | if (!GetUserNameExW(NameDisplay, nameBuffer, &bufsize)) { 39 | return QStringLiteral("Unknown User"); // should never happen (translate?) 40 | } 41 | return QString::fromWCharArray(nameBuffer); 42 | } 43 | 44 | #endif 45 | 46 | #endif // SYSTEMINFORMATION_P_H 47 | -------------------------------------------------------------------------------- /src/thumb_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/kxmlgui/cd72d6ddaa512c8ef2a25bf776989cb9c99a2d88/src/thumb_frame.png -------------------------------------------------------------------------------- /src/ui_standards.rc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | &File 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | &Game 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | &Edit 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | &Move 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | &View 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | &Go 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | &Bookmarks 144 | 145 | 146 | 147 | 148 | 149 | &Tools 150 | 151 | 152 | 153 | &Settings 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | &Help 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | Main Toolbar 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include(ECMMarkAsTest) 3 | 4 | find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Test) 5 | 6 | macro(xmlgui_executable_tests) 7 | foreach(_testname ${ARGN}) 8 | add_executable(${_testname} ${_testname}.cpp) 9 | target_link_libraries(${_testname} Qt6::Test KF6::CoreAddons KF6::WidgetsAddons KF6::I18n KF6::XmlGui) 10 | ecm_mark_as_test(${_testname}) 11 | endforeach(_testname) 12 | endmacro() 13 | 14 | xmlgui_executable_tests( 15 | kbugreporttest 16 | kmainwindowrestoretest 17 | kmainwindowtest 18 | krulertest 19 | ktoolbartest 20 | kxmlguitest 21 | kxmlguiwindowtest 22 | kwindowtest 23 | ) 24 | 25 | # KTextWidgets dependency is only needed for this test 26 | find_package(KF6TextWidgets QUIET) 27 | if(TARGET KF6::TextWidgets) 28 | add_subdirectory(krichtexteditor) 29 | endif() 30 | -------------------------------------------------------------------------------- /tests/kbugreporttest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2005 Joseph Wenninger 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main(int argc, char **argv) 14 | { 15 | QApplication a(argc, argv); 16 | a.setQuitOnLastWindowClosed(false); 17 | 18 | // First a bug report to bugs.kde.org 19 | KAboutData about(QStringLiteral("kbugreporttest"), i18n("kbugreporttest"), QStringLiteral("version")); 20 | KBugReport rep(about); 21 | rep.exec(); 22 | 23 | // Then a bug report by email. 24 | // Change the email address to check if it worked :) 25 | KAboutData about1(QStringLiteral("kbugreporttest"), 26 | i18n("kbugreporttest"), 27 | QStringLiteral("version"), 28 | i18n("description"), 29 | KAboutLicense::Unknown, 30 | i18n("copyright"), 31 | i18n("bug report tool"), 32 | QString(), 33 | QStringLiteral("null@bugs.kde.org")); 34 | KBugReport rep1(about1); 35 | rep1.exec(); 36 | 37 | // Then a web bug report. 38 | KAboutData about2(QStringLiteral("kbugreporttest"), 39 | i18n("kbugreporttest"), 40 | QStringLiteral("version"), 41 | i18n("description"), 42 | KAboutLicense::Unknown, 43 | i18n("copyright"), 44 | i18n("bug report tool"), 45 | QString(), 46 | QStringLiteral("https://bugs.kde.org")); 47 | KBugReport rep2(about2); 48 | rep2.exec(); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /tests/kmainwindowrestoretest.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "kmainwindowrestoretest.h" 3 | 4 | #include 5 | #include 6 | 7 | // clang-format off 8 | #define MAKE_WINDOW( kind, title ) do { \ 9 | MainWin##kind * m = new MainWin##kind; \ 10 | m->setCaption( title ); \ 11 | m->setCentralWidget( new QLabel( title, m ) ); \ 12 | m->show(); \ 13 | } while ( false ) 14 | // clang-format on 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | QApplication::setApplicationName(QStringLiteral("kmainwindowrestoretest")); 19 | QApplication app(argc, argv); 20 | 21 | if (qApp->isSessionRestored()) { 22 | kRestoreMainWindows(); 23 | kRestoreMainWindows(); 24 | kRestoreMainWindows(); // should be equivalent to RESTORE() 25 | } else { 26 | MAKE_WINDOW(1, QStringLiteral("First 1")); 27 | MAKE_WINDOW(1, QStringLiteral("Second 1")); 28 | MAKE_WINDOW(2, QStringLiteral("Only 2")); 29 | MAKE_WINDOW(3, QStringLiteral("First 3")); 30 | MAKE_WINDOW(4, QStringLiteral("First 4")); 31 | MAKE_WINDOW(4, QStringLiteral("Second 4")); 32 | MAKE_WINDOW(3, QStringLiteral("Second 3")); 33 | MAKE_WINDOW(4, QStringLiteral("Third 4")); 34 | MAKE_WINDOW(5, QStringLiteral("First 5")); 35 | MAKE_WINDOW(5, QStringLiteral("Second 5")); 36 | MAKE_WINDOW(1, QStringLiteral("Only 6")); 37 | } 38 | 39 | return app.exec(); 40 | } 41 | 42 | #include "moc_kmainwindowrestoretest.cpp" 43 | -------------------------------------------------------------------------------- /tests/kmainwindowrestoretest.h: -------------------------------------------------------------------------------- 1 | #ifndef _KDEUI_TESTS_KMAINWINDOWRESTORETEST_H_ 2 | #define _KDEUI_TESTS_KMAINWINDOWRESTORETEST_H_ 3 | 4 | #include 5 | 6 | class MainWin1 : public KMainWindow 7 | { 8 | Q_OBJECT 9 | public: 10 | MainWin1() 11 | : KMainWindow() 12 | { 13 | } 14 | ~MainWin1() override 15 | { 16 | } 17 | }; 18 | 19 | class MainWin2 : public KMainWindow 20 | { 21 | Q_OBJECT 22 | public: 23 | MainWin2() 24 | : KMainWindow() 25 | { 26 | } 27 | ~MainWin2() override 28 | { 29 | } 30 | }; 31 | 32 | class MainWin3 : public KMainWindow 33 | { 34 | Q_OBJECT 35 | public: 36 | MainWin3() 37 | : KMainWindow() 38 | { 39 | } 40 | ~MainWin3() override 41 | { 42 | } 43 | }; 44 | 45 | class MainWin4 : public KMainWindow 46 | { 47 | Q_OBJECT 48 | public: 49 | MainWin4() 50 | : KMainWindow() 51 | { 52 | } 53 | ~MainWin4() override 54 | { 55 | } 56 | }; 57 | 58 | class MainWin5 : public KMainWindow 59 | { 60 | Q_OBJECT 61 | public: 62 | MainWin5() 63 | : KMainWindow() 64 | { 65 | } 66 | ~MainWin5() override 67 | { 68 | } 69 | }; 70 | 71 | class MainWin6 : public KMainWindow 72 | { 73 | Q_OBJECT 74 | public: 75 | MainWin6() 76 | : KMainWindow() 77 | { 78 | } 79 | ~MainWin6() override 80 | { 81 | } 82 | }; 83 | 84 | #endif // _KDEUI_TESTS_KMAINWINDOWRESTORETEST_H_ 85 | -------------------------------------------------------------------------------- /tests/kmainwindowtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2002 Simon Hausmann 3 | SPDX-FileCopyrightText: 2005-2006 David Faure 4 | 5 | SPDX-License-Identifier: LGPL-2.0-or-later 6 | */ 7 | 8 | #include "kmainwindowtest.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | MainWindow::MainWindow() 17 | { 18 | QTimer::singleShot(2 * 1000, this, &MainWindow::showMessage); 19 | 20 | setCentralWidget(new QLabel(QStringLiteral("foo"), this)); 21 | 22 | menuBar()->addAction(QStringLiteral("hi")); 23 | } 24 | 25 | void MainWindow::showMessage() 26 | { 27 | statusBar()->show(); 28 | statusBar()->showMessage(QStringLiteral("test")); 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | QApplication::setApplicationName(QStringLiteral("kmainwindowtest")); 34 | QApplication app(argc, argv); 35 | 36 | MainWindow *mw = new MainWindow; // deletes itself when closed 37 | mw->show(); 38 | 39 | return app.exec(); 40 | } 41 | 42 | #include "moc_kmainwindowtest.cpp" 43 | -------------------------------------------------------------------------------- /tests/kmainwindowtest.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2002 Simon Hausmann 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #ifndef KMAINWINDOWTEST_H 8 | #define KMAINWINDOWTEST_H 9 | 10 | #include 11 | 12 | class MainWindow : public KMainWindow 13 | { 14 | Q_OBJECT 15 | public: 16 | MainWindow(); 17 | 18 | private Q_SLOTS: 19 | void showMessage(); 20 | }; 21 | 22 | #endif // KMAINWINDOWTEST_H 23 | -------------------------------------------------------------------------------- /tests/krichtexteditor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(krichtexteditor) 2 | 3 | target_sources(krichtexteditor PRIVATE 4 | main.cpp 5 | krichtexteditor.cpp 6 | ) 7 | 8 | target_include_directories(krichtexteditor PRIVATE 9 | ${CMAKE_CURRENT_SOURCE_DIR}/.. 10 | ${CMAKE_CURRENT_BINARY_DIR}/.. 11 | ) 12 | ecm_mark_as_test(krichtexteditor) 13 | target_link_libraries(krichtexteditor Qt6::Test KF6::ConfigWidgets KF6::TextWidgets KF6::XmlGui) 14 | 15 | #install(TARGETS krichtexteditor DESTINATION ${KDE_INSTALL_BINDIR}) 16 | #install(FILES krichtexteditorui.rc DESTINATION ${KDE_INSTALL_KXMLGUIDIR}/krichtexteditor) 17 | 18 | -------------------------------------------------------------------------------- /tests/krichtexteditor/krichtexteditor.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | KDE Rich Text Editor 3 | SPDX-FileCopyrightText: 2008 Stephen Kelly 4 | 5 | SPDX-License-Identifier: LGPL-2.1-or-later 6 | */ 7 | 8 | #include "krichtexteditor.h" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | KRichTextEditor::KRichTextEditor() 22 | : KXmlGuiWindow() 23 | { 24 | setupActions(); 25 | 26 | textArea = new KRichTextWidget(this); 27 | setCentralWidget(textArea); 28 | 29 | actionCollection()->addActions(textArea->createActions()); 30 | 31 | setupGUI(KXmlGuiWindow::Default, QFINDTESTDATA("krichtexteditorui.rc")); 32 | 33 | itemLabel = new QLabel; 34 | statusBar()->addWidget(itemLabel); 35 | 36 | connect(textArea, &KRichTextWidget::cursorPositionChanged, this, &KRichTextEditor::cursorPositionChanged); 37 | } 38 | 39 | KRichTextEditor::~KRichTextEditor() 40 | { 41 | } 42 | 43 | void KRichTextEditor::setupActions() 44 | { 45 | KStandardActions::quit(qApp, &QCoreApplication::quit, actionCollection()); 46 | 47 | KStandardActions::open(this, &KRichTextEditor::openFile, actionCollection()); 48 | 49 | KStandardActions::save(this, &KRichTextEditor::saveFile, actionCollection()); 50 | 51 | KStandardActions::saveAs(this, qOverload<>(&KRichTextEditor::saveFileAs), actionCollection()); 52 | 53 | KStandardActions::openNew(this, &KRichTextEditor::newFile, actionCollection()); 54 | } 55 | 56 | void KRichTextEditor::cursorPositionChanged() 57 | { 58 | // Show link target in status bar 59 | if (textArea->textCursor().charFormat().isAnchor()) { 60 | QString text = textArea->currentLinkText(); 61 | QString url = textArea->currentLinkUrl(); 62 | itemLabel->setText(text + QStringLiteral(" -> ") + url); 63 | } else { 64 | itemLabel->setText(QString()); 65 | } 66 | } 67 | 68 | void KRichTextEditor::newFile() 69 | { 70 | // maybeSave 71 | fileName.clear(); 72 | textArea->clear(); 73 | } 74 | 75 | void KRichTextEditor::saveFileAs(const QString &outputFileName) 76 | { 77 | QSaveFile file(outputFileName); 78 | if (!file.open(QIODevice::WriteOnly)) { 79 | return; 80 | } 81 | 82 | QByteArray outputByteArray; 83 | outputByteArray.append(textArea->toHtml().toUtf8()); 84 | file.write(outputByteArray); 85 | if (!file.commit()) { 86 | return; 87 | } 88 | 89 | fileName = outputFileName; 90 | } 91 | 92 | void KRichTextEditor::saveFileAs() 93 | { 94 | saveFileAs(QFileDialog::getSaveFileName()); 95 | } 96 | 97 | void KRichTextEditor::saveFile() 98 | { 99 | if (!fileName.isEmpty()) { 100 | saveFileAs(fileName); 101 | } else { 102 | saveFileAs(); 103 | } 104 | } 105 | 106 | void KRichTextEditor::openFile() 107 | { 108 | QString fileNameFromDialog = QFileDialog::getOpenFileName(); 109 | if (fileNameFromDialog.isEmpty()) { 110 | return; 111 | } 112 | 113 | QFile file(fileNameFromDialog); 114 | if (file.open(QIODevice::ReadOnly)) { 115 | textArea->setTextOrHtml(QTextStream(&file).readAll()); 116 | fileName = fileNameFromDialog; 117 | } 118 | } 119 | 120 | #include "moc_krichtexteditor.cpp" 121 | -------------------------------------------------------------------------------- /tests/krichtexteditor/krichtexteditor.h: -------------------------------------------------------------------------------- 1 | /* 2 | KDE Rich Text Editor 3 | SPDX-FileCopyrightText: 2008 Stephen Kelly 4 | 5 | SPDX-License-Identifier: LGPL-2.1-or-later 6 | */ 7 | 8 | #ifndef KRICHTEXTEDITOR_H 9 | #define KRICHTEXTEDITOR_H 10 | 11 | #include 12 | 13 | #include 14 | 15 | //@cond PRIVATE 16 | 17 | class QLabel; 18 | 19 | /*! 20 | * @internal 21 | * Test window for testing KRichTextWidget 22 | */ 23 | class KRichTextEditor : public KXmlGuiWindow 24 | { 25 | Q_OBJECT 26 | public: 27 | KRichTextEditor(); 28 | ~KRichTextEditor() override; 29 | 30 | void setupActions(); 31 | 32 | private Q_SLOTS: 33 | void newFile(); 34 | void openFile(); 35 | void saveFile(); 36 | void saveFileAs(); 37 | void saveFileAs(const QString &outputFileName); 38 | void cursorPositionChanged(); 39 | 40 | private: 41 | KRichTextWidget *textArea; 42 | QString fileName; 43 | QLabel *itemLabel; 44 | }; 45 | 46 | //@endcond 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /tests/krichtexteditor/krichtexteditorui.rc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | F&ormat 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | &Alignment 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Text Toolbar 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Format Toolbar 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /tests/krichtexteditor/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | KDE Rich Text Editor 3 | SPDX-FileCopyrightText: 2008 Stephen Kelly 4 | 5 | SPDX-License-Identifier: LGPL-2.1-or-later 6 | */ 7 | 8 | #include "krichtexteditor.h" 9 | #include 10 | 11 | int main(int argc, char **argv) 12 | { 13 | QApplication::setApplicationName(QStringLiteral("krichtexteditor")); 14 | QApplication app(argc, argv); 15 | KRichTextEditor *mw = new KRichTextEditor(); 16 | mw->show(); 17 | return app.exec(); 18 | } 19 | -------------------------------------------------------------------------------- /tests/krulertest.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | 3 | #ifndef krulertest_h 4 | #define krulertest_h 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | class KRuler; 11 | class QWidget; 12 | class QGridLayout; 13 | class QGroupBox; 14 | class QLabel; 15 | class QSpinBox; 16 | class QDoubleSpinBox; 17 | 18 | class MouseWidget : public QFrame 19 | { 20 | Q_OBJECT 21 | public: 22 | MouseWidget(QWidget *parent = nullptr); 23 | 24 | Q_SIGNALS: 25 | void newXPos(int); 26 | void newYPos(int); 27 | void newWidth(int); 28 | void newHeight(int); 29 | 30 | protected: 31 | void mousePressEvent(QMouseEvent *) override; 32 | void mouseReleaseEvent(QMouseEvent *) override; 33 | void mouseMoveEvent(QMouseEvent *) override; 34 | void resizeEvent(QResizeEvent *) override; 35 | 36 | private: 37 | bool mouseButtonDown; 38 | }; 39 | 40 | class KRulerTest : public QWidget 41 | { 42 | Q_OBJECT 43 | public: 44 | KRulerTest(); 45 | ~KRulerTest() override; 46 | 47 | private Q_SLOTS: 48 | void slotNewWidth(int); 49 | void slotNewHeight(int); 50 | 51 | void slotSetTinyMarks(bool); 52 | void slotSetLittleMarks(bool); 53 | void slotSetMediumMarks(bool); 54 | void slotSetBigMarks(bool); 55 | void slotSetEndMarks(bool); 56 | void slotSetRulerPointer(bool); 57 | 58 | void slotSetRulerLength(int); 59 | void slotFixRulerLength(bool); 60 | void slotSetMStyle(int); 61 | void slotUpdateShowMarks(); 62 | void slotCheckLength(bool); 63 | 64 | void slotSetRotate(double); 65 | void slotSetXTrans(double); 66 | void slotSetYTrans(double); 67 | 68 | private: 69 | KRuler *hruler, *vruler; 70 | QGridLayout *layout; 71 | QFrame *mainframe = nullptr; 72 | MouseWidget *bigwidget = nullptr; 73 | QFrame *miniwidget = nullptr; 74 | 75 | QLabel *mouse_message; 76 | QGroupBox *showMarks, *lineEdit, *vertrot; 77 | QCheckBox *showTM, *showLM, *showMM, *showBM, *showEM, *showPT, *fixLen; 78 | QSpinBox *beginMark, *endMark, *lengthInput; 79 | QDoubleSpinBox *transX, *transY, *rotV; 80 | QGroupBox *metricstyle; 81 | QRadioButton *pixelmetric, *inchmetric, *mmmetric, *cmmetric, *mmetric; 82 | }; 83 | #endif 84 | -------------------------------------------------------------------------------- /tests/ktoolbartest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | // This is a test for "Automatically hide extra toolbar separators" 9 | // If several separators are next to each other, only one should show up. 10 | 11 | int main(int argc, char **argv) 12 | { 13 | QApplication::setApplicationName(QStringLiteral("kactiontest")); 14 | QApplication app(argc, argv); 15 | 16 | KActionCollection coll(static_cast(nullptr)); 17 | 18 | QAction *action1 = coll.addAction(QStringLiteral("test1")); 19 | action1->setText(QStringLiteral("test1")); 20 | QAction *action2 = coll.addAction(QStringLiteral("test2")); 21 | action2->setText(QStringLiteral("test2")); 22 | QAction *action3 = coll.addAction(QStringLiteral("test3")); 23 | action3->setText(QStringLiteral("test3")); 24 | QAction *action4 = coll.addAction(QStringLiteral("test4")); 25 | action4->setText(QStringLiteral("test4")); 26 | QAction *action5 = coll.addAction(QStringLiteral("test5")); 27 | action5->setText(QStringLiteral("test5")); 28 | QAction *action6 = coll.addAction(QStringLiteral("test6")); 29 | action6->setText(QStringLiteral("test6")); 30 | QAction *action7 = coll.addAction(QStringLiteral("test7")); 31 | action7->setText(QStringLiteral("test7")); 32 | 33 | QMainWindow *mw = new QMainWindow(); 34 | KToolBar *tb = new KToolBar(mw); 35 | mw->addToolBar(tb); 36 | 37 | action2->setSeparator(true); 38 | action3->setSeparator(true); 39 | action7->setSeparator(true); 40 | 41 | coll.addAssociatedWidget(tb); 42 | 43 | mw->show(); 44 | 45 | app.exec(); 46 | 47 | mw->show(); 48 | 49 | action2->setVisible(false); 50 | 51 | app.exec(); 52 | 53 | mw->show(); 54 | 55 | action1->setVisible(false); 56 | 57 | return app.exec(); 58 | } 59 | -------------------------------------------------------------------------------- /tests/kwindowtest.h: -------------------------------------------------------------------------------- 1 | #ifndef KWINDOWTEST_H 2 | #define KWINDOWTEST_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class QTextEdit; 12 | class QComboBox; 13 | class QLineEdit; 14 | 15 | class TestWindow : public KXmlGuiWindow 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | TestWindow(QWidget *parent = nullptr); 21 | ~TestWindow() override; 22 | 23 | public Q_SLOTS: 24 | void beFixed(); 25 | void beYFixed(); 26 | 27 | void slotNew(); 28 | void slotPrint(); 29 | void slotReturn(); 30 | void slotSave(); 31 | void slotList(const QString &str); 32 | void slotOpen(); 33 | void slotCompletion(); 34 | void slotCompletionsMenu(QAction *action); 35 | void slotInsertClock(); 36 | void slotLined(); 37 | void slotImportant(); 38 | void slotExit(); 39 | void slotFrame(); 40 | void slotListCompletion(); 41 | void slotMessage(int, bool); 42 | void slotToggle(bool); 43 | void slotClearCombo(); 44 | void slotGoGoGoo(); 45 | void slotInsertListInCombo(); 46 | void slotMakeItem3Current(); 47 | void slotToggled(QAction *action); 48 | 49 | protected: 50 | QMenu *itemsMenu; 51 | QMenu *completions; 52 | QStatusBar *statusBar; 53 | KToolBar *tb; 54 | KToolBar *tb1; 55 | class QLineEdit *testLineEdit; 56 | class QComboBox *testComboBox; 57 | QAction *fileNewAction; 58 | QAction *exitAction; 59 | bool lineL; 60 | bool exitB; 61 | bool greenF; 62 | bool ena; 63 | QTextEdit *widget; 64 | QTimer *timer; 65 | QProgressBar *pr; 66 | }; 67 | #endif 68 | -------------------------------------------------------------------------------- /tests/kwindowtest.rc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | &File 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | F&ile2 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | &Settings 29 | 30 | 31 | 32 | 33 | 34 | 35 | Toolbar 1 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Toolbar 2 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /tests/kxmlguitest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2001 Simon Hausmann 3 | 4 | SPDX-License-Identifier: LGPL-2.0-or-later 5 | */ 6 | 7 | #include "kxmlguitest.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | void Client::slotSec() 21 | { 22 | qDebug() << "Client::slotSec()"; 23 | } 24 | 25 | int main(int argc, char **argv) 26 | { 27 | QApplication::setApplicationName(QStringLiteral("test")); 28 | QApplication app(argc, argv); 29 | QAction *a; 30 | 31 | KMainWindow *mainwindow = new KMainWindow; 32 | 33 | QLineEdit *line = new QLineEdit(mainwindow); 34 | mainwindow->setCentralWidget(line); 35 | 36 | mainwindow->show(); 37 | 38 | KXMLGUIBuilder *builder = new KXMLGUIBuilder(mainwindow); 39 | 40 | KXMLGUIFactory *factory = new KXMLGUIFactory(builder); 41 | 42 | Client *shell = new Client; 43 | shell->setComponentName(QStringLiteral("konqueror"), QStringLiteral("Konqueror")); 44 | 45 | a = new QAction(QIcon::fromTheme(QStringLiteral("view-split-left-right")), QStringLiteral("Split"), shell); 46 | shell->actionCollection()->addAction(QStringLiteral("splitviewh"), a); 47 | 48 | shell->setXMLFile(QFINDTESTDATA("kxmlguitest_shell.rc")); 49 | 50 | factory->addClient(shell); 51 | 52 | Client *part = new Client; 53 | 54 | a = new QAction(QIcon::fromTheme(QStringLiteral("zoom-out")), QStringLiteral("decfont"), part); 55 | part->actionCollection()->addAction(QStringLiteral("decFontSizes"), a); 56 | a = new QAction(QIcon::fromTheme(QStringLiteral("security-low")), QStringLiteral("sec"), part); 57 | part->actionCollection()->addAction(QStringLiteral("security"), a); 58 | KActionCollection::setDefaultShortcuts(a, QList() << QKeySequence{Qt::ALT | Qt::Key_1}); 59 | a->connect(a, &QAction::triggered, part, &Client::slotSec); 60 | 61 | part->setXMLFile(QFINDTESTDATA("kxmlguitest_part.rc")); 62 | 63 | factory->addClient(part); 64 | for (int i = 0; i < 10; ++i) { 65 | factory->removeClient(part); 66 | factory->addClient(part); 67 | } 68 | 69 | return app.exec(); 70 | } 71 | 72 | #include "moc_kxmlguitest.cpp" 73 | -------------------------------------------------------------------------------- /tests/kxmlguitest.h: -------------------------------------------------------------------------------- 1 | #ifndef KXMLGUITEST_H 2 | #define KXMLGUITEST_H 3 | 4 | #include 5 | #include 6 | 7 | class Client : public QObject, public KXMLGUIClient 8 | { 9 | Q_OBJECT 10 | public: 11 | Client() 12 | { 13 | } 14 | 15 | using KXMLGUIClient::setComponentName; 16 | using KXMLGUIClient::setXMLFile; 17 | 18 | public Q_SLOTS: 19 | void slotSec(); 20 | }; 21 | #endif 22 | -------------------------------------------------------------------------------- /tests/kxmlguitest_part.rc: -------------------------------------------------------------------------------- 1 | 2 | 3 | Main Toolbar 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/kxmlguitest_shell.rc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Main Toolbar 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/kxmlguiwindowtest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of the KDE libraries 3 | SPDX-FileCopyrightText: 2008 Rafael Fernández López 4 | 5 | SPDX-License-Identifier: LGPL-2.0-only 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // BUG: if this symbol is defined the problem consists on: 21 | // - main window is created. 22 | // - settings are saved (and applied), but in this case no toolbars exist yet, so they don't 23 | // apply to any toolbar. 24 | // - after 1 second the GUI is created. 25 | // 26 | // How to reproduce ? 27 | // - Move one toolbar to other place (bottom, left, right, or deattach it). 28 | // - Close the test (so settings are saved). 29 | // - Reopen the test. The toolbar you moved is not keeping the place you specified. 30 | #define REPRODUCE_TOOLBAR_BUG 31 | 32 | class MainWindow : public KXmlGuiWindow 33 | { 34 | Q_OBJECT 35 | 36 | public: 37 | MainWindow(QWidget *parent = nullptr); 38 | 39 | public Q_SLOTS: 40 | void slotTest(); 41 | void slotCreate(); 42 | 43 | private: 44 | void setupActions(); 45 | }; 46 | 47 | void MainWindow::slotTest() 48 | { 49 | KMessageBox::information(nullptr, QStringLiteral("Test"), QStringLiteral("Test")); 50 | } 51 | 52 | void MainWindow::slotCreate() 53 | { 54 | setupGUI(ToolBar | Keys); 55 | createGUI(xmlFile()); 56 | 57 | if (autoSaveConfigGroup().isValid()) { 58 | applyMainWindowSettings(autoSaveConfigGroup()); 59 | } 60 | } 61 | 62 | void MainWindow::setupActions() 63 | { 64 | QAction *testAction = new QAction(this); 65 | testAction->setText(QStringLiteral("Test")); 66 | testAction->setIcon(QIcon::fromTheme(QStringLiteral("kde"))); 67 | actionCollection()->addAction(QStringLiteral("test"), testAction); 68 | connect(testAction, &QAction::triggered, this, &MainWindow::slotTest); 69 | 70 | KStandardActions::quit(qApp, &QCoreApplication::quit, actionCollection()); 71 | 72 | setAutoSaveSettings(); 73 | 74 | // BUG: if the GUI is created after an amount of time (so settings have been saved), then toolbars 75 | // are shown misplaced. KMainWindow uses a 500 ms timer to save window settings. 76 | #ifdef REPRODUCE_TOOLBAR_BUG 77 | QTimer::singleShot(1000, this, &MainWindow::slotCreate); // more than 500 ms so the main window has saved settings. 78 | // We can think of this case on natural applications when they 79 | // load plugins and change parts. It can take 1 second perfectly. 80 | #else 81 | QTimer::singleShot(0, this, &MainWindow::slotCreate); 82 | #endif 83 | } 84 | 85 | MainWindow::MainWindow(QWidget *parent) 86 | : KXmlGuiWindow(parent) 87 | { 88 | setXMLFile(QFINDTESTDATA("kxmlguiwindowtestui.rc"), true); 89 | // Because we use a full path in setXMLFile, we need to call setLocalXMLFile too. 90 | // In your apps, just pass a relative filename to setXMLFile instead. 91 | setLocalXMLFile(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/kxmlguiwindowtest/kxmlguiwindowtestui.rc")); 92 | 93 | setCentralWidget(new QTextEdit(this)); 94 | setupActions(); 95 | } 96 | 97 | int main(int argc, char **argv) 98 | { 99 | QApplication app(argc, argv); 100 | 101 | MainWindow *mainWindow = new MainWindow; 102 | mainWindow->show(); 103 | 104 | return app.exec(); 105 | } 106 | 107 | #include "kxmlguiwindowtest.moc" 108 | -------------------------------------------------------------------------------- /tests/kxmlguiwindowtestui.rc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Main Toolbar 6 | 7 | 8 | 9 | Other Toolbar 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | --------------------------------------------------------------------------------