Import Upstream version 5.24.6

This commit is contained in:
rtlhq 2022-10-06 20:50:12 +08:00
commit 850d7e45e3
804 changed files with 180572 additions and 0 deletions

2
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,2 @@
# clang-format
24192da4d63dc5026d4da5285cfcad698767bae4

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
*~
build/
apidocs/
Doxyfile
*.patch
CMakeCache.txt
CMakeFiles
cmake_install.cmake
CMakeLists.txt.user
CMakeLists.txt.user.*
.clang-format
/build*/
cmake-build-debug*
.idea
/compile_commands.json
.clangd
.cache

6
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml

27
.kde-ci.yml Normal file
View File

@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
Dependencies:
- 'on': ['@all']
'require':
'frameworks/extra-cmake-modules': '@latest'
'frameworks/kactivities': '@latest'
'frameworks/kauth': '@latest'
'frameworks/kcmutils': '@latest'
'frameworks/kcodecs': '@latest'
'frameworks/kcompletion': '@latest'
'frameworks/kconfig': '@latest'
'frameworks/kconfigwidgets': '@latest'
'frameworks/kcoreaddons': '@latest'
'frameworks/kdeclarative': '@latest'
'frameworks/ki18n': '@latest'
'frameworks/kiconthemes': '@latest'
'frameworks/kio': '@latest'
'frameworks/kjobwidgets': '@latest'
'frameworks/kpty': '@latest'
'frameworks/kservice': '@latest'
'frameworks/ksu': '@latest'
'frameworks/kwidgetsaddons': '@latest'
'frameworks/kwindowsystem': '@latest'
'frameworks/solid': '@latest'
'plasma/plasma-workspace': '@same'

136
CMakeLists.txt Normal file
View File

@ -0,0 +1,136 @@
cmake_minimum_required(VERSION 3.16)
project(KDE-CLI-Tools)
set(PROJECT_VERSION "5.24.6")
set(QT_MIN_VERSION "5.15.0")
set(KF5_MIN_VERSION "5.86")
set(KDE_COMPILERSETTINGS_LEVEL "5.82")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMMarkAsTest)
include(ECMMarkNonGuiExecutable)
include(FeatureSummary)
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists)
include(ECMOptionalAddSubdirectory)
include(KDEClangFormat)
include(KDEGitCommitHooks)
find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
Widgets
Svg
DBus
)
find_package(Qt5Test ${QT_MIN_VERSION} CONFIG QUIET)
set_package_properties(Qt5Test PROPERTIES
PURPOSE "Required for tests"
TYPE OPTIONAL
)
add_feature_info("Qt5Test" Qt5Test_FOUND "Required for building tests")
if (NOT Qt5Test_FOUND)
set(BUILD_TESTING OFF CACHE BOOL "Build the testing tree.")
endif()
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
Config
DocTools
IconThemes
I18n
KCMUtils
KIO
Service
WindowSystem
Activities
Declarative
OPTIONAL_COMPONENTS
Su
QUIET
)
find_package(LibKWorkspace ${PROJECT_VERSION} REQUIRED)
# Disables automatic conversions from QString (or char *) to QUrl.
add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
find_package(X11)
find_package(XCB COMPONENTS XCB)
if(X11_FOUND AND XCB_XCB_FOUND)
set(HAVE_X11 1)
find_package(Qt5X11Extras ${QT_MIN_VERSION} CONFIG)
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(doc)
function(install_compat_symlink executable_target)
add_custom_command(TARGET ${executable_target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${executable_target} ${executable_target}5)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${executable_target}5 DESTINATION ${KDE_INSTALL_FULL_BINDIR})
endfunction()
add_subdirectory(kcmshell)
add_subdirectory(keditfiletype)
add_subdirectory(kmimetypefinder)
add_subdirectory(ktraderclient)
add_subdirectory(kioclient)
add_subdirectory(ksvgtopng)
add_subdirectory(kdeinhibit)
add_subdirectory(plasma-open-settings)
if(Qt5X11Extras_FOUND)
add_subdirectory(kstart)
endif()
if(KF5Su_FOUND)
add_subdirectory(kdesu)
endif()
if(UNIX)
add_subdirectory(kdeeject)
add_subdirectory(kbroadcastnotification)
endif()
check_include_files(sys/wait.h HAVE_SYS_WAIT_H)
check_include_file("sys/prctl.h" HAVE_SYS_PRCTL_H)
check_symbol_exists(PR_SET_DUMPABLE "sys/prctl.h" HAVE_PR_SET_DUMPABLE)
check_include_file("sys/procctl.h" HAVE_SYS_PROCCTL_H)
check_symbol_exists(PROC_TRACE_CTL "sys/procctl.h" HAVE_PROC_TRACE_CTL)
if (HAVE_PR_SET_DUMPABLE OR HAVE_PROC_TRACE_CTL)
set(CAN_DISABLE_PTRACE TRUE)
endif()
add_feature_info("prctl-dumpable"
CAN_DISABLE_PTRACE
"Required for disallowing ptrace on kdesu process")
configure_file (config-kde-cli-tools.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kde-cli-tools.h )
# add clang-format target for all our real source files
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES *.cpp *.h)
kde_clang_format(${ALL_CLANG_FORMAT_SOURCE_FILES})
kde_configure_git_pre_commit_hook(CHECKS CLANG_FORMAT)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
find_package(KF5I18n CONFIG REQUIRED)
ki18n_install(po)
find_package(KF5DocTools CONFIG)
if(KF5DocTools_FOUND)
kdoctools_install(po)
endif()

85
LICENSES/Artistic-2.0.txt Normal file
View File

@ -0,0 +1,85 @@
The Artistic License 2.0
Copyright (c) 2000-2006, The Perl Foundation.
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Preamble
This license establishes the terms under which a given free software Package may be copied, modified, distributed, and/or redistributed. The intent is that the Copyright Holder maintains some artistic control over the development of that Package while still keeping the Package available as open source and free software.
You are always permitted to make arrangements wholly outside of this license directly with the Copyright Holder of a given Package. If the terms of this license do not permit the full use that you propose to make of the Package, you should contact the Copyright Holder and seek a different licensing arrangement.
Definitions
"Copyright Holder" means the individual(s) or organization(s) named in the copyright notice for the entire Package.
"Contributor" means any party that has contributed code or other material to the Package, in accordance with the Copyright Holder's procedures.
"You" and "your" means any person who would like to copy, distribute, or modify the Package.
"Package" means the collection of files distributed by the Copyright Holder, and derivatives of that collection and/or of those files. A given Package may consist of either the Standard Version, or a Modified Version.
"Distribute" means providing a copy of the Package or making it accessible to anyone else, or in the case of a company or organization, to others outside of your company or organization.
"Distributor Fee" means any fee that you charge for Distributing this Package or providing support for this Package to another party. It does not mean licensing fees.
"Standard Version" refers to the Package if it has not been modified, or has been modified only in ways explicitly requested by the Copyright Holder.
"Modified Version" means the Package, if it has been changed, and such changes were not explicitly requested by the Copyright Holder.
"Original License" means this Artistic License as Distributed with the Standard Version of the Package, in its current version or as it may be modified by The Perl Foundation in the future.
"Source" form means the source code, documentation source, and configuration files for the Package.
"Compiled" form means the compiled bytecode, object code, binary, or any other form resulting from mechanical transformation or translation of the Source form.
Permission for Use and Modification Without Distribution
(1) You are permitted to use the Standard Version and create and use Modified Versions for any purpose without restriction, provided that you do not Distribute the Modified Version.
Permissions for Redistribution of the Standard Version
(2) You may Distribute verbatim copies of the Source form of the Standard Version of this Package in any medium without restriction, either gratis or for a Distributor Fee, provided that you duplicate all of the original copyright notices and associated disclaimers. At your discretion, such verbatim copies may or may not include a Compiled form of the Package.
(3) You may apply any bug fixes, portability changes, and other modifications made available from the Copyright Holder. The resulting Package will still be considered the Standard Version, and as such will be subject to the Original License.
Distribution of Modified Versions of the Package as Source
(4) You may Distribute your Modified Version as Source (either gratis or for a Distributor Fee, and with or without a Compiled form of the Modified Version) provided that you clearly document how it differs from the Standard Version, including, but not limited to, documenting any non-standard features, executables, or modules, and provided that you do at least ONE of the following:
(a) make the Modified Version available to the Copyright Holder of the Standard Version, under the Original License, so that the Copyright Holder may include your modifications in the Standard Version.
(b) ensure that installation of your Modified Version does not prevent the user installing or running the Standard Version. In addition, the Modified Version must bear a name that is different from the name of the Standard Version.
(c) allow anyone who receives a copy of the Modified Version to make the Source form of the Modified Version available to others under
(i) the Original License or
(ii) a license that permits the licensee to freely copy, modify and redistribute the Modified Version using the same licensing terms that apply to the copy that the licensee received, and requires that the Source form of the Modified Version, and of any works derived from it, be made freely available in that license fees are prohibited but Distributor Fees are allowed.
Distribution of Compiled Forms of the Standard Version or Modified Versions without the Source
(5) You may Distribute Compiled forms of the Standard Version without the Source, provided that you include complete instructions on how to get the Source of the Standard Version. Such instructions must be valid at the time of your distribution. If these instructions, at any time while you are carrying out such distribution, become invalid, you must provide new instructions on demand or cease further distribution. If you provide valid instructions or cease distribution within thirty days after you become aware that the instructions are invalid, then you do not forfeit any of your rights under this license.
(6) You may Distribute a Modified Version in Compiled form without the Source, provided that you comply with Section 4 with respect to the Source of the Modified Version.
Aggregating or Linking the Package
(7) You may aggregate the Package (either the Standard Version or Modified Version) with other packages and Distribute the resulting aggregation provided that you do not charge a licensing fee for the Package. Distributor Fees are permitted, and licensing fees for other components in the aggregation are permitted. The terms of this license apply to the use and Distribution of the Standard or Modified Versions as included in the aggregation.
(8) You are permitted to link Modified and Standard Versions with other works, to embed the Package in a larger work of your own, or to build stand-alone binary or bytecode versions of applications that include the Package, and Distribute the result without restriction, provided the result does not expose a direct interface to the Package.
Items That are Not Considered Part of a Modified Version
(9) Works (including, but not limited to, modules and scripts) that merely extend or make use of the Package, do not, by themselves, cause the Package to be a Modified Version. In addition, such works are not considered parts of the Package itself, and are not subject to the terms of this license.
General Provisions
(10) Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
(11) If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
(12) This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
(13) This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
(14) Disclaimer of Warranty:
THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,130 @@
GNU Free Documentation License
Version 1.2, November 2002
Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
C. State on the Title page the name of the publisher of the Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties--for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements".
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.

311
LICENSES/GPL-2.0-only.txt Normal file
View File

@ -0,0 +1,311 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public License is intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users. This General Public License applies to
most of the Free Software Foundation's software and to any other program whose
authors commit to using it. (Some other Free Software Foundation software
is covered by the GNU Lesser General Public License instead.) You can apply
it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must give the recipients all the rights that you have. You
must make sure that they, too, receive or can get the source code. And you
must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2)
offer you this license which gives you legal permission to copy, distribute
and/or modify the software.
Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If
the software is modified by someone else and passed on, we want its recipients
to know that what they have is not the original, so that any problems introduced
by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that redistributors of a free program will individually
obtain patent licenses, in effect making the program proprietary. To prevent
this, we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms
of this General Public License. The "Program", below, refers to any such program
or work, and a "work based on the Program" means either the Program or any
derivative work under copyright law: that is to say, a work containing the
Program or a portion of it, either verbatim or with modifications and/or translated
into another language. (Hereinafter, translation is included without limitation
in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running the Program
is not restricted, and the output from the Program is covered only if its
contents constitute a work based on the Program (independent of having been
made by running the Program). Whether that is true depends on what the Program
does.
1. You may copy and distribute verbatim copies of the Program's source code
as you receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice and disclaimer of warranty;
keep intact all the notices that refer to this License and to the absence
of any warranty; and give any other recipients of the Program a copy of this
License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it,
thus forming a work based on the Program, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:
a) You must cause the modified files to carry prominent notices stating that
you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or
in part contains or is derived from the Program or any part thereof, to be
licensed as a whole at no charge to all third parties under the terms of this
License.
c) If the modified program normally reads commands interactively when run,
you must cause it, when started running for such interactive use in the most
ordinary way, to print or display an announcement including an appropriate
copyright notice and a notice that there is no warranty (or else, saying that
you provide a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this License.
(Exception: if the Program itself is interactive but does not normally print
such an announcement, your work based on the Program is not required to print
an announcement.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Program, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Program.
In addition, mere aggregation of another work not based on the Program with
the Program (or with a work based on the Program) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.
3. You may copy and distribute the Program (or a work based on it, under Section
2) in object code or executable form under the terms of Sections 1 and 2 above
provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source code,
which must be distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give
any third party, for a charge no more than your cost of physically performing
source distribution, a complete machine-readable copy of the corresponding
source code, to be distributed under the terms of Sections 1 and 2 above on
a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute
corresponding source code. (This alternative is allowed only for noncommercial
distribution and only if you received the program in object code or executable
form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making
modifications to it. For an executable work, complete source code means all
the source code for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation and installation
of the executable. However, as a special exception, the source code distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.
If distribution of executable or object code is made by offering access to
copy from a designated place, then offering equivalent access to copy the
source code from the same place counts as distribution of the source code,
even though third parties are not compelled to copy the source along with
the object code.
4. You may not copy, modify, sublicense, or distribute the Program except
as expressly provided under this License. Any attempt otherwise to copy, modify,
sublicense or distribute the Program is void, and will automatically terminate
your rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses terminated
so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Program or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Program
(or any work based on the Program), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program),
the recipient automatically receives a license from the original licensor
to copy, distribute or modify the Program subject to these terms and conditions.
You may not impose any further restrictions on the recipients' exercise of
the rights granted herein. You are not responsible for enforcing compliance
by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Program at all. For example, if a
patent license would not permit royalty-free redistribution of the Program
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply and
the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system, which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Program under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of
the General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Program does not specify a version number of this License, you may choose
any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For software which is copyrighted by the Free Software Foundation,
write to the Free Software Foundation; we sometimes make exceptions for this.
Our decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing and reuse
of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively convey the exclusion
of warranty; and each file should have at least the "copyright" line and a
pointer to where the full notice is found.
one line to give the program's name and an idea of what it does. Copyright
(C) yyyy name of author
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how
to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when
it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software,
and you are welcome to redistribute it under certain conditions; type `show
c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may be
called something other than `show w' and `show c'; they could even be mouse-clicks
or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
(which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice

View File

@ -0,0 +1,311 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public License is intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users. This General Public License applies to
most of the Free Software Foundation's software and to any other program whose
authors commit to using it. (Some other Free Software Foundation software
is covered by the GNU Lesser General Public License instead.) You can apply
it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must give the recipients all the rights that you have. You
must make sure that they, too, receive or can get the source code. And you
must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2)
offer you this license which gives you legal permission to copy, distribute
and/or modify the software.
Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If
the software is modified by someone else and passed on, we want its recipients
to know that what they have is not the original, so that any problems introduced
by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that redistributors of a free program will individually
obtain patent licenses, in effect making the program proprietary. To prevent
this, we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms
of this General Public License. The "Program", below, refers to any such program
or work, and a "work based on the Program" means either the Program or any
derivative work under copyright law: that is to say, a work containing the
Program or a portion of it, either verbatim or with modifications and/or translated
into another language. (Hereinafter, translation is included without limitation
in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running the Program
is not restricted, and the output from the Program is covered only if its
contents constitute a work based on the Program (independent of having been
made by running the Program). Whether that is true depends on what the Program
does.
1. You may copy and distribute verbatim copies of the Program's source code
as you receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice and disclaimer of warranty;
keep intact all the notices that refer to this License and to the absence
of any warranty; and give any other recipients of the Program a copy of this
License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion of it,
thus forming a work based on the Program, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:
a) You must cause the modified files to carry prominent notices stating that
you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in whole or
in part contains or is derived from the Program or any part thereof, to be
licensed as a whole at no charge to all third parties under the terms of this
License.
c) If the modified program normally reads commands interactively when run,
you must cause it, when started running for such interactive use in the most
ordinary way, to print or display an announcement including an appropriate
copyright notice and a notice that there is no warranty (or else, saying that
you provide a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this License.
(Exception: if the Program itself is interactive but does not normally print
such an announcement, your work based on the Program is not required to print
an announcement.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Program, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Program.
In addition, mere aggregation of another work not based on the Program with
the Program (or with a work based on the Program) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.
3. You may copy and distribute the Program (or a work based on it, under Section
2) in object code or executable form under the terms of Sections 1 and 2 above
provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable source code,
which must be distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three years, to give
any third party, for a charge no more than your cost of physically performing
source distribution, a complete machine-readable copy of the corresponding
source code, to be distributed under the terms of Sections 1 and 2 above on
a medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer to distribute
corresponding source code. (This alternative is allowed only for noncommercial
distribution and only if you received the program in object code or executable
form with such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for making
modifications to it. For an executable work, complete source code means all
the source code for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation and installation
of the executable. However, as a special exception, the source code distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.
If distribution of executable or object code is made by offering access to
copy from a designated place, then offering equivalent access to copy the
source code from the same place counts as distribution of the source code,
even though third parties are not compelled to copy the source along with
the object code.
4. You may not copy, modify, sublicense, or distribute the Program except
as expressly provided under this License. Any attempt otherwise to copy, modify,
sublicense or distribute the Program is void, and will automatically terminate
your rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses terminated
so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Program or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Program
(or any work based on the Program), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the Program),
the recipient automatically receives a license from the original licensor
to copy, distribute or modify the Program subject to these terms and conditions.
You may not impose any further restrictions on the recipients' exercise of
the rights granted herein. You are not responsible for enforcing compliance
by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Program at all. For example, if a
patent license would not permit royalty-free redistribution of the Program
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply and
the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system, which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Program under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions of
the General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Program does not specify a version number of this License, you may choose
any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For software which is copyrighted by the Free Software Foundation,
write to the Free Software Foundation; we sometimes make exceptions for this.
Our decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing and reuse
of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively convey the exclusion
of warranty; and each file should have at least the "copyright" line and a
pointer to where the full notice is found.
one line to give the program's name and an idea of what it does. Copyright
(C) yyyy name of author
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how
to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when
it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software,
and you are welcome to redistribute it under certain conditions; type `show
c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may be
called something other than `show w' and `show c'; they could even be mouse-clicks
or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
(which makes passes at compilers) written by James Hacker.
signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice

604
LICENSES/GPL-3.0-only.txt Normal file
View File

@ -0,0 +1,604 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for software and
other kinds of works.
The licenses for most software and other practical works are designed to take
away your freedom to share and change the works. By contrast, the GNU General
Public License is intended to guarantee your freedom to share and change all
versions of a program--to make sure it remains free software for all its users.
We, the Free Software Foundation, use the GNU General Public License for most
of our software; it applies also to any other work released this way by its
authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for them if you wish), that
you receive source code or can get it if you want it, that you can change
the software or use pieces of it in new free programs, and that you know you
can do these things.
To protect your rights, we need to prevent others from denying you these rights
or asking you to surrender the rights. Therefore, you have certain responsibilities
if you distribute copies of the software, or if you modify it: responsibilities
to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must pass on to the recipients the same freedoms that you received.
You must make sure that they, too, receive or can get the source code. And
you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert
copyright on the software, and (2) offer you this License giving you legal
permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that
there is no warranty for this free software. For both users' and authors'
sake, the GPL requires that modified versions be marked as changed, so that
their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified
versions of the software inside them, although the manufacturer can do so.
This is fundamentally incompatible with the aim of protecting users' freedom
to change the software. The systematic pattern of such abuse occurs in the
area of products for individuals to use, which is precisely where it is most
unacceptable. Therefore, we have designed this version of the GPL to prohibit
the practice for those products. If such problems arise substantially in other
domains, we stand ready to extend this provision to those domains in future
versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States
should not allow patents to restrict development and use of software on general-purpose
computers, but in those that do, we wish to avoid the special danger that
patents applied to a free program could make it effectively proprietary. To
prevent this, the GPL assures that patents cannot be used to render the program
non-free.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS
0. Definitions.
“This License” refers to version 3 of the GNU General Public License.
“Copyright” also means copyright-like laws that apply to other kinds of works,
such as semiconductor masks.
“The Program” refers to any copyrightable work licensed under this License.
Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals
or organizations.
To “modify” a work means to copy from or adapt all or part of the work in
a fashion requiring copyright permission, other than the making of an exact
copy. The resulting work is called a “modified version” of the earlier work
or a work “based on” the earlier work.
A “covered work” means either the unmodified Program or a work based on the
Program.
To “propagate” a work means to do anything with it that, without permission,
would make you directly or secondarily liable for infringement under applicable
copyright law, except executing it on a computer or modifying a private copy.
Propagation includes copying, distribution (with or without modification),
making available to the public, and in some countries other activities as
well.
To “convey” a work means any kind of propagation that enables other parties
to make or receive copies. Mere interaction with a user through a computer
network, with no transfer of a copy, is not conveying.
An interactive user interface displays “Appropriate Legal Notices” to the
extent that it includes a convenient and prominently visible feature that
(1) displays an appropriate copyright notice, and (2) tells the user that
there is no warranty for the work (except to the extent that warranties are
provided), that licensees may convey the work under this License, and how
to view a copy of this License. If the interface presents a list of user commands
or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The “source code” for a work means the preferred form of the work for making
modifications to it. “Object code” means any non-source form of a work.
A “Standard Interface” means an interface that either is an official standard
defined by a recognized standards body, or, in the case of interfaces specified
for a particular programming language, one that is widely used among developers
working in that language.
The “System Libraries” of an executable work include anything, other than
the work as a whole, that (a) is included in the normal form of packaging
a Major Component, but which is not part of that Major Component, and (b)
serves only to enable use of the work with that Major Component, or to implement
a Standard Interface for which an implementation is available to the public
in source code form. A “Major Component”, in this context, means a major essential
component (kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to produce
the work, or an object code interpreter used to run it.
The “Corresponding Source” for a work in object code form means all the source
code needed to generate, install, and (for an executable work) run the object
code and to modify the work, including scripts to control those activities.
However, it does not include the work's System Libraries, or general-purpose
tools or generally available free programs which are used unmodified in performing
those activities but which are not part of the work. For example, Corresponding
Source includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically linked
subprograms that the work is specifically designed to require, such as by
intimate data communication or control flow between those subprograms and
other parts of the work.
The Corresponding Source need not include anything that users can regenerate
automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright
on the Program, and are irrevocable provided the stated conditions are met.
This License explicitly affirms your unlimited permission to run the unmodified
Program. The output from running a covered work is covered by this License
only if the output, given its content, constitutes a covered work. This License
acknowledges your rights of fair use or other equivalent, as provided by copyright
law.
You may make, run and propagate covered works that you do not convey, without
conditions so long as your license otherwise remains in force. You may convey
covered works to others for the sole purpose of having them make modifications
exclusively for you, or provide you with facilities for running those works,
provided that you comply with the terms of this License in conveying all material
for which you do not control copyright. Those thus making or running the covered
works for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of your copyrighted
material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure
under any applicable law fulfilling obligations under article 11 of the WIPO
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention
of technological measures to the extent such circumvention is effected by
exercising rights under this License with respect to the covered work, and
you disclaim any intention to limit operation or modification of the work
as a means of enforcing, against the work's users, your or third parties'
legal rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive
it, in any medium, provided that you conspicuously and appropriately publish
on each copy an appropriate copyright notice; keep intact all notices stating
that this License and any non-permissive terms added in accord with section
7 apply to the code; keep intact all notices of the absence of any warranty;
and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you
may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce
it from the Program, in the form of source code under the terms of section
4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and
giving a relevant date.
b) The work must carry prominent notices stating that it is released under
this License and any conditions added under section 7. This requirement modifies
the requirement in section 4 to “keep intact all notices”.
c) You must license the entire work, as a whole, under this License to anyone
who comes into possession of a copy. This License will therefore apply, along
with any applicable section 7 additional terms, to the whole of the work,
and all its parts, regardless of how they are packaged. This License gives
no permission to license the work in any other way, but it does not invalidate
such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate
Legal Notices; however, if the Program has interactive interfaces that do
not display Appropriate Legal Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent works,
which are not by their nature extensions of the covered work, and which are
not combined with it such as to form a larger program, in or on a volume of
a storage or distribution medium, is called an “aggregate” if the compilation
and its resulting copyright are not used to limit the access or legal rights
of the compilation's users beyond what the individual works permit. Inclusion
of a covered work in an aggregate does not cause this License to apply to
the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections
4 and 5, provided that you also convey the machine-readable Corresponding
Source under the terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by the Corresponding Source fixed
on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by a written offer, valid for
at least three years and valid for as long as you offer spare parts or customer
support for that product model, to give anyone who possesses the object code
either (1) a copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical medium customarily
used for software interchange, for a price no more than your reasonable cost
of physically performing this conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written
offer to provide the Corresponding Source. This alternative is allowed only
occasionally and noncommercially, and only if you received the object code
with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis
or for a charge), and offer equivalent access to the Corresponding Source
in the same way through the same place at no further charge. You need not
require recipients to copy the Corresponding Source along with the object
code. If the place to copy the object code is a network server, the Corresponding
Source may be on a different server (operated by you or a third party) that
supports equivalent copying facilities, provided you maintain clear directions
next to the object code saying where to find the Corresponding Source. Regardless
of what server hosts the Corresponding Source, you remain obligated to ensure
that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform
other peers where the object code and Corresponding Source of the work are
being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from
the Corresponding Source as a System Library, need not be included in conveying
the object code work.
A “User Product” is either (1) a “consumer product”, which means any tangible
personal property which is normally used for personal, family, or household
purposes, or (2) anything designed or sold for incorporation into a dwelling.
In determining whether a product is a consumer product, doubtful cases shall
be resolved in favor of coverage. For a particular product received by a particular
user, “normally used” refers to a typical or common use of that class of product,
regardless of the status of the particular user or of the way in which the
particular user actually uses, or expects or is expected to use, the product.
A product is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent the
only significant mode of use of the product.
“Installation Information” for a User Product means any methods, procedures,
authorization keys, or other information required to install and execute modified
versions of a covered work in that User Product from a modified version of
its Corresponding Source. The information must suffice to ensure that the
continued functioning of the modified object code is in no case prevented
or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically
for use in, a User Product, and the conveying occurs as part of a transaction
in which the right of possession and use of the User Product is transferred
to the recipient in perpetuity or for a fixed term (regardless of how the
transaction is characterized), the Corresponding Source conveyed under this
section must be accompanied by the Installation Information. But this requirement
does not apply if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has been installed
in ROM).
The requirement to provide Installation Information does not include a requirement
to continue to provide support service, warranty, or updates for a work that
has been modified or installed by the recipient, or for the User Product in
which it has been modified or installed. Access to a network may be denied
when the modification itself materially and adversely affects the operation
of the network or violates the rules and protocols for communication across
the network.
Corresponding Source conveyed, and Installation Information provided, in accord
with this section must be in a format that is publicly documented (and with
an implementation available to the public in source code form), and must require
no special password or key for unpacking, reading or copying.
7. Additional Terms.
“Additional permissions” are terms that supplement the terms of this License
by making exceptions from one or more of its conditions. Additional permissions
that are applicable to the entire Program shall be treated as though they
were included in this License, to the extent that they are valid under applicable
law. If additional permissions apply only to part of the Program, that part
may be used separately under those permissions, but the entire Program remains
governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional
permissions may be written to require their own removal in certain cases when
you modify the work.) You may place additional permissions on material, added
by you to a covered work, for which you have or can give appropriate copyright
permission.
Notwithstanding any other provision of this License, for material you add
to a covered work, you may (if authorized by the copyright holders of that
material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of
sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author
attributions in that material or in the Appropriate Legal Notices displayed
by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring
that modified versions of such material be marked in reasonable ways as different
from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors
of the material; or
e) Declining to grant rights under trademark law for use of some trade names,
trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by
anyone who conveys the material (or modified versions of it) with contractual
assumptions of liability to the recipient, for any liability that these contractual
assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered “further restrictions”
within the meaning of section 10. If the Program as you received it, or any
part of it, contains a notice stating that it is governed by this License
along with a term that is a further restriction, you may remove that term.
If a license document contains a further restriction but permits relicensing
or conveying under this License, you may add to a covered work material governed
by the terms of that license document, provided that the further restriction
does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place,
in the relevant source files, a statement of the additional terms that apply
to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form
of a separately written license, or stated as exceptions; the above requirements
apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided
under this License. Any attempt otherwise to propagate or modify it is void,
and will automatically terminate your rights under this License (including
any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from
a particular copyright holder is reinstated (a) provisionally, unless and
until the copyright holder explicitly and finally terminates your license,
and (b) permanently, if the copyright holder fails to notify you of the violation
by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently
if the copyright holder notifies you of the violation by some reasonable means,
this is the first time you have received notice of violation of this License
(for any work) from that copyright holder, and you cure the violation prior
to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses
of parties who have received copies or rights from you under this License.
If your rights have been terminated and not permanently reinstated, you do
not qualify to receive new licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy
of the Program. Ancillary propagation of a covered work occurring solely as
a consequence of using peer-to-peer transmission to receive a copy likewise
does not require acceptance. However, nothing other than this License grants
you permission to propagate or modify any covered work. These actions infringe
copyright if you do not accept this License. Therefore, by modifying or propagating
a covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives
a license from the original licensors, to run, modify and propagate that work,
subject to this License. You are not responsible for enforcing compliance
by third parties with this License.
An “entity transaction” is a transaction transferring control of an organization,
or substantially all assets of one, or subdividing an organization, or merging
organizations. If propagation of a covered work results from an entity transaction,
each party to that transaction who receives a copy of the work also receives
whatever licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the Corresponding
Source of the work from the predecessor in interest, if the predecessor has
it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights
granted or affirmed under this License. For example, you may not impose a
license fee, royalty, or other charge for exercise of rights granted under
this License, and you may not initiate litigation (including a cross-claim
or counterclaim in a lawsuit) alleging that any patent claim is infringed
by making, using, selling, offering for sale, or importing the Program or
any portion of it.
11. Patents.
A “contributor” is a copyright holder who authorizes use under this License
of the Program or a work on which the Program is based. The work thus licensed
is called the contributor's “contributor version”.
A contributor's “essential patent claims” are all patent claims owned or controlled
by the contributor, whether already acquired or hereafter acquired, that would
be infringed by some manner, permitted by this License, of making, using,
or selling its contributor version, but do not include claims that would be
infringed only as a consequence of further modification of the contributor
version. For purposes of this definition, “control” includes the right to
grant patent sublicenses in a manner consistent with the requirements of this
License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
license under the contributor's essential patent claims, to make, use, sell,
offer for sale, import and otherwise run, modify and propagate the contents
of its contributor version.
In the following three paragraphs, a “patent license” is any express agreement
or commitment, however denominated, not to enforce a patent (such as an express
permission to practice a patent or covenant not to sue for patent infringement).
To “grant” such a patent license to a party means to make such an agreement
or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the
Corresponding Source of the work is not available for anyone to copy, free
of charge and under the terms of this License, through a publicly available
network server or other readily accessible means, then you must either (1)
cause the Corresponding Source to be so available, or (2) arrange to deprive
yourself of the benefit of the patent license for this particular work, or
(3) arrange, in a manner consistent with the requirements of this License,
to extend the patent license to downstream recipients. “Knowingly relying”
means you have actual knowledge that, but for the patent license, your conveying
the covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that country
that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement,
you convey, or propagate by procuring conveyance of, a covered work, and grant
a patent license to some of the parties receiving the covered work authorizing
them to use, propagate, modify or convey a specific copy of the covered work,
then the patent license you grant is automatically extended to all recipients
of the covered work and works based on it.
A patent license is “discriminatory” if it does not include within the scope
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
of one or more of the rights that are specifically granted under this License.
You may not convey a covered work if you are a party to an arrangement with
a third party that is in the business of distributing software, under which
you make payment to the third party based on the extent of your activity of
conveying the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory patent
license (a) in connection with copies of the covered work conveyed by you
(or copies made from those copies), or (b) primarily for and in connection
with specific products or compilations that contain the covered work, unless
you entered into that arrangement, or that patent license was granted, prior
to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied
license or other defenses to infringement that may otherwise be available
to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise)
that contradict the conditions of this License, they do not excuse you from
the conditions of this License. If you cannot convey a covered work so as
to satisfy simultaneously your obligations under this License and any other
pertinent obligations, then as a consequence you may not convey it at all.
For example, if you agree to terms that obligate you to collect a royalty
for further conveying from those to whom you convey the Program, the only
way you could satisfy both those terms and this License would be to refrain
entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to
link or combine any covered work with a work licensed under version 3 of the
GNU Affero General Public License into a single combined work, and to convey
the resulting work. The terms of this License will continue to apply to the
part which is the covered work, but the special requirements of the GNU Affero
General Public License, section 13, concerning interaction through a network
will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the
GNU General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
that a certain numbered version of the GNU General Public License “or any
later version” applies to it, you have the option of following the terms and
conditions either of that numbered version or of any later version published
by the Free Software Foundation. If the Program does not specify a version
number of the GNU General Public License, you may choose any version ever
published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of
the GNU General Public License can be used, that proxy's public statement
of acceptance of a version permanently authorizes you to choose that version
for the Program.
Later license versions may give you additional or different permissions. However,
no additional obligations are imposed on any author or copyright holder as
a result of your choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot
be given local legal effect according to their terms, reviewing courts shall
apply local law that most closely approximates an absolute waiver of all civil
liability in connection with the Program, unless a warranty or assumption
of liability accompanies a copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively state the exclusion
of warranty; and each file should have at least the “copyright” line and a
pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like
this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under certain
conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands might
be different; for a GUI interface, you would use an “about box”.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a “copyright disclaimer” for the program, if necessary. For
more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General Public
License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

444
LICENSES/LGPL-2.0-only.txt Normal file
View File

@ -0,0 +1,444 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
[This is the first released version of the library GPL. It is numbered 2
because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public Licenses are intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users.
This license, the Library General Public License, applies to some specially
designated Free Software Foundation software, and to any other libraries whose
authors decide to use it. You can use it for your libraries, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis or for
a fee, you must give the recipients all the rights that we gave you. You must
make sure that they, too, receive or can get the source code. If you link
a program with the library, you must provide complete object files to the
recipients so that they can relink them with the library, after making changes
to the library and recompiling it. And you must show them these terms so they
know their rights.
Our method of protecting your rights has two steps: (1) copyright the library,
and (2) offer you this license which gives you legal permission to copy, distribute
and/or modify the library.
Also, for each distributor's protection, we want to make certain that everyone
understands that there is no warranty for this free library. If the library
is modified by someone else and passed on, we want its recipients to know
that what they have is not the original version, so that any problems introduced
by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that companies distributing free software will individually
obtain patent licenses, thus in effect transforming the program into proprietary
software. To prevent this, we have made it clear that any patent must be licensed
for everyone's free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary GNU
General Public License, which was designed for utility programs. This license,
the GNU Library General Public License, applies to certain designated libraries.
This license is quite different from the ordinary one; be sure to read it
in full, and don't assume that anything in it is the same as in the ordinary
license.
The reason we have a separate public license for some libraries is that they
blur the distinction we usually make between modifying or adding to a program
and simply using it. Linking a program with a library, without changing the
library, is in some sense simply using the library, and is analogous to running
a utility program or application program. However, in a textual and legal
sense, the linked executable is a combined work, a derivative of the original
library, and the ordinary General Public License treats it as such.
Because of this blurred distinction, using the ordinary General Public License
for libraries did not effectively promote software sharing, because most developers
did not use the libraries. We concluded that weaker conditions might promote
sharing better.
However, unrestricted linking of non-free programs would deprive the users
of those programs of all benefit from the free status of the libraries themselves.
This Library General Public License is intended to permit developers of non-free
programs to use free libraries, while preserving your freedom as a user of
such programs to change the free libraries that are incorporated in them.
(We have not seen how to achieve this as regards changes in header files,
but we have achieved it as regards changes in the actual functions of the
Library.) The hope is that this will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and modification
follow. Pay close attention to the difference between a "work based on the
library" and a "work that uses the library". The former contains code derived
from the library, while the latter only works together with the library.
Note that it is possible for a library to be covered by the ordinary General
Public License rather than by this special one.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which contains a
notice placed by the copyright holder or other authorized party saying it
may be distributed under the terms of this Library General Public License
(also called "this License"). Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data prepared
so as to be conveniently linked with application programs (which use some
of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has
been distributed under these terms. A "work based on the Library" means either
the Library or any derivative work under copyright law: that is to say, a
work containing the Library or a portion of it, either verbatim or with modifications
and/or translated straightforwardly into another language. (Hereinafter, translation
is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications
to it. For a library, complete source code means all the source code for all
modules it contains, plus any associated interface definition files, plus
the scripts used to control compilation and installation of the library.
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running a program
using the Library is not restricted, and output from such a program is covered
only if its contents constitute a work based on the Library (independent of
the use of the Library in a tool for writing it). Whether that is true depends
on what the Library does and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and disclaimer
of warranty; keep intact all the notices that refer to this License and to
the absence of any warranty; and distribute a copy of this License along with
the Library.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of it,
thus forming a work based on the Library, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that
you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all
third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of
data to be supplied by an application program that uses the facility, other
than as an argument passed when the facility is invoked, then you must make
a good faith effort to ensure that, in the event an application does not supply
such function or table, the facility still operates, and performs whatever
part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose
that is entirely well-defined independent of the application. Therefore, Subsection
2d requires that any application-supplied function or table used by this function
must be optional: if the application does not supply it, the square root function
must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Library, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Library, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Library.
In addition, mere aggregation of another work not based on the Library with
the Library (or with a work based on the Library) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.
3. You may opt to apply the terms of the ordinary GNU General Public License
instead of this License to a given copy of the Library. To do this, you must
alter all the notices that refer to this License, so that they refer to the
ordinary GNU General Public License, version 2, instead of to this License.
(If a newer version than version 2 of the ordinary GNU General Public License
has appeared, then you can specify that version instead if you wish.) Do not
make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy,
so the ordinary GNU General Public License applies to all subsequent copies
and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the Library
into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of
it, under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you accompany it with the complete corresponding
machine-readable source code, which must be distributed under the terms of
Sections 1 and 2 above on a medium customarily used for software interchange.
If distribution of object code is made by offering access to copy from a designated
place, then offering equivalent access to copy the source code from the same
place satisfies the requirement to distribute the source code, even though
third parties are not compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but
is designed to work with the Library by being compiled or linked with it,
is called a "work that uses the Library". Such a work, in isolation, is not
a derivative work of the Library, and therefore falls outside the scope of
this License.
However, linking a "work that uses the Library" with the Library creates an
executable that is a derivative of the Library (because it contains portions
of the Library), rather than a "work that uses the library". The executable
is therefore covered by this License. Section 6 states terms for distribution
of such executables.
When a "work that uses the Library" uses material from a header file that
is part of the Library, the object code for the work may be a derivative work
of the Library even though the source code is not. Whether this is true is
especially significant if the work can be linked without the Library, or if
the work is itself a library. The threshold for this to be true is not precisely
defined by law.
If such an object file uses only numerical parameters, data structure layouts
and accessors, and small macros and small inline functions (ten lines or less
in length), then the use of the object file is unrestricted, regardless of
whether it is legally a derivative work. (Executables containing this object
code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute
the object code for the work under the terms of Section 6. Any executables
containing that work also fall under Section 6, whether or not they are linked
directly with the Library itself.
6. As an exception to the Sections above, you may also compile or link a "work
that uses the Library" with the Library to produce a work containing portions
of the Library, and distribute that work under terms of your choice, provided
that the terms permit modification of the work for the customer's own use
and reverse engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the Library
is used in it and that the Library and its use are covered by this License.
You must supply a copy of this License. If the work during execution displays
copyright notices, you must include the copyright notice for the Library among
them, as well as a reference directing the user to the copy of this License.
Also, you must do one of these things:
a) Accompany the work with the complete corresponding machine-readable source
code for the Library including whatever changes were used in the work (which
must be distributed under Sections 1 and 2 above); and, if the work is an
executable linked with the Library, with the complete machine-readable "work
that uses the Library", as object code and/or source code, so that the user
can modify the Library and then relink to produce a modified executable containing
the modified Library. (It is understood that the user who changes the contents
of definitions files in the Library will not necessarily be able to recompile
the application to use the modified definitions.)
b) Accompany the work with a written offer, valid for at least three years,
to give the same user the materials specified in Subsection 6a, above, for
a charge no more than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy from a designated
place, offer equivalent access to copy the above specified materials from
the same place.
d) Verify that the user has already received a copy of these materials or
that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library" must
include any data and utility programs needed for reproducing the executable
from it. However, as a special exception, the source code distributed need
not include anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the operating
system on which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license restrictions of
other proprietary libraries that do not normally accompany the operating system.
Such a contradiction means you cannot use both them and the Library together
in an executable that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side
in a single library together with other library facilities not covered by
this License, and distribute such a combined library, provided that the separate
distribution of the work based on the Library and of the other library facilities
is otherwise permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work based on the
Library, uncombined with any other library facilities. This must be distributed
under the terms of the Sections above.
b) Give prominent notice with the combined library of the fact that part of
it is a work based on the Library, and explaining where to find the accompanying
uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library
except as expressly provided under this License. Any attempt otherwise to
copy, modify, sublicense, link with, or distribute the Library is void, and
will automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Library or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Library
(or any work based on the Library), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library),
the recipient automatically receives a license from the original licensor
to copy, distribute, link with or modify the Library subject to these terms
and conditions. You may not impose any further restrictions on the recipients'
exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties to this License.
11. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Library at all. For example, if a
patent license would not permit royalty-free redistribution of the Library
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Library under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions of
the Library General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to address
new problems or concerns.
Each version is given a distinguishing version number. If the Library specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Library does not specify a license version number, you may choose any version
ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs
whose distribution conditions are incompatible with these, write to the author
to ask for permission. For software which is copyrighted by the Free Software
Foundation, write to the Free Software Foundation; we sometimes make exceptions
for this. Our decision will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible
use to the public, we recommend making it free software that everyone can
redistribute and change. You can do so by permitting redistribution under
these terms (or, alternatively, under the terms of the ordinary General Public
License).
To apply these terms, attach the following notices to the library. It is safest
to attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the "copyright"
line and a pointer to where the full notice is found.
one line to give the library's name and an idea of what it does.
Copyright (C) year name of author
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
more details.
You should have received a copy of the GNU Library General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the library, if necessary. Here
is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.
signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

View File

@ -0,0 +1,444 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
[This is the first released version of the library GPL. It is numbered 2
because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public Licenses are intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users.
This license, the Library General Public License, applies to some specially
designated Free Software Foundation software, and to any other libraries whose
authors decide to use it. You can use it for your libraries, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis or for
a fee, you must give the recipients all the rights that we gave you. You must
make sure that they, too, receive or can get the source code. If you link
a program with the library, you must provide complete object files to the
recipients so that they can relink them with the library, after making changes
to the library and recompiling it. And you must show them these terms so they
know their rights.
Our method of protecting your rights has two steps: (1) copyright the library,
and (2) offer you this license which gives you legal permission to copy, distribute
and/or modify the library.
Also, for each distributor's protection, we want to make certain that everyone
understands that there is no warranty for this free library. If the library
is modified by someone else and passed on, we want its recipients to know
that what they have is not the original version, so that any problems introduced
by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that companies distributing free software will individually
obtain patent licenses, thus in effect transforming the program into proprietary
software. To prevent this, we have made it clear that any patent must be licensed
for everyone's free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary GNU
General Public License, which was designed for utility programs. This license,
the GNU Library General Public License, applies to certain designated libraries.
This license is quite different from the ordinary one; be sure to read it
in full, and don't assume that anything in it is the same as in the ordinary
license.
The reason we have a separate public license for some libraries is that they
blur the distinction we usually make between modifying or adding to a program
and simply using it. Linking a program with a library, without changing the
library, is in some sense simply using the library, and is analogous to running
a utility program or application program. However, in a textual and legal
sense, the linked executable is a combined work, a derivative of the original
library, and the ordinary General Public License treats it as such.
Because of this blurred distinction, using the ordinary General Public License
for libraries did not effectively promote software sharing, because most developers
did not use the libraries. We concluded that weaker conditions might promote
sharing better.
However, unrestricted linking of non-free programs would deprive the users
of those programs of all benefit from the free status of the libraries themselves.
This Library General Public License is intended to permit developers of non-free
programs to use free libraries, while preserving your freedom as a user of
such programs to change the free libraries that are incorporated in them.
(We have not seen how to achieve this as regards changes in header files,
but we have achieved it as regards changes in the actual functions of the
Library.) The hope is that this will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and modification
follow. Pay close attention to the difference between a "work based on the
library" and a "work that uses the library". The former contains code derived
from the library, while the latter only works together with the library.
Note that it is possible for a library to be covered by the ordinary General
Public License rather than by this special one.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which contains a
notice placed by the copyright holder or other authorized party saying it
may be distributed under the terms of this Library General Public License
(also called "this License"). Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data prepared
so as to be conveniently linked with application programs (which use some
of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has
been distributed under these terms. A "work based on the Library" means either
the Library or any derivative work under copyright law: that is to say, a
work containing the Library or a portion of it, either verbatim or with modifications
and/or translated straightforwardly into another language. (Hereinafter, translation
is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications
to it. For a library, complete source code means all the source code for all
modules it contains, plus any associated interface definition files, plus
the scripts used to control compilation and installation of the library.
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running a program
using the Library is not restricted, and output from such a program is covered
only if its contents constitute a work based on the Library (independent of
the use of the Library in a tool for writing it). Whether that is true depends
on what the Library does and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and disclaimer
of warranty; keep intact all the notices that refer to this License and to
the absence of any warranty; and distribute a copy of this License along with
the Library.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of it,
thus forming a work based on the Library, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that
you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all
third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of
data to be supplied by an application program that uses the facility, other
than as an argument passed when the facility is invoked, then you must make
a good faith effort to ensure that, in the event an application does not supply
such function or table, the facility still operates, and performs whatever
part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose
that is entirely well-defined independent of the application. Therefore, Subsection
2d requires that any application-supplied function or table used by this function
must be optional: if the application does not supply it, the square root function
must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Library, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Library, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Library.
In addition, mere aggregation of another work not based on the Library with
the Library (or with a work based on the Library) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.
3. You may opt to apply the terms of the ordinary GNU General Public License
instead of this License to a given copy of the Library. To do this, you must
alter all the notices that refer to this License, so that they refer to the
ordinary GNU General Public License, version 2, instead of to this License.
(If a newer version than version 2 of the ordinary GNU General Public License
has appeared, then you can specify that version instead if you wish.) Do not
make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy,
so the ordinary GNU General Public License applies to all subsequent copies
and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the Library
into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of
it, under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you accompany it with the complete corresponding
machine-readable source code, which must be distributed under the terms of
Sections 1 and 2 above on a medium customarily used for software interchange.
If distribution of object code is made by offering access to copy from a designated
place, then offering equivalent access to copy the source code from the same
place satisfies the requirement to distribute the source code, even though
third parties are not compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but
is designed to work with the Library by being compiled or linked with it,
is called a "work that uses the Library". Such a work, in isolation, is not
a derivative work of the Library, and therefore falls outside the scope of
this License.
However, linking a "work that uses the Library" with the Library creates an
executable that is a derivative of the Library (because it contains portions
of the Library), rather than a "work that uses the library". The executable
is therefore covered by this License. Section 6 states terms for distribution
of such executables.
When a "work that uses the Library" uses material from a header file that
is part of the Library, the object code for the work may be a derivative work
of the Library even though the source code is not. Whether this is true is
especially significant if the work can be linked without the Library, or if
the work is itself a library. The threshold for this to be true is not precisely
defined by law.
If such an object file uses only numerical parameters, data structure layouts
and accessors, and small macros and small inline functions (ten lines or less
in length), then the use of the object file is unrestricted, regardless of
whether it is legally a derivative work. (Executables containing this object
code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute
the object code for the work under the terms of Section 6. Any executables
containing that work also fall under Section 6, whether or not they are linked
directly with the Library itself.
6. As an exception to the Sections above, you may also compile or link a "work
that uses the Library" with the Library to produce a work containing portions
of the Library, and distribute that work under terms of your choice, provided
that the terms permit modification of the work for the customer's own use
and reverse engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the Library
is used in it and that the Library and its use are covered by this License.
You must supply a copy of this License. If the work during execution displays
copyright notices, you must include the copyright notice for the Library among
them, as well as a reference directing the user to the copy of this License.
Also, you must do one of these things:
a) Accompany the work with the complete corresponding machine-readable source
code for the Library including whatever changes were used in the work (which
must be distributed under Sections 1 and 2 above); and, if the work is an
executable linked with the Library, with the complete machine-readable "work
that uses the Library", as object code and/or source code, so that the user
can modify the Library and then relink to produce a modified executable containing
the modified Library. (It is understood that the user who changes the contents
of definitions files in the Library will not necessarily be able to recompile
the application to use the modified definitions.)
b) Accompany the work with a written offer, valid for at least three years,
to give the same user the materials specified in Subsection 6a, above, for
a charge no more than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy from a designated
place, offer equivalent access to copy the above specified materials from
the same place.
d) Verify that the user has already received a copy of these materials or
that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library" must
include any data and utility programs needed for reproducing the executable
from it. However, as a special exception, the source code distributed need
not include anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the operating
system on which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license restrictions of
other proprietary libraries that do not normally accompany the operating system.
Such a contradiction means you cannot use both them and the Library together
in an executable that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side
in a single library together with other library facilities not covered by
this License, and distribute such a combined library, provided that the separate
distribution of the work based on the Library and of the other library facilities
is otherwise permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work based on the
Library, uncombined with any other library facilities. This must be distributed
under the terms of the Sections above.
b) Give prominent notice with the combined library of the fact that part of
it is a work based on the Library, and explaining where to find the accompanying
uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library
except as expressly provided under this License. Any attempt otherwise to
copy, modify, sublicense, link with, or distribute the Library is void, and
will automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Library or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Library
(or any work based on the Library), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library),
the recipient automatically receives a license from the original licensor
to copy, distribute, link with or modify the Library subject to these terms
and conditions. You may not impose any further restrictions on the recipients'
exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties to this License.
11. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Library at all. For example, if a
patent license would not permit royalty-free redistribution of the Library
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Library under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions of
the Library General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to address
new problems or concerns.
Each version is given a distinguishing version number. If the Library specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Library does not specify a license version number, you may choose any version
ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs
whose distribution conditions are incompatible with these, write to the author
to ask for permission. For software which is copyrighted by the Free Software
Foundation, write to the Free Software Foundation; we sometimes make exceptions
for this. Our decision will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible
use to the public, we recommend making it free software that everyone can
redistribute and change. You can do so by permitting redistribution under
these terms (or, alternatively, under the terms of the ordinary General Public
License).
To apply these terms, attach the following notices to the library. It is safest
to attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the "copyright"
line and a pointer to where the full notice is found.
one line to give the library's name and an idea of what it does.
Copyright (C) year name of author
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for
more details.
You should have received a copy of the GNU Library General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the library, if necessary. Here
is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.
signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

462
LICENSES/LGPL-2.1-only.txt Normal file
View File

@ -0,0 +1,462 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts as
the successor of the GNU Library Public License, version 2, hence the version
number 2.1.]
Preamble
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public Licenses are intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users.
This license, the Lesser General Public License, applies to some specially
designated software packages--typically libraries--of the Free Software Foundation
and other authors who decide to use it. You can use it too, but we suggest
you first think carefully about whether this license or the ordinary General
Public License is the better strategy to use in any particular case, based
on the explanations below.
When we speak of free software, we are referring to freedom of use, not price.
Our General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish); that you receive source code or can get it if you want it; that you
can change the software and use pieces of it in new free programs; and that
you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors
to deny you these rights or to ask you to surrender these rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for
a fee, you must give the recipients all the rights that we gave you. You must
make sure that they, too, receive or can get the source code. If you link
other code with the library, you must provide complete object files to the
recipients, so that they can relink them with the library after making changes
to the library and recompiling it. And you must show them these terms so they
know their rights.
We protect your rights with a two-step method: (1) we copyright the library,
and (2) we offer you this license, which gives you legal permission to copy,
distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no
warranty for the free library. Also, if the library is modified by someone
else and passed on, the recipients should know that what they have is not
the original version, so that the original author's reputation will not be
affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free
program. We wish to make sure that a company cannot effectively restrict the
users of a free program by obtaining a restrictive license from a patent holder.
Therefore, we insist that any patent license obtained for a version of the
library must be consistent with the full freedom of use specified in this
license.
Most GNU software, including some libraries, is covered by the ordinary GNU
General Public License. This license, the GNU Lesser General Public License,
applies to certain designated libraries, and is quite different from the ordinary
General Public License. We use this license for certain libraries in order
to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared
library, the combination of the two is legally speaking a combined work, a
derivative of the original library. The ordinary General Public License therefore
permits such linking only if the entire combination fits its criteria of freedom.
The Lesser General Public License permits more lax criteria for linking other
code with the library.
We call this license the "Lesser" General Public License because it does Less
to protect the user's freedom than the ordinary General Public License. It
also provides other free software developers Less of an advantage over competing
non-free programs. These disadvantages are the reason we use the ordinary
General Public License for many libraries. However, the Lesser license provides
advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the
widest possible use of a certain library, so that it becomes a de-facto standard.
To achieve this, non-free programs must be allowed to use the library. A more
frequent case is that a free library does the same job as widely used non-free
libraries. In this case, there is little to gain by limiting the free library
to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs
enables a greater number of people to use a large body of free software. For
example, permission to use the GNU C Library in non-free programs enables
many more people to use the whole GNU operating system, as well as its variant,
the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users'
freedom, it does ensure that the user of a program that is linked with the
Library has the freedom and the wherewithal to run that program using a modified
version of the Library.
The precise terms and conditions for copying, distribution and modification
follow. Pay close attention to the difference between a "work based on the
library" and a "work that uses the library". The former contains code derived
from the library, whereas the latter must be combined with the library in
order to run.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other program
which contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Lesser General
Public License (also called "this License"). Each licensee is addressed as
"you".
A "library" means a collection of software functions and/or data prepared
so as to be conveniently linked with application programs (which use some
of those functions and data) to form executables.
The "Library", below, refers to any such software library or work which has
been distributed under these terms. A "work based on the Library" means either
the Library or any derivative work under copyright law: that is to say, a
work containing the Library or a portion of it, either verbatim or with modifications
and/or translated straightforwardly into another language. (Hereinafter, translation
is included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for making modifications
to it. For a library, complete source code means all the source code for all
modules it contains, plus any associated interface definition files, plus
the scripts used to control compilation and installation of the library.
Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running a program
using the Library is not restricted, and output from such a program is covered
only if its contents constitute a work based on the Library (independent of
the use of the Library in a tool for writing it). Whether that is true depends
on what the Library does and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's complete source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and disclaimer
of warranty; keep intact all the notices that refer to this License and to
the absence of any warranty; and distribute a copy of this License along with
the Library.
You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Library or any portion of it,
thus forming a work based on the Library, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices stating that
you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no charge to all
third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a table of
data to be supplied by an application program that uses the facility, other
than as an argument passed when the facility is invoked, then you must make
a good faith effort to ensure that, in the event an application does not supply
such function or table, the facility still operates, and performs whatever
part of its purpose remains meaningful.
(For example, a function in a library to compute square roots has a purpose
that is entirely well-defined independent of the application. Therefore, Subsection
2d requires that any application-supplied function or table used by this function
must be optional: if the application does not supply it, the square root function
must still compute square roots.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Library, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Library, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Library.
In addition, mere aggregation of another work not based on the Library with
the Library (or with a work based on the Library) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.
3. You may opt to apply the terms of the ordinary GNU General Public License
instead of this License to a given copy of the Library. To do this, you must
alter all the notices that refer to this License, so that they refer to the
ordinary GNU General Public License, version 2, instead of to this License.
(If a newer version than version 2 of the ordinary GNU General Public License
has appeared, then you can specify that version instead if you wish.) Do not
make any other change in these notices.
Once this change is made in a given copy, it is irreversible for that copy,
so the ordinary GNU General Public License applies to all subsequent copies
and derivative works made from that copy.
This option is useful when you wish to copy part of the code of the Library
into a program that is not a library.
4. You may copy and distribute the Library (or a portion or derivative of
it, under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you accompany it with the complete corresponding
machine-readable source code, which must be distributed under the terms of
Sections 1 and 2 above on a medium customarily used for software interchange.
If distribution of object code is made by offering access to copy from a designated
place, then offering equivalent access to copy the source code from the same
place satisfies the requirement to distribute the source code, even though
third parties are not compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the Library, but
is designed to work with the Library by being compiled or linked with it,
is called a "work that uses the Library". Such a work, in isolation, is not
a derivative work of the Library, and therefore falls outside the scope of
this License.
However, linking a "work that uses the Library" with the Library creates an
executable that is a derivative of the Library (because it contains portions
of the Library), rather than a "work that uses the library". The executable
is therefore covered by this License. Section 6 states terms for distribution
of such executables.
When a "work that uses the Library" uses material from a header file that
is part of the Library, the object code for the work may be a derivative work
of the Library even though the source code is not. Whether this is true is
especially significant if the work can be linked without the Library, or if
the work is itself a library. The threshold for this to be true is not precisely
defined by law.
If such an object file uses only numerical parameters, data structure layouts
and accessors, and small macros and small inline functions (ten lines or less
in length), then the use of the object file is unrestricted, regardless of
whether it is legally a derivative work. (Executables containing this object
code plus portions of the Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may distribute
the object code for the work under the terms of Section 6. Any executables
containing that work also fall under Section 6, whether or not they are linked
directly with the Library itself.
6. As an exception to the Sections above, you may also combine or link a "work
that uses the Library" with the Library to produce a work containing portions
of the Library, and distribute that work under terms of your choice, provided
that the terms permit modification of the work for the customer's own use
and reverse engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the Library
is used in it and that the Library and its use are covered by this License.
You must supply a copy of this License. If the work during execution displays
copyright notices, you must include the copyright notice for the Library among
them, as well as a reference directing the user to the copy of this License.
Also, you must do one of these things:
a) Accompany the work with the complete corresponding machine-readable source
code for the Library including whatever changes were used in the work (which
must be distributed under Sections 1 and 2 above); and, if the work is an
executable linked with the Library, with the complete machine-readable "work
that uses the Library", as object code and/or source code, so that the user
can modify the Library and then relink to produce a modified executable containing
the modified Library. (It is understood that the user who changes the contents
of definitions files in the Library will not necessarily be able to recompile
the application to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the Library. A
suitable mechanism is one that (1) uses at run time a copy of the library
already present on the user's computer system, rather than copying library
functions into the executable, and (2) will operate properly with a modified
version of the library, if the user installs one, as long as the modified
version is interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least three years,
to give the same user the materials specified in Subsection 6a, above, for
a charge no more than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy from a designated
place, offer equivalent access to copy the above specified materials from
the same place.
e) Verify that the user has already received a copy of these materials or
that you have already sent this user a copy.
For an executable, the required form of the "work that uses the Library" must
include any data and utility programs needed for reproducing the executable
from it. However, as a special exception, the materials to be distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.
It may happen that this requirement contradicts the license restrictions of
other proprietary libraries that do not normally accompany the operating system.
Such a contradiction means you cannot use both them and the Library together
in an executable that you distribute.
7. You may place library facilities that are a work based on the Library side-by-side
in a single library together with other library facilities not covered by
this License, and distribute such a combined library, provided that the separate
distribution of the work based on the Library and of the other library facilities
is otherwise permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work based on the
Library, uncombined with any other library facilities. This must be distributed
under the terms of the Sections above.
b) Give prominent notice with the combined library of the fact that part of
it is a work based on the Library, and explaining where to find the accompanying
uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute the Library
except as expressly provided under this License. Any attempt otherwise to
copy, modify, sublicense, link with, or distribute the Library is void, and
will automatically terminate your rights under this License. However, parties
who have received copies, or rights, from you under this License will not
have their licenses terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Library or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Library
(or any work based on the Library), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the Library),
the recipient automatically receives a license from the original licensor
to copy, distribute, link with or modify the Library subject to these terms
and conditions. You may not impose any further restrictions on the recipients'
exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties with this License.
11. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Library at all. For example, if a
patent license would not permit royalty-free redistribution of the Library
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Library under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new versions of
the Lesser General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to address
new problems or concerns.
Each version is given a distinguishing version number. If the Library specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Library does not specify a license version number, you may choose any version
ever published by the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free programs
whose distribution conditions are incompatible with these, write to the author
to ask for permission. For software which is copyrighted by the Free Software
Foundation, write to the Free Software Foundation; we sometimes make exceptions
for this. Our decision will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest possible
use to the public, we recommend making it free software that everyone can
redistribute and change. You can do so by permitting redistribution under
these terms (or, alternatively, under the terms of the ordinary General Public
License).
To apply these terms, attach the following notices to the library. It is safest
to attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the "copyright"
line and a pointer to where the full notice is found.
one line to give the library's name and an idea of what it does.
Copyright (C) year name of author
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc., 51
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information
on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the library, if necessary. Here
is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in
the library `Frob' (a library for tweaking knobs) written
by James Random Hacker.
signature of Ty Coon, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

144
LICENSES/LGPL-3.0-only.txt Normal file
View File

@ -0,0 +1,144 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates the terms
and conditions of version 3 of the GNU General Public License, supplemented
by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser General
Public License, and the "GNU GPL" refers to version 3 of the GNU General Public
License.
"The Library" refers to a covered work governed by this License, other than
an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided by the
Library, but which is not otherwise based on the Library. Defining a subclass
of a class defined by the Library is deemed a mode of using an interface provided
by the Library.
A "Combined Work" is a work produced by combining or linking an Application
with the Library. The particular version of the Library with which the Combined
Work was made is also called the "Linked Version".
The "Minimal Corresponding Source" for a Combined Work means the Corresponding
Source for the Combined Work, excluding any source code for portions of the
Combined Work that, considered in isolation, are based on the Application,
and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the object
code and/or source code for the Application, including any data and utility
programs needed for reproducing the Combined Work from the Application, but
excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License without
being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a facility
refers to a function or data to be supplied by an Application that uses the
facility (other than as an argument passed when the facility is invoked),
then you may convey a copy of the modified version:
a) under this License, provided that you make a good faith effort to ensure
that, in the event an Application does not supply the function or data, the
facility still operates, and performs whatever part of its purpose remains
meaningful, or
b) under the GNU GPL, with none of the additional permissions of this License
applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from a header
file that is part of the Library. You may convey such object code under terms
of your choice, provided that, if the incorporated material is not limited
to numerical parameters, data structure layouts and accessors, or small macros,
inline functions and templates (ten or fewer lines in length), you do both
of the following:
a) Give prominent notice with each copy of the object code that the Library
is used in it and that the Library and its use are covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that, taken together,
effectively do not restrict modification of the portions of the Library contained
in the Combined Work and reverse engineering for debugging such modifications,
if you also do each of the following:
a) Give prominent notice with each copy of the Combined Work that the Library
is used in it and that the Library and its use are covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during execution, include
the copyright notice for the Library among these notices, as well as a reference
directing the user to the copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this License,
and the Corresponding Application Code in a form suitable for, and under terms
that permit, the user to recombine or relink the Application with a modified
version of the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
1) Use a suitable shared library mechanism for linking with the Library.
A suitable mechanism is one that (a) uses at run time a copy of the Library
already present on the user's computer system, and (b) will operate properly
with a modified version of the Library that is interface-compatible with the
Linked Version.
e) Provide Installation Information, but only if you would otherwise be required
to provide such information under section 6 of the GNU GPL, and only to the
extent that such information is necessary to install and execute a modified
version of the Combined Work produced by recombining or relinking the Application
with a modified version of the Linked Version. (If you use option 4d0, the
Installation Information must accompany the Minimal Corresponding Source and
Corresponding Application Code. If you use option 4d1, you must provide the
Installation Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the Library side
by side in a single library together with other library facilities that are
not Applications and are not covered by this License, and convey such a combined
library under terms of your choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based on the
Library, uncombined with any other library facilities, conveyed under the
terms of this License.
b) Give prominent notice with the combined library that part of it is a work
based on the Library, and explaining where to find the accompanying uncombined
form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions of the
GNU Lesser General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to address
new problems or concerns.
Each version is given a distinguishing version number. If the Library as you
received it specifies that a certain numbered version of the GNU Lesser General
Public License "or any later version" applies to it, you have the option of
following the terms and conditions either of that published version or of
any later version published by the Free Software Foundation. If the Library
as you received it does not specify a version number of the GNU Lesser General
Public License, you may choose any version of the GNU Lesser General Public
License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide whether
future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is permanent
authorization for you to choose that version for the Library.

View File

@ -0,0 +1,12 @@
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3 of
the license or (at your option) at any later version that is
accepted by the membership of KDE e.V. (or its successor
approved by the membership of KDE e.V.), which shall act as a
proxy as defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

View File

@ -0,0 +1,12 @@
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the license or (at your option) any later version
that is accepted by the membership of KDE e.V. (or its successor
approved by the membership of KDE e.V.), which shall act as a
proxy as defined in Section 6 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

View File

@ -0,0 +1,7 @@
/* Define to 1 if you have the <sys/wait.h> header file. */
#cmakedefine HAVE_SYS_WAIT_H 1
#cmakedefine01 HAVE_SYS_PRCTL_H
#cmakedefine01 HAVE_PR_SET_DUMPABLE
#cmakedefine01 HAVE_SYS_PROCCTL_H
#cmakedefine01 HAVE_PROC_TRACE_CTL
#define HAVE_X11 ${X11_FOUND}

2
doc/CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
ecm_optional_add_subdirectory(kcontrol5)
ecm_optional_add_subdirectory(kdesu)

View File

@ -0,0 +1 @@
ecm_optional_add_subdirectory(filetypes)

View File

@ -0,0 +1,2 @@
########### install files ###############
kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR kcontrol5/filetypes)

View File

@ -0,0 +1,366 @@
<?xml version="1.0" ?>
<!DOCTYPE article PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN"
"dtd/kdedbx45.dtd" [
<!ENTITY % addindex "IGNORE">
<!ENTITY % English "INCLUDE" > <!-- change language only here -->
]>
<article id="filetypes" lang="&language;">
<articleinfo>
<title>File Associations</title>
<authorgroup>
<author>&Mike.McBride; &Mike.McBride.mail;</author>
<!-- TRANS:ROLES_OF_TRANSLATORS -->
</authorgroup>
<date>2016-11-11</date>
<releaseinfo>Plasma 5.8</releaseinfo>
<keywordset>
<keyword>KDE</keyword>
<keyword>Systemsettings</keyword>
<keyword>files association</keyword>
<keyword>association</keyword>
</keywordset>
</articleinfo>
<sect1 id="file-assoc">
<title>File Associations</title>
<sect2 id="file-assoc-intro">
<title>Introduction</title>
<para>One of the most convenient aspects of &kde;, is its ability to
automatically match a data file with its application. As an example,
when you click on your favorite &calligrawords; document in the filemanager, &kde;
automatically starts &calligrawords;, and automatically loads that file into
&calligrawords; so you can begin working on it.</para>
<para>In the example above, the &calligrawords; Data file is
<emphasis>associated</emphasis> with &calligrawords; (the application). These
file associations are crucial to the functioning of &kde;.</para>
<para>When &kde; is installed, it automatically creates hundreds of file
associations to many of the most common data types. These initial
associations are based on the most commonly included software, and the
most common user preferences.</para>
<para>Unfortunately, &kde; can not:</para>
<itemizedlist>
<listitem><para>predict every possible combination of software and data files</para></listitem>
<listitem><para>prepare for file formats not yet invented</para></listitem>
<listitem><para>or predict everyone's favorite application for certain file formats</para></listitem>
</itemizedlist>
<para>You can change your current file associations or add new file
associations using this module.</para>
<para>Each file association is recorded as a &MIME; type.
&MIME; stands for <quote>Multipurpose Internet Mail
Extensions</quote>. It allows a computer to determine the type of file,
without opening and analyzing the format of each and every file.</para>
</sect2>
<sect2 id="file-assoc-use">
<title>How to use this module</title>
<para>You can start this module
by opening &systemsettings; and selecting <menuchoice><guimenu>Applications</guimenu>
<guimenuitem>File Associations</guimenuitem></menuchoice> in the
<guilabel>Personalization</guilabel> category. Alternatively, you can start it by
typing <command>kcmshell5 filetypes</command> from the terminal or &krunner;.</para>
<para>The file associations are organized into several categories, and
at a minimum you will have:</para>
<orderedlist>
<listitem><para>Application</para></listitem>
<listitem><para>Audio</para></listitem>
<listitem><para>Image</para></listitem>
<listitem><para>Inode</para></listitem>
<listitem><para>Message</para></listitem>
<listitem><para>Multipart</para></listitem>
<listitem><para>Text</para></listitem>
<listitem><para>Video</para></listitem>
</orderedlist>
<para>All of the file associations are sorted into one of these
categories.</para>
<note><para>There is no functional difference between any of the
categories. These categories are designed to help organize your file
associations, but they do not alter the associations in any way.
</para></note>
<para>The categories are listed in the box labeled <guilabel>Known
Types</guilabel>.</para>
<para>You can explore each of these categories, and see the file
associations contained within each one, by simply double-clicking on the
category name. You will be presented with a list of the associated
&MIME; types under that category.</para>
<tip><para>You can also search for a particular &MIME; type by using the
search box. The search box is labeled <guilabel>Search for file type or
filename pattern...</guilabel> and is located above the category list.</para>
<para>Simply type the first letter of the &MIME; type you are interested
in. The categories are automatically expanded, and only the &MIME; types
that include that letter are displayed.</para>
<para>You can then enter a second character and the &MIME; types will be
further limited to &MIME; types containing those two
characters.</para></tip>
<sect3 id="file-assoc-use-add">
<title>Adding a new MIME type</title>
<para>If you want to add a new &MIME; type to your file associations,
you can click on the <guibutton>Add...</guibutton> button. A small
dialog box will appear. You select the category from the drop down
box labeled <guilabel>Group:</guilabel>, and type the &MIME; name in the
blank labeled <guilabel>Type name:</guilabel>. Click <guibutton>OK</guibutton>
to add the new &MIME; type, or click <guibutton>Cancel</guibutton> to not add
any new &MIME; types.</para>
</sect3>
<sect3 id="file-assoc-use-del">
<title>Removing a MIME type</title>
<para>If you want to remove a &MIME; type, simply select the &MIME;
type you want to delete by clicking once with the mouse on the &MIME;
type name. Then click the button labeled
<guibutton>Remove</guibutton>. The &MIME; type will be deleted
immediately.</para>
<para>You can remove only your own &MIME; types.</para>
</sect3>
<sect3 id="file-assoc-use-edit">
<title>Editing a MIME types properties</title>
<para>Before you can edit a &MIME; types property, you must first
specify which &MIME; type. Simply browse through the categories until
you find the &MIME; type you want to edit, then click once on it with
the mouse.</para>
<para>As soon as you have selected the &MIME; type, the current values of
the &MIME; type will appear in the module window.</para>
<para>You will notice the current values are split into two tabs:
<guilabel>General</guilabel> and <guilabel>Embedding</guilabel></para>
<variablelist>
<varlistentry>
<term><guilabel>General</guilabel></term>
<listitem>
<para>There are 4 properties for each &MIME; type in this tab:</para>
<orderedlist>
<listitem><para><guilabel>Mime Type Icon</guilabel> is the icon that
will be visible when using &dolphin; or &konqueror; as a file
manager.</para></listitem>
<listitem><para><guilabel>Filename Patterns</guilabel> is a search
pattern which &kde; will use to determine the &MIME; type.</para></listitem>
<listitem><para><guilabel>Description:</guilabel> is a short description
of the file type. This is for your benefit only.</para></listitem>
<listitem><para><guilabel>Application Preference Order</guilabel>
determines which applications will be associated with the specified
&MIME; type.</para></listitem>
</orderedlist>
</listitem>
</varlistentry>
<varlistentry>
<term><guilabel>Embedding Tab</guilabel></term>
<listitem>
<para>The Embedding tab allows you to determine if a file will be
viewed within a filemanager window, or by starting the
application.</para>
</listitem>
</varlistentry>
</variablelist>
</sect3>
<sect3 id="file-assoc-use-icon">
<title>Changing the Icon</title>
<para>To change the icon, simply click on the Icon button. A dialog box
will appear, which will show you all available icons. Simply click once
with the mouse on the icon of your choice, and click
<guibutton>OK</guibutton>.</para>
</sect3>
<sect3 id="file-assoc-use-pattern">
<title>Editing the MIME type patterns</title>
<para>The box labeled <guilabel>Filename Patterns</guilabel>, determines
what files will be included within this &MIME; type.</para>
<para>Usually, files are selected based on their suffix. (Examples:
Files that end with <literal role="extension">.wav</literal> are sound
files, using the WAV format and files that end in <literal
role="extension">.c</literal> are program files written in C).</para>
<para>You should enter your filename mask in this combo box.</para>
<para>The asterisk (<literal>*</literal>) is a wildcard character that
will be used with nearly every &MIME; type mask. A complete discussion
of wildcards is beyond the scope of this manual, but it is important
to understand that the asterisk (in this context),
<quote>matches</quote> any number of characters. As an example:
<userinput>*.pdf</userinput> will match
<filename>Datafile.pdf</filename>, <filename>Graphics.pdf</filename>
and <filename>User.pdf</filename>, but not <filename>PDF</filename>,
<filename>Datafile.PDF</filename>, or
<filename>.pdf</filename>.</para>
<tip><para>It is very beneficial to have multiple masks. One for lower
case, one for upper case, &etc; This will help ensure that &kde; can
determine the file type more accurately.</para></tip>
</sect3>
<sect3 id="file-assoc-use-desc">
<title>Editing a MIME types description</title>
<para>You can type a short description of the &MIME; type in the text
box labeled <guilabel>Description:</guilabel>. This label is to help
you, it does not affect the function of the &MIME; type.</para>
</sect3>
<sect3 id="file-assoc-use-app">
<title>Editing the application associations</title>
<para>There are five buttons (<guibutton>Move Up</guibutton>,
<guibutton>Move Down</guibutton>, <guibutton>Add...</guibutton>, <guibutton>Edit...</guibutton> and
<guibutton>Remove</guibutton>) and a list box (which lists the
applications) which are used to configure the applications.</para>
<para>The list box lists all of the applications associated with a
specific &MIME; type. The list is in a specific order. The top
application is the first application tried. The next application down
the list is the second, &etc;</para>
<note><para>What do you mean there is more than one application per
&MIME; type? Why is this necessary?</para>
<para>We started out by saying that &kde; comes preconfigured with
hundreds of file associations. The reality is, each system that &kde;
is installed on has a different selection of applications. By
allowing multiple associations per &MIME; type, &kde; can continue to
operate when a certain application is not installed on the
system.</para>
<para>As an example:</para>
<para>For the &MIME; type <literal>pdf</literal>, there are two
applications associated with this file type. The first program is
called &okular;. If your system does not
have &okular; installed, then &kde;
automatically starts the second application &krita;.
As you can see, this will help keep &kde; running
strong as you add and subtract applications.</para></note>
<para>We have established that the order is important. You can change
the order of the applications by clicking once with the mouse on the
application you want to move, and then clicking either <guibutton>Move
Up</guibutton> or <guibutton>Move Down</guibutton>. This will shift
the currently selected application up or down the list of
applications. </para>
<para>You can add new applications to the list by clicking the button
labeled <guibutton>Add...</guibutton>. A dialog box will appear. Using the
dialog box, you can select the application you want to use for this &MIME;
type. Click <guibutton>OK</guibutton> when you are done, and the
application will be added to the current list.</para>
<para>To change the options of an application for a particular &MIME; type
select it in the list and then press the <guibutton>Edit...</guibutton> button.
This opens a new dialog with <guilabel>General</guilabel>, <guilabel>Permissions</guilabel>,
<guilabel>Application</guilabel> and <guilabel>Details</guilabel> tabs.
On the <guilabel>Application</guilabel> tab you can edit <guilabel>Name:</guilabel>,
<guilabel>Description:</guilabel> and <guilabel>Comment:</guilabel>.
In the <guilabel>Command:</guilabel> field you can have several place holders
following the command, which will be replaced with the actual values
when the actual program is run:</para>
<itemizedlist>
<listitem><para>%f - a single file name</para></listitem>
<listitem><para>%F - a list of files; use for applications that can open several local files
at once</para></listitem>
<listitem><para>%u - a single &URL;</para></listitem>
<listitem><para>%U - a list of &URL;s</para></listitem>
<listitem><para>%d - the folder of the file to open</para></listitem>
<listitem><para>%D - a list of folders</para></listitem>
<listitem><para>%i - the icon</para></listitem>
<listitem><para>%m - the mini-icon</para></listitem>
<listitem><para>%c - the caption</para></listitem>
</itemizedlist>
<para>You can remove an application (thereby ensuring that the
application will never run with this &MIME; type by clicking once on the
name of the application, and clicking the <guibutton>Remove</guibutton>
button.</para>
<tip><para>It is a good idea to use the <guibutton>Move Up</guibutton>
and <guibutton>Move Down</guibutton> buttons to adjust the unwanted
application to a lower position in the list, rather than deleting the
application from the list entirely. Once you have deleted an
application, if your preferred application should become compromised,
there will not be an application to view the data document.</para></tip>
</sect3>
<sect3 id="file-assoc-embedding">
<title>Embedding</title>
<para>These settings are valid only for &konqueror; used as file manager, &dolphin;
is not able to use embedded views and opens a file always in the associated application.</para>
<para>By clicking on the <guilabel>Embedding</guilabel> tab, you are
presented with four radio buttons in the <guilabel>Left Click Action in Konqueror</guilabel>
group. These determine how the filemanager views the selected &MIME; type:</para>
<variablelist>
<varlistentry><term>Show file in embedded viewer</term>
<listitem><para>If this is selected, the file will be shown <emphasis>within</emphasis> the filemanager window.</para></listitem></varlistentry>
<varlistentry><term>Show file in separate viewer</term>
<listitem><para>This will cause a separate window to be created when showing this &MIME; type.</para></listitem></varlistentry>
<varlistentry><term>Use settings for 'application' group</term>
<listitem><para>This will cause the &MIME; type to use the settings for the &MIME; type group.
(if you are editing an audio &MIME; type, then the settings for the audio group are used).</para></listitem></varlistentry>
<varlistentry><term>Ask whether to save to disk instead</term>
<listitem><para>This setting applies only to &konqueror; in browser mode and determines
if the file is shown in an embedded viewer or if you are asked to save the file to disk instead.</para></listitem></varlistentry>
</variablelist>
<para>Below this is a listbox labeled <guilabel>Services Preference
Order</guilabel>.</para>
<para>When you use a filemanager like &dolphin; or &konqueror;, you can
<mousebutton>right</mousebutton> mouse click, and a menu will with an
entry labeled <guimenuitem>Open with...</guimenuitem> will appear. This box
lists the applications that will appear, in the order they will
appear, under this menu.</para>
<para>You can use the <guibutton>Move Up</guibutton> and
<guibutton>Move Down</guibutton> buttons to change the order.</para>
</sect3>
<sect3 id="file-assoc-use-done">
<title>Making changes permanent</title>
<para>When you are done making any changes to &MIME; types, you can click
<guibutton>Apply</guibutton> to make your changes permanent, but keep
you in this module.</para>
</sect3>
</sect2>
</sect1>
</article>

7
doc/kdesu/CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
########### install files ###############
#
#
kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR kdesu)
kdoctools_create_manpage(man-kdesu.1.docbook 1 INSTALL_DESTINATION ${KDE_INSTALL_MANDIR})

339
doc/kdesu/index.docbook Normal file
View File

@ -0,0 +1,339 @@
<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN"
"dtd/kdedbx45.dtd" [
<!ENTITY kappname "&kdesu;">
<!ENTITY package "kdebase">
<!ENTITY % addindex "IGNORE">
<!ENTITY % English "INCLUDE" > <!-- change language only here -->
]>
<book id="kdesu" lang="&language;">
<bookinfo>
<title>The &kdesu; handbook</title>
<authorgroup>
<author>&Geert.Jansen; &Geert.Jansen.mail;</author>
<!-- TRANS:ROLES_OF_TRANSLATORS -->
</authorgroup>
<copyright>
<year>2000</year>
<holder>&Geert.Jansen;</holder>
</copyright>
<legalnotice>&FDLNotice;</legalnotice>
<date>2010-09-21</date>
<releaseinfo>KDE 4.5</releaseinfo>
<abstract><para>&kdesu; is a graphical front end for the &UNIX;
<command>su</command> command.</para></abstract>
<keywordset>
<keyword>KDE</keyword>
<keyword>su</keyword>
<keyword>password</keyword>
<keyword>root</keyword>
</keywordset>
</bookinfo>
<chapter id="introduction">
<title>Introduction</title>
<!-- from kdebase/runtime/kdesu/FAQ since rev 855297
kdesu is a libexec program, so does not normally reside in your PATH.
Use something like:
<command>$(kf5-config - -path libexec)kdesu - - program_to_run
https://bugs.kde.org/show_bug.cgi?id=194267
"one needs to create a
~/.kde/share/config/kdesurc file to tell KDE to use sudo instead of su."
~/.kde/share/config/kdesurc
[super-user-command]
super-user-command=sudo
does this really work?
-->
<para>Welcome to &kdesu;! &kdesu; is a graphical front end for the
&UNIX; <command>su</command> command for the K Desktop Environment.
It allows you to run a program as different user by supplying the
password for that user. &kdesu; is an unprivileged program; it uses
the system's <command>su</command>.</para>
<para>&kdesu; has one additional feature: it can remember passwords
for you. If you are using this feature, you only need to enter the
password once for each command. See <xref
linkend="sec-password-keeping"/> for more information on this and a
security analysis.</para>
<para>This program is meant to be started from the command line or
from <filename>.desktop</filename> files. Although it asks for the
<systemitem class="username">root</systemitem> password using a &GUI;
dialog, I consider it to be more of a command line &lt;-&gt; &GUI;
glue instead of a pure &GUI; program.</para>
<para>Since <command>kdesu</command> is no longer installed in <userinput>
$(kf5-config --prefix)</userinput>/bin but in <userinput>kf5-config --path libexec</userinput>
and therefore not in your <envar>Path</envar>, you have to use <userinput>$(kf5-config
--path libexec)<command>kdesu</command></userinput> to launch <command>kdesu</command>.</para>
</chapter>
<chapter id="using-kdesu">
<title>Using &kdesu;</title>
<para>Usage of &kdesu; is easy. The syntax is like this:</para>
<cmdsynopsis>
<command>kdesu</command>
<group choice="opt"><option>-c</option> <replaceable> command</replaceable></group>
<group choice="opt"><option>-d</option></group>
<group choice="opt"><option>-f</option> <replaceable> file</replaceable></group>
<group choice="opt"><option>-i</option> <replaceable> icon name</replaceable></group>
<group choice="opt"><option>-n</option></group>
<group choice="opt"><option>-p</option> <replaceable> priority</replaceable></group>
<group choice="opt"><option>-r</option></group>
<group choice="opt"><option>-s</option></group>
<group choice="opt"><option>-t</option></group>
<group choice="opt"><option>-u</option> <replaceable> user</replaceable></group>
<group choice="opt"><option>--noignorebutton</option></group>
<group choice="opt"><option>--attach</option> <replaceable> winid</replaceable></group>
<!--group choice="opt"><option>- -nonewdcop</option></group>
<group><arg choice="req"><replaceable>command</replaceable> <arg><replaceable>arg1</replaceable></arg>
<arg><replaceable>arg2</replaceable></arg>
<arg rep="repeat"><replaceable></replaceable></arg></arg></group-->
</cmdsynopsis>
<cmdsynopsis>
<command>kdesu</command>
<arg choice="opt">&kde; Generic Options</arg>
<arg choice="opt">&Qt; Generic Options</arg>
</cmdsynopsis>
<para>The command line options are explained below.</para>
<variablelist>
<varlistentry>
<term><option>-c <replaceable>command</replaceable></option></term>
<listitem><para>This specifies the command to run as root. It has to be passed
in one argument. So if, for example, you want to start a new file manager, you
would enter at the prompt: <userinput>$(kf5-config --path libexec)<command>kdesu <option>-c <replaceable>
&dolphin;</replaceable></option></command></userinput></para></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option></term>
<listitem><para>Show debug information.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-f <replaceable>file</replaceable></option></term>
<listitem><para>This option allow efficient use of &kdesu; in
<filename>.desktop</filename> files. It tells &kdesu; to examine the
file specified by <parameter>file</parameter>. If this file is
writable by the current user, &kdesu; will execute the command as the
current user. If it is not writable, the command is executed as user
<parameter>user</parameter> (defaults to root).</para>
<para><parameter>file</parameter> is evaluated like this: if
<parameter>file</parameter> starts with a <literal>/</literal>, it is
taken as an absolute filename. Otherwise, it is taken as the name of a
global &kde; configuration file.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-i</option> <replaceable>icon name</replaceable></term>
<listitem><para>Specify icon to use in the password dialog. You may specify
just the name, without any extension.</para>
<para>For instance to run &konqueror; in filemanager mode and show the
&konqueror; icon in the password dialog:</para>
<screen><userinput>$(kf5-config --path libexec)<command>kdesu</command> <option>-i konqueror</option>
<option>-c "konqueror --profile filemanagement"</option></userinput></screen>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-n</option></term>
<listitem><para>Do not keep the password. This disables the <guilabel>keep
password</guilabel> checkbox in the password dialog.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-p</option> <replaceable>priority</replaceable></term>
<listitem>
<para>Set priority value. The priority is an arbitrary number between 0 and
100, where 100 means highest priority, and 0 means lowest. The default is
50.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-r</option></term>
<listitem><para>Use realtime scheduling.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-s</option></term>
<listitem><para>Stop the kdesu daemon. See <xref
linkend="sec-password-keeping"/>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-t</option></term>
<listitem><para>Enable terminal output. This disables password keeping. This is
largely for debugging purposes; if you want to run a console mode app, use the
standard <command>su</command> instead.</para> </listitem>
</varlistentry>
<varlistentry>
<term><option>-u</option> <replaceable> user</replaceable></term>
<listitem><para>While the most common use for &kdesu; is to run a command as
the superuser, you can supply any user name and the appropriate
password.</para>
</listitem>
</varlistentry>
</variablelist>
</chapter>
<chapter id="Internals">
<title>Internals</title>
<sect1 id="x-authentication">
<title>X authentication</title>
<para>The program you execute will run under the root user id and will
generally have no authority to access your X display. &kdesu; gets
around this by adding an authentication cookie for your display to a
temporary <filename>.Xauthority</filename> file. After the command
exits, this file is removed. </para>
<para>If you don't use X cookies, you are on your own. &kdesu; will
detect this and will not add a cookie but you will have to make sure
that root is allowed to access to your display.</para>
</sect1>
<sect1 id="interface-to-su">
<title>Interface to <command>su</command></title>
<para>&kdesu; uses the sytem's <command>su</command> for acquiring
priviliges. In this section, I explain the details of how &kdesu; does
this. </para>
<para>Because some <command>su</command> implementations (&ie; the one
from &RedHat;) don't want to read the password from
<literal>stdin</literal>, &kdesu; creates a pty/tty pair and executes
<command>su</command> with its standard filedescriptors connected to
the tty.</para>
<para>To execute the command the user selected, rather than an
interactive shell, &kdesu; uses the <option>-c</option> argument with
<command>su</command>. This argument is understood by every shell that
I know of so it should work portably. <command>su</command> passes
this <option>-c</option> argument to the target user's shell, and the
shell executes the program. Example command: <command>su <option>root
-c <replaceable>the_program</replaceable></option></command>.</para>
<para>Instead of executing the user command directly with
<command>su</command>, &kdesu; executes a little stub program called
<application>kdesu_stub</application>. This stub (running as the
target user), requests some information from &kdesu; over the pty/tty
channel (the stub's stdin and stdout) and then executes the user's
program. The information passed over is: the X display, an X
authentication cookie (if available), the <envar>PATH</envar> and the
command to run. The reason why a stub program is used is that the X
cookie is private information and therefore cannot be passed on the
command line.</para>
</sect1>
<sect1 id="password-checking">
<title>Password Checking</title>
<para>&kdesu; will check the password you entered and gives an error
message if it is not correct. The checking is done by executing a test
program: <filename>/bin/true</filename>. If this succeeds, the
password is assumed to be correct.</para>
</sect1>
<sect1 id="sec-password-keeping">
<title>Password Keeping</title>
<para>For your comfort, &kdesu; implements a <quote>keep
password</quote> feature. If you are interested in security, you
should read this paragraph.</para>
<para>Allowing &kdesu; to remember passwords opens up a (small)
security hole in your system. Obviously, &kdesu; does not allow
anybody but your user id to use the passwords, but, if done without
caution, this would lowers <systemitem
class="username">root</systemitem>'s security level to that of a
normal user (you). A hacker who breaks into your account, would get
<systemitem class="username">root</systemitem> access. &kdesu; tries
to prevent this. The security scheme it uses is, in my opinion at
least, reasonably safe and is explained here.</para>
<para>&kdesu; uses a daemon, called
<application>kdesud</application>. The daemon listens to a &UNIX;
socket in <filename>/tmp</filename> for commands. The mode of the
socket is 0600 so that only your user id can connect to it. If
password keeping is enabled, &kdesu; executes commands through this
daemon. It writes the command and <systemitem
class="username">root</systemitem>'s password to the socket and the
daemon executes the command using <command>su</command>, as describe
before. After this, the command and the password are not thrown
away. Instead, they are kept for a specified amount of time. This is
the timeout value from in the control module. If another request for
the same command is coming within this time period, the client does
not have to supply the password. To keep hackers who broke into your
account from stealing passwords from the daemon (for example, by
attaching a debugger), the daemon is installed set-group-id
nogroup. This should prevent all normal users (including you) from
getting passwords from the <application>kdesud</application>
process. Also, the daemon sets the <envar>DISPLAY</envar> environment
variable to the value it had when it was started. The only thing a
hacker can do is execute an application on your display.</para>
<para>One weak spot in this scheme is that the programs you execute
are probably not written with security in mind (like setuid
<systemitem class="username">root</systemitem> programs). This means
that they might have buffer overruns or other problems and a hacker
could exploit those.</para>
<para>The use of the password keeping feature is a tradeoff between
security and comfort. I encourage you to think it over and decide for
yourself if you want to use it or not.</para>
</sect1>
</chapter>
<chapter id="Author">
<title>Author</title>
<para>&kdesu;</para>
<para>Copyright 2000 &Geert.Jansen;</para>
<para>&kdesu; is written by &Geert.Jansen;. It is somewhat based on
Pietro Iglio's &kdesu;, version 0.3. Pietro and I agreed that I will
maintain this program in the future.</para>
<para>The author can be reached through email at &Geert.Jansen.mail;.
Please report any bugs you find to me so that I can fix them. If you
have a suggestion, feel free to contact me.</para>
<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
&underFDL;
&underArtisticLicense;
</chapter>
</book>
<!--
Local Variables:
mode: sgml
sgml-omittag: nil
sgml-shorttag: t
End:
-->

View File

@ -0,0 +1,194 @@
<?xml version="1.0" ?>
<!DOCTYPE refentry PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
<!ENTITY % English "INCLUDE">
]>
<refentry lang="&language;">
<refentryinfo>
<title>KDE User's Manual</title>
<author>&Lauri.Watts; &Lauri.Watts.mail;</author>
<date>2010-09-18</date>
<productname>K Desktop Environment</productname>
</refentryinfo>
<refmeta>
<refentrytitle><command>kdesu</command></refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname><command>kdesu</command></refname>
<refpurpose>Runs a program with elevated privileges</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>kdesu</command>
<group choice="opt"><option>-c</option> <replaceable> command</replaceable></group>
<group choice="opt"><option>-d</option></group>
<group choice="opt"><option>-f</option> <replaceable> file</replaceable></group>
<group choice="opt"><option>-i</option> <replaceable> icon name</replaceable></group>
<group choice="opt"><option>-n</option></group>
<group choice="opt"><option>-p</option> <replaceable> priority</replaceable></group>
<group choice="opt"><option>-r</option></group>
<group choice="opt"><option>-s</option></group>
<group choice="opt"><option>-t</option></group>
<group choice="opt"><option>-u</option> <replaceable> user</replaceable></group>
<group choice="opt"><option>--noignorebutton</option></group>
<group choice="opt"><option>--attach</option> <replaceable> winid</replaceable></group>
<!--group choice="opt"><option>- -nonewdcop</option></group>
<group><arg choice="req"><replaceable>command</replaceable> <arg><replaceable>arg1</replaceable></arg>
<arg><replaceable>arg2</replaceable></arg>
<arg rep="repeat"><replaceable></replaceable></arg></arg></group-->
</cmdsynopsis>
<cmdsynopsis>
<command>kdesu</command>
<arg choice="opt">&kde; Generic Options</arg>
<arg choice="opt">&Qt; Generic Options</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>&kdesu; is a graphical front end for the
&UNIX; <command>su</command> command for the K Desktop Environment.
It allows you to run a program as different user by supplying the
password for that user. &kdesu; is an unprivileged program; it uses
the system's <command>su</command>.</para>
<para>&kdesu; has one additional feature: it can optionally remember passwords
for you. If you are using this feature, you only need to enter the
password once for each command.</para>
<para>This program is meant to be started from the command line or
from <filename>.desktop</filename> files.</para>
<para>Since <command>kdesu</command> is no longer installed in <userinput>
$(kf5-config --prefix)</userinput>/bin but in <userinput>kf5-config --path libexec</userinput>
and therefore not in your <envar>Path</envar>, you have to use <userinput>$(kf5-config
--path libexec)<command>kdesu</command></userinput> to launch <command>kdesu</command>.</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term><option>-c <replaceable>command</replaceable></option></term>
<listitem><para>This specifies the command to run as root. It has to be passed
in one argument. So if, for example, you want to start a new file manager, you
would enter at the prompt: <userinput>$(kf5-config --path libexec)<command>kdesu <option>-c <replaceable>
&dolphin;</replaceable></option></command></userinput></para></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option></term>
<listitem><para>Show debug information.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-f <replaceable>file</replaceable></option></term>
<listitem><para>This option allow efficient use of &kdesu; in
<filename>.desktop</filename> files. It tells &kdesu; to examine the
file specified by <parameter>file</parameter>. If this file is
writable by the current user, &kdesu; will execute the command as the
current user. If it is not writable, the command is executed as user
<parameter>user</parameter> (defaults to root).</para>
<para><parameter>file</parameter> is evaluated like this: if
<parameter>file</parameter> starts with a <literal>/</literal>, it is
taken as an absolute filename. Otherwise, it is taken as the name of a
global &kde; configuration file.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-i</option> <replaceable>icon name</replaceable></term>
<listitem><para>Specify icon to use in the password dialog. You may specify
just the name, without any extension.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-n</option></term>
<listitem><para>Do not keep the password. This disables the <guilabel>keep
password</guilabel> checkbox in the password dialog.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-p</option> <replaceable>priority</replaceable></term>
<listitem>
<para>Set priority value. The priority is an arbitrary number between 0 and
100, where 100 means highest priority, and 0 means lowest. The default is
50.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-r</option></term>
<listitem><para>Use realtime scheduling.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-s</option></term>
<listitem><para>Stop the kdesu daemon. This is the daemon that caches
successful passwords in the background. This feature may also be disabled with
<option>-n</option> when &kdesu; is initially run.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-t</option></term>
<listitem><para>Enable terminal output. This disables password keeping. This is
largely for debugging purposes; if you want to run a console mode app, use the
standard <command>su</command> instead.</para> </listitem>
</varlistentry>
<varlistentry>
<term><option>-u</option> <replaceable> user</replaceable></term>
<listitem><para>While the most common use for &kdesu; is to run a command as
the superuser, you can supply any user name and the appropriate
password.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--noignorebutton</option></term>
<listitem><para>Do not display an ignore button.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--attach</option> <replaceable> winid</replaceable></term>
<listitem><para>Makes the dialog transient for an X app specified by winid.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<para>su(1)</para>
<para>More detailed user documentation is available from <ulink
url="help:/kdesu">help:/kdesu</ulink>
(either enter this &URL; into &konqueror;, or run
<userinput><command>khelpcenter</command>
<parameter>help:/kdesu</parameter></userinput>).</para>
</refsect1>
<refsect1>
<title>Examples</title>
<para>Run <command>kfmclient</command> as user <systemitem
class="username">jim</systemitem>, and show the &konqueror; icon in the
password dialog:</para>
<screen><userinput>$(kf5-config --path libexec)<command>kdesu</command> <option>-u jim</option> <option>-i konqueror</option> <command>kfmclient</command></userinput></screen>
</refsect1>
<refsect1>
<title>Authors</title>
<para>&kdesu; was written by
&Geert.Jansen; &Geert.Jansen.mail;
and <personname><firstname>Pietro</firstname><surname>Iglio</surname></personname>
<email>iglio@fub.it</email>.
</para>
</refsect1>
</refentry>

View File

@ -0,0 +1,5 @@
add_executable(kbroadcastnotification main.cpp)
target_compile_definitions(kbroadcastnotification PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(kbroadcastnotification Qt::DBus KF5::CoreAddons KF5::I18n)
install(TARGETS kbroadcastnotification ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kbroadcastnotification.pot

View File

@ -0,0 +1,105 @@
/*
* SPDX-FileCopyrightText: 2016 Kai Uwe Broulik <kde@privat.broulik.de>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QTimer>
#include <KAboutData>
#include <KLocalizedString>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
KLocalizedString::setApplicationDomain("kbroadcastnotification");
KAboutData aboutData(QStringLiteral("kbroadcastnotification"),
i18n("Broadcast Notifications"),
QLatin1String(PROJECT_VERSION),
i18n("A tool that emits a notification for all users by sending it on the system DBus"),
KAboutLicense::GPL,
i18n("(c) 2016 Kai Uwe Broulik"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
QCommandLineOption applicationNameOption(QStringLiteral("application"),
i18n("Name of the application that should be associated with this notification"),
QStringLiteral("application"));
parser.addOption(applicationNameOption);
QCommandLineOption summaryOption(QStringLiteral("summary"), i18n("A brief one-line summary of the notification"), QStringLiteral("summary"));
parser.addOption(summaryOption);
QCommandLineOption iconOption(QStringLiteral("icon"), i18n("Icon for the notification"), QStringLiteral("icon"));
parser.addOption(iconOption);
QCommandLineOption uidsOption(
QStringLiteral("uids"),
i18n("A comma-separated list of user IDs this notification should be sent to. If omitted, the notification will be sent to all users."),
QStringLiteral("uids"));
parser.addOption(uidsOption);
QCommandLineOption timeoutOption(QStringLiteral("timeout"), i18n("Timeout for the notification"), QStringLiteral("timeout"));
parser.addOption(timeoutOption);
QCommandLineOption persistentOption(QStringLiteral("persistent"), i18n("Keep the notification in the history until the user closes it"));
parser.addOption(persistentOption);
parser.addPositionalArgument(QStringLiteral("body"), i18n("The actual notification body text"));
parser.process(app);
aboutData.processCommandLine(&parser);
QVariantMap properties;
if (parser.isSet(applicationNameOption)) {
properties.insert(QStringLiteral("appName"), parser.value(applicationNameOption));
}
if (parser.isSet(summaryOption)) {
properties.insert(QStringLiteral("summary"), parser.value(summaryOption));
}
if (parser.isSet(iconOption)) {
properties.insert(QStringLiteral("appIcon"), parser.value(iconOption));
}
if (parser.isSet(uidsOption)) {
const QStringList &uids = parser.value(uidsOption).split(QLatin1Char(','), Qt::SkipEmptyParts);
if (!uids.isEmpty()) {
properties.insert(QStringLiteral("uids"), uids);
}
}
if (parser.isSet(timeoutOption)) {
bool ok;
const int timeout = parser.value(timeoutOption).toInt(&ok);
if (ok) {
properties.insert(QStringLiteral("timeout"), timeout);
}
}
if (parser.isSet(persistentOption)) { // takes precedence over timeout if both are set
properties.insert(QStringLiteral("timeout"), 0); // 0 = persistent, -1 = server default
}
const auto &positionalArgs = parser.positionalArguments();
if (positionalArgs.count() == 1) {
properties.insert(QStringLiteral("body"), positionalArgs.first());
}
if (properties.isEmpty()) {
parser.showHelp(1); // never returns
}
QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/org/kde/kbroadcastnotification"),
QStringLiteral("org.kde.BroadcastNotifications"),
QStringLiteral("Notify"));
message.setArguments({properties});
QDBusConnection::systemBus().send(message);
// FIXME can we detect that the message was sent to the bus?
QTimer::singleShot(500, &app, QCoreApplication::quit);
return app.exec();
}

18
kcmshell/CMakeLists.txt Normal file
View File

@ -0,0 +1,18 @@
set(kcmshell_KDEINIT_SRCS main.cpp )
add_executable(kcmshell5 ${kcmshell_KDEINIT_SRCS})
target_compile_definitions(kcmshell5 PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
ecm_mark_nongui_executable(kcmshell5)
target_link_libraries(kcmshell5
Qt::DBus
KF5::KCMUtils
KF5::I18n
KF5::WindowSystem
KF5::Activities
KF5::QuickAddons
PW::KWorkspace
)
install(TARGETS kcmshell5 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

21
kcmshell/Mainpage.dox Normal file
View File

@ -0,0 +1,21 @@
/** @mainpage ./kcmshell
KCMShell is a small utility to host System Settings modules independently of
SystemSettings.
@authors
Matthias Hoelzer-Kluepfel \<hoelzer@kde.org\><br>
Matthias Elter \<elter@kde.org\><br>
Waldo Bastian \<bastian@kde.org\><br>
Frans Englich \<frans.englich@telia.com\>
@maintainers
[Unknown/None]
@licenses
@gpl
*/
// DOXYGEN_SET_PROJECT_NAME = KCMShell
// vim:ts=4:sw=4:expandtab:filetype=doxygen

2
kcmshell/Messages.sh Normal file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kcmshell5.pot

355
kcmshell/main.cpp Normal file
View File

@ -0,0 +1,355 @@
/*
SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "main.h"
#include <config-kde-cli-tools.h>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QDBusInterface>
#include <QDBusServiceWatcher>
#include <QDebug>
#include <QIcon>
#include <QRegularExpression>
#include <QStandardPaths>
#include <KAboutData>
#include <KActivities/ResourceInstance>
#include <KAuthorized>
#include <KCModuleProxy>
#include <KLocalizedString>
#include <KPluginMetaData>
#include <KQuickAddons/QtQuickSettings>
#include <KServiceTypeTrader>
#include <KStartupInfo>
#include <kworkspace.h>
#include <algorithm>
#include <iostream>
inline QVector<KPluginMetaData> findKCMsMetaData()
{
QVector<KPluginMetaData> metaDataList = KPluginMetaData::findPlugins(QStringLiteral("plasma/kcms"));
metaDataList << KPluginMetaData::findPlugins(QStringLiteral("plasma/kcms/systemsettings"));
metaDataList << KPluginMetaData::findPlugins(QStringLiteral("plasma/kcms/systemsettings_qwidgets"));
metaDataList << KPluginMetaData::findPlugins(QStringLiteral("plasma/kcms/kinfocenter"));
return metaDataList;
}
static KService::List listModules()
{
// First condition is what systemsettings does, second what kinfocenter does, make sure this is kept in sync
// We need the exist calls because otherwise the trader language aborts if the property doesn't exist and the second part of the or is not evaluated
KService::List services =
KServiceTypeTrader::self()->query(QStringLiteral("KCModule"),
QStringLiteral("(exist [X-KDE-System-Settings-Parent-Category] and [X-KDE-System-Settings-Parent-Category] != '') or "
"(exist [X-KDE-ParentApp] and [X-KDE-ParentApp] == 'kinfocenter')"));
auto it = std::remove_if(services.begin(), services.end(), [](const KService::Ptr &service) {
return !KAuthorized::authorizeControlModule(service->menuId());
});
services.erase(it, services.end());
std::stable_sort(services.begin(), services.end(), [](const KService::Ptr s1, const KService::Ptr s2) {
return QString::compare(s1->desktopEntryName(), s2->desktopEntryName(), Qt::CaseInsensitive) < 0;
});
return services;
}
static KService::Ptr locateModule(const QString &module)
{
QString path = module;
if (!path.endsWith(QLatin1String(".desktop"))) {
path += QStringLiteral(".desktop");
}
KService::Ptr service = KService::serviceByStorageId(path);
if (!service) {
return KService::Ptr();
}
if (!service->hasServiceType(QStringLiteral("KCModule"))) {
// Not a KCModule. E.g. "kcmshell5 akonadi" finds services/kresources/kabc/akonadi.desktop, unrelated.
return KService::Ptr();
}
if (service->noDisplay()) {
qDebug() << module << "should not be loaded.";
return KService::Ptr();
}
return service;
}
bool KCMShell::isRunning()
{
const QString owner = QDBusConnection::sessionBus().interface()->serviceOwner(m_serviceName);
if (owner == QDBusConnection::sessionBus().baseService()) {
return false; // We are the one and only.
}
qDebug() << "kcmshell5 with modules '" << m_serviceName << "' is already running.";
QDBusInterface iface(m_serviceName, QStringLiteral("/KCModule/dialog"), QStringLiteral("org.kde.KCMShellMultiDialog"));
QDBusReply<void> reply = iface.call(QStringLiteral("activate"), KStartupInfo::startupId());
if (!reply.isValid()) {
qDebug() << "Calling D-Bus function dialog::activate() failed.";
return false; // Error, we have to do it ourselves.
}
return true;
}
KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent)
: KCMultiDialog(parent)
{
setFaceType(dialogFace);
setModal(false);
QDBusConnection::sessionBus().registerObject(QStringLiteral("/KCModule/dialog"), this, QDBusConnection::ExportScriptableSlots);
connect(this, &KCMShellMultiDialog::currentPageChanged, this, [](KPageWidgetItem *newPage, KPageWidgetItem *oldPage) {
Q_UNUSED(oldPage);
KCModuleProxy *activeModule = newPage->widget()->findChild<KCModuleProxy *>();
if (activeModule) {
KActivities::ResourceInstance::notifyAccessed(QUrl(QLatin1String("kcm:") + activeModule->metaData().pluginId()),
QStringLiteral("org.kde.systemsettings"));
}
});
}
void KCMShellMultiDialog::activate(const QByteArray &asn_id)
{
#ifdef HAVE_X11
setAttribute(Qt::WA_NativeWindow, true);
KStartupInfo::setNewStartupId(windowHandle(), asn_id);
#endif
}
void KCMShell::setServiceName(const QString &dbusName)
{
m_serviceName = QLatin1String("org.kde.kcmshell_") + dbusName;
QDBusConnection::sessionBus().registerService(m_serviceName);
}
void KCMShell::waitForExit()
{
QDBusServiceWatcher *watcher = new QDBusServiceWatcher(this);
watcher->setConnection(QDBusConnection::sessionBus());
watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
watcher->addWatchedService(m_serviceName);
connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &KCMShell::appExit);
exec();
}
void KCMShell::appExit(const QString &appId, const QString &oldName, const QString &newName)
{
Q_UNUSED(appId);
Q_UNUSED(newName);
if (!oldName.isEmpty()) {
qDebug() << "'" << appId << "' closed, quitting.";
qApp->quit();
}
}
int main(int _argc, char *_argv[])
{
const bool qpaVariable = qEnvironmentVariableIsSet("QT_QPA_PLATFORM");
KWorkSpace::detectPlatform(_argc, _argv);
KCMShell app(_argc, _argv);
if (!qpaVariable) {
// don't leak the env variable to processes we start
qunsetenv("QT_QPA_PLATFORM");
}
KLocalizedString::setApplicationDomain("kcmshell5");
KQuickAddons::QtQuickSettings::init();
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
KAboutData aboutData(QStringLiteral("kcmshell5"), //
i18n("System Settings Module"),
QLatin1String(PROJECT_VERSION),
i18n("A tool to start single system settings modules"),
KAboutLicense::GPL,
i18n("(c) 1999-2016, The KDE Developers"));
aboutData.addAuthor(i18n("Frans Englich"), i18n("Maintainer"), QStringLiteral("frans.englich@kde.org"));
aboutData.addAuthor(i18n("Daniel Molkentin"), QString(), QStringLiteral("molkentin@kde.org"));
aboutData.addAuthor(i18n("Matthias Hoelzer-Kluepfel"), QString(), QStringLiteral("hoelzer@kde.org"));
aboutData.addAuthor(i18n("Matthias Elter"), QString(), QStringLiteral("elter@kde.org"));
aboutData.addAuthor(i18n("Matthias Ettrich"), QString(), QStringLiteral("ettrich@kde.org"));
aboutData.addAuthor(i18n("Waldo Bastian"), QString(), QStringLiteral("bastian@kde.org"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addOption(QCommandLineOption(QStringLiteral("list"), i18n("List all possible modules")));
parser.addPositionalArgument(QStringLiteral("module"), i18n("Configuration module to open"));
parser.addOption(QCommandLineOption(QStringLiteral("lang"), i18n("Specify a particular language"), QLatin1String("language")));
parser.addOption(QCommandLineOption(QStringLiteral("silent"), i18n("Do not display main window")));
parser.addOption(QCommandLineOption(QStringLiteral("args"), i18n("Arguments for the module"), QLatin1String("arguments")));
parser.addOption(QCommandLineOption(QStringLiteral("icon"), i18n("Use a specific icon for the window"), QLatin1String("icon")));
parser.addOption(QCommandLineOption(QStringLiteral("caption"), i18n("Use a specific caption for the window"), QLatin1String("caption")));
parser.parse(app.arguments());
aboutData.processCommandLine(&parser);
parser.process(app);
const QString lang = parser.value(QStringLiteral("lang"));
if (!lang.isEmpty()) {
std::cout << i18n("--lang is deprecated. Please set the LANGUAGE environment variable instead").toLocal8Bit().constData() << std::endl;
}
if (parser.isSet(QStringLiteral("list"))) {
std::cout << i18n("The following modules are available:").toLocal8Bit().constData() << '\n';
QVector<KPluginMetaData> plugins = findKCMsMetaData();
const KService::List services = listModules();
for (const auto &service : services) {
const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("/kservices5/") + service->entryPath());
plugins << KPluginMetaData::fromDesktopFile(file);
}
int maxLen = 0;
for (const auto &plugin : plugins) {
const int len = plugin.pluginId().size();
maxLen = std::max(maxLen, len);
}
for (const auto &plugin : plugins) {
QString comment = plugin.description();
if (comment.isEmpty()) {
comment = i18n("No description available");
}
const QString entry = QStringLiteral("%1 - %2").arg(plugin.pluginId().leftJustified(maxLen, QLatin1Char(' ')), comment);
std::cout << entry.toLocal8Bit().constData() << '\n';
}
std::cout << std::endl;
return 0;
}
if (parser.positionalArguments().isEmpty()) {
parser.showHelp();
return -1;
}
QString serviceName;
QList<KPluginMetaData> metaDataList;
QStringList args = parser.positionalArguments();
args.removeDuplicates();
for (const QString &arg : args) {
KPluginMetaData data(arg);
if (data.isValid()) {
metaDataList << data;
} else {
// Look in the namespaces for systemsettings/kinfocenter
const static auto knownKCMs = findKCMsMetaData();
const QStringList possibleIds{arg, QStringLiteral("kcm_") + arg, QStringLiteral("kcm") + arg};
bool foundKCM = std::any_of(knownKCMs.begin(), knownKCMs.end(), [&possibleIds, &metaDataList](const KPluginMetaData &data) {
bool idMatches = possibleIds.contains(data.pluginId());
if (idMatches) {
metaDataList << data;
}
return idMatches;
});
if (foundKCM) {
continue;
}
KService::Ptr service = locateModule(arg);
if (!service) {
service = locateModule(QStringLiteral("kcm_") + arg);
}
if (!service) {
service = locateModule(QStringLiteral("kcm") + arg);
}
if (service) {
if (!serviceName.isEmpty()) {
serviceName += QLatin1Char('_');
}
serviceName += arg;
const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("/kservices5/") + service->entryPath());
auto data = KPluginMetaData::fromDesktopFile(file);
metaDataList << data;
} else {
std::cerr << i18n("Could not find module '%1'. See kcmshell5 --list for the full list of modules.", arg).toLocal8Bit().constData() << std::endl;
}
}
}
/* Check if this particular module combination is already running */
app.setServiceName(serviceName);
if (app.isRunning()) {
app.waitForExit();
return 0;
}
KPageDialog::FaceType ftype = KPageDialog::Plain;
const int modCount = metaDataList.count();
if (modCount == 0) {
return -1;
}
if (modCount > 1) {
ftype = KPageDialog::List;
}
KCMShellMultiDialog *dlg = new KCMShellMultiDialog(ftype);
dlg->setAttribute(Qt::WA_DeleteOnClose);
if (parser.isSet(QStringLiteral("caption"))) {
dlg->setWindowTitle(parser.value(QStringLiteral("caption")));
} else if (modCount == 1) {
dlg->setWindowTitle(metaDataList.constFirst().name());
}
const QStringList moduleArgs = parser.value(QStringLiteral("args")).split(QRegularExpression(QStringLiteral(" +")));
for (const KPluginMetaData &m : std::as_const(metaDataList)) {
dlg->addModule(m, moduleArgs);
}
if (parser.isSet(QStringLiteral("icon"))) {
dlg->setWindowIcon(QIcon::fromTheme(parser.value(QStringLiteral("icon"))));
} else {
dlg->setWindowIcon(QIcon::fromTheme(metaDataList.constFirst().iconName()));
}
if (app.desktopFileName() == QLatin1String("org.kde.kcmshell5")) {
const QString path = metaDataList.constFirst().metaDataFileName();
if (path.endsWith(QLatin1String(".desktop"))) {
app.setDesktopFileName(path);
} else {
app.setDesktopFileName(metaDataList.constFirst().pluginId());
}
}
dlg->show();
app.exec();
return 0;
}
// vim: sw=4 et sts=4

90
kcmshell/main.h Normal file
View File

@ -0,0 +1,90 @@
/*
SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef MAIN_H
#define MAIN_H
#include <KCMultiDialog>
#include <KPageDialog>
#include <QApplication>
/**
* The application instance for kcmshell.
*/
class KCMShell : public QApplication
{
Q_OBJECT
public:
KCMShell(int &argc, char **argv)
: QApplication(argc, argv)
{
}
/**
* Sets m_serviceName basically to @p serviceName,
* and then registers with D-BUS.
*
* @param serviceName name to set the D-BUS name to
*/
void setServiceName(const QString &serviceName);
/**
* Waits until the last instance of kcmshell with the same
* module as this one exits, and then exits.
*/
void waitForExit();
/**
* @return true if the shell is running
*/
bool isRunning();
private Q_SLOTS:
/**
*/
void appExit(const QString &appId, const QString &, const QString &);
private:
/**
* The D-Bus name which actually is registered.
* For example "kcmshell_mouse".
*/
QString m_serviceName;
};
/**
* Essentially a plain KCMultiDialog, but has the additional functionality
* of allowing it to be told to request windows focus.
*
* @author Waldo Bastian <bastian@kde.org>
*/
class KCMShellMultiDialog : public KCMultiDialog
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.KCMShellMultiDialog")
public:
/**
* Constructor. Parameter @p dialogFace is passed to KCMultiDialog
* unchanged.
*/
explicit KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent = nullptr);
public Q_SLOTS:
/**
* Activate a module with id @p asn_id . This is used when
* black helicopters are spotted overhead.
*/
virtual Q_SCRIPTABLE void activate(const QByteArray &asn_id);
};
// vim: sw=4 et sts=4
#endif // MAIN_H

1
kdeeject/CMakeLists.txt Normal file
View File

@ -0,0 +1 @@
install(PROGRAMS kdeeject DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF5})

34
kdeeject/kdeeject Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
# Script used by kdesktop to eject a removable media (CDROM/Tape/SCSI/Floppy)
# Relies on the 'eject' program, 'cdcontrol' on *BSD
#
# Copyright GPL v2 by David Faure <david@mandrakesoft.com>
#
if test $# -ge 1 -a "$1" != "--help"; then
quiet=0
if test "$1" = "-q"; then
quiet=1
shift
fi
# Checking for stuff in the PATH is ugly with sh.
# I guess this is the reason for making this a kde app...
OS=`uname -s`
case "$OS" in
OpenBSD)
cdio -f $1 eject >/dev/null 2>&1
;;
*BSD)
dev=`echo $1 | sed -E -e 's#/dev/##' -e 's/([0-9])./\1/'`
cdcontrol -f $dev eject >/dev/null 2>&1
;;
*)
eject $1 >/dev/null 2>&1
;;
esac
if test $quiet -eq 0; then
kdialog --title "KDE Eject" --error "Eject $1 failed!"
fi
else
kdialog --title "KDE Eject" --msgbox "Usage: $0 <name> where name is a device or a mountpoint."
fi
exit 1

View File

@ -0,0 +1,3 @@
add_executable(kde-inhibit main.cpp)
target_link_libraries(kde-inhibit Qt::Core Qt::DBus KF5::I18n KF5::CoreAddons)
install(TARGETS kde-inhibit ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

84
kdeinhibit/main.cpp Normal file
View File

@ -0,0 +1,84 @@
/********************************************************************
This file is part of the KDE project.
SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*********************************************************************/
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDebug>
#include <KLocalizedString>
#include <KProcess>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QCoreApplication::setApplicationName(QStringLiteral("kdeinhibit"));
QCommandLineParser parser;
parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
parser.setApplicationDescription(i18n("Inhibit various desktop functions whilst a command runs"));
QCommandLineOption powerOption(QStringLiteral("power"), i18n("Inhibit power management"));
parser.addOption(powerOption);
QCommandLineOption screenSaverOption(QStringLiteral("screenSaver"), i18n("Inhibit screensaver"));
parser.addOption(screenSaverOption);
QCommandLineOption colorCorrectOption(QStringLiteral("colorCorrect"), i18n("Inhibit colour correction (night mode)"));
parser.addOption(colorCorrectOption);
parser.addPositionalArgument(QStringLiteral("command..."), i18n("Command to run"));
parser.addHelpOption();
parser.process(app);
QStringList command = parser.positionalArguments();
if (command.isEmpty()) {
parser.showHelp(-1);
}
auto warnOnError = [](const QDBusMessage &reply) {
if (reply.type() == QDBusMessage::ErrorMessage) {
qWarning() << "Inhibit failed" << reply.errorMessage();
}
};
if (parser.isSet(powerOption)) {
QDBusMessage inhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
QStringLiteral("Inhibit"));
inhibitCall.setArguments({i18nc("Script as in shell script", "Running Script"), command.first()});
warnOnError(QDBusConnection::sessionBus().call(inhibitCall));
// ignore reply with the cookie as we don't really care if it failed
}
if (parser.isSet(screenSaverOption)) {
QDBusMessage inhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"),
QStringLiteral("/org/freedesktop/ScreenSaver"),
QStringLiteral("org.freedesktop.ScreenSaver"),
QStringLiteral("Inhibit"));
inhibitCall.setArguments({i18nc("Script as in shell script", "Running Script"), command.first()});
warnOnError(QDBusConnection::sessionBus().call(inhibitCall));
}
if (parser.isSet(colorCorrectOption)) {
QDBusMessage inhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.kde.KWin"),
QStringLiteral("/ColorCorrect"),
QStringLiteral("org.kde.kwin.ColorCorrect"),
QStringLiteral("inhibit"));
// no arguments needed
warnOnError(QDBusConnection::sessionBus().call(inhibitCall));
}
// finally run the script and exit when we're done
KProcess::execute(command);
// we don't explicitly uninhibit as closing our DBus connection will release everything automatically
}

17
kdesu/CMakeLists.txt Normal file
View File

@ -0,0 +1,17 @@
add_executable(kdesu_executable kdesu.cpp sudlg.cpp sudlg.h)
target_compile_definitions(kdesu_executable PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
# in KDELibsDependencies.cmake installed by kdelibs there is a dependency to "kdesu"
# which is then recognized here as the target name for this executable
# so give the target here a different name and use the OUTPUT_NAME property to
# give it the name kdesu
set_target_properties(kdesu_executable PROPERTIES OUTPUT_NAME kdesu)
target_link_libraries(kdesu_executable KF5::WidgetsAddons KF5::I18n KF5::ConfigCore KF5::WindowSystem KF5::Su)
install(TARGETS kdesu_executable DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF5})

72
kdesu/FAQ Normal file
View File

@ -0,0 +1,72 @@
Q: On my SuSE system, KDE su does not compile. I get an error that some Qt
header files cannot be found.
A: Install the package qtcompat.
Q: Is KDE su safe?
A: No program is 100% safe. However, KDE su is not setuid root and it
handles the password you enter with great care so it should be safe
enough.
Q: How safe is password keeping?
A: Enabling password keeping is less secure that disabling it. However, the
scheme kdesu uses to keep passwords prevents everyone (including you, the
user) from accessing them. Please see the HTML documentation for a full
description of this scheme.
Q: Can I execute tty applications with kdesu?
A: No. TTY application will probably never be supported. Use the Unix su for
those.
NOTE: As of version 0.94, tty _output_ _only_ is supported with the `-t'
switch. This disables password keeping, though.
Q: What systems does KDE su support?
A: Tested are:
* Linux 2.x (Redhat 6.x, Mandrake "Cooker", Debian potato, SuSE 6.1)
* Solaris 7 (intel)
* FreeBSD 3.2 (intel, w/ egcs 1.1.2)
It will probably work on more systems but I cannot test that.
Q: Why doesn't it support every system that is out there.
A: KDE su needs to setup a pty/tty pair for communicating with `su'. This is
because some `su' implementations refuse to read a password from stdin if
that is not a tty. Setting up a pty/tty pair is not completely portable.
Q: A good debug tip?
A: If kdesu doesn't fire up your application, use the '-t' switch.
This way, you'll get terminal output. Maybe there is something wrong with
the program you're trying to run.
Q: I always get the warning: "Terminal output not available on non-terminal".
A: Maybe you're not logged on from a terminal but probably you're using
UNIX98 pty's without glibc 2.1 (Linux). The glibc 2.0 ttyname() function
incorrectly reports that UNIX98 slave pty's are no tty's.
Q: Why not use DBUS for the communications with the daemon?
A: KDE su needs one instance of the daemon per host, instead of per desktop
session.
Q: How do I attach the dialog box properly to my program?
A: Using --attach <winid>. In C++, for example, you can call kdesu like:
QStringList arguments;
arguments << "--attach" << QString::number(window()->winId())
arguments << "--" << "program_to_run";
//kdesu is a libexec program, so it will not be in the path. findExe will find it correctly anyway
QString su = KStandardDirs::findExe("kdesu");
if(su.isEmpty()) return false; //Cannot find kdesu
QProcess *process = new QProcess(NULL);
connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processFailed()));
connect(process, SIGNAL(finished( int, QProcess::ExitStatus) ), this, SLOT(processFinished()));
process->start(su, arguments);
Q: How do I use kdesu from a bash script?
A: kdesu is a libexec program, so does not normally reside in your PATH.
Use something like:
$(kde4-config --path libexec)kdesu -- program_to_run
If you want kdesu to attach as a proper dialog box of the current
konsole window, you can do (bash specific):
$(kde4-config --path libexec)kdesu ${WINDOWID:+--attach $WINDOWID} -- program_to_run

152
kdesu/LICENSE.readme Normal file
View File

@ -0,0 +1,152 @@
kdesu - a KDE front end to su
AMMENDMENT: Geert Jansen relicensed his contributions
under the following terms:
=== Cut ===
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
=== Cut ===
The license below is only for reference once the remaining copyright
holders have approved this licensing change.
Copyright (c) 1998 by Pietro Iglio <iglio@fub.it>
Copyright (c) 1999,2000 by Geert Jansen <jansen@kde.org>
The "Artistic License"
Preamble
The intent of this document is to state the conditions under which a
Package may be copied, such that the Copyright Holder maintains some
semblance of artistic control over the development of the package,
while giving the users of the package the right to use and
distribute the Package in a more-or-less customary fashion, plus the
right to make reasonable modifications.
Definitions:
* "Package" refers to the collection of files distributed by the
Copyright Holder, and derivatives of that collection of files
created through textual modification.
* "Standard Version" refers to such a Package if it has not been
modified, or has been modified in accordance with the wishes of
the Copyright Holder.
* "Copyright Holder" is whoever is named in the copyright or
copyrights for the package.
* "You" is you, if you're thinking about copying or distributing
this Package.
* "Reasonable copying fee" is whatever you can justify on the
basis of media cost, duplication charges, time of people
involved, and so on. (You will not be required to justify it to
the Copyright Holder, but only to the computing community at
large as a market that must bear the fee.)
* "Freely Available" means that no fee is charged for the item
itself, though there may be fees involved in handling the item.
It also means that recipients of the item may redistribute it
under the same conditions they received it.
1. You may make and give away verbatim copies of the source form of
the Standard Version of this Package without restriction, provided
that you duplicate all of the original copyright notices and
associated disclaimers.
2. You may apply bug fixes, portability fixes and other
modifications derived from the Public Domain or from the Copyright
Holder. A Package modified in such a way shall still be considered
the Standard Version.
3. You may otherwise modify your copy of this Package in any way,
provided that you insert a prominent notice in each changed file
stating how and when you changed that file, and provided that you do
at least ONE of the following:
a) place your modifications in the Public Domain or
otherwise make them Freely Available, such as by posting
said modifications to Usenet or an equivalent medium, or
placing the modifications on a major archive site such as
ftp.uu.net, or by allowing the Copyright Holder to include
your modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation
or organization.
c) rename any non-standard executables so the names do not
conflict with standard executables, which must also be
provided, and provide a separate manual page for each
non-standard executable that clearly documents how it
differs from the Standard Version.
d) make other distribution arrangements with the Copyright
Holder.
4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and
library files, together with instructions (in the manual
page or equivalent) on where to get the Standard Version.
b) accompany the distribution with the machine-readable
source of the Package with your modifications.
c) accompany any non-standard executables with their
corresponding Standard Version executables, giving the
non-standard executables non-standard names, and clearly
documenting the differences in manual pages (or
equivalent), together with instructions on where to get
the Standard Version.
d) make other distribution arrangements with the Copyright
Holder.
5. You may charge a reasonable copying fee for any distribution of
this Package. You may charge any fee you choose for support of this
Package. You may not charge a fee for this Package itself. However,
you may distribute this Package in aggregate with other (possibly
commercial) programs as part of a larger (possibly commercial)
software distribution provided that you do not advertise this
Package as a product of your own.
6. The scripts and library files supplied as input to or produced as
output from the programs of this Package do not automatically fall
under the copyright of this Package, but belong to whomever
generated them, and may be sold commercially, and may be aggregated
with this Package.
7. C or perl subroutines supplied by you and linked into this
Package shall not be considered part of this Package.
8. The name of the Copyright Holder may not be used to endorse or
promote products derived from this software without specific prior
written permission.
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End

2
kdesu/Messages.sh Normal file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kdesu5.pot

34
kdesu/README Normal file
View File

@ -0,0 +1,34 @@
KDESU: A KDE front end for `su'.
What is it?
KDE su is a graphical front end to the Unix `su' utility. It allows you
to run programs as another user by entering their password.
It is _not_ a setuid root program, it runs completely unprivileged.
The system's program `su' is used for acquiring privileges.
Usage:
$ kdesu -h
$ kdesu -c konsole
Please see the HTML documentation!
Notes and Acknowledgements:
Credits go to Pietro Iglio. He was the original author of KDE su
(until version 0.3). I was writing a similar program when I
found out that KDE su already existed. We decided to merge our
projects and that I would continue with it.
If you find any bug of have a suggestion, feel free to contact me
at <kde@geeksrus.net>.
License:
KDE su comes under the "Artistic License". See the file LICENSE.readme
for the exact terms.
Alan Eldridge 2002/10/12 <kde@geeksrus.net>

472
kdesu/kdesu.cpp Normal file
View File

@ -0,0 +1,472 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kdesu.
* SPDX-FileCopyrightText: 1998 Pietro Iglio <iglio@fub.it>
* SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
* SPDX-License-Identifier: Artistic-2.0
*/
#include <config-kde-cli-tools.h>
#include <errno.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/time.h>
#if defined(HAVE_SYS_WAIT_H)
#include <sys/wait.h>
#endif
#if HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#endif
#if HAVE_SYS_PROCCTL_H
#include <sys/procctl.h>
#include <unistd.h>
#endif
#include <QApplication>
#include <QCommandLineParser>
#include <QFile>
#include <QFileInfo>
#include <QLoggingCategory>
#include <KSharedConfig>
#include <kaboutdata.h>
#include <kconfiggroup.h>
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <kshell.h>
#include <kstartupinfo.h>
#include <kuser.h>
#include <kwindowsystem.h>
#include <kdesu/client.h>
#include <kdesu/defaults.h>
#include <kdesu/su.h>
#include "sudlg.h"
#define ERR strerror(errno)
static QLoggingCategory category("org.kde.kdesu");
QByteArray command;
const char *Version = PROJECT_VERSION;
// NOTE: if you change the position of the -u switch, be sure to adjust it
// at the beginning of main()
#if 0
// D-BUS has no equivalent
QByteArray dcopNetworkId()
{
QByteArray result;
result.resize(1025);
QFile file(DCOPClient::dcopServerFile());
if (!file.open(QIODevice::ReadOnly))
return "";
int i = file.readLine(result.data(), 1024);
if (i <= 0)
return "";
result.data()[i-1] = '\0'; // strip newline
return result;
}
#endif
static int startApp(QCommandLineParser &p);
int main(int argc, char *argv[])
{
// disable ptrace
#if HAVE_PR_SET_DUMPABLE
prctl(PR_SET_DUMPABLE, 0);
#endif
#if HAVE_PROC_TRACE_CTL
int mode = PROC_TRACE_CTL_DISABLE;
procctl(P_PID, getpid(), PROC_TRACE_CTL, &mode);
#endif
QApplication app(argc, argv);
// FIXME: this can be considered a poor man's solution, as it's not
// directly obvious to a gui user. :)
// anyway, i vote against removing it even when we have a proper gui
// implementation. -- ossi
QByteArray duser = qgetenv("ADMIN_ACCOUNT");
if (duser.isEmpty()) {
duser = "root";
}
KLocalizedString::setApplicationDomain("kdesu5");
KAboutData aboutData(QStringLiteral("kdesu"),
i18n("KDE su"),
QLatin1String(Version),
i18n("Runs a program with elevated privileges."),
KAboutLicense::Artistic,
i18n("Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"));
aboutData.addAuthor(i18n("Geert Jansen"), i18n("Maintainer"), QStringLiteral("jansen@kde.org"), QStringLiteral("http://www.stack.nl/~geertj/"));
aboutData.addAuthor(i18n("Pietro Iglio"), i18n("Original author"), QStringLiteral("iglio@fub.it"));
app.setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-password")));
KAboutData::setApplicationData(aboutData);
// NOTE: if you change the position of the -u switch, be sure to adjust it
// at the beginning of main()
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addPositionalArgument(QStringLiteral("command"), i18n("Specifies the command to run as separate arguments"));
parser.addOption(QCommandLineOption(QStringLiteral("c"), i18n("Specifies the command to run as one string"), QStringLiteral("command")));
parser.addOption(QCommandLineOption(QStringLiteral("f"), i18n("Run command under target uid if <file> is not writable"), QStringLiteral("file")));
parser.addOption(QCommandLineOption(QStringLiteral("u"), i18n("Specifies the target uid"), QStringLiteral("user"), QString::fromLatin1(duser)));
parser.addOption(QCommandLineOption(QStringLiteral("n"), i18n("Do not keep password")));
parser.addOption(QCommandLineOption(QStringLiteral("s"), i18n("Stop the daemon (forgets all passwords)")));
parser.addOption(QCommandLineOption(QStringLiteral("t"), i18n("Enable terminal output (no password keeping)")));
parser.addOption(
QCommandLineOption(QStringLiteral("p"), i18n("Set priority value: 0 <= prio <= 100, 0 is lowest"), QStringLiteral("prio"), QStringLiteral("50")));
parser.addOption(QCommandLineOption(QStringLiteral("r"), i18n("Use realtime scheduling")));
parser.addOption(QCommandLineOption(QStringLiteral("noignorebutton"), i18n("Do not display ignore button")));
parser.addOption(QCommandLineOption(QStringLiteral("i"), i18n("Specify icon to use in the password dialog"), QStringLiteral("icon name")));
parser.addOption(QCommandLineOption(QStringLiteral("d"), i18n("Do not show the command to be run in the dialog")));
#ifdef HAVE_X11
/* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach.
* For consistancy, we silently map --embed to --attach */
parser.addOption(QCommandLineOption(QStringLiteral("attach"),
i18nc("Transient means that the kdesu app will be attached to the app specified by the winid so that it is like a "
"dialog box rather than some separate program",
"Makes the dialog transient for an X app specified by winid"),
QStringLiteral("winid")));
parser.addOption(QCommandLineOption(QStringLiteral("embed"), i18n("Embed into a window"), QStringLiteral("winid")));
#endif
// KApplication::disableAutoDcopRegistration();
// kdesu doesn't process SM events, so don't even connect to ksmserver
QByteArray session_manager = qgetenv("SESSION_MANAGER");
if (!session_manager.isEmpty()) {
unsetenv("SESSION_MANAGER");
}
// but propagate it to the started app
if (!session_manager.isEmpty()) {
setenv("SESSION_MANAGER", session_manager.data(), 1);
}
{
#ifdef HAVE_X11
KStartupInfoId id;
id.initId();
id.setupStartupEnv(); // make DESKTOP_STARTUP_ID env. var. available again
#endif
}
parser.process(app);
aboutData.processCommandLine(&parser);
int result = startApp(parser);
if (result == 127) {
KMessageBox::sorry(nullptr, i18n("Cannot execute command '%1'.", QString::fromLocal8Bit(command)));
}
if (result == -2) {
KMessageBox::sorry(nullptr, i18n("Cannot execute command '%1'. It contains invalid characters.", QString::fromLocal8Bit(command)));
}
return result;
}
static int startApp(QCommandLineParser &p)
{
// Stop daemon and exit?
if (p.isSet(QStringLiteral("s"))) {
KDEsuClient client;
if (client.ping() == -1) {
qCCritical(category) << "Daemon not running -- nothing to stop\n";
p.showHelp(1);
}
if (client.stopServer() != -1) {
qCDebug(category) << "Daemon stopped\n";
exit(0);
}
qCCritical(category) << "Could not stop daemon\n";
p.showHelp(1);
}
QString icon;
if (p.isSet(QStringLiteral("i"))) {
icon = p.value(QStringLiteral("i"));
}
bool prompt = true;
if (p.isSet(QStringLiteral("d"))) {
prompt = false;
}
// Get target uid
const QByteArray user = p.value(QStringLiteral("u")).toLocal8Bit();
QByteArray auth_user = user;
struct passwd *pw = getpwnam(user.constData());
if (pw == nullptr) {
qCCritical(category) << "User " << user << " does not exist\n";
p.showHelp(1);
}
bool other_uid = (getuid() != pw->pw_uid);
bool change_uid = other_uid;
if (!change_uid) {
char *cur_user = getenv("USER");
if (!cur_user) {
cur_user = getenv("LOGNAME");
}
change_uid = (!cur_user || user != cur_user);
}
// If file is writeable, do not change uid
QString file = p.value(QStringLiteral("f"));
if (other_uid && !file.isEmpty()) {
if (file.startsWith(QLatin1Char('/'))) {
file = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, file);
if (file.isEmpty()) {
qCCritical(category) << "Config file not found: " << file;
p.showHelp(1);
}
}
QFileInfo fi(file);
if (!fi.exists()) {
qCCritical(category) << "File does not exist: " << file;
p.showHelp(1);
}
change_uid = !fi.isWritable();
}
// Get priority/scheduler
QString tmp = p.value(QStringLiteral("p"));
bool ok;
int priority = tmp.toInt(&ok);
if (!ok || (priority < 0) || (priority > 100)) {
qCCritical(category) << i18n("Illegal priority: %1", tmp);
p.showHelp(1);
}
int scheduler = SuProcess::SchedNormal;
if (p.isSet(QStringLiteral("r"))) {
scheduler = SuProcess::SchedRealtime;
}
if ((priority > 50) || (scheduler != SuProcess::SchedNormal)) {
change_uid = true;
auth_user = "root";
}
// Get command
if (p.isSet(QStringLiteral("c"))) {
command = p.value(QStringLiteral("c")).toLocal8Bit();
// Accepting additional arguments here is somewhat weird,
// but one can conceive use cases: have a complex command with
// redirections and additional file names which need to be quoted
// safely.
} else {
if (p.positionalArguments().count() == 0) {
qCCritical(category) << i18n("No command specified.");
p.showHelp(1);
}
}
const auto positionalArguments = p.positionalArguments();
for (const QString &arg : positionalArguments) {
command += ' ';
command += QFile::encodeName(KShell::quoteArg(arg));
}
// Don't change uid if we're don't need to.
if (!change_uid) {
int result = system(command.constData());
result = WEXITSTATUS(result);
return result;
}
// Check for daemon and start if necessary
bool just_started = false;
bool have_daemon = true;
KDEsuClient client;
if (!client.isServerSGID()) {
qCWarning(category) << "Daemon not safe (not sgid), not using it.\n";
have_daemon = false;
} else if (client.ping() == -1) {
if (client.startServer() == -1) {
qCWarning(category) << "Could not start daemon, reduced functionality.\n";
have_daemon = false;
}
just_started = true;
}
// Try to exec the command with kdesud.
bool keep = !p.isSet(QStringLiteral("n")) && have_daemon;
bool terminal = p.isSet(QStringLiteral("t"));
bool withIgnoreButton = !p.isSet(QStringLiteral("noignorebutton"));
int winid = -1;
bool attach = p.isSet(QStringLiteral("attach"));
if (attach) {
winid = p.value(QStringLiteral("attach")).toInt(&attach, 0); // C style parsing. If the string begins with "0x", base 16 is used; if the string begins
// with "0", base 8 is used; otherwise, base 10 is used.
if (!attach) {
qCWarning(category) << "Specified winid to attach to is not a valid number";
}
} else if (p.isSet(QStringLiteral("embed"))) {
/* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach.
* For consistancy, we silently map --embed to --attach */
attach = true;
winid = p.value(QStringLiteral("embed")).toInt(&attach, 0); // C style parsing. If the string begins with "0x", base 16 is used; if the string begins
// with "0", base 8 is used; otherwise, base 10 is used.
if (!attach) {
qCWarning(category) << "Specified winid to attach to is not a valid number";
}
}
QList<QByteArray> env;
QByteArray options;
env << ("DESKTOP_STARTUP_ID=" + KStartupInfo::startupId());
// TODO: Maybe should port this to XDG_*, somehow?
// if (pw->pw_uid)
// {
// // Only propagate KDEHOME for non-root users,
// // root uses KDEROOTHOME
//
// // Translate the KDEHOME of this user to the new user.
// QString kdeHome = KGlobal::dirs()->relativeLocation("home", KGlobal::dirs()->localkdedir());
// if (kdeHome[0] != '/')
// kdeHome.prepend("~/");
// else
// kdeHome.clear(); // Use default
//
// env << ("KDEHOME="+ QFile::encodeName(kdeHome));
// }
KUser u;
env << (QByteArray)("KDESU_USER=" + u.loginName().toLocal8Bit());
if (keep && !terminal && !just_started) {
client.setPriority(priority);
client.setScheduler(scheduler);
int result = client.exec(command, user, options, env);
if (result == 0) {
result = client.exitCode();
return result;
}
}
// Set core dump size to 0 because we will have
// root's password in memory.
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = 0;
if (setrlimit(RLIMIT_CORE, &rlim)) {
qCCritical(category) << "rlimit(): " << ERR;
p.showHelp(1);
}
// Read configuration
KConfigGroup config(KSharedConfig::openConfig(), "Passwords");
int timeout = config.readEntry("Timeout", defTimeout);
// Check if we need a password
SuProcess proc;
proc.setUser(auth_user);
int needpw = proc.checkNeedPassword();
if (needpw < 0) {
QString err = i18n("Su returned with an error.\n");
KMessageBox::error(nullptr, err);
p.showHelp(1);
}
if (needpw == 0) {
keep = 0;
qDebug() << "Don't need password!!\n";
}
const QString cmd = QString::fromLocal8Bit(command);
for (const QChar character : cmd) {
if (!character.isPrint() && character.category() != QChar::Other_Surrogate) {
return -2;
}
}
// Start the dialog
QString password;
if (needpw) {
#ifdef HAVE_X11
KStartupInfoId id;
id.initId();
KStartupInfoData data;
data.setSilent(KStartupInfoData::Yes);
KStartupInfo::sendChange(id, data);
#endif
KDEsuDialog dlg(user, auth_user, keep && !terminal, icon, withIgnoreButton);
if (prompt) {
dlg.addCommentLine(i18n("Command:"), QFile::decodeName(command));
}
if (defKeep) {
dlg.setKeepPassword(true);
}
if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) {
QString prio;
if (scheduler == SuProcess::SchedRealtime) {
prio += i18n("realtime: ");
}
prio += QStringLiteral("%1/100").arg(priority);
if (prompt) {
dlg.addCommentLine(i18n("Priority:"), prio);
}
}
// Attach dialog
#ifdef HAVE_X11
if (attach) {
dlg.setAttribute(Qt::WA_NativeWindow, true);
KWindowSystem::setMainWindow(dlg.windowHandle(), WId(winid));
}
#endif
int ret = dlg.exec();
if (ret == KDEsuDialog::Rejected) {
#ifdef HAVE_X11
KStartupInfo::sendFinish(id);
#endif
p.showHelp(1);
}
if (ret == KDEsuDialog::AsUser) {
change_uid = false;
}
password = dlg.password();
keep = dlg.keepPassword();
#ifdef HAVE_X11
data.setSilent(KStartupInfoData::No);
KStartupInfo::sendChange(id, data);
#endif
}
// Some events may need to be handled (like a button animation)
qApp->processEvents();
// Run command
if (!change_uid) {
int result = system(command.constData());
result = WEXITSTATUS(result);
return result;
} else if (keep && have_daemon) {
client.setPass(password.toLocal8Bit().constData(), timeout);
client.setPriority(priority);
client.setScheduler(scheduler);
int result = client.exec(command, user, options, env);
if (result == 0) {
result = client.exitCode();
return result;
}
} else {
SuProcess proc;
proc.setTerminal(terminal);
proc.setErase(true);
proc.setUser(user);
proc.setEnvironment(env);
proc.setPriority(priority);
proc.setScheduler(scheduler);
proc.setCommand(command);
int result = proc.exec(password.toLocal8Bit().constData());
return result;
}
return -1;
}

116
kdesu/sudlg.cpp Normal file
View File

@ -0,0 +1,116 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kdesu.
* SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
* SPDX-License-Identifier: Artistic-2.0
*/
#include "sudlg.h"
#include <KLocalizedString>
#include <QPushButton>
#include <qstyle.h>
KDEsuDialog::KDEsuDialog(QByteArray user, QByteArray authUser, bool enableKeep, const QString &icon, bool withIgnoreButton)
: KPasswordDialog(nullptr, enableKeep ? ShowKeepPassword : NoFlags)
{
if (!icon.isEmpty()) {
setIcon(QIcon::fromTheme(icon));
}
if (withIgnoreButton) {
buttonBox()->addButton(QDialogButtonBox::Ignore);
}
proc.setUser(authUser);
setWindowTitle(i18n("Run as %1", QString::fromLatin1(user)));
QString prompt;
if (proc.useUsersOwnPassword()) {
prompt = i18n("Please enter your password below.");
} else {
if (authUser == "root") {
if (withIgnoreButton) {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs <b>root privileges</b>. "
"Please enter <b>root's</b> password below or click "
"Ignore to continue with your current privileges.")
+ QStringLiteral("</qt>");
} else {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs <b>root privileges</b>. "
"Please enter <b>root's</b> password below.")
+ QStringLiteral("</qt>");
}
} else {
if (withIgnoreButton) {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs additional privileges. "
"Please enter the password for <b>%1</b> below or click "
"Ignore to continue with your current privileges.",
QString::fromLatin1(authUser))
+ QStringLiteral("</qt>");
} else {
prompt = QStringLiteral("<qt>")
+ i18n("The action you requested needs additional privileges. "
"Please enter the password for <b>%1</b> below.",
QString::fromLatin1(authUser))
+ QStringLiteral("</qt>");
}
}
}
setPrompt(prompt);
if (withIgnoreButton) {
connect(buttonBox()->button(QDialogButtonBox::Ignore), &QAbstractButton::clicked, this, &KDEsuDialog::slotUser1);
}
}
KDEsuDialog::~KDEsuDialog()
{
}
bool KDEsuDialog::checkPassword()
{
int status = proc.checkInstall(password().toLocal8Bit().constData());
switch (status) {
case -1:
showErrorMessage(i18n("Conversation with su failed."), UsernameError);
return false;
case 0:
return true;
case SuProcess::SuNotFound:
showErrorMessage(i18n("The program 'su' could not be found.<br />"
"Ensure your PATH is set correctly."),
FatalError);
return false;
case SuProcess::SuNotAllowed:
// This is actually never returned, as kdesu cannot tell the difference.
showErrorMessage(QLatin1String("The impossible happened."), FatalError);
return false;
case SuProcess::SuIncorrectPassword:
showErrorMessage(i18n("Permission denied.<br />"
"Possibly incorrect password, please try again.<br />"
"On some systems, you need to be in a special "
"group (often: wheel) to use this program."),
PasswordError);
return false;
default:
showErrorMessage(i18n("Internal error: illegal return from "
"SuProcess::checkInstall()"),
FatalError);
done(Rejected);
return false;
}
}
void KDEsuDialog::slotUser1()
{
done(AsUser);
}

38
kdesu/sudlg.h Normal file
View File

@ -0,0 +1,38 @@
/* vi: ts=8 sts=4 sw=4
*
* This file is part of the KDE project, module kdesu.
* SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
* SPDX-License-Identifier: Artistic-2.0
*/
#ifndef __SuDlg_h_Included__
#define __SuDlg_h_Included__
#include <QByteArray>
#include <KPasswordDialog>
#include <kdesu/su.h>
using namespace KDESu;
class KDEsuDialog : public KPasswordDialog
{
Q_OBJECT
public:
KDEsuDialog(QByteArray user, QByteArray authUser, bool enableKeep, const QString &icon, bool withIgnoreButton);
~KDEsuDialog() override;
enum ResultCodes { AsUser = 10 };
private Q_SLOTS:
void slotUser1();
protected:
bool checkPassword() override;
private:
SuProcess proc;
};
#endif // __SuDlg_h_Included__

View File

@ -0,0 +1,62 @@
add_subdirectory(tests)
# KI18N Translation Domain for this library
add_definitions(-DTRANSLATION_DOMAIN=\"kcm5_filetypes\")
set(libfiletypes_SRCS
filetypedetails.cpp
filegroupdetails.cpp
kservicelistwidget.cpp
typeslistitem.cpp
mimetypedata.cpp
mimetypewriter.cpp
newtypedlg.cpp
kserviceselectdlg.cpp
filetypedetails.h
filegroupdetails.h
kservicelistwidget.h
typeslistitem.h
mimetypedata.h
mimetypewriter.h
newtypedlg.h
kserviceselectdlg.h
)
########### next target ###############
set(kcm_filetypes_SRCS filetypesview.cpp ${libfiletypes_SRCS})
kcoreaddons_add_plugin(kcm_filetypes SOURCES ${kcm_filetypes_SRCS} INSTALL_NAMESPACE "plasma/kcms/systemsettings_qwidgets")
target_link_libraries(kcm_filetypes
KF5::ConfigWidgets
KF5::IconThemes
KF5::I18n
KF5::KIOWidgets # KOpenWithDialog, KBuildSycocaProgressDialog
Qt::DBus
)
########### next target ###############
set(keditfiletype_SRCS keditfiletype.cpp keditfiletype.h ${libfiletypes_SRCS})
add_executable(keditfiletype ${keditfiletype_SRCS})
target_compile_definitions(keditfiletype PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(keditfiletype
KF5::ConfigCore
KF5::IconThemes
KF5::KIOWidgets # KOpenWithDialog, KBuildSycocaProgressDialog
KF5::WindowSystem
KF5::I18n
KF5::Service
Qt::DBus
)
install_compat_symlink(keditfiletype)
install(TARGETS keditfiletype DESTINATION ${KDE_INSTALL_FULL_BINDIR})
########### install files ###############
install( FILES kcm_filetypes.desktop DESTINATION ${KDE_INSTALL_APPDIR} )
install( PROGRAMS org.kde.keditfiletype.desktop DESTINATION ${KDE_INSTALL_APPDIR} )

View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kcm5_filetypes.pot

View File

@ -0,0 +1,59 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#include "filegroupdetails.h"
#include "mimetypedata.h"
#include <QButtonGroup>
#include <QGroupBox>
#include <QLayout>
#include <QRadioButton>
#include <klocalizedstring.h>
FileGroupDetails::FileGroupDetails(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout *secondLayout = new QVBoxLayout(this);
QGroupBox *autoEmbedBox = new QGroupBox(i18n("Left Click Action (only for Konqueror file manager)"));
m_autoEmbed = new QButtonGroup(autoEmbedBox);
secondLayout->addWidget(autoEmbedBox);
// The order of those two items is very important. If you change it, fix typeslistitem.cpp !
QRadioButton *r1 = new QRadioButton(i18n("Show file in embedded viewer"));
QRadioButton *r2 = new QRadioButton(i18n("Show file in separate viewer"));
QVBoxLayout *autoEmbedBoxLayout = new QVBoxLayout(autoEmbedBox);
autoEmbedBoxLayout->addWidget(r1);
autoEmbedBoxLayout->addWidget(r2);
m_autoEmbed->addButton(r1, 0);
m_autoEmbed->addButton(r2, 1);
connect(m_autoEmbed, SIGNAL(buttonClicked(int)), SLOT(slotAutoEmbedClicked(int)));
autoEmbedBox->setWhatsThis(
i18n("Here you can configure what the Konqueror file manager"
" will do when you click on a file belonging to this group. Konqueror can display the file in"
" an embedded viewer or start up a separate application. You can change this setting for a"
" specific file type in the 'Embedding' tab of the file type configuration. Dolphin "
" shows files always in a separate viewer"));
secondLayout->addStretch();
}
void FileGroupDetails::setMimeTypeData(MimeTypeData *mimeTypeData)
{
Q_ASSERT(mimeTypeData->isMeta());
m_mimeTypeData = mimeTypeData;
m_autoEmbed->button(m_mimeTypeData->autoEmbed())->setChecked(true);
}
void FileGroupDetails::slotAutoEmbedClicked(int button)
{
if (!m_mimeTypeData) {
return;
}
m_mimeTypeData->setAutoEmbed((MimeTypeData::AutoEmbed)button);
Q_EMIT changed(true);
}

View File

@ -0,0 +1,39 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef FILEGROUPDETAILS_H
#define FILEGROUPDETAILS_H
#include <QWidget>
class MimeTypeData;
class QButtonGroup;
/**
* This widget contains the details for a filetype group.
* Currently this only involves the embedding configuration.
*/
class FileGroupDetails : public QWidget
{
Q_OBJECT
public:
explicit FileGroupDetails(QWidget *parent = nullptr);
void setMimeTypeData(MimeTypeData *mimeTypeData);
Q_SIGNALS:
void changed(bool);
protected Q_SLOTS:
void slotAutoEmbedClicked(int button);
private:
MimeTypeData *m_mimeTypeData;
// Embedding config
QButtonGroup *m_autoEmbed;
};
#endif

View File

@ -0,0 +1,363 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
// Own
#include "filetypedetails.h"
// Qt
#include <QBoxLayout>
#include <QButtonGroup>
#include <QCheckBox>
#include <QDebug>
#include <QInputDialog>
#include <QLabel>
#include <QLayout>
#include <QListWidget>
#include <QPushButton>
#include <QRadioButton>
// KDE
#include <kconfig.h>
#include <kconfiggroup.h>
#include <kiconbutton.h>
#include <kicondialog.h>
#include <klineedit.h>
#include <klocalizedstring.h>
#include <ksharedconfig.h>
// Local
#include "kservicelistwidget.h"
#include "typeslistitem.h"
FileTypeDetails::FileTypeDetails(QWidget *parent)
: QWidget(parent)
, m_mimeTypeData(nullptr)
, m_item(nullptr)
{
QVBoxLayout *topLayout = new QVBoxLayout(this);
topLayout->setContentsMargins(0, 0, 0, 0);
m_mimeTypeLabel = new QLabel(this);
m_mimeTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
topLayout->addWidget(m_mimeTypeLabel, 0, Qt::AlignCenter);
m_tabWidget = new QTabWidget(this);
topLayout->addWidget(m_tabWidget);
QString wtstr;
// First tab - General
QWidget *firstWidget = new QWidget(m_tabWidget);
QVBoxLayout *firstLayout = new QVBoxLayout(firstWidget);
QHBoxLayout *hBox = new QHBoxLayout();
firstLayout->addLayout(hBox);
iconButton = new KIconButton(firstWidget);
iconButton->setIconType(KIconLoader::Desktop, KIconLoader::MimeType);
connect(iconButton, &KIconButton::iconChanged, this, &FileTypeDetails::updateIcon);
iconButton->setWhatsThis(
i18n("This button displays the icon associated"
" with the selected file type. Click on it to choose a different icon."));
iconButton->setFixedSize(70, 70);
iconLabel = nullptr;
hBox->addWidget(iconButton);
QGroupBox *gb = new QGroupBox(i18n("Filename Patterns"), firstWidget);
hBox->addWidget(gb);
hBox = new QHBoxLayout(gb);
extensionLB = new QListWidget(gb);
connect(extensionLB, &QListWidget::itemSelectionChanged, this, &FileTypeDetails::enableExtButtons);
hBox->addWidget(extensionLB);
extensionLB->setFixedHeight(extensionLB->minimumSizeHint().height());
extensionLB->setWhatsThis(
i18n("This box contains a list of patterns that can be"
" used to identify files of the selected type. For example, the pattern *.txt is"
" associated with the file type 'text/plain'; all files ending in '.txt' are recognized"
" as plain text files."));
QVBoxLayout *vbox = new QVBoxLayout();
hBox->addLayout(vbox);
addExtButton = new QPushButton(i18n("Add..."), gb);
addExtButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
addExtButton->setEnabled(false);
connect(addExtButton, &QAbstractButton::clicked, this, &FileTypeDetails::addExtension);
vbox->addWidget(addExtButton);
addExtButton->setWhatsThis(i18n("Add a new pattern for the selected file type."));
removeExtButton = new QPushButton(i18n("Remove"), gb);
removeExtButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
removeExtButton->setEnabled(false);
connect(removeExtButton, &QAbstractButton::clicked, this, &FileTypeDetails::removeExtension);
vbox->addWidget(removeExtButton);
removeExtButton->setWhatsThis(i18n("Remove the selected filename pattern."));
vbox->addStretch(1);
gb->setFixedHeight(gb->minimumSizeHint().height());
description = new KLineEdit(firstWidget);
description->setClearButtonEnabled(true);
connect(description, &QLineEdit::textChanged, this, &FileTypeDetails::updateDescription);
QHBoxLayout *descriptionBox = new QHBoxLayout;
descriptionBox->addWidget(new QLabel(i18n("Description:"), firstWidget));
descriptionBox->addWidget(description);
firstLayout->addLayout(descriptionBox);
wtstr = i18n(
"You can enter a short description for files of the selected"
" file type (e.g. 'HTML Page'). This description will be used by applications"
" like Konqueror to display directory content.");
description->setWhatsThis(wtstr);
serviceListWidget = new KServiceListWidget(KServiceListWidget::SERVICELIST_APPLICATIONS, firstWidget);
connect(serviceListWidget, &KServiceListWidget::changed, this, &FileTypeDetails::changed);
firstLayout->addWidget(serviceListWidget, 5);
// Second tab - Embedding
QWidget *secondWidget = new QWidget(m_tabWidget);
QVBoxLayout *secondLayout = new QVBoxLayout(secondWidget);
m_autoEmbedBox = new QGroupBox(i18n("Left Click Action in Konqueror"), secondWidget);
secondLayout->addWidget(m_autoEmbedBox);
m_autoEmbedBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
QRadioButton *embViewerRadio = new QRadioButton(i18n("Show file in embedded viewer"));
QRadioButton *sepViewerRadio = new QRadioButton(i18n("Show file in separate viewer"));
m_rbGroupSettings = new QRadioButton(QStringLiteral("Use settings for '%1' group"));
m_chkAskSave = new QCheckBox(i18n("Ask whether to save to disk instead (only for Konqueror browser)"));
connect(m_chkAskSave, &QAbstractButton::toggled, this, &FileTypeDetails::slotAskSaveToggled);
m_autoEmbedGroup = new QButtonGroup(m_autoEmbedBox);
m_autoEmbedGroup->addButton(embViewerRadio, 0);
m_autoEmbedGroup->addButton(sepViewerRadio, 1);
m_autoEmbedGroup->addButton(m_rbGroupSettings, 2);
connect(m_autoEmbedGroup, SIGNAL(buttonClicked(int)), SLOT(slotAutoEmbedClicked(int)));
vbox = new QVBoxLayout(m_autoEmbedBox);
vbox->addWidget(embViewerRadio);
vbox->addWidget(sepViewerRadio);
vbox->addWidget(m_rbGroupSettings);
vbox->addWidget(m_chkAskSave);
m_autoEmbedBox->setWhatsThis(
i18n("Here you can configure what the Konqueror file manager"
" will do when you click on a file of this type. Konqueror can either display the file in"
" an embedded viewer, or start up a separate application. If set to 'Use settings for G group',"
" the file manager will behave according to the settings of the group G to which this type belongs;"
" for instance, 'image' if the current file type is image/png. Dolphin"
" always shows files in a separate viewer."));
embedServiceListWidget = new KServiceListWidget(KServiceListWidget::SERVICELIST_SERVICES, secondWidget);
// embedServiceListWidget->setMinimumHeight( serviceListWidget->sizeHint().height() );
connect(embedServiceListWidget, &KServiceListWidget::changed, this, &FileTypeDetails::changed);
secondLayout->addWidget(embedServiceListWidget);
m_tabWidget->addTab(firstWidget, i18n("&General"));
m_tabWidget->addTab(secondWidget, i18n("&Embedding"));
}
void FileTypeDetails::updateRemoveButton()
{
removeExtButton->setEnabled(extensionLB->count() > 0);
}
void FileTypeDetails::updateIcon(const QString &icon)
{
if (!m_mimeTypeData) {
return;
}
m_mimeTypeData->setUserSpecifiedIcon(icon);
if (m_item) {
m_item->setIcon(icon);
}
Q_EMIT changed(true);
}
void FileTypeDetails::updateDescription(const QString &desc)
{
if (!m_mimeTypeData) {
return;
}
m_mimeTypeData->setComment(desc);
Q_EMIT changed(true);
}
void FileTypeDetails::addExtension()
{
if (!m_mimeTypeData) {
return;
}
bool ok;
QString ext = QInputDialog::getText(this, i18n("Add New Extension"), i18n("Extension:"), QLineEdit::Normal, QStringLiteral("*."), &ok);
if (ok) {
extensionLB->addItem(ext);
QStringList patt = m_mimeTypeData->patterns();
patt += ext;
m_mimeTypeData->setPatterns(patt);
updateRemoveButton();
Q_EMIT changed(true);
}
}
void FileTypeDetails::removeExtension()
{
if (extensionLB->currentRow() == -1) {
return;
}
if (!m_mimeTypeData) {
return;
}
QStringList patt = m_mimeTypeData->patterns();
patt.removeAll(extensionLB->currentItem()->text());
m_mimeTypeData->setPatterns(patt);
delete extensionLB->takeItem(extensionLB->currentRow());
updateRemoveButton();
Q_EMIT changed(true);
}
void FileTypeDetails::slotAutoEmbedClicked(int button)
{
if (!m_mimeTypeData || (button > 2)) {
return;
}
m_mimeTypeData->setAutoEmbed((MimeTypeData::AutoEmbed)button);
updateAskSave();
Q_EMIT changed(true);
}
void FileTypeDetails::updateAskSave()
{
if (!m_mimeTypeData) {
return;
}
QMimeDatabase db;
MimeTypeData::AutoEmbed autoEmbed = m_mimeTypeData->autoEmbed();
if (m_mimeTypeData->isMeta() && autoEmbed == MimeTypeData::UseGroupSetting) {
// Resolve by looking at group (we could cache groups somewhere to avoid the re-parsing?)
autoEmbed = MimeTypeData(m_mimeTypeData->majorType()).autoEmbed();
}
const QString mimeType = m_mimeTypeData->name();
QString dontAskAgainName;
if (autoEmbed == MimeTypeData::Yes) { // Embedded
dontAskAgainName = QStringLiteral("askEmbedOrSave") + mimeType;
} else {
dontAskAgainName = QStringLiteral("askSave") + mimeType;
}
KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
// default value
bool ask = config->group("Notification Messages").readEntry(dontAskAgainName, QString()).isEmpty();
// per-mimetype override if there's one
m_mimeTypeData->getAskSave(ask);
bool neverAsk = false;
if (autoEmbed == MimeTypeData::Yes) {
const QMimeType mime = db.mimeTypeForName(mimeType);
if (mime.isValid()) {
// SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
// NOTE: Keep this function in sync with
// kparts/src/browseropenorsavequestion.cpp BrowserOpenOrSaveQuestionPrivate::autoEmbedMimeType
// Don't ask for:
// - html (even new tabs would ask, due to about:blank!)
// - dirs obviously (though not common over HTTP :),
// - images (reasoning: no need to save, most of the time, because fast to see)
// e.g. postscript is different, because takes longer to read, so
// it's more likely that the user might want to save it.
// - multipart/* ("server push", see kmultipart)
// clang-format off
if (mime.inherits(QStringLiteral("text/html"))
|| mime.inherits(QStringLiteral("application/xml"))
|| mime.inherits(QStringLiteral("inode/directory"))
|| mimeType.startsWith(QLatin1String("image"))
|| mime.inherits(QStringLiteral("multipart/x-mixed-replace"))
|| mime.inherits(QStringLiteral("multipart/replace"))) {
neverAsk = true;
}
// clang-format on
}
}
m_chkAskSave->blockSignals(true);
m_chkAskSave->setChecked(ask && !neverAsk);
m_chkAskSave->setEnabled(!neverAsk);
m_chkAskSave->blockSignals(false);
}
void FileTypeDetails::slotAskSaveToggled(bool askSave)
{
if (!m_mimeTypeData) {
return;
}
m_mimeTypeData->setAskSave(askSave);
Q_EMIT changed(true);
}
void FileTypeDetails::setMimeTypeData(MimeTypeData *mimeTypeData, TypesListItem *item)
{
m_mimeTypeData = mimeTypeData;
m_item = item; // can be 0
Q_ASSERT(mimeTypeData);
m_mimeTypeLabel->setText(i18n("File type %1", mimeTypeData->name()));
if (iconButton) {
iconButton->setIcon(mimeTypeData->icon());
iconButton->setToolTip(mimeTypeData->icon());
} else {
iconLabel->setPixmap(QIcon::fromTheme(mimeTypeData->icon()).pixmap(KIconLoader::SizeLarge));
}
description->setText(mimeTypeData->comment());
m_rbGroupSettings->setText(i18n("Use settings for '%1' group", mimeTypeData->majorType()));
extensionLB->clear();
addExtButton->setEnabled(true);
removeExtButton->setEnabled(false);
serviceListWidget->setMimeTypeData(mimeTypeData);
embedServiceListWidget->setMimeTypeData(mimeTypeData);
m_autoEmbedGroup->button(mimeTypeData->autoEmbed())->setChecked(true);
m_rbGroupSettings->setEnabled(mimeTypeData->canUseGroupSetting());
extensionLB->addItems(mimeTypeData->patterns());
updateAskSave();
}
void FileTypeDetails::enableExtButtons()
{
removeExtButton->setEnabled(true);
}
void FileTypeDetails::refresh()
{
if (!m_mimeTypeData) {
return;
}
// Called when ksycoca has been updated -> refresh data, then widgets
m_mimeTypeData->refresh();
setMimeTypeData(m_mimeTypeData, m_item);
}

View File

@ -0,0 +1,91 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef FILETYPEDETAILS_H
#define FILETYPEDETAILS_H
#include <QTabWidget>
class KIconButton;
class MimeTypeData;
class TypesListItem;
class QLabel;
class QListWidget;
class QGroupBox;
class QButtonGroup;
class QCheckBox;
class QRadioButton;
class KLineEdit;
class QPushButton;
class KServiceListWidget;
/**
* This widget contains the right part of the file type configuration
* dialog, that shows the details for a file type.
* It is implemented as a separate class so that it can be used by
* the keditfiletype program to show the details of a single mimetype.
*/
class FileTypeDetails : public QWidget
{
Q_OBJECT
public:
explicit FileTypeDetails(QWidget *parent = nullptr);
/**
* Set a non-gui "mimetype data" to work on,
* and optionally a gui "treeview item", to update its icon if set.
*/
void setMimeTypeData(MimeTypeData *mimeTypeData, TypesListItem *item = nullptr);
/**
* Called when ksycoca has changed
*/
void refresh();
protected:
void updateRemoveButton();
void updateAskSave();
Q_SIGNALS:
void embedMajor(const QString &major, bool &embed); // To adjust whether major type is being embedded
void changed(bool);
protected Q_SLOTS:
void updateIcon(const QString &icon);
void updateDescription(const QString &desc);
void addExtension();
void removeExtension();
void enableExtButtons();
void slotAutoEmbedClicked(int button);
void slotAskSaveToggled(bool);
private:
MimeTypeData *m_mimeTypeData;
TypesListItem *m_item; // can be 0, in keditfiletype!
QLabel *m_mimeTypeLabel;
QTabWidget *m_tabWidget;
// First tab - General
KIconButton *iconButton;
QLabel *iconLabel; // if icon cannot be changed
QListWidget *extensionLB;
QPushButton *addExtButton, *removeExtButton;
KLineEdit *description;
KServiceListWidget *serviceListWidget;
// Second tab - Embedding
QGroupBox *m_autoEmbedBox;
QButtonGroup *m_autoEmbedGroup;
KServiceListWidget *embedServiceListWidget;
QRadioButton *m_rbOpenSeparate;
QCheckBox *m_chkAskSave;
QRadioButton *m_rbGroupSettings;
};
#endif

View File

@ -0,0 +1,484 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000-2008 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2008 Urs Wolfer <uwolfer @ kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
// Own
#include "filetypesview.h"
#include "mimetypewriter.h"
// Qt
#include <QBoxLayout>
#include <QLayout>
#include <QPushButton>
#include <QStandardPaths>
#include <QTimer>
#include <qdbusconnection.h>
#include <qdbusmessage.h>
#include <qdebug.h>
// KDE
#include <kbuildsycocaprogressdialog.h>
#include <klineedit.h>
#include <klocalizedstring.h>
#include <kservicetypeprofile.h>
#include <ksycoca.h>
// Local
#include "filegroupdetails.h"
#include "filetypedetails.h"
#include "newtypedlg.h"
K_PLUGIN_CLASS_WITH_JSON(FileTypesView, "kcm_filetypes.json")
FileTypesView::FileTypesView(QWidget *parent, const QVariantList &)
: KCModule(parent)
{
m_fileTypesConfig = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
setQuickHelp(
i18n("<p><h1>File Associations</h1>"
" This module allows you to choose which applications are associated"
" with a given type of file. File types are also referred to as MIME types"
" (MIME is an acronym which stands for \"Multipurpose Internet Mail"
" Extensions\").</p><p> A file association consists of the following:"
" <ul><li>Rules for determining the MIME-type of a file, for example"
" the filename pattern *.png, which means 'all files with names that end"
" in .png', is associated with the MIME type \"image/png\";</li>"
" <li>A short description of the MIME-type, for example the description"
" of the MIME type \"image/png\" is simply 'PNG image';</li>"
" <li>An icon to be used for displaying files of the given MIME-type,"
" so that you can easily identify the type of file in a file"
" manager or file-selection dialog (at least for the types you use often);</li>"
" <li>A list of the applications which can be used to open files of the"
" given MIME-type -- if more than one application can be used then the"
" list is ordered by priority.</li></ul>"
" You may be surprised to find that some MIME types have no associated"
" filename patterns; in these cases, KDE is able to determine the"
" MIME-type by directly examining the contents of the file.</p>"));
setButtons(Help | Apply);
QString wtstr;
QHBoxLayout *l = new QHBoxLayout(this);
QVBoxLayout *leftLayout = new QVBoxLayout();
l->addLayout(leftLayout);
patternFilterLE = new KLineEdit(this);
patternFilterLE->setClearButtonEnabled(true);
patternFilterLE->setTrapReturnKey(true);
patternFilterLE->setPlaceholderText(i18n("Search for file type or filename pattern..."));
leftLayout->addWidget(patternFilterLE);
connect(patternFilterLE, &QLineEdit::textChanged, this, &FileTypesView::slotFilter);
wtstr = i18n(
"Enter a part of a filename pattern, and only file types with a "
"matching file pattern will appear in the list. Alternatively, enter "
"a part of a file type name as it appears in the list.");
patternFilterLE->setWhatsThis(wtstr);
typesLV = new TypesListTreeWidget(this);
typesLV->setHeaderLabel(i18n("Known Types"));
leftLayout->addWidget(typesLV);
connect(typesLV, &QTreeWidget::currentItemChanged, this, &FileTypesView::updateDisplay);
connect(typesLV, &QTreeWidget::itemDoubleClicked, this, &FileTypesView::slotDoubleClicked);
typesLV->setWhatsThis(
i18n("Here you can see a hierarchical list of"
" the file types which are known on your system. Click on the '+' sign"
" to expand a category, or the '-' sign to collapse it. Select a file type"
" (e.g. text/html for HTML files) to view/edit the information for that"
" file type using the controls on the right."));
QHBoxLayout *btnsLay = new QHBoxLayout();
leftLayout->addLayout(btnsLay);
btnsLay->addStretch(1);
QPushButton *addTypeB = new QPushButton(i18n("Add..."), this);
addTypeB->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
connect(addTypeB, &QAbstractButton::clicked, this, &FileTypesView::addType);
btnsLay->addWidget(addTypeB);
addTypeB->setWhatsThis(i18n("Click here to add a new file type."));
m_removeTypeB = new QPushButton(i18n("&Remove"), this);
m_removeTypeB->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
connect(m_removeTypeB, &QAbstractButton::clicked, this, &FileTypesView::removeType);
btnsLay->addWidget(m_removeTypeB);
m_removeTypeB->setEnabled(false);
m_removeButtonSaysRevert = false;
// For the right panel, prepare a widget stack
m_widgetStack = new QStackedWidget(this);
l->addWidget(m_widgetStack);
// File Type Details
m_details = new FileTypeDetails(m_widgetStack);
connect(m_details, &FileTypeDetails::changed, this, &FileTypesView::setDirty);
connect(m_details, &FileTypeDetails::embedMajor, this, &FileTypesView::slotEmbedMajor);
m_widgetStack->insertWidget(1, m_details /*id*/);
// File Group Details
m_groupDetails = new FileGroupDetails(m_widgetStack);
connect(m_groupDetails, &FileGroupDetails::changed, this, &FileTypesView::setDirty);
m_widgetStack->insertWidget(2, m_groupDetails /*id*/);
// Widget shown on startup
m_emptyWidget = new QLabel(i18n("Select a file type by name or by extension"), m_widgetStack);
m_emptyWidget->setAlignment(Qt::AlignCenter);
m_widgetStack->insertWidget(3, m_emptyWidget);
m_widgetStack->setCurrentWidget(m_emptyWidget);
connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), SLOT(slotDatabaseChanged(QStringList)));
}
FileTypesView::~FileTypesView()
{
}
void FileTypesView::setDirty(bool state)
{
Q_EMIT changed(state);
m_dirty = state;
}
// To order the mimetype list
static bool mimeTypeLessThan(const QMimeType &m1, const QMimeType &m2)
{
return m1.name() < m2.name();
}
// Note that this method loses any newly-added (and not saved yet) mimetypes.
// So this is really only for load().
void FileTypesView::readFileTypes()
{
typesLV->clear();
m_majorMap.clear();
m_itemList.clear();
QMimeDatabase db;
QList<QMimeType> mimetypes = db.allMimeTypes();
std::sort(mimetypes.begin(), mimetypes.end(), mimeTypeLessThan);
auto it2(mimetypes.constBegin());
for (; it2 != mimetypes.constEnd(); ++it2) {
const QString mimetype = (*it2).name();
const int index = mimetype.indexOf(QLatin1Char('/'));
const QString maj = mimetype.left(index);
TypesListItem *groupItem = m_majorMap.value(maj);
if (!groupItem) {
groupItem = new TypesListItem(typesLV, maj);
m_majorMap.insert(maj, groupItem);
}
TypesListItem *item = new TypesListItem(groupItem, (*it2));
m_itemList.append(item);
}
updateDisplay(nullptr);
}
void FileTypesView::slotEmbedMajor(const QString &major, bool &embed)
{
TypesListItem *groupItem = m_majorMap.value(major);
if (!groupItem) {
return;
}
embed = (groupItem->mimeTypeData().autoEmbed() == MimeTypeData::Yes);
}
void FileTypesView::slotFilter(const QString &patternFilter)
{
for (int i = 0; i < typesLV->topLevelItemCount(); ++i) {
typesLV->topLevelItem(i)->setHidden(true);
}
// insert all items and their group that match the filter
for (TypesListItem *it : qAsConst(m_itemList)) {
const MimeTypeData &mimeTypeData = it->mimeTypeData();
if (patternFilter.isEmpty() || mimeTypeData.matchesFilter(patternFilter)) {
TypesListItem *group = m_majorMap.value(mimeTypeData.majorType());
Q_ASSERT(group);
if (group) {
group->setHidden(false);
it->setHidden(false);
}
} else {
it->setHidden(true);
}
}
}
void FileTypesView::addType()
{
const QStringList allGroups = m_majorMap.keys();
NewTypeDialog dialog(allGroups, this);
if (dialog.exec()) {
const QString newMimeType = dialog.group() + QLatin1Char('/') + dialog.text();
TypesListItem *group = m_majorMap.value(dialog.group());
if (!group) {
group = new TypesListItem(typesLV, dialog.group());
m_majorMap.insert(dialog.group(), group);
}
// find out if our group has been filtered out -> insert if necessary
QTreeWidgetItem *item = typesLV->topLevelItem(0);
bool insert = true;
while (item) {
if (item == group) {
insert = false;
break;
}
item = typesLV->itemBelow(item);
}
if (insert) {
typesLV->addTopLevelItem(group);
}
TypesListItem *tli = new TypesListItem(group, newMimeType);
m_itemList.append(tli);
group->setExpanded(true);
tli->setSelected(true);
setDirty(true);
}
}
void FileTypesView::removeType()
{
TypesListItem *current = static_cast<TypesListItem *>(typesLV->currentItem());
if (!current) {
return;
}
const MimeTypeData &mimeTypeData = current->mimeTypeData();
// Can't delete groups nor essential mimetypes (but the button should be
// disabled already in these cases, so this is just extra safety).
if (mimeTypeData.isMeta() || mimeTypeData.isEssential()) {
return;
}
if (!mimeTypeData.isNew()) {
removedList.append(mimeTypeData.name());
}
if (m_removeButtonSaysRevert) {
// Nothing else to do for now, until saving
updateDisplay(current);
} else {
QTreeWidgetItem *li = typesLV->itemAbove(current);
if (!li) {
li = typesLV->itemBelow(current);
}
if (!li) {
li = current->parent();
}
current->parent()->takeChild(current->parent()->indexOfChild(current));
m_itemList.removeAll(current);
if (li) {
li->setSelected(true);
}
}
setDirty(true);
}
void FileTypesView::slotDoubleClicked(QTreeWidgetItem *item)
{
if (!item) {
return;
}
item->setExpanded(!item->isExpanded());
}
void FileTypesView::updateDisplay(QTreeWidgetItem *item)
{
TypesListItem *tlitem = static_cast<TypesListItem *>(item);
updateRemoveButton(tlitem);
if (!item) {
m_widgetStack->setCurrentWidget(m_emptyWidget);
return;
}
const bool wasDirty = m_dirty;
MimeTypeData &mimeTypeData = tlitem->mimeTypeData();
if (mimeTypeData.isMeta()) { // is a group
m_widgetStack->setCurrentWidget(m_groupDetails);
m_groupDetails->setMimeTypeData(&mimeTypeData);
} else {
m_widgetStack->setCurrentWidget(m_details);
m_details->setMimeTypeData(&mimeTypeData);
}
// Updating the display indirectly called change(true)
if (!wasDirty) {
setDirty(false);
}
}
void FileTypesView::updateRemoveButton(TypesListItem *tlitem)
{
bool canRemove = false;
m_removeButtonSaysRevert = false;
if (tlitem) {
const MimeTypeData &mimeTypeData = tlitem->mimeTypeData();
if (!mimeTypeData.isMeta() && !mimeTypeData.isEssential()) {
if (mimeTypeData.isNew()) {
canRemove = true;
} else {
// We can only remove mimetypes that we defined ourselves, not those from freedesktop.org
const QString mimeType = mimeTypeData.name();
qDebug() << mimeType << "hasDefinitionFile:" << MimeTypeWriter::hasDefinitionFile(mimeType);
if (MimeTypeWriter::hasDefinitionFile(mimeType)) {
canRemove = true;
// Is there a global definition for it?
const QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, //
QLatin1String("mime/") + mimeType + QStringLiteral(".xml"));
qDebug() << mimeFiles;
if (mimeFiles.count() >= 2 /*a local and a global*/) {
m_removeButtonSaysRevert = true;
qDebug() << removedList;
if (removedList.contains(mimeType)) {
canRemove = false; // already on the "to be reverted" list, user needs to save now
}
}
}
}
}
}
if (m_removeButtonSaysRevert) {
m_removeTypeB->setText(i18n("&Revert"));
m_removeTypeB->setToolTip(i18n("Revert this file type to its initial system-wide definition"));
m_removeTypeB->setWhatsThis(
i18n("Click here to revert this file type to its initial system-wide definition, which undoes any changes made to the file type. Note that "
"system-wide file types cannot be deleted. You can however empty their pattern list, to "
"minimize the chances of them being used (but the file type determination from file contents can still end up using them)."));
} else {
m_removeTypeB->setText(i18n("&Remove"));
m_removeTypeB->setToolTip(i18n("Delete this file type definition completely"));
m_removeTypeB->setWhatsThis(
i18n("Click here to delete this file type definition completely. This is only possible for user-defined file types. System-wide file types cannot "
"be deleted. You can however empty their pattern list, to minimize the chances of "
"them being used (but the file type determination from file contents can still end up using them)."));
}
m_removeTypeB->setEnabled(canRemove);
}
void FileTypesView::save()
{
bool needUpdateMimeDb = false;
bool needUpdateSycoca = false;
bool didIt = false;
// first, remove those items which we are asked to remove.
for (const QString &mime : qAsConst(removedList)) {
MimeTypeWriter::removeOwnMimeType(mime);
didIt = true;
needUpdateMimeDb = true;
needUpdateSycoca = true; // remove offers for this mimetype
}
removedList.clear();
// now go through all entries and sync those which are dirty.
// don't use typesLV, it may be filtered
for (auto it = m_majorMap.cbegin(); it != m_majorMap.cend(); ++it) {
TypesListItem *tli = it.value();
if (tli->mimeTypeData().isDirty()) {
qDebug() << "Entry " << tli->name() << " is dirty. Saving.";
if (tli->mimeTypeData().sync()) {
needUpdateMimeDb = true;
}
didIt = true;
}
}
for (TypesListItem *tli : qAsConst(m_itemList)) {
if (tli->mimeTypeData().isDirty()) {
if (tli->mimeTypeData().isServiceListDirty()) {
needUpdateSycoca = true;
}
qDebug() << "Entry " << tli->name() << " is dirty. Saving.";
if (tli->mimeTypeData().sync()) {
needUpdateMimeDb = true;
}
didIt = true;
}
}
m_fileTypesConfig->sync();
setDirty(false);
if (needUpdateMimeDb) {
MimeTypeWriter::runUpdateMimeDatabase();
}
if (needUpdateSycoca) {
KBuildSycocaProgressDialog::rebuildKSycoca(this);
}
if (didIt) { // TODO make more specific: only if autoEmbed changed? Well, maybe this is useful for icon and glob changes too...
// Trigger reparseConfiguration of filetypesrc in konqueror
// TODO: the same for dolphin. Or we should probably define a global signal for this.
// Or a KGlobalSettings thing.
QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KonqMain"), //
QStringLiteral("org.kde.Konqueror.Main"),
QStringLiteral("reparseConfiguration"));
QDBusConnection::sessionBus().send(message);
}
updateDisplay(typesLV->currentItem());
}
void FileTypesView::load()
{
setEnabled(false);
setCursor(Qt::WaitCursor);
readFileTypes();
unsetCursor();
setDirty(false);
setEnabled(true);
}
void FileTypesView::slotDatabaseChanged(const QStringList &changedResources)
{
qDebug() << changedResources;
if (changedResources.contains(QStringLiteral("xdgdata-mime")) // changes in mimetype definitions
|| changedResources.contains(QStringLiteral("services"))) { // changes in .desktop files
m_details->refresh();
// ksycoca has new KMimeTypes objects for us, make sure to update
// our 'copies' to be in sync with it. Not important for OK, but
// important for Apply (how to differentiate those 2?).
// See BR 35071.
for (TypesListItem *tli : qAsConst(m_itemList)) {
tli->mimeTypeData().refresh();
}
}
}
void FileTypesView::defaults()
{
}
#include "filetypesview.moc"

View File

@ -0,0 +1,95 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000-2008 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2008 Urs Wolfer <uwolfer @ kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#ifndef FILETYPESVIEW_H
#define FILETYPESVIEW_H
#include <QLabel>
#include <QList>
#include <QMap>
#include <QStackedWidget>
#include <KCModule>
#include <KSharedConfig>
#include "typeslistitem.h"
class QLabel;
class QTreeWidget;
class QTreeWidgetItem;
class QPushButton;
class KLineEdit;
class FileTypeDetails;
class FileGroupDetails;
class QStackedWidget;
class FileTypesView : public KCModule
{
Q_OBJECT
public:
FileTypesView(QWidget *parent, const QVariantList &args);
~FileTypesView() override;
void load() override;
void save() override;
void defaults() override;
protected Q_SLOTS:
void addType();
void removeType();
void updateDisplay(QTreeWidgetItem *);
void slotDoubleClicked(QTreeWidgetItem *);
void slotFilter(const QString &patternFilter);
void setDirty(bool state);
void slotDatabaseChanged(const QStringList &changedResources);
void slotEmbedMajor(const QString &major, bool &embed);
private:
void readFileTypes();
void updateRemoveButton(TypesListItem *item);
private:
QTreeWidget *typesLV;
QPushButton *m_removeTypeB;
QStackedWidget *m_widgetStack;
FileTypeDetails *m_details;
FileGroupDetails *m_groupDetails;
QLabel *m_emptyWidget;
KLineEdit *patternFilterLE;
QStringList removedList;
bool m_dirty;
bool m_removeButtonSaysRevert;
QMap<QString, TypesListItem *> m_majorMap; // groups
QList<TypesListItem *> m_itemList;
KSharedConfig::Ptr m_fileTypesConfig;
};
// helper class for loading the icon on request instead of preloading lots of probably
// unused icons which takes quite a lot of time
class TypesListTreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit TypesListTreeWidget(QWidget *parent)
: QTreeWidget(parent)
{
}
protected:
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
static_cast<TypesListItem *>(itemFromIndex(index))->loadIcon();
QTreeWidget::drawRow(painter, option, index);
}
};
#endif

View File

@ -0,0 +1,99 @@
[Desktop Entry]
Icon=preferences-desktop-filetype-association
Type=Application
NoDisplay=true
Exec=systemsettings kcm_filetypes
Name=File Associations
Name[af]=Lêer Assosiasies
Name[ar]=ارتباطات الملفّات
Name[as]=নথিপত্ৰৰ সম্বন্ধ
Name[az]=Fayl Bağlantıları
Name[be]=Асацыяцыі файлаў
Name[be@latin]=Poviazi dla fajłaŭ
Name[bg]=Файлови асоциации
Name[bn]=ফাইল অ্যাসোসিয়েশন
Name[bn_IN]=ফাইল-অ্যাপ্লিকেশন জুটি
Name[br]=Kevreañ restroù
Name[bs]=Pridruženja datotekema
Name[ca]=Associacions de fitxers
Name[ca@valencia]=Associacions de fitxers
Name[cs]=Asociace souborů
Name[csb]=Pòwiązania lopków
Name[cy]=Cysylltiadau Ffeiliau
Name[da]=Filtilknytninger
Name[de]=Dateizuordnungen
Name[el]=Συσχετίσεις αρχείων
Name[en_GB]=File Associations
Name[eo]=Dosierasocioj
Name[es]=Asociaciones de archivos
Name[et]=Failide seosed
Name[eu]=Fitxategi-elkartzeak
Name[fa]=تداعی کاربردهای پرونده
Name[fi]=Tiedostokytkökset
Name[fr]=Associations de fichiers
Name[fy]=Triemassosjaasjes
Name[ga]=Comhcheangail Chomhaid
Name[gl]=Asociacións de ficheiros
Name[gu]=ફાઇલ જોડાણો
Name[he]=שיוכי קבצים
Name[hi]=फ़ाइल असोसिएशन
Name[hne]=फाइल असोसिएसन
Name[hr]=Pridruživanje datoteka
Name[hsb]=Datajowe asociacije
Name[hu]=Fájltársítások
Name[ia]=Associationes de file
Name[id]=Keterkaitan File
Name[is]=Skráavensl
Name[it]=Associazioni dei file
Name[ja]=ファイルの関連付け
Name[ka]=ფაილთა მიბმა
Name[kk]=Файл сәйкестіктері
Name[km]=​ទំនាក់​ទំនង​ឯកសារ
Name[kn]=ಕಡತ ಸಾಹಚರ್ಯಗಳು
Name[ko]=파일 연결
Name[ku]=Têkiliyên Pelan
Name[lt]=Failų sąsajos
Name[lv]=Failu asociācijas
Name[mai]=फाइल असोसिएशन
Name[mk]=Асоцијации на датотеки
Name[ml]=ഫയല്‍ ബന്ധപ്പെടുത്തലുകള്‍
Name[mr]=फाईल संलग्नता
Name[nb]=Filtilknytninger
Name[nds]=Datei-Toornen
Name[ne]=फाइल संयोजन
Name[nl]=Bestandsassociaties
Name[nn]=Filtilknytingar
Name[oc]=Associacions de fichièrs
Name[or]=ଫାଇଲ ସଂସ୍ଥା
Name[pa]=ਫਾਈਲ ਸਬੰਧ
Name[pl]=Skojarzenia plików
Name[pt]=Associação de Ficheiros
Name[pt_BR]=Associações de arquivos
Name[ro]=Asociere fișiere
Name[ru]=Привязки файлов
Name[se]=Fiilačatnagasat
Name[si]=ගොනු සහායක
Name[sk]=Asociácie súborov
Name[sl]=Datotečne asociacije
Name[sr]=Придружења фајловима
Name[sr@ijekavian]=Придружења фајловима
Name[sr@ijekavianlatin]=Pridruženja fajlovima
Name[sr@latin]=Pridruženja fajlovima
Name[sv]=Filbindningar
Name[ta]=கோப்பு தொடர்புகள்
Name[te]=దస్త్రపు సంభందములు
Name[tg]=Муносибати файлҳо
Name[th]=กำหนดการใช้แฟ้ม
Name[tr]=Dosya İlişkilendirmeleri
Name[ug]=ھۆججەت باغلىنىش
Name[uk]=Прив’язка файлів
Name[uz]=Fayl turi bilan\nbogʻliqlar
Name[uz@cyrillic]=Файл тури билан\nбоғлиқлар
Name[vi]=Liên kết tệp
Name[wa]=Assoçnaedje des fitchîs
Name[xh]=Uyelemaniso Lwefayile
Name[x-test]=xxFile Associationsxx
Name[zh_CN]=文件关联
Name[zh_TW]=檔案關聯

View File

@ -0,0 +1,193 @@
{
"KPlugin": {
"Description": "Configure file associations",
"Description[ca@valencia]": "Configura les associacions de fitxers",
"Description[ca]": "Configura les associacions de fitxers",
"Description[cs]": "Nastavení asociací souborů",
"Description[de]": "Dateizuordnungen einrichten",
"Description[en_GB]": "Configure file associations",
"Description[es]": "Configurar las asociaciones de archivos",
"Description[eu]": "Konfiguratu fitxategi-elkartzeak",
"Description[fi]": "Tiedostokytkösasetukset",
"Description[fr]": "Configurer les associations de fichiers",
"Description[ia]": "Configura associationes de file",
"Description[it]": "Configura le associazioni dei file",
"Description[ko]": "파일 연결 설정",
"Description[nl]": "Hier kunt u de bestandsassociaties instellen",
"Description[pl]": "Ustawienia skojarzeń plików",
"Description[pt_BR]": "Configurar associações dos arquivos",
"Description[ru]": "Настройка привязки файлов",
"Description[sk]": "Nastavenia asociácií súborov",
"Description[sl]": "Nastavi datotečne asociacije",
"Description[sv]": "Anpassa filbindningar",
"Description[tr]": "Dosya ilişkilendirmelerini yapılandır",
"Description[uk]": "Налаштування прив’язки файлів",
"Description[vi]": "Cấu hình liên kết tệp",
"Description[x-test]": "xxConfigure file associationsxx",
"Description[zh_CN]": "配置文件关联",
"Icon": "preferences-desktop-filetype-association",
"Name": "File Associations",
"Name[af]": "Lêer Assosiasies",
"Name[ar]": "ارتباطات الملفّات",
"Name[as]": "নথিপত্ৰৰ সম্বন্ধ",
"Name[az]": "Fayl Bağlantıları",
"Name[be@latin]": "Poviazi dla fajłaŭ",
"Name[be]": "Асацыяцыі файлаў",
"Name[bg]": "Файлови асоциации",
"Name[bn]": "ফাইল অ্যাসোসিয়েশন",
"Name[bn_IN]": "ফাইল-অ্যাপ্লিকেশন জুটি",
"Name[br]": "Kevreañ restroù",
"Name[bs]": "Pridruženja datotekema",
"Name[ca@valencia]": "Associacions de fitxers",
"Name[ca]": "Associacions de fitxers",
"Name[cs]": "Asociace souborů",
"Name[csb]": "Pòwiązania lopków",
"Name[cy]": "Cysylltiadau Ffeiliau",
"Name[da]": "Filtilknytninger",
"Name[de]": "Dateizuordnungen",
"Name[el]": "Συσχετίσεις αρχείων",
"Name[en_GB]": "File Associations",
"Name[eo]": "Dosierasocioj",
"Name[es]": "Asociaciones de archivos",
"Name[et]": "Failide seosed",
"Name[eu]": "Fitxategi-elkartzeak",
"Name[fa]": "تداعی کاربردهای پرونده",
"Name[fi]": "Tiedostokytkökset",
"Name[fr]": "Associations de fichiers",
"Name[fy]": "Triemassosjaasjes",
"Name[ga]": "Comhcheangail Chomhaid",
"Name[gl]": "Asociacións de ficheiros",
"Name[gu]": "ફાઇલ જોડાણો",
"Name[he]": "שיוכי קבצים",
"Name[hi]": "फ़ाइल असोसिएशन",
"Name[hne]": "फाइल असोसिएसन",
"Name[hr]": "Pridruživanje datoteka",
"Name[hsb]": "Datajowe asociacije",
"Name[hu]": "Fájltársítások",
"Name[ia]": "Associationes de file",
"Name[id]": "Keterkaitan File",
"Name[is]": "Skráavensl",
"Name[it]": "Associazioni dei file",
"Name[ja]": "ファイルの関連付け",
"Name[ka]": "ფაილთა მიბმა",
"Name[kk]": "Файл сәйкестіктері",
"Name[km]": "​ទំនាក់​ទំនង​ឯកសារ",
"Name[kn]": "ಕಡತ ಸಾಹಚರ್ಯಗಳು",
"Name[ko]": "파일 연결",
"Name[ku]": "Têkiliyên Pelan",
"Name[lt]": "Failų sąsajos",
"Name[lv]": "Failu asociācijas",
"Name[mai]": "फाइल असोसिएशन",
"Name[mk]": "Асоцијации на датотеки",
"Name[ml]": "ഫയല്‍ ബന്ധപ്പെടുത്തലുകള്‍",
"Name[mr]": "फाईल संलग्नता",
"Name[nb]": "Filtilknytninger",
"Name[nds]": "Datei-Toornen",
"Name[ne]": "फाइल संयोजन",
"Name[nl]": "Bestandsassociaties",
"Name[nn]": "Filtilknytingar",
"Name[oc]": "Associacions de fichièrs",
"Name[or]": "ଫାଇଲ ସଂସ୍ଥା",
"Name[pa]": "ਫਾਈਲ ਸਬੰਧ",
"Name[pl]": "Skojarzenia plików",
"Name[pt]": "Associação de Ficheiros",
"Name[pt_BR]": "Associações de arquivos",
"Name[ro]": "Asociere fișiere",
"Name[ru]": "Привязки файлов",
"Name[se]": "Fiilačatnagasat",
"Name[si]": "ගොනු සහායක",
"Name[sk]": "Asociácie súborov",
"Name[sl]": "Datotečne asociacije",
"Name[sr@ijekavian]": "Придружења фајловима",
"Name[sr@ijekavianlatin]": "Pridruženja fajlovima",
"Name[sr@latin]": "Pridruženja fajlovima",
"Name[sr]": "Придружења фајловима",
"Name[sv]": "Filbindningar",
"Name[ta]": "கோப்பு தொடர்புகள்",
"Name[te]": "దస్త్రపు సంభందములు",
"Name[tg]": "Муносибати файлҳо",
"Name[th]": "กำหนดการใช้แฟ้ม",
"Name[tr]": "Dosya İlişkilendirmeleri",
"Name[ug]": "ھۆججەت باغلىنىش",
"Name[uk]": "Прив’язка файлів",
"Name[uz@cyrillic]": "Файл тури билан\\nбоғлиқлар",
"Name[uz]": "Fayl turi bilan\\nbogʻliqlar",
"Name[vi]": "Liên kết tệp",
"Name[wa]": "Assoçnaedje des fitchîs",
"Name[x-test]": "xxFile Associationsxx",
"Name[xh]": "Uyelemaniso Lwefayile",
"Name[zh_CN]": "文件关联",
"Name[zh_TW]": "檔案關聯",
"ServiceTypes": [
"KCModule"
]
},
"X-DocPath": "kcontrol5/filetypes/index.html",
"X-KDE-Keywords": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[ar]": "أنواع الملفّات,ارتباطات الملفّات,أنواع مايم,أنماط الملفّات,ملفّات,نمط",
"X-KDE-Keywords[az]": "Fayl növləri,Fayl bağlantıları,Mime növləri,Fayl nümunələri,Fayllar,Nümunələr",
"X-KDE-Keywords[bg]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,Файлове,Видове,Асоциации,Шаблони",
"X-KDE-Keywords[bn]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[bs]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,tipovi datoteka,pridruživanje datoteka,uzorci datoteka,uzorci",
"X-KDE-Keywords[ca@valencia]": "Tipus de fitxer,Associacions de fitxer,Tipus MIME,Patrons de fitxer,Fitxers,Patró",
"X-KDE-Keywords[ca]": "Tipus de fitxer,Associacions de fitxer,Tipus MIME,Patrons de fitxer,Fitxers,Patró",
"X-KDE-Keywords[cs]": "Typy souborů,Asociace souborů, Typy MIME,Vzory souborů,Soubory,Vzor",
"X-KDE-Keywords[da]": "filtyper,filtilknytninger,MIME-typer,filmønstre,filer,mønstre",
"X-KDE-Keywords[de]": "Dateitypen,Dateizuordnungen,MIME-Typen,Dateimuster,Filter,Muster,Dateien",
"X-KDE-Keywords[el]": "Τύποι αρχείων,συσχετίσεις αρχείων,τύποι mime,μοτίβα αρχείων,αρχεία,μοτίβο",
"X-KDE-Keywords[en_GB]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[eo]": "Dosieraranĝoj,Dosierasocioj,MIME-tipoj,Dosierŝablonoj,Dosieroj,Ŝablono",
"X-KDE-Keywords[es]": "Tipos de archivo,Asociaciones de archivos,tipos Mime,Patrones de archivo,Archivos,Patrón",
"X-KDE-Keywords[et]": "failitüübid,failiseosed,MIME tüübid,failimustrid,failid,muster",
"X-KDE-Keywords[eu]": "Fitxategi-motak,Fitxategi-elkartzeak,MIME motak,Fitxategi-ereduak,Fitxategiak,Eredua",
"X-KDE-Keywords[fa]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[fi]": "Tiedostotyypit,Tiedostokytkökset,MIME-tyypit,Tiedostokuviot,Tiedostot,Kuvio",
"X-KDE-Keywords[fr]": "Types de fichiers, associations de fichiers, modèles de fichiers, fichiers, modèle",
"X-KDE-Keywords[ga]": "Cineálacha,Comhcheangail,MIME,Patrúin,Patrún,Comhaid",
"X-KDE-Keywords[gl]": "Tipos de ficheiro, asociacións de ficheiros, tipos mime, ficheiros, padrón",
"X-KDE-Keywords[gu]": "ફાઇલપ્રકારો,ફાઇલ જોડાણો,માઇમ પ્રકારો,ફાઇલ ભાતો,ફાઇલો,ભાતો",
"X-KDE-Keywords[he]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,סוגי קבצים,שיוכי קבצים,סוגי קבצים,קבצים",
"X-KDE-Keywords[hi]": "फ़ाइल प्रकार, फ़ाइल संघ, माइम प्रकार, फ़ाइल पैटर्न, फ़ाइलें, पैटर्न",
"X-KDE-Keywords[hsb]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,mustr, dataja,asociacija",
"X-KDE-Keywords[hu]": "Fájltípusok,Fájltársítások,MIME-típusok,Fájlminták,Fájlok,Minta",
"X-KDE-Keywords[ia]": "Typos de file,Associationes de file,Typos Mime,Patronos de File,Files,Patrono",
"X-KDE-Keywords[id]": "Tipe File,Keterkaitan File,Tipe Mime,Pola File,File,Pola",
"X-KDE-Keywords[is]": "Skráagerðir,Skráavensl,Mime-tegund,Skráamynstur,Skrár,Mynstur",
"X-KDE-Keywords[it]": "Tipi di file,associazioni di file,tipi mime,schemi di file,file,schema",
"X-KDE-Keywords[ja]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[kk]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[km]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[ko]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,파일 형식,파일 연결,MIME 형식",
"X-KDE-Keywords[lt]": "Failų tipai,Failai,Sąsajos,Susiejimai,Failo,Mime tipai,Failo šablonai,Failai,Šablonas",
"X-KDE-Keywords[lv]": "Failu tipi,failu asociācijas,mime tipi,failu paraugi,failu,paraugs",
"X-KDE-Keywords[mr]": "फाईल प्रकार, फाईल संलग्नता, माइम प्रकार, फाईल नमूना",
"X-KDE-Keywords[nb]": "Filtyper,Filtilknytninger,Mimetyper,Filnavnmønstre,Filer,Mønster",
"X-KDE-Keywords[nds]": "Dateitypen,Dateitoornen,MIME-Typen,Dateimustern,Dateien,Muster",
"X-KDE-Keywords[nl]": "Bestandstypen,bestandsassociaties,Mime-typen,bestandspatronen,bestanden,patroon",
"X-KDE-Keywords[nn]": "Filtypar,filetternamn,etternamn,filtilknytingar,MIME-typar,filmønster,filer,mønster",
"X-KDE-Keywords[pa]": "ਫਾਈਲਕਿਸਮ,ਫਾਈਲ ਸਬੰਧ,ਮਾਈਮ ਕਿਸਮ,ਫਾਈਲ ਪੈਟਰਨ,ਫਾਈਲਾਂ,ਪੈਟਰਨ",
"X-KDE-Keywords[pl]": "typy plików,skojarzenia plików,typy mime,wzorce plików,pliki,wzorzec",
"X-KDE-Keywords[pt]": "Tipos de ficheiros,Associações de ficheiros,Tipos MIME,Padrões de ficheiros,Ficheiros,Padrão",
"X-KDE-Keywords[pt_BR]": "Tipos de arquivos,Associações de arquivos,Tipos MIME,Padrões de arquivos,Arquivos,Padrão",
"X-KDE-Keywords[ro]": "tipuri de fișier,asociere de fișiere,tipuri mime,fișiere,model",
"X-KDE-Keywords[ru]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,типы файлов,привязки файлов,типы MIME,шаблоны файлов,файлы,шаблон",
"X-KDE-Keywords[sk]": "Filetypes,File Associations,Mime Typy,File Patterns,Súbory,Vzory",
"X-KDE-Keywords[sl]": "vrste datotek,datotečne vrste,vrste mime,zvrsti mime,datotečne povezave,datoteke,vzorci,datotečni vzorci",
"X-KDE-Keywords[sr@ijekavian]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,тип фајла,придружења фајла,МИМЕ тип,образац фајла,образац",
"X-KDE-Keywords[sr@ijekavianlatin]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,tip fajla,pridruženja fajla,MIME tip,obrazac fajla,obrazac",
"X-KDE-Keywords[sr@latin]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,tip fajla,pridruženja fajla,MIME tip,obrazac fajla,obrazac",
"X-KDE-Keywords[sr]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,тип фајла,придружења фајла,МИМЕ тип,образац фајла,образац",
"X-KDE-Keywords[sv]": "Filtyper,Filbindningar,Mime-typer,Filmönster,Filer,Mönster",
"X-KDE-Keywords[tg]": "Намуди файлҳо,Муносибати файлҳо,Навъи қиёфа,Қолабҳои файл,Файлҳо,Қолабҳо",
"X-KDE-Keywords[tr]": "Dosya tipleri,Dosya İlişkileri, Mime Tipleri,Dosya Desenleri,Dosyalar,Desen",
"X-KDE-Keywords[ug]": "ھۆججەت تىپى، ھۆججەت مۇناسىۋەتلىرى، Mime تىپلىرى، ھۆججەت ئەندىزىلىرى، ھۆججەتلەر، ئەندىزە",
"X-KDE-Keywords[uk]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,файл,файли,типи файлів,тип,прив’язка,прив’язування,відповідність,взірці,шаблон,файли,взірець,файла",
"X-KDE-Keywords[vi]": "Kiểu tệp,Tệp tương ứng,Kiểu MIME,Mẫu tệp,Tệp, Mẫu,Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-Keywords[wa]": "Sôres di fitchîs,assoçnaedjes des fitchîs,assoçnaedjes di fitchîs,sôres mime,patrons di fitchîs,patron d' fitchîs,modeles di fitchîs,fitchîs,patron,modele",
"X-KDE-Keywords[x-test]": "xxFiletypesxx,xxFile Associationsxx,xxMime Typesxx,xxFile Patternsxx,xxFilesxx,xxPatternxx",
"X-KDE-Keywords[zh_CN]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern,文件类型,文件关联,后缀名,文件",
"X-KDE-Keywords[zh_TW]": "Filetypes,File Associations,Mime Types,File Patterns,Files,Pattern",
"X-KDE-ParentApp": "kcontrol",
"X-KDE-System-Settings-Parent-Category": "applications",
"X-KDE-Weight": 50
}

View File

@ -0,0 +1,203 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
// Own
#include "keditfiletype.h"
#include "mimetypewriter.h"
// Qt
#include <QApplication>
#include <QBoxLayout>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDebug>
#include <QDialogButtonBox>
#include <QFile>
#include <QPushButton>
// KDE
#include <kaboutdata.h>
#include <kbuildsycocaprogressdialog.h>
#include <klocalizedstring.h>
#include <kservicetypeprofile.h>
#include <ksycoca.h>
#include <kwindowsystem.h>
// Local
#include "filetypedetails.h"
#include "typeslistitem.h"
FileTypeDialog::FileTypeDialog(MimeTypeData *mime)
: QDialog(nullptr)
, m_mimeTypeData(mime)
{
init();
}
FileTypeDialog::~FileTypeDialog()
{
delete m_details;
}
void FileTypeDialog::init()
{
m_details = new FileTypeDetails(this);
m_details->setMimeTypeData(m_mimeTypeData);
connect(m_details, &FileTypeDetails::changed, this, &FileTypeDialog::clientChanged);
m_buttonBox = new QDialogButtonBox;
m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel);
connect(m_buttonBox, SIGNAL(accepted()), SLOT(accept()));
connect(m_buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, this, &FileTypeDialog::save);
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
// This code is very similar to kcdialog.cpp
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(m_details);
layout->addWidget(m_buttonBox);
// TODO setHelp()
setApplyButtonEnabled(false);
connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), SLOT(slotDatabaseChanged(QStringList)));
}
void FileTypeDialog::setApplyButtonEnabled(bool enabled)
{
m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(enabled);
}
void FileTypeDialog::save()
{
if (m_mimeTypeData->isDirty()) {
const bool servicesDirty = m_mimeTypeData->isServiceListDirty();
if (m_mimeTypeData->sync()) {
MimeTypeWriter::runUpdateMimeDatabase();
}
if (servicesDirty) {
KBuildSycocaProgressDialog::rebuildKSycoca(this);
}
// Trigger reparseConfiguration of filetypesrc in konqueror
QDBusMessage message =
QDBusMessage::createSignal(QStringLiteral("/KonqMain"), QStringLiteral("org.kde.Konqueror.Main"), QStringLiteral("reparseConfiguration"));
QDBusConnection::sessionBus().send(message);
}
}
void FileTypeDialog::accept()
{
save();
QDialog::accept();
}
void FileTypeDialog::clientChanged(bool state)
{
m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(state);
m_buttonBox->button(QDialogButtonBox::Apply)->setEnabled(state);
}
void FileTypeDialog::slotDatabaseChanged(const QStringList &changedResources)
{
qDebug() << changedResources;
if (changedResources.contains(QStringLiteral("xdgdata-mime")) // changes in mimetype definitions
|| changedResources.contains(QStringLiteral("services"))) { // changes in .desktop files
m_details->refresh();
}
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
app.setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-filetype-association")));
KAboutData aboutData(QStringLiteral("keditfiletype"),
i18n("File Type Editor"),
QLatin1String(PROJECT_VERSION),
i18n("KDE file type editor - simplified version for editing a single file type"),
KAboutLicense::GPL,
i18n("(c) 2000, KDE developers"));
aboutData.addAuthor(i18n("Preston Brown"), QString(), QStringLiteral("pbrown@kde.org"));
aboutData.addAuthor(i18n("David Faure"), QString(), QStringLiteral("faure@kde.org"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("parent"),
i18n("Makes the dialog transient for the window specified by winid"),
QStringLiteral("winid")));
parser.addPositionalArgument(QStringLiteral("mimetype"), i18n("File type to edit (e.g. text/html)"));
parser.process(app);
aboutData.processCommandLine(&parser);
if (parser.positionalArguments().count() == 0) {
parser.showHelp();
}
QMimeDatabase db;
const QString arg = parser.positionalArguments().at(0);
MimeTypeData *mimeTypeData = nullptr;
const bool createType = arg.startsWith(QLatin1Char('*'));
if (createType) {
QString mimeString = QStringLiteral("application/x-kdeuser%1");
QString mimeTypeName;
int inc = 0;
bool ok = false;
do {
++inc;
mimeTypeName = mimeString.arg(inc);
ok = !db.mimeTypeForName(mimeTypeName).isValid();
} while (!ok);
QStringList patterns;
if (arg.length() > 2) {
patterns << arg.toLower() << arg.toUpper();
}
QString comment;
if (arg.startsWith(QLatin1String("*.")) && arg.length() >= 3) {
const QString type = arg.mid(3).prepend(arg[2].toUpper());
comment = i18n("%1 File", type);
}
mimeTypeData = new MimeTypeData(mimeTypeName, true); // new mimetype
mimeTypeData->setComment(comment);
mimeTypeData->setPatterns(patterns);
} else {
const QString mimeTypeName = arg;
QMimeType mime = db.mimeTypeForName(mimeTypeName);
if (!mime.isValid()) {
qCritical() << "Mimetype" << mimeTypeName << "not found";
return 1;
}
mimeTypeData = new MimeTypeData(mime);
}
FileTypeDialog dlg(mimeTypeData);
if (parser.isSet(QStringLiteral("parent"))) {
bool ok;
long id = parser.value(QStringLiteral("parent")).toLong(&ok);
if (ok) {
dlg.setAttribute(Qt::WA_NativeWindow, true);
KWindowSystem::setMainWindow(dlg.windowHandle(), WId(id));
}
}
if (!createType) {
dlg.setWindowTitle(i18n("Edit File Type %1", mimeTypeData->name()));
} else {
dlg.setWindowTitle(i18n("Create New File Type %1", mimeTypeData->name()));
dlg.setApplyButtonEnabled(true);
}
dlg.show(); // non-modal
return app.exec();
}

View File

@ -0,0 +1,46 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000, 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef __keditfiletype_h
#define __keditfiletype_h
#include <QDialog>
#include <QMimeDatabase>
#include <QMimeType>
class QDialogButtonBox;
class MimeTypeData;
class FileTypeDetails;
// A dialog for ONE file type to be edited.
class FileTypeDialog : public QDialog
{
Q_OBJECT
public:
explicit FileTypeDialog(MimeTypeData *mime);
~FileTypeDialog() override;
void setApplyButtonEnabled(bool);
public Q_SLOTS:
void accept() override;
protected Q_SLOTS:
void clientChanged(bool state);
void slotDatabaseChanged(const QStringList &changedResources);
private Q_SLOTS:
void save();
private:
void init();
FileTypeDetails *m_details;
MimeTypeData *m_mimeTypeData;
QDialogButtonBox *m_buttonBox;
};
#endif

View File

@ -0,0 +1,403 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2003 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2002 Daniel Molkentin <molkentin@kde.org>
SPDX-License-Identifier: GPL-2.0-only
*/
// Own
#include "kservicelistwidget.h"
// Qt
#include <QBoxLayout>
#include <QDebug>
#include <QLayout>
#include <QPushButton>
#include <QStandardPaths>
// KDE
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <kopenwithdialog.h>
#include <kpropertiesdialog.h>
// Local
#include "kserviceselectdlg.h"
#include "mimetypedata.h"
KServiceListItem::KServiceListItem(const KService::Ptr &pService, int kind)
: QListWidgetItem()
, storageId(pService->storageId())
, desktopPath(pService->entryPath())
{
if (kind == KServiceListWidget::SERVICELIST_APPLICATIONS) {
setText(pService->name());
} else {
setText(i18n("%1 (%2)", pService->name(), pService->desktopEntryName()));
}
setIcon(QIcon::fromTheme(pService->icon()));
if (!pService->isApplication()) {
localPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kservices5/") + desktopPath;
} else {
localPath = pService->locateLocal();
}
}
KServiceListWidget::KServiceListWidget(int kind, QWidget *parent)
: QGroupBox(kind == SERVICELIST_APPLICATIONS ? i18n("Application Preference Order") : i18n("Services Preference Order"), parent)
, m_kind(kind)
, m_mimeTypeData(nullptr)
{
QHBoxLayout *lay = new QHBoxLayout(this);
servicesLB = new QListWidget(this);
connect(servicesLB, &QListWidget::itemSelectionChanged, this, &KServiceListWidget::enableMoveButtons);
lay->addWidget(servicesLB);
connect(servicesLB, &QListWidget::itemDoubleClicked, this, &KServiceListWidget::editService);
QString wtstr = (kind == SERVICELIST_APPLICATIONS ? i18n("This is a list of applications associated with files of the selected"
" file type. This list is shown in Konqueror's context menus when you select"
" \"Open With...\". If more than one application is associated with this file type,"
" then the list is ordered by priority with the uppermost item taking precedence"
" over the others.")
: i18n("This is a list of services associated with files of the selected"
" file type. This list is shown in Konqueror's context menus when you select"
" a \"Preview with...\" option. If more than one service is associated with this file type,"
" then the list is ordered by priority with the uppermost item taking precedence"
" over the others."));
setWhatsThis(wtstr);
servicesLB->setWhatsThis(wtstr);
QVBoxLayout *btnsLay = new QVBoxLayout();
lay->addLayout(btnsLay);
servUpButton = new QPushButton(i18n("Move &Up"), this);
servUpButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
servUpButton->setEnabled(false);
connect(servUpButton, &QAbstractButton::clicked, this, &KServiceListWidget::promoteService);
btnsLay->addWidget(servUpButton);
servUpButton->setWhatsThis(kind == SERVICELIST_APPLICATIONS ? i18n("Assigns a higher priority to the selected\n"
"application, moving it up in the list. Note: This\n"
"only affects the selected application if the file type is\n"
"associated with more than one application.")
: i18n("Assigns a higher priority to the selected\n"
"service, moving it up in the list."));
servDownButton = new QPushButton(i18n("Move &Down"), this);
servDownButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
servDownButton->setEnabled(false);
connect(servDownButton, &QAbstractButton::clicked, this, &KServiceListWidget::demoteService);
btnsLay->addWidget(servDownButton);
servDownButton->setWhatsThis(kind == SERVICELIST_APPLICATIONS ? i18n("Assigns a lower priority to the selected\n"
"application, moving it down in the list. Note: This \n"
"only affects the selected application if the file type is\n"
"associated with more than one application.")
: i18n("Assigns a lower priority to the selected\n"
"service, moving it down in the list."));
servNewButton = new QPushButton(i18n("Add..."), this);
servNewButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
servNewButton->setEnabled(false);
connect(servNewButton, &QAbstractButton::clicked, this, &KServiceListWidget::addService);
btnsLay->addWidget(servNewButton);
servNewButton->setWhatsThis(i18n("Add a new application for this file type."));
servEditButton = new QPushButton(i18n("Edit..."), this);
servEditButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
servEditButton->setEnabled(false);
connect(servEditButton, &QAbstractButton::clicked, this, &KServiceListWidget::editService);
btnsLay->addWidget(servEditButton);
servEditButton->setWhatsThis(i18n("Edit command line of the selected application."));
servRemoveButton = new QPushButton(i18n("Remove"), this);
servRemoveButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
servRemoveButton->setEnabled(false);
connect(servRemoveButton, &QAbstractButton::clicked, this, &KServiceListWidget::removeService);
btnsLay->addWidget(servRemoveButton);
servRemoveButton->setWhatsThis(i18n("Remove the selected application from the list."));
btnsLay->addStretch(1);
}
void KServiceListWidget::setMimeTypeData(MimeTypeData *mimeTypeData)
{
m_mimeTypeData = mimeTypeData;
if (servNewButton) {
servNewButton->setEnabled(true);
}
// will need a selection
servUpButton->setEnabled(false);
servDownButton->setEnabled(false);
servicesLB->clear();
servicesLB->setEnabled(false);
if (m_mimeTypeData) {
const QStringList services = (m_kind == SERVICELIST_APPLICATIONS) ? m_mimeTypeData->appServices() : m_mimeTypeData->embedServices();
if (services.isEmpty()) {
if (m_kind == SERVICELIST_APPLICATIONS) {
servicesLB->addItem(i18nc("No applications associated with this file type", "None"));
} else {
servicesLB->addItem(i18nc("No components associated with this file type", "None"));
}
} else {
for (const QString &service : services) {
KService::Ptr pService = KService::serviceByStorageId(service);
if (pService) {
servicesLB->addItem(new KServiceListItem(pService, m_kind));
}
}
servicesLB->setEnabled(true);
}
}
if (servRemoveButton) {
servRemoveButton->setEnabled(servicesLB->currentRow() > -1);
}
if (servEditButton) {
servEditButton->setEnabled(servicesLB->currentRow() > -1);
}
}
void KServiceListWidget::promoteService()
{
if (!servicesLB->isEnabled()) {
return;
}
int selIndex = servicesLB->currentRow();
if (selIndex == 0) {
return;
}
QListWidgetItem *selItem = servicesLB->item(selIndex);
servicesLB->takeItem(selIndex);
servicesLB->insertItem(selIndex - 1, selItem);
servicesLB->setCurrentRow(selIndex - 1);
updatePreferredServices();
Q_EMIT changed(true);
}
void KServiceListWidget::demoteService()
{
if (!servicesLB->isEnabled()) {
return;
}
int selIndex = servicesLB->currentRow();
if (selIndex == servicesLB->count() - 1) {
return;
}
QListWidgetItem *selItem = servicesLB->item(selIndex);
servicesLB->takeItem(selIndex);
servicesLB->insertItem(selIndex + 1, selItem);
servicesLB->setCurrentRow(selIndex + 1);
updatePreferredServices();
Q_EMIT changed(true);
}
void KServiceListWidget::addService()
{
if (!m_mimeTypeData) {
return;
}
KService::Ptr service;
if (m_kind == SERVICELIST_APPLICATIONS) {
KOpenWithDialog dlg(m_mimeTypeData->name(), QString(), this);
dlg.setSaveNewApplications(true);
if (dlg.exec() != QDialog::Accepted) {
return;
}
service = dlg.service();
Q_ASSERT(service);
if (!service) {
return; // Don't crash if KOpenWith wasn't able to create service.
}
} else {
KServiceSelectDlg dlg(m_mimeTypeData->name(), QString(), this);
if (dlg.exec() != QDialog::Accepted) {
return;
}
service = dlg.service();
Q_ASSERT(service);
if (!service) {
return;
}
}
// Did the list simply show "None"?
const bool hadDummyEntry = (m_kind == SERVICELIST_APPLICATIONS) ? m_mimeTypeData->appServices().isEmpty() : m_mimeTypeData->embedServices().isEmpty();
if (hadDummyEntry) {
delete servicesLB->takeItem(0); // Remove the "None" item.
servicesLB->setEnabled(true);
} else {
// check if it is a duplicate entry
for (int index = 0; index < servicesLB->count(); index++) {
if (static_cast<KServiceListItem *>(servicesLB->item(index))->desktopPath == service->entryPath()) {
// ##### shouldn't we make the existing entry the default one?
return;
}
}
}
servicesLB->insertItem(0, new KServiceListItem(service, m_kind));
servicesLB->setCurrentItem(nullptr);
updatePreferredServices();
Q_EMIT changed(true);
}
void KServiceListWidget::editService()
{
if (!m_mimeTypeData) {
return;
}
const int selected = servicesLB->currentRow();
if (selected < 0) {
return;
}
// Only edit applications, not services as
// they don't have any parameters
if (m_kind != SERVICELIST_APPLICATIONS) {
return;
}
// Just like popping up an add dialog except that we
// pass the current command line as a default
KServiceListItem *selItem = (KServiceListItem *)servicesLB->item(selected);
const QString desktopPath = selItem->desktopPath;
KService::Ptr service = KService::serviceByDesktopPath(desktopPath);
if (!service) {
return;
}
QString path = service->entryPath();
{
// If the path to the desktop file is relative, try to get the full
// path from QStandardPaths.
QString fullPath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, path);
if (!fullPath.isEmpty()) {
path = fullPath;
}
}
KFileItem item(QUrl::fromLocalFile(path), QStringLiteral("application/x-desktop"), KFileItem::Unknown);
KPropertiesDialog dlg(item, this);
if (dlg.exec() != QDialog::Accepted) {
return;
}
// Note that at this point, ksycoca has been updated,
// and setMimeTypeData has been called again, so all the items have been recreated.
// Reload service
service = KService::serviceByDesktopPath(desktopPath);
if (!service) {
return;
}
// Remove the old one...
delete servicesLB->takeItem(selected);
// ...check that it's not a duplicate entry...
bool addIt = true;
for (int index = 0; index < servicesLB->count(); index++) {
if (static_cast<KServiceListItem *>(servicesLB->item(index))->desktopPath == service->entryPath()) {
addIt = false;
break;
}
}
// ...and add it in the same place as the old one:
if (addIt) {
servicesLB->insertItem(selected, new KServiceListItem(service, m_kind));
servicesLB->setCurrentRow(selected);
}
updatePreferredServices();
Q_EMIT changed(true);
}
void KServiceListWidget::removeService()
{
if (!m_mimeTypeData) {
return;
}
int selected = servicesLB->currentRow();
if (selected >= 0) {
delete servicesLB->takeItem(selected);
updatePreferredServices();
Q_EMIT changed(true);
}
// Update buttons and service list again (e.g. to re-add "None")
setMimeTypeData(m_mimeTypeData);
}
void KServiceListWidget::updatePreferredServices()
{
if (!m_mimeTypeData) {
return;
}
QStringList sl;
unsigned int count = servicesLB->count();
for (unsigned int i = 0; i < count; i++) {
KServiceListItem *sli = (KServiceListItem *)servicesLB->item(i);
sl.append(sli->storageId);
}
sl.removeDuplicates();
if (m_kind == SERVICELIST_APPLICATIONS) {
m_mimeTypeData->setAppServices(sl);
} else {
m_mimeTypeData->setEmbedServices(sl);
}
}
void KServiceListWidget::enableMoveButtons()
{
int idx = servicesLB->currentRow();
if (servicesLB->model()->rowCount() <= 1) {
servUpButton->setEnabled(false);
servDownButton->setEnabled(false);
} else if (idx == (servicesLB->model()->rowCount() - 1)) {
servUpButton->setEnabled(true);
servDownButton->setEnabled(false);
} else if (idx == 0) {
servUpButton->setEnabled(false);
servDownButton->setEnabled(true);
} else {
servUpButton->setEnabled(true);
servDownButton->setEnabled(true);
}
if (servRemoveButton) {
servRemoveButton->setEnabled(true);
}
if (servEditButton) {
servEditButton->setEnabled(m_kind == SERVICELIST_APPLICATIONS);
}
}

View File

@ -0,0 +1,70 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2003 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2002 Daniel Molkentin <molkentin@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef _KSERVICELISTWIDGET_H
#define _KSERVICELISTWIDGET_H
#include <QGroupBox>
#include <QListWidget>
#include <kservice.h>
class QPushButton;
class MimeTypeData;
class KService;
class KServiceListItem : public QListWidgetItem
{
public:
KServiceListItem(const KService::Ptr &pService, int kind);
QString storageId;
QString desktopPath;
QString localPath;
};
/**
* This widget holds a list of services, with 5 buttons to manage it.
* It's a separate class so that it can be used by both tabs of the
* module, once for applications and once for services.
* The "kind" is determined by the argument given to the constructor.
*/
class KServiceListWidget : public QGroupBox
{
Q_OBJECT
public:
enum {
SERVICELIST_APPLICATIONS,
SERVICELIST_SERVICES,
};
explicit KServiceListWidget(int kind, QWidget *parent = nullptr);
void setMimeTypeData(MimeTypeData *item);
Q_SIGNALS:
void changed(bool);
protected Q_SLOTS:
void promoteService();
void demoteService();
void addService();
void editService();
void removeService();
void enableMoveButtons();
protected:
void updatePreferredServices();
private:
int m_kind;
QListWidget *servicesLB;
QPushButton *servUpButton, *servDownButton;
QPushButton *servNewButton, *servEditButton, *servRemoveButton;
MimeTypeData *m_mimeTypeData;
};
#endif

View File

@ -0,0 +1,60 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "kserviceselectdlg.h"
#include "kservicelistwidget.h"
#include <QDialogButtonBox>
#include <QLabel>
#include <QVBoxLayout>
#include <KLocalizedString>
KServiceSelectDlg::KServiceSelectDlg(const QString & /*serviceType*/, const QString & /*value*/, QWidget *parent)
: QDialog(parent)
{
setObjectName(QLatin1String("serviceSelectDlg"));
setModal(true);
setWindowTitle(i18n("Add Service"));
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(new QLabel(i18n("Select service:")));
m_listbox = new QListWidget();
m_buttonBox = new QDialogButtonBox;
m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
// Can't make a KTrader query since we don't have a servicetype to give,
// we want all services that are not applications.......
// So we have to do it the slow way
// ### Why can't we query for KParts/ReadOnlyPart as the servicetype? Should work fine!
const KService::List allServices = KService::allServices();
for (const auto &service : allServices) {
if (service->hasServiceType(QStringLiteral("KParts/ReadOnlyPart"))) {
m_listbox->addItem(new KServiceListItem(service, KServiceListWidget::SERVICELIST_SERVICES));
}
}
m_listbox->model()->sort(0);
m_listbox->setMinimumHeight(350);
m_listbox->setMinimumWidth(400);
layout->addWidget(m_listbox);
layout->addWidget(m_buttonBox);
connect(m_listbox, &QListWidget::itemDoubleClicked, this, &QDialog::accept);
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
KServiceSelectDlg::~KServiceSelectDlg()
{
}
KService::Ptr KServiceSelectDlg::service()
{
int selIndex = m_listbox->currentRow();
KServiceListItem *selItem = static_cast<KServiceListItem *>(m_listbox->item(selIndex));
return KService::serviceByDesktopPath(selItem->desktopPath);
}

View File

@ -0,0 +1,42 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef __kserviceselectdlg_h
#define __kserviceselectdlg_h
#include <QDialog>
#include <QListWidget>
#include <kservice.h>
class QDialogButtonBox;
class KServiceSelectDlg : public QDialog
{
Q_OBJECT
public:
/**
* Create a dialog to select a service (not application) for a given service type.
*
* @param serviceType the service type we want to choose a service for.
* @param value is the initial service to select (not implemented currently)
* @param parent parent widget
*/
explicit KServiceSelectDlg(const QString &serviceType, const QString &value = QString(), QWidget *parent = nullptr);
~KServiceSelectDlg() override;
/**
* @return the chosen service
*/
KService::Ptr service();
private:
QListWidget *m_listbox;
QDialogButtonBox *m_buttonBox;
};
#endif

View File

@ -0,0 +1,587 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2003, 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#include "mimetypedata.h"
#include "mimetypewriter.h"
#include <KApplicationTrader>
#include <QFileInfo>
#include <QStandardPaths>
#include <QXmlStreamReader>
#include <kconfiggroup.h>
#include <kmimetypetrader.h>
#include <kprotocolmanager.h>
#include <kservice.h>
#include <ksharedconfig.h>
#include <qdebug.h>
MimeTypeData::MimeTypeData(const QString &major)
: m_askSave(AskSaveDefault)
, m_bNewItem(false)
, m_bFullInit(true)
, m_isGroup(true)
, m_appServicesModified(false)
, m_embedServicesModified(false)
, m_userSpecifiedIconModified(false)
, m_major(major)
{
m_autoEmbed = readAutoEmbed();
}
MimeTypeData::MimeTypeData(const QMimeType &mime)
: m_mimetype(mime)
, m_askSave(AskSaveDefault)
, // TODO: the code for initializing this is missing. FileTypeDetails initializes the checkbox instead...
m_bNewItem(false)
, m_bFullInit(false)
, m_isGroup(false)
, m_appServicesModified(false)
, m_embedServicesModified(false)
, m_userSpecifiedIconModified(false)
{
const QString mimeName = m_mimetype.name();
Q_ASSERT(!mimeName.isEmpty());
const int index = mimeName.indexOf(QLatin1Char('/'));
if (index != -1) {
m_major = mimeName.left(index);
m_minor = mimeName.mid(index + 1);
} else {
m_major = mimeName;
}
initFromQMimeType();
}
MimeTypeData::MimeTypeData(const QString &mimeName, bool)
: m_askSave(AskSaveDefault)
, m_bNewItem(true)
, m_bFullInit(false)
, m_isGroup(false)
, m_appServicesModified(false)
, m_embedServicesModified(false)
, m_userSpecifiedIconModified(false)
{
const int index = mimeName.indexOf(QLatin1Char('/'));
if (index != -1) {
m_major = mimeName.left(index);
m_minor = mimeName.mid(index + 1);
} else {
m_major = mimeName;
}
m_autoEmbed = UseGroupSetting;
// all the rest is empty by default
}
void MimeTypeData::initFromQMimeType()
{
m_comment = m_mimetype.comment();
setPatterns(m_mimetype.globPatterns());
m_autoEmbed = readAutoEmbed();
// Parse XML file to find out if the user specified a custom icon name
QString file = name().toLower() + QLatin1String(".xml");
QStringList mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("mime/") + file);
if (mimeFiles.isEmpty()) {
// This is for shared-mime-info < 1.3 that did not lowecase mime names
file = name() + QLatin1String(".xml");
mimeFiles = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("mime/") + file);
if (mimeFiles.isEmpty()) {
qWarning() << "No file found for" << file << ", even though the file appeared in a directory listing.";
qWarning() << "Either it was just removed, or the directory doesn't have executable permission...";
qWarning() << QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("mime"), QStandardPaths::LocateDirectory);
return;
}
}
// Reverse iterator to get global first, then local.
for (auto rIt = mimeFiles.crbegin(); rIt != mimeFiles.crend(); ++rIt) {
const QString fullPath = *rIt;
QFile qfile(fullPath);
if (!qfile.open(QFile::ReadOnly)) {
continue;
}
QXmlStreamReader xml(&qfile);
if (xml.readNextStartElement()) {
if (xml.name() != QLatin1String("mime-type")) {
continue;
}
const QString mimeName = xml.attributes().value(QLatin1String("type")).toString();
if (mimeName.isEmpty()) {
continue;
}
if (QString::compare(mimeName, name(), Qt::CaseInsensitive) != 0) {
qWarning() << "Got name" << mimeName << "in file" << file << "expected" << name();
}
while (xml.readNextStartElement()) {
const QStringRef tag = xml.name();
if (tag == QLatin1String("icon")) {
m_userSpecifiedIcon = xml.attributes().value(QLatin1String("name")).toString();
}
xml.skipCurrentElement();
}
}
}
}
MimeTypeData::AutoEmbed MimeTypeData::readAutoEmbed() const
{
const KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
const QString key = QStringLiteral("embed-") + name();
const KConfigGroup group(config, "EmbedSettings");
if (m_isGroup) {
// embedding is false by default except for image/*, multipart/* and inode/* (hardcoded in konq)
const bool defaultValue = (m_major == QLatin1String("image") || m_major == QLatin1String("multipart") || m_major == QLatin1String("inode"));
return group.readEntry(key, defaultValue) ? Yes : No;
} else {
if (group.hasKey(key)) {
return group.readEntry(key, false) ? Yes : No;
}
// TODO if ( !mimetype.property( "X-KDE-LocalProtocol" ).toString().isEmpty() )
// TODO return MimeTypeData::Yes; // embed by default for zip, tar etc.
return MimeTypeData::UseGroupSetting;
}
}
void MimeTypeData::writeAutoEmbed()
{
KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
if (!config->isConfigWritable(true)) {
return;
}
const QString key = QStringLiteral("embed-") + name();
KConfigGroup group(config, "EmbedSettings");
if (m_isGroup) {
group.writeEntry(key, m_autoEmbed == Yes);
} else {
if (m_autoEmbed == UseGroupSetting) {
group.deleteEntry(key);
} else {
group.writeEntry(key, m_autoEmbed == Yes);
}
}
}
bool MimeTypeData::isEssential() const
{
// Keep in sync with KMimeType::checkEssentialMimeTypes
const QString n = name();
if (n == QLatin1String("application/octet-stream")) {
return true;
}
if (n == QLatin1String("inode/directory")) {
return true;
}
if (n == QLatin1String("inode/blockdevice")) {
return true;
}
if (n == QLatin1String("inode/chardevice")) {
return true;
}
if (n == QLatin1String("inode/socket")) {
return true;
}
if (n == QLatin1String("inode/fifo")) {
return true;
}
if (n == QLatin1String("application/x-shellscript")) {
return true;
}
if (n == QLatin1String("application/x-executable")) {
return true;
}
if (n == QLatin1String("application/x-desktop")) {
return true;
}
return false;
}
void MimeTypeData::setUserSpecifiedIcon(const QString &icon)
{
if (icon == m_userSpecifiedIcon) {
return;
}
m_userSpecifiedIcon = icon;
m_userSpecifiedIconModified = true;
}
QStringList MimeTypeData::getAppOffers() const
{
QStringList serviceIds;
const KService::List offerList = KApplicationTrader::queryByMimeType(name());
for (const auto &servicePtr : offerList) {
serviceIds.append(servicePtr->storageId());
}
return serviceIds;
}
QStringList MimeTypeData::getPartOffers() const
{
QStringList servicesIds;
const KService::List partOfferList = KMimeTypeTrader::self()->query(name(), QStringLiteral("KParts/ReadOnlyPart"));
for (const auto &servicePtr : partOfferList) {
servicesIds.append(servicePtr->storageId());
}
return servicesIds;
}
void MimeTypeData::getMyServiceOffers() const
{
m_appServices = getAppOffers();
m_embedServices = getPartOffers();
m_bFullInit = true;
}
QStringList MimeTypeData::appServices() const
{
if (!m_bFullInit) {
getMyServiceOffers();
}
return m_appServices;
}
QStringList MimeTypeData::embedServices() const
{
if (!m_bFullInit) {
getMyServiceOffers();
}
return m_embedServices;
}
bool MimeTypeData::isMimeTypeDirty() const
{
Q_ASSERT(!m_isGroup);
if (m_bNewItem) {
return true;
}
if (!m_mimetype.isValid()) {
qWarning() << "MimeTypeData for" << name() << "says 'not new' but is without a mimetype? Should not happen.";
return true;
}
if (m_mimetype.comment() != m_comment) {
qDebug() << "Mimetype Comment Dirty: old=" << m_mimetype.comment() << "m_comment=" << m_comment;
return true;
}
if (m_userSpecifiedIconModified) {
qDebug() << "m_userSpecifiedIcon has changed. Now set to" << m_userSpecifiedIcon;
return true;
}
QStringList storedPatterns = m_mimetype.globPatterns();
storedPatterns.sort(); // see ctor
if (storedPatterns != m_patterns) {
qDebug() << "Mimetype Patterns Dirty: old=" << storedPatterns << "m_patterns=" << m_patterns;
return true;
}
if (readAutoEmbed() != m_autoEmbed) {
return true;
}
return false;
}
bool MimeTypeData::isServiceListDirty() const
{
return !m_isGroup && (m_appServicesModified || m_embedServicesModified);
}
bool MimeTypeData::isDirty() const
{
if (m_bNewItem) {
qDebug() << "New item, need to save it";
return true;
}
if (!m_isGroup) {
if (isServiceListDirty()) {
return true;
}
if (isMimeTypeDirty()) {
return true;
}
} else { // is a group
if (readAutoEmbed() != m_autoEmbed) {
return true;
}
}
if (m_askSave != AskSaveDefault) {
return true;
}
// nothing seems to have changed, it's not dirty.
return false;
}
bool MimeTypeData::sync()
{
if (m_isGroup) {
writeAutoEmbed();
return false;
}
if (m_askSave != AskSaveDefault) {
KSharedConfig::Ptr config = KSharedConfig::openConfig(QStringLiteral("filetypesrc"), KConfig::NoGlobals);
if (!config->isConfigWritable(true)) {
return false;
}
KConfigGroup cg = config->group("Notification Messages");
if (m_askSave == AskSaveYes) {
// Ask
cg.deleteEntry(QStringLiteral("askSave") + name());
cg.deleteEntry(QStringLiteral("askEmbedOrSave") + name());
} else {
// Do not ask, open
cg.writeEntry(QStringLiteral("askSave") + name(), QStringLiteral("no"));
cg.writeEntry(QStringLiteral("askEmbedOrSave") + name(), QStringLiteral("no"));
}
}
writeAutoEmbed();
bool needUpdateMimeDb = false;
if (isMimeTypeDirty()) {
MimeTypeWriter mimeTypeWriter(name());
mimeTypeWriter.setComment(m_comment);
if (!m_userSpecifiedIcon.isEmpty()) {
mimeTypeWriter.setIconName(m_userSpecifiedIcon);
}
mimeTypeWriter.setPatterns(m_patterns);
if (!mimeTypeWriter.write()) {
return false;
}
m_userSpecifiedIconModified = false;
needUpdateMimeDb = true;
}
syncServices();
return needUpdateMimeDb;
}
static const char s_DefaultApplications[] = "Default Applications";
static const char s_AddedAssociations[] = "Added Associations";
static const char s_RemovedAssociations[] = "Removed Associations";
void MimeTypeData::syncServices()
{
if (!m_bFullInit) {
return;
}
KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::GenericConfigLocation);
if (!profile->isConfigWritable(true)) { // warn user if mimeapps.list is root-owned (#155126/#94504)
return;
}
const QStringList oldAppServices = getAppOffers();
if (oldAppServices != m_appServices) {
// Save the default application according to mime-apps-spec 1.0
KConfigGroup defaultApp(profile, s_DefaultApplications);
saveDefaultApplication(defaultApp, m_appServices);
// Save preferred services
KConfigGroup addedApps(profile, s_AddedAssociations);
saveServices(addedApps, m_appServices);
KConfigGroup removedApps(profile, s_RemovedAssociations);
saveRemovedServices(removedApps, m_appServices, oldAppServices);
}
const QStringList oldPartServices = getPartOffers();
if (oldPartServices != m_embedServices) {
// Handle removed services
KConfigGroup addedParts(profile, "Added KDE Service Associations");
saveServices(addedParts, m_embedServices);
KConfigGroup removedParts(profile, "Removed KDE Service Associations");
saveRemovedServices(removedParts, m_embedServices, oldPartServices);
}
// Clean out any kde-mimeapps.list which would take precedence any cancel our changes.
const QString desktops = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP"));
const auto desktopsSplit = desktops.split(QLatin1Char(':'), Qt::SkipEmptyParts);
for (const QString &desktop : desktopsSplit) {
const QString file =
QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + desktop.toLower() + QLatin1String("-mimeapps.list");
if (QFileInfo::exists(file)) {
qDebug() << "Cleaning up" << file;
KConfig conf(file, KConfig::NoGlobals);
KConfigGroup(&conf, s_DefaultApplications).deleteEntry(name());
KConfigGroup(&conf, s_AddedAssociations).deleteEntry(name());
KConfigGroup(&conf, s_RemovedAssociations).deleteEntry(name());
}
}
m_appServicesModified = false;
m_embedServicesModified = false;
}
static QStringList collectStorageIds(const QStringList &services)
{
QStringList storageIds;
for (const QString &service : services) {
KService::Ptr pService = KService::serviceByStorageId(service);
if (!pService) {
qWarning() << "service with storage id" << service << "not found";
continue; // Where did that one go?
}
storageIds.append(pService->storageId());
}
return storageIds;
}
void MimeTypeData::saveRemovedServices(KConfigGroup &config, const QStringList &services, const QStringList &oldServices)
{
QStringList removedServiceList = config.readXdgListEntry(name());
for (const QString &service : services) {
// If removedServiceList.contains(service), then it was previously removed but has been added back
removedServiceList.removeAll(service);
}
for (const QString &oldService : oldServices) {
if (!services.contains(oldService)) {
// The service was in m_appServices (or m_embedServices) but has been removed
removedServiceList.append(oldService);
}
}
if (removedServiceList.isEmpty()) {
config.deleteEntry(name());
} else {
config.writeXdgListEntry(name(), removedServiceList);
}
}
void MimeTypeData::saveServices(KConfigGroup &config, const QStringList &services)
{
if (services.isEmpty()) {
config.deleteEntry(name());
} else {
config.writeXdgListEntry(name(), collectStorageIds(services));
}
}
void MimeTypeData::saveDefaultApplication(KConfigGroup &config, const QStringList &services)
{
if (services.isEmpty()) {
config.deleteEntry(name());
return;
}
const QStringList storageIds = collectStorageIds(services);
if (!storageIds.isEmpty()) {
const QString firstStorageId = storageIds.at(0);
config.writeXdgListEntry(name(), {firstStorageId});
}
}
void MimeTypeData::refresh()
{
if (m_isGroup) {
return;
}
QMimeDatabase db;
m_mimetype = db.mimeTypeForName(name());
if (m_mimetype.isValid()) {
if (m_bNewItem) {
qDebug() << "OK, created" << name();
m_bNewItem = false; // if this was a new mimetype, we just created it
}
if (!isMimeTypeDirty()) {
// Update from the xml, in case something was changed from out of this kcm
// (e.g. using KOpenWithDialog, or keditfiletype + kcmshell filetypes)
initFromQMimeType();
}
if (!m_appServicesModified && !m_embedServicesModified) {
m_bFullInit = false; // refresh services too
}
}
}
void MimeTypeData::getAskSave(bool &_askSave)
{
if (m_askSave == AskSaveYes) {
_askSave = true;
}
if (m_askSave == AskSaveNo) {
_askSave = false;
}
}
void MimeTypeData::setAskSave(bool _askSave)
{
m_askSave = _askSave ? AskSaveYes : AskSaveNo;
}
bool MimeTypeData::canUseGroupSetting() const
{
// "Use group settings" isn't available for zip, tar etc.; those have a builtin default...
if (!m_mimetype.isValid()) { // e.g. new mimetype
return true;
}
const bool hasLocalProtocolRedirect = !KProtocolManager::protocolForArchiveMimetype(name()).isEmpty();
return !hasLocalProtocolRedirect;
}
void MimeTypeData::setPatterns(const QStringList &p)
{
m_patterns = p;
// Sort them, since update-mime-database doesn't respect order (order of globs file != order of xml),
// and this code says things like if (m_mimetype.patterns() == m_patterns).
// We could also sort in KMimeType::setPatterns but this would just slow down the
// normal use case (anything else than this KCM) for no good reason.
m_patterns.sort();
}
bool MimeTypeData::matchesFilter(const QString &filter) const
{
if (name().contains(filter, Qt::CaseInsensitive)) {
return true;
}
if (m_comment.contains(filter, Qt::CaseInsensitive)) {
return true;
}
if (!m_patterns.filter(filter, Qt::CaseInsensitive).isEmpty()) {
return true;
}
return false;
}
void MimeTypeData::setAppServices(const QStringList &dsl)
{
if (!m_bFullInit) {
getMyServiceOffers(); // so that m_bFullInit is true
}
m_appServices = dsl;
m_appServicesModified = true;
}
void MimeTypeData::setEmbedServices(const QStringList &dsl)
{
if (!m_bFullInit) {
getMyServiceOffers(); // so that m_bFullInit is true
}
m_embedServices = dsl;
m_embedServicesModified = true;
}
QString MimeTypeData::icon() const
{
if (!m_userSpecifiedIcon.isEmpty()) {
return m_userSpecifiedIcon;
}
if (m_mimetype.isValid()) {
return m_mimetype.iconName();
}
return QString();
}

View File

@ -0,0 +1,178 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2003, 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef MIMETYPEDATA_H
#define MIMETYPEDATA_H
#include <QMimeDatabase>
#include <QMimeType>
class KConfigGroup;
/**
* This is a non-gui (data) class, that represents a mimetype.
* It is a QMimeType plus the changes we made to it.
*/
class MimeTypeData
{
public:
// Constructor used for groups
explicit MimeTypeData(const QString &major);
// Real constructor, used for an existing mimetype.
explicit MimeTypeData(const QMimeType &mime);
// Real constructor, used for a new mimetype.
explicit MimeTypeData(const QString &mimeName, bool /*unused, just to distinguish from the other QString ctor*/);
QString name() const
{
return m_isGroup ? m_major : m_major + QLatin1Char('/') + m_minor;
}
QString majorType() const
{
return m_major;
}
QString minorType() const
{
return m_minor;
}
void setMinor(const QString &m)
{
m_minor = m;
}
QString comment() const
{
return m_comment;
}
void setComment(const QString &c)
{
m_comment = c;
}
/**
* Returns true if "this" is a group
*/
bool isMeta() const
{
return m_isGroup;
}
/**
* Returns true if the type is essential, i.e. can't be deleted
* (see KMimeType::checkEssentialMimeTypes)
*/
bool isEssential() const;
QString icon() const;
void setUserSpecifiedIcon(const QString &icon);
QStringList patterns() const
{
return m_patterns;
}
void setPatterns(const QStringList &p);
QStringList appServices() const;
void setAppServices(const QStringList &dsl);
QStringList embedServices() const;
void setEmbedServices(const QStringList &dsl);
enum AutoEmbed {
Yes = 0,
No = 1,
UseGroupSetting = 2,
};
AutoEmbed autoEmbed() const
{
return m_autoEmbed;
}
void setAutoEmbed(AutoEmbed a)
{
m_autoEmbed = a;
}
const QMimeType &mimeType() const
{
return m_mimetype;
}
bool canUseGroupSetting() const;
void getAskSave(bool &);
void setAskSave(bool);
/**
* Returns true if the mimetype data has any unsaved changes.
*/
bool isDirty() const;
/**
* Returns true if the mimetype data has any unsaved changes in the service list.
*/
bool isServiceListDirty() const;
/**
* Save changes to disk.
* Does not check isDirty(), so the common idiom is if (data.isDirty()) { needUpdate = data.sync(); }
* Returns true if update-mime-database needs to be run afterwards
*/
bool sync();
/**
* Update m_mimetype from the xml when Apply is pressed
*/
void refresh();
/**
* Return true if this is a new mimetype, i.e. one that is not yet on disk
*/
bool isNew() const
{
return m_bNewItem;
}
/**
* Helper method for the filtering in the listview
*/
bool matchesFilter(const QString &filter) const;
private:
void initFromQMimeType();
AutoEmbed readAutoEmbed() const;
void writeAutoEmbed();
bool isMimeTypeDirty() const; // whether the mimetype definition file needs saving
QStringList getAppOffers() const;
QStringList getPartOffers() const;
void getMyServiceOffers() const;
void syncServices();
void saveServices(KConfigGroup &config, const QStringList &services);
void saveDefaultApplication(KConfigGroup &config, const QStringList &services);
void saveRemovedServices(KConfigGroup &config, const QStringList &services, const QStringList &oldServices);
QMimeType m_mimetype;
enum AskSave {
AskSaveYes = 0,
AskSaveNo = 1,
AskSaveDefault = 2,
};
AskSave m_askSave : 3;
AutoEmbed m_autoEmbed : 3;
bool m_bNewItem : 1;
mutable bool m_bFullInit : 1; // lazy init of m_appServices and m_embedServices
bool m_isGroup : 1;
bool m_appServicesModified : 1;
bool m_embedServicesModified : 1;
bool m_userSpecifiedIconModified : 1;
QString m_major, m_minor, m_comment, m_userSpecifiedIcon;
QStringList m_patterns;
mutable QStringList m_appServices;
mutable QStringList m_embedServices;
};
#endif /* MIMETYPEDATA_H */

View File

@ -0,0 +1,165 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2007, 2008 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "mimetypewriter.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QMimeDatabase>
#include <QMimeType>
#include <QStandardPaths>
#include <QXmlStreamWriter>
#include <kprocess.h>
class MimeTypeWriterPrivate
{
public:
QString localFilePath() const;
QString m_mimeType;
QString m_comment;
QString m_iconName;
QStringList m_patterns;
QString m_marker;
};
MimeTypeWriter::MimeTypeWriter(const QString &mimeType)
: d(new MimeTypeWriterPrivate)
{
d->m_mimeType = mimeType;
Q_ASSERT(!mimeType.isEmpty());
}
MimeTypeWriter::~MimeTypeWriter()
{
delete d;
}
void MimeTypeWriter::setComment(const QString &comment)
{
d->m_comment = comment;
}
void MimeTypeWriter::setPatterns(const QStringList &patterns)
{
d->m_patterns = patterns;
}
void MimeTypeWriter::setIconName(const QString &iconName)
{
d->m_iconName = iconName;
}
void MimeTypeWriter::setMarker(const QString &marker)
{
d->m_marker = marker;
}
bool MimeTypeWriter::write()
{
const QString packageFileName = d->localFilePath();
qDebug() << "writing" << packageFileName;
QFile packageFile(packageFileName);
if (!packageFile.open(QIODevice::WriteOnly)) {
qCritical() << "Couldn't open" << packageFileName << "for writing";
return false;
}
QXmlStreamWriter writer(&packageFile);
writer.setAutoFormatting(true);
writer.writeStartDocument();
if (!d->m_marker.isEmpty()) {
writer.writeComment(d->m_marker);
}
const QString nsUri = QStringLiteral("http://www.freedesktop.org/standards/shared-mime-info");
writer.writeDefaultNamespace(nsUri);
writer.writeStartElement(QStringLiteral("mime-info"));
writer.writeStartElement(nsUri, QStringLiteral("mime-type"));
writer.writeAttribute(QStringLiteral("type"), d->m_mimeType);
if (!d->m_comment.isEmpty()) {
writer.writeStartElement(nsUri, QStringLiteral("comment"));
writer.writeCharacters(d->m_comment);
writer.writeEndElement(); // comment
}
if (!d->m_iconName.isEmpty()) {
// User-specified icon name
writer.writeStartElement(nsUri, QStringLiteral("icon"));
writer.writeAttribute(QStringLiteral("name"), d->m_iconName);
writer.writeEndElement(); // icon
}
// Allow this local definition to override the global definition
writer.writeStartElement(nsUri, QStringLiteral("glob-deleteall"));
writer.writeEndElement(); // glob-deleteall
for (const QString &pattern : qAsConst(d->m_patterns)) {
writer.writeStartElement(nsUri, QStringLiteral("glob"));
writer.writeAttribute(QStringLiteral("pattern"), pattern);
writer.writeEndElement(); // glob
}
writer.writeEndElement(); // mime-info
writer.writeEndElement(); // mime-type
writer.writeEndDocument();
return true;
}
void MimeTypeWriter::runUpdateMimeDatabase()
{
const QString localPackageDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/");
Q_ASSERT(!localPackageDir.isEmpty());
KProcess proc;
proc << QStringLiteral("update-mime-database");
proc << localPackageDir;
const int exitCode = proc.execute();
if (exitCode) {
qWarning() << proc.program() << "exited with error code" << exitCode;
}
}
QString MimeTypeWriterPrivate::localFilePath() const
{
// XDG shared mime: we must write into a <kdehome>/share/mime/packages/ file...
// To simplify our job, let's use one "input" file per mimetype, in the user's dir.
// (this writes into $HOME/.local/share/mime by default)
//
// We could also use Override.xml, says the spec, but then we'd need to merge with other mimetypes,
// and in ~/.local we don't really expect other packages to be installed anyway...
QString baseName = m_mimeType;
baseName.replace(QLatin1Char('/'), QLatin1Char('-'));
QString packagesDirName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/") + QStringLiteral("packages/");
// create the directory, the saving will fail if it doesn't exist (bug#356237)
QDir(packagesDirName).mkpath(QStringLiteral("."));
return packagesDirName + baseName + QStringLiteral(".xml");
}
static QString existingDefinitionFile(const QString &mimeType)
{
QString baseName = mimeType;
baseName.replace(QLatin1Char('/'), QLatin1Char('-'));
return QStandardPaths::locate(QStandardPaths::GenericDataLocation,
QLatin1String("mime/") + QStringLiteral("packages/") + baseName + QStringLiteral(".xml"));
}
bool MimeTypeWriter::hasDefinitionFile(const QString &mimeType)
{
return !existingDefinitionFile(mimeType).isEmpty();
}
void MimeTypeWriter::removeOwnMimeType(const QString &mimeType)
{
const QString file = existingDefinitionFile(mimeType);
Q_ASSERT(!file.isEmpty());
QFile::remove(file);
// We must also remove the generated XML file, update-mime-database doesn't do that, for unknown media types
QString xmlFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("mime/") + mimeType + QStringLiteral(".xml"));
QFile::remove(xmlFile);
}
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes

View File

@ -0,0 +1,87 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2007, 2008 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#ifndef MIMETYPEWRITER_H
#define MIMETYPEWRITER_H
class QStringList;
class QString;
class MimeTypeWriterPrivate;
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes
/**
* MimeTypeWriter writes out the definition of a mimetype
* in a XDG shared-mime-info compliant way.
*/
class MimeTypeWriter
{
public:
MimeTypeWriter(const QString &mimeType);
~MimeTypeWriter();
/**
* Sets the comment describing this mimetype.
* It is strongly recommended to call this.
*/
void setComment(const QString &comment);
/**
* Define the patterns associated with this mimetype,
* like "*.png"
*/
void setPatterns(const QStringList &patterns);
/**
* Optional: set a user-specified icon name for this mimetype.
* Otherwise the icon name is based on the mimetype name.
*/
void setIconName(const QString &iconName);
/**
* Sets a string that will be written out as an XML comment
* in the XML definition file, to make it possible to recognize
* this file later on. Used by nspluginscan.
*/
void setMarker(const QString &marker);
/**
* Write out the mimetype definition file
* Returns true on success
*/
bool write();
/**
* Returns true if a mimetype definition file already exists
* for the given mimetype.
*
* NOTE: this is not the same as testing whether the
* mimetype is defined in general (for instance by freedesktop.org.xml)
* you should use db.mimeTypeForName() for that.
* This method is only for mimetypes generated by MimeTypeWriter.
*/
static bool hasDefinitionFile(const QString &mimeType);
/**
* Remove mimetype created by MimeTypeWriter.
* Assumes hasDefinitionFile(mimeType).
* Remember to call runUpdateMimeDatabase afterwards!
*/
static void removeOwnMimeType(const QString &mimeType);
/**
* Call this once after writing as many mimetypes as you want,
* to let update-mime-database process the new mimetype xml files.
*/
static void runUpdateMimeDatabase();
private:
MimeTypeWriterPrivate *const d;
};
/// WARNING: this code is duplicated between apps/nsplugins and runtime/filetypes
#endif /* MIMETYPEWRITER_H */

View File

@ -0,0 +1,79 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
SPDX-FileCopyrightText: 2008 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
// Own
#include "newtypedlg.h"
// Qt
#include <QBoxLayout>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QFormLayout>
#include <QFrame>
#include <QLabel>
#include <QLayout>
// KDE
#include <klineedit.h>
#include <klocalizedstring.h>
NewTypeDialog::NewTypeDialog(const QStringList &groups, QWidget *parent)
: QDialog(parent)
{
setModal(true);
setWindowTitle(i18n("Create New File Type"));
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QFormLayout *formLayout = new QFormLayout;
QLabel *l = new QLabel(i18n("Group:"));
m_groupCombo = new QComboBox;
m_groupCombo->setEditable(true);
m_groupCombo->addItems(groups);
m_groupCombo->setCurrentIndex(m_groupCombo->findText(QStringLiteral("application"))); // certainly a better default than "all"
formLayout->addRow(l, m_groupCombo);
m_groupCombo->setWhatsThis(
i18n("Select the category under which"
" the new file type should be added."));
// Line 1: mimetype name
l = new QLabel(i18n("Type name:"));
m_typeEd = new KLineEdit;
formLayout->addRow(l, m_typeEd);
m_typeEd->setWhatsThis(
i18n("Type the name of the file type. For instance, if you selected 'image' as category and you type 'custom' here, the file type 'image/custom' will "
"be created."));
m_typeEd->setFocus();
m_buttonBox = new QDialogButtonBox;
m_buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
mainLayout->addLayout(formLayout);
mainLayout->addWidget(m_buttonBox);
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
// Set a minimum width so that caption is not half-hidden
setMinimumWidth(300);
}
QString NewTypeDialog::group() const
{
return m_groupCombo->currentText();
}
QString NewTypeDialog::text() const
{
return m_typeEd->text();
}

View File

@ -0,0 +1,36 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef _NEWTYPEDLG_H
#define _NEWTYPEDLG_H
#include <QDialog>
class QDialogButtonBox;
class QStringList;
class KLineEdit;
class QComboBox;
/**
* A dialog for creating a new file type, with
* - a combobox for choosing the group
* - a line-edit for entering the name of the file type
* The rest (description, patterns, icon, apps) can be set later in the filetypesview anyway.
*/
class NewTypeDialog : public QDialog
{
public:
explicit NewTypeDialog(const QStringList &groups, QWidget *parent);
QString group() const;
QString text() const;
private:
KLineEdit *m_typeEd;
QComboBox *m_groupCombo;
QDialogButtonBox *m_buttonBox;
};
#endif

View File

@ -0,0 +1,80 @@
[Desktop Entry]
Name=keditfiletype
Name[az]=keditfiletype
Name[ca]=keditfiletype
Name[ca@valencia]=keditfiletype
Name[cs]=keditfiletype
Name[da]=keditfiletype
Name[de]=keditfiletype
Name[el]=keditfiletype
Name[en_GB]=keditfiletype
Name[es]=keditfiletype
Name[et]=keditfiletype
Name[eu]=keditfiletype
Name[fi]=keditfiletype
Name[fr]=keditfiletype
Name[gl]=keditfiletype
Name[hsb]=keditfiletype
Name[hu]=keditfiletype
Name[ia]=keditfiletype
Name[id]=keditfiletype
Name[it]=keditfiletype
Name[ko]=keditfiletype
Name[lt]=keditfiletype
Name[nl]=keditfiletype
Name[nn]=keditfiletype
Name[pl]=keditfiletype
Name[pt]=keditfiletype
Name[pt_BR]=keditfiletype
Name[ru]=keditfiletype
Name[sk]=keditfiletype
Name[sl]=keditfiletype
Name[sv]=filtypeditor
Name[tg]=keditfiletype
Name[uk]=keditfiletype
Name[x-test]=xxkeditfiletypexx
Name[zh_CN]=文件类型编辑
Name[zh_TW]=keditfiletype
GenericName=File Type Editor
GenericName[az]=Fayl növü redaktoru
GenericName[ca]=Editor per als tipus de fitxers
GenericName[ca@valencia]=Editor per als tipus de fitxers
GenericName[cs]=Editor typu souboru
GenericName[da]=Redigering af filtyper
GenericName[de]=Dateityp-Editor
GenericName[el]=Επεξεργαστής τ'υπου αρχείου
GenericName[en_GB]=File Type Editor
GenericName[es]=Editor de tipo de archivo
GenericName[et]=Failitüübi redaktor
GenericName[eu]=Fitxategi-mota editorea
GenericName[fi]=Tiedostotyyppimuokkain
GenericName[fr]=Éditeur de type de fichier
GenericName[gl]=Editor de tipos de ficheiro
GenericName[hsb]=Wobdźěłar za družinu dataje
GenericName[hu]=Fájltípusszerkesztő
GenericName[ia]=Editor de typo de file
GenericName[id]=Pengedit Tipe File
GenericName[it]=Editor dei tipi di file
GenericName[ko]=파일 형식 편집기
GenericName[lt]=Failų tipų redaktorius
GenericName[nl]=Bewerker van bestandstype
GenericName[nn]=Filtyperedigering
GenericName[pl]=Edytor rodzaju pliku
GenericName[pt]=Editor de Tipos de Ficheiros
GenericName[pt_BR]=Editor de tipo de arquivo
GenericName[ru]=Редактор типов файлов
GenericName[sk]=Editor súborových typov
GenericName[sl]=Urejevalnik vrst datotek
GenericName[sv]=Filtypeditor
GenericName[tg]=Муҳаррири навъи файл
GenericName[tr]=Dosya Türü Düzenleyici
GenericName[uk]=Редактор типів файлів
GenericName[vi]=Trình biên tập kiểu tệp
GenericName[x-test]=xxFile Type Editorxx
GenericName[zh_CN]=文件类型编辑器
GenericName[zh_TW]=檔案類型編輯工具
Exec=keditfiletype5
Icon=preferences-desktop-filetype-association
Type=Application
Terminal=false
NoDisplay=true

View File

@ -0,0 +1,18 @@
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )
########### filetypestest ###############
add_executable(filetypestest
filetypestest.cpp
../mimetypedata.cpp
../mimetypewriter.cpp
)
ecm_mark_as_test(filetypestest)
add_test(NAME filetypestest COMMAND filetypestest)
target_link_libraries(filetypestest
KF5::KIOCore
KF5::Service
Qt::Core
Qt::Gui
Qt::Test
)

View File

@ -0,0 +1,418 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2007 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include <kservice.h>
#include <kconfiggroup.h>
#include <kdesktopfile.h>
#include <ksycoca.h>
// Qt
#include <QDir>
#include <QLoggingCategory>
#include <QProcess>
#include <QSignalSpy>
#include <QStandardPaths>
#include <QTest>
#include <mimetypedata.h>
#include <mimetypewriter.h>
// Unfortunately this isn't available in non-developer builds of Qt...
// extern Q_CORE_EXPORT int qmime_secondsBetweenChecks; // see qmimeprovider.cpp
class FileTypesTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase()
{
QLoggingCategory::setFilterRules(QStringLiteral("kf.coreaddons.kdirwatch.debug=true"));
QStandardPaths::setTestModeEnabled(true);
// update-mime-database needs to know about that test directory for the mimetype pattern change in testMimeTypePatterns to have an effect
qputenv("XDG_DATA_HOME", QFile::encodeName(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)));
m_mimeTypeCreatedSuccessfully = false;
QStringList appsDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
// qDebug() << appsDirs;
m_localApps = appsDirs.first() + QLatin1Char('/');
m_localConfig = QDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
QVERIFY(QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/mime/packages")));
QFile::remove(m_localConfig.filePath(QStringLiteral("mimeapps.list")));
QFile::remove(m_localConfig.filePath(QStringLiteral("filetypesrc")));
// Create fake applications for some tests below.
fakeApplication = QStringLiteral("fakeapplication.desktop");
createDesktopFile(m_localApps + fakeApplication, {QStringLiteral("image/png")});
fakeApplication2 = QStringLiteral("fakeapplication2.desktop");
createDesktopFile(m_localApps + fakeApplication2, {QStringLiteral("image/png"), QStringLiteral("text/plain")});
// Cleanup after testMimeTypePatterns if it failed mid-way
const QString packageFileName =
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/") + QStringLiteral("packages/text-plain.xml");
if (!packageFileName.isEmpty()) {
QFile::remove(packageFileName);
MimeTypeWriter::runUpdateMimeDatabase();
}
KService::Ptr fakeApplicationService = KService::serviceByStorageId(fakeApplication);
QVERIFY(fakeApplicationService);
}
void testMimeTypeGroupAutoEmbed()
{
MimeTypeData data(QStringLiteral("text"));
QCOMPARE(data.majorType(), QStringLiteral("text"));
QCOMPARE(data.name(), QStringLiteral("text"));
QVERIFY(data.isMeta());
QCOMPARE(data.autoEmbed(), MimeTypeData::No); // text doesn't autoembed by default
QVERIFY(!data.isDirty());
data.setAutoEmbed(MimeTypeData::Yes);
QCOMPARE(data.autoEmbed(), MimeTypeData::Yes);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // save to disk. Should succeed, but return false (no need to run update-mime-database)
QVERIFY(!data.isDirty());
// Check what's on disk by creating another MimeTypeData instance
MimeTypeData data2(QStringLiteral("text"));
QCOMPARE(data2.autoEmbed(), MimeTypeData::Yes);
QVERIFY(!data2.isDirty());
data2.setAutoEmbed(MimeTypeData::No); // revert to default, for next time
QVERIFY(data2.isDirty());
QVERIFY(!data2.sync());
QVERIFY(!data2.isDirty());
// TODO test askSave after cleaning up the code
}
void testMimeTypeAutoEmbed()
{
QMimeDatabase db;
MimeTypeData data(db.mimeTypeForName(QStringLiteral("text/plain")));
QCOMPARE(data.majorType(), QStringLiteral("text"));
QCOMPARE(data.minorType(), QStringLiteral("plain"));
QCOMPARE(data.name(), QStringLiteral("text/plain"));
QVERIFY(!data.isMeta());
QCOMPARE(data.autoEmbed(), MimeTypeData::UseGroupSetting);
QVERIFY(!data.isDirty());
data.setAutoEmbed(MimeTypeData::Yes);
QCOMPARE(data.autoEmbed(), MimeTypeData::Yes);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // save to disk. Should succeed, but return false (no need to run update-mime-database)
QVERIFY(!data.isDirty());
// Check what's on disk by creating another MimeTypeData instance
MimeTypeData data2(db.mimeTypeForName(QStringLiteral("text/plain")));
QCOMPARE(data2.autoEmbed(), MimeTypeData::Yes);
QVERIFY(!data2.isDirty());
data2.setAutoEmbed(MimeTypeData::UseGroupSetting); // revert to default, for next time
QVERIFY(data2.isDirty());
QVERIFY(!data2.sync());
QVERIFY(!data2.isDirty());
}
void testMimeTypePatterns()
{
// Given the text/plain mimetype
QMimeDatabase db;
MimeTypeData data(db.mimeTypeForName(QStringLiteral("text/plain")));
QCOMPARE(data.name(), QStringLiteral("text/plain"));
QCOMPARE(data.majorType(), QStringLiteral("text"));
QCOMPARE(data.minorType(), QStringLiteral("plain"));
QVERIFY(!data.isMeta());
QStringList patterns = data.patterns();
QVERIFY(patterns.contains(QStringLiteral("*.txt")));
QVERIFY(!patterns.contains(QStringLiteral("*.toto")));
// When the user changes the patterns
const QStringList origPatterns = patterns;
patterns.removeAll(QStringLiteral("*.txt"));
patterns.append(QStringLiteral("*.toto")); // yes, a french guy wrote this, as you can see
patterns.sort(); // for future comparisons
QVERIFY(!data.isDirty());
data.setPatterns(patterns);
QVERIFY(data.isDirty());
const bool needUpdateMimeDb = data.sync();
QVERIFY(needUpdateMimeDb);
MimeTypeWriter::runUpdateMimeDatabase();
// Then the GUI and the QMimeDatabase API should show the new patterns
QCOMPARE(data.patterns(), patterns);
data.refresh(); // reload from the xml
QCOMPARE(data.patterns(), patterns);
// Check what's in QMimeDatabase
QStringList newPatterns = db.mimeTypeForName(QStringLiteral("text/plain")).globPatterns();
newPatterns.sort();
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 2)
QEXPECT_FAIL("", "QTBUG-85436 is only fixed in Qt 5.15.2", Continue);
#endif
QCOMPARE(newPatterns, patterns);
if (newPatterns == patterns) { // TODO Qt6: remove the if (keep the QVERIFY!)
QVERIFY(!data.isDirty());
}
// And then removing the custom file by hand should revert to the initial state
const QString packageFileName =
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/mime/") + QStringLiteral("packages/text-plain.xml");
QVERIFY(!packageFileName.isEmpty());
QFile::remove(packageFileName);
MimeTypeWriter::runUpdateMimeDatabase();
// Check what's in QMimeDatabase
newPatterns = db.mimeTypeForName(QStringLiteral("text/plain")).globPatterns();
newPatterns.sort();
QCOMPARE(newPatterns, origPatterns);
}
void testAddService()
{
QMimeDatabase db;
QString mimeTypeName = QStringLiteral("application/rtf"); // use inherited mimetype to test #321706
MimeTypeData data(db.mimeTypeForName(mimeTypeName));
QStringList appServices = data.appServices();
// qDebug() << appServices;
QVERIFY(appServices.contains(fakeApplication2));
QVERIFY(!appServices.contains(fakeApplication)); // already there? hmm can't really test then
QVERIFY(!data.isDirty());
appServices.prepend(fakeApplication);
data.setAppServices(appServices);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
QVERIFY(!data.isDirty());
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkAddedAssociationsContains(mimeTypeName, fakeApplication);
// Test reordering apps, i.e. move fakeApplication under oldPreferredApp
appServices.removeFirst();
appServices.insert(1, fakeApplication);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
QVERIFY(!data.isDirty());
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkAddedAssociationsContains(mimeTypeName, fakeApplication);
// Then we get the signal that kbuildsycoca changed
data.refresh();
// Now test removing (in the same test, since it's inter-dependent)
QVERIFY(appServices.removeAll(fakeApplication) > 0);
data.setAppServices(appServices);
QVERIFY(data.isDirty());
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
}
void testRemoveTwice()
{
QMimeDatabase db;
// Remove fakeApplication from image/png
QString mimeTypeName = QStringLiteral("image/png");
MimeTypeData data(db.mimeTypeForName(mimeTypeName));
QStringList appServices = data.appServices();
qDebug() << "initial list for" << mimeTypeName << appServices;
QVERIFY(appServices.removeAll(fakeApplication) > 0);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
// Remove fakeApplication2 from image/png; must keep the previous entry in "Removed Associations"
qDebug() << "Removing fakeApplication2";
QVERIFY(appServices.removeAll(fakeApplication2) > 0);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication2);
// And now re-add fakeApplication2...
qDebug() << "Re-adding fakeApplication2";
appServices.prepend(fakeApplication2);
data.setAppServices(appServices);
QVERIFY(!data.sync()); // success, but no need to run update-mime-database
runKBuildSycoca();
// Check what's in ksycoca
checkMimeTypeServices(mimeTypeName, appServices);
// Check what's in mimeapps.list
checkRemovedAssociationsContains(mimeTypeName, fakeApplication);
checkRemovedAssociationsDoesNotContain(mimeTypeName, fakeApplication2);
}
void testCreateMimeType()
{
QMimeDatabase db;
const QString mimeTypeName = QStringLiteral("fake/unit-test-fake-mimetype");
// Clean up after previous runs if necessary
if (MimeTypeWriter::hasDefinitionFile(mimeTypeName)) {
MimeTypeWriter::removeOwnMimeType(mimeTypeName);
}
MimeTypeData data(mimeTypeName, true);
data.setComment(QStringLiteral("Fake MimeType"));
QStringList patterns = QStringList() << QStringLiteral("*.pkg.tar.gz");
data.setPatterns(patterns);
QVERIFY(data.isDirty());
QVERIFY(data.sync());
MimeTypeWriter::runUpdateMimeDatabase();
// QMimeDatabase doesn't even try to update the cache if less than
// 5000 ms have passed (can't use qmime_secondsBetweenChecks)
QTest::qSleep(5000);
QMimeType mime = db.mimeTypeForName(mimeTypeName);
QVERIFY(mime.isValid());
QCOMPARE(mime.comment(), QStringLiteral("Fake MimeType"));
QCOMPARE(mime.globPatterns(), patterns); // must sort them if more than one
// Testcase for the shaman.xml bug
QCOMPARE(db.mimeTypeForFile(QStringLiteral("/whatever/foo.pkg.tar.gz")).name(), QStringLiteral("fake/unit-test-fake-mimetype"));
m_mimeTypeCreatedSuccessfully = true;
}
void testDeleteMimeType()
{
QMimeDatabase db;
if (!m_mimeTypeCreatedSuccessfully) {
QSKIP("This test relies on testCreateMimeType");
}
const QString mimeTypeName = QStringLiteral("fake/unit-test-fake-mimetype");
QVERIFY(MimeTypeWriter::hasDefinitionFile(mimeTypeName));
MimeTypeWriter::removeOwnMimeType(mimeTypeName);
MimeTypeWriter::runUpdateMimeDatabase();
// QMimeDatabase doesn't even try to update the cache if less than
// 5000 ms have passed (can't use qmime_secondsBetweenChecks)
QTest::qSleep(5000);
const QMimeType mime = db.mimeTypeForName(mimeTypeName);
QVERIFY2(!mime.isValid(), qPrintable(mimeTypeName));
}
void testModifyMimeTypeComment() // of a system mimetype. And check that it's re-read correctly.
{
QMimeDatabase db;
QString mimeTypeName = QStringLiteral("image/png");
MimeTypeData data(db.mimeTypeForName(mimeTypeName));
QCOMPARE(data.comment(), QString::fromLatin1("PNG image"));
QString fakeComment = QStringLiteral("PNG image [testing]");
data.setComment(fakeComment);
QVERIFY(data.isDirty());
QVERIFY(data.sync());
MimeTypeWriter::runUpdateMimeDatabase();
QMimeType mime = db.mimeTypeForName(mimeTypeName);
QVERIFY(mime.isValid());
QCOMPARE(mime.comment(), fakeComment);
// Cleanup
QVERIFY(MimeTypeWriter::hasDefinitionFile(mimeTypeName));
MimeTypeWriter::removeOwnMimeType(mimeTypeName);
}
void cleanupTestCase()
{
const QString localAppsDir = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
QFile::remove(localAppsDir + QLatin1String("/fakeapplication.desktop"));
QFile::remove(localAppsDir + QLatin1String("/fakeapplication2.desktop"));
}
private: // helper methods
void checkAddedAssociationsContains(const QString &mimeTypeName, const QString &application)
{
const KConfig config(m_localConfig.filePath(QStringLiteral("mimeapps.list")), KConfig::NoGlobals);
const KConfigGroup group(&config, "Added Associations");
const QStringList addedEntries = group.readXdgListEntry(mimeTypeName);
if (!addedEntries.contains(application)) {
qWarning() << addedEntries << "does not contain" << application;
QVERIFY(addedEntries.contains(application));
}
}
void checkRemovedAssociationsContains(const QString &mimeTypeName, const QString &application)
{
const KConfig config(m_localConfig.filePath(QStringLiteral("mimeapps.list")), KConfig::NoGlobals);
const KConfigGroup group(&config, "Removed Associations");
const QStringList removedEntries = group.readXdgListEntry(mimeTypeName);
if (!removedEntries.contains(application)) {
qWarning() << removedEntries << "does not contain" << application;
QVERIFY(removedEntries.contains(application));
}
}
void checkRemovedAssociationsDoesNotContain(const QString &mimeTypeName, const QString &application)
{
const KConfig config(m_localConfig.filePath(QStringLiteral("mimeapps.list")), KConfig::NoGlobals);
const KConfigGroup group(&config, "Removed Associations");
const QStringList removedEntries = group.readXdgListEntry(mimeTypeName);
if (removedEntries.contains(application)) {
qWarning() << removedEntries << "contains" << application;
QVERIFY(!removedEntries.contains(application));
}
}
void runKBuildSycoca()
{
// Wait for notifyDatabaseChanged DBus signal
// (The real KCM code simply does the refresh in a slot, asynchronously)
QProcess proc;
// proc.setProcessChannelMode(QProcess::ForwardedChannels);
const QString kbuildsycoca = QStandardPaths::findExecutable(QLatin1String(KBUILDSYCOCA_EXENAME));
QVERIFY(!kbuildsycoca.isEmpty());
QStringList args;
args << QStringLiteral("--testmode");
proc.start(kbuildsycoca, args);
QSignalSpy spy(KSycoca::self(), SIGNAL(databaseChanged(QStringList)));
proc.waitForFinished();
qDebug() << "waiting for signal";
QVERIFY(spy.wait(10000));
qDebug() << "got signal";
}
void createDesktopFile(const QString &path, const QStringList &mimeTypes)
{
KDesktopFile file(path);
KConfigGroup group = file.desktopGroup();
group.writeEntry("Name", "FakeApplication");
group.writeEntry("Type", "Application");
group.writeEntry("Exec", "ls");
group.writeXdgListEntry("MimeType", mimeTypes);
}
void checkMimeTypeServices(const QString &mimeTypeName, const QStringList &expectedServices)
{
QMimeDatabase db;
MimeTypeData data2(db.mimeTypeForName(mimeTypeName));
if (data2.appServices() != expectedServices) {
qDebug() << "got" << data2.appServices() << "expected" << expectedServices;
}
QCOMPARE(data2.appServices(), expectedServices);
}
QString fakeApplication; // storage id of the fake application
QString fakeApplication2; // storage id of the fake application2
QString m_localApps;
QDir m_localConfig;
bool m_mimeTypeCreatedSuccessfully;
};
QTEST_MAIN(FileTypesTest)
#include "filetypestest.moc"

View File

@ -0,0 +1,51 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2003, 2007 David Faure <faure@kde.org>
SPDX-FileCopyrightText: 2008 Urs Wolfer <uwolfer @ kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
// Own
#include "typeslistitem.h"
// Qt
#include <QDebug>
TypesListItem::TypesListItem(QTreeWidget *parent, const QString &major)
: QTreeWidgetItem(parent)
, m_mimetypeData(major)
{
setText(0, major);
}
TypesListItem::TypesListItem(TypesListItem *parent, QMimeType mimetype)
: QTreeWidgetItem(parent)
, m_mimetypeData(mimetype)
{
setText(0, m_mimetypeData.minorType());
}
TypesListItem::TypesListItem(TypesListItem *parent, const QString &newMimetype)
: QTreeWidgetItem(parent)
, m_mimetypeData(newMimetype, true)
{
setText(0, m_mimetypeData.minorType());
}
TypesListItem::~TypesListItem()
{
}
void TypesListItem::setIcon(const QString &icon)
{
m_mimetypeData.setUserSpecifiedIcon(icon);
loadIcon(true);
}
void TypesListItem::loadIcon(bool forceReload)
{
if ((!m_mimetypeData.icon().isEmpty() && icon(0).isNull()) || forceReload) {
QTreeWidgetItem::setIcon(0, QIcon::fromTheme(m_mimetypeData.icon()));
}
}

View File

@ -0,0 +1,61 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2003 Waldo Bastian <bastian@kde.org>
SPDX-FileCopyrightText: 2003 David Faure <faure@kde.org>
SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only
*/
#ifndef TYPESLISTITEM_H
#define TYPESLISTITEM_H
#include "mimetypedata.h"
#include <QTreeWidgetItem>
#include <QMimeDatabase>
#include <QMimeType>
// TODO different subclasses for mimetypes and groups?
class TypesListItem : public QTreeWidgetItem
{
public:
/**
* Create a filetype group
*/
TypesListItem(QTreeWidget *parent, const QString &major);
/**
* Create a filetype item inside a group, for an existing mimetype
*/
TypesListItem(TypesListItem *parent, QMimeType mimetype);
/**
* Create a filetype item inside a group, for a new mimetype
*/
TypesListItem(TypesListItem *parent, const QString &newMimetype);
~TypesListItem() override;
void setIcon(const QString &icon);
QString name() const
{
return m_mimetypeData.name();
}
const MimeTypeData &mimeTypeData() const
{
return m_mimetypeData;
}
MimeTypeData &mimeTypeData()
{
return m_mimetypeData;
}
void loadIcon(bool forceReload = false);
private:
MimeTypeData m_mimetypeData;
};
#endif

36
kioclient/CMakeLists.txt Normal file
View File

@ -0,0 +1,36 @@
if (NOT TARGET KF5::KIOWidgets)
set(KIOCORE_ONLY ON)
add_definitions(-DKIOCORE_ONLY=1)
set(kio_libs KF5::KIOCore)
else ()
set(kio_libs KF5::KIOWidgets)
endif ()
function(add_kioclient_interface TARGET_NAME)
add_executable(${TARGET_NAME} kioclient.cpp)
string(TOUPPER "${TARGET_NAME}" UPPER_TARGET_NAME)
target_compile_definitions(${TARGET_NAME} PRIVATE "-DKIOCLIENT_AS_${UPPER_TARGET_NAME}")
target_compile_definitions(${TARGET_NAME} PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(${TARGET_NAME} Qt::DBus Qt::Widgets KF5::CoreAddons ${kio_libs} KF5::I18n)
install_compat_symlink(${TARGET_NAME})
install(TARGETS ${TARGET_NAME} DESTINATION ${KDE_INSTALL_FULL_BINDIR})
endfunction()
#we compile every file with different definitions, so it will behave slightly different
add_kioclient_interface(kioclient)
add_kioclient_interface(kdecp)
add_kioclient_interface(kdemv)
#kioclient is not marked as nongui since download and openProperties do graphical things
ecm_mark_nongui_executable(kdemv)
ecm_mark_nongui_executable(kdecp)
if (NOT KIOCORE_ONLY)
add_executable(kde-open kioclient.cpp)
target_compile_definitions(kde-open PRIVATE "-DKIOCLIENT_AS_KDEOPEN")
target_compile_definitions(kde-open PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(kde-open Qt::DBus KF5::CoreAddons KF5::KIOWidgets KF5::I18n)
install_compat_symlink(kde-open)
install(TARGETS kde-open DESTINATION ${KDE_INSTALL_FULL_BINDIR})
endif()

2
kioclient/Messages.sh Executable file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kioclient.pot

576
kioclient/kioclient.cpp Normal file
View File

@ -0,0 +1,576 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 1999-2006 David Faure <faure@kde.org>
SPDX-License-Identifier: LGPL-2.0-only
*/
#include "kioclient.h"
#include "kio_version.h"
#include "urlinfo.h"
#include <KIO/CopyJob>
#include <KIO/DeleteJob>
#include <kio/listjob.h>
#include <kio/transferjob.h>
#ifndef KIOCORE_ONLY
#include <KIO/ApplicationLauncherJob>
#include <KIO/JobUiDelegate>
#include <KIO/OpenUrlJob>
#include <KIO/StatJob>
#include <KIO/UDSEntry>
#include <KPropertiesDialog>
#include <KService>
#endif
#include <KAboutData>
#include <KLocalizedString>
#include <QCommandLineParser>
#include <QDBusConnection>
#include <QDebug>
#include <QFileDialog>
#include <QUrlQuery>
#include <iostream>
bool ClientApp::m_ok = true;
static bool s_interactive = false;
static KIO::JobFlags s_jobFlags = KIO::DefaultFlags;
static QUrl makeURL(const QString &urlArg)
{
return QUrl::fromUserInput(urlArg, QDir::currentPath());
}
static QList<QUrl> makeUrls(const QStringList &urlArgs)
{
QList<QUrl> ret;
for (const QString &url : urlArgs) {
ret += makeURL(url);
}
return ret;
}
#ifdef KIOCLIENT_AS_KIOCLIENT
static void usage()
{
puts(i18n("\nSyntax:\n").toLocal8Bit().constData());
puts(i18n(" kioclient openProperties 'url'\n"
" # Opens a properties menu\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient exec 'url' ['mimetype']\n"
" # Tries to open the document pointed to by 'url', in the application\n"
" # associated with it in KDE. You may omit 'mimetype'.\n"
" # In this case the mimetype is determined\n"
" # automatically. Of course URL may be the URL of a\n"
" # document, or it may be a *.desktop file.\n"
" # 'url' can be an executable, too.\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient move 'src' 'dest'\n"
" # Moves the URL 'src' to 'dest'.\n"
" # 'src' may be a list of URLs.\n")
.toLocal8Bit()
.constData());
puts(i18n(" # 'dest' may be \"trash:/\" to move the files\n"
" # to the trash.\n")
.toLocal8Bit()
.constData());
puts(i18n(" # the short version kioclient mv\n"
" # is also available.\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient download ['src']\n"
" # Copies the URL 'src' to a user-specified location'.\n"
" # 'src' may be a list of URLs, if not present then\n"
" # a URL will be requested.\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient copy 'src' 'dest'\n"
" # Copies the URL 'src' to 'dest'.\n"
" # 'src' may be a list of URLs.\n")
.toLocal8Bit()
.constData());
puts(i18n(" # the short version kioclient cp\n"
" # is also available.\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient cat 'url'\n"
" # Writes out the contents of 'url' to stdout\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient ls 'url'\n"
" # Lists the contents of the directory 'url' to stdout\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient remove 'url'\n"
" # Removes the URL\n"
" # 'url' may be a list of URLs.\n")
.toLocal8Bit()
.constData());
puts(i18n(" # the short version kioclient rm\n"
" # is also available.\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient stat 'url'\n"
" # Shows all of the available information for 'url'\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient appmenu\n"
" # Opens a basic application launcher.\n\n")
.toLocal8Bit()
.constData());
puts(i18n("*** Examples:\n").toLocal8Bit().constData());
puts(i18n(" kioclient exec file:/home/weis/data/test.html\n"
" // Opens the file with default binding\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient exec ftp://localhost/\n"
" // Opens new window with URL\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient exec file:/root/Desktop/emacs.desktop\n"
" // Starts emacs\n\n")
.toLocal8Bit()
.constData());
puts(i18n(" kioclient exec .\n"
" // Opens the current directory. Very convenient.\n\n")
.toLocal8Bit()
.constData());
}
#endif
int main(int argc, char **argv)
{
#ifdef KIOCORE_ONLY
QCoreApplication app(argc, argv);
#else
QApplication app(argc, argv);
#endif
KLocalizedString::setApplicationDomain("kioclient");
QString appName = QStringLiteral("kioclient");
QString programName = i18n("KIO Client");
QString description = i18n("Command-line tool for network-transparent operations");
QString version = QLatin1String(PROJECT_VERSION);
KAboutData data(appName, programName, version, description, KAboutLicense::LGPL_V2);
KAboutData::setApplicationData(data);
QCommandLineParser parser;
data.setupCommandLine(&parser);
parser.addOption(QCommandLineOption(QStringLiteral("interactive"), i18n("Use message boxes and other native notifications")));
parser.addOption(QCommandLineOption(QStringLiteral("noninteractive"),
i18n("Non-interactive use: no message boxes. If you don't want a "
"graphical connection, use --platform offscreen")));
#if !defined(KIOCLIENT_AS_KDEOPEN)
parser.addOption(QCommandLineOption(QStringLiteral("overwrite"), i18n("Overwrite destination if it exists (for copy and move)")));
#endif
#if defined(KIOCLIENT_AS_KDEOPEN)
parser.addPositionalArgument(QStringLiteral("url"), i18n("file or URL"), i18n("urls..."));
#elif defined(KIOCLIENT_AS_KDECP)
parser.addPositionalArgument(QStringLiteral("src"), i18n("Source URL or URLs"), i18n("urls..."));
parser.addPositionalArgument(QStringLiteral("dest"), i18n("Destination URL"), i18n("url"));
#elif defined(KIOCLIENT_AS_KDEMV)
parser.addPositionalArgument(QStringLiteral("src"), i18n("Source URL or URLs"), i18n("urls..."));
parser.addPositionalArgument(QStringLiteral("dest"), i18n("Destination URL"), i18n("url"));
#elif defined(KIOCLIENT_AS_KIOCLIENT)
parser.addOption(QCommandLineOption(QStringLiteral("commands"), i18n("Show available commands")));
parser.addPositionalArgument(QStringLiteral("command"), i18n("Command (see --commands)"), i18n("command"));
parser.addPositionalArgument(QStringLiteral("URLs"), i18n("Arguments for command"), i18n("urls..."));
#endif
// KCmdLineArgs::addTempFileOption();
parser.process(app);
data.processCommandLine(&parser);
#ifdef KIOCLIENT_AS_KIOCLIENT
if (argc == 1 || parser.isSet(QStringLiteral("commands"))) {
puts(parser.helpText().toLocal8Bit().constData());
puts("\n\n");
usage();
return 0;
}
#endif
ClientApp client;
return client.doIt(parser) ? 0 /*no error*/ : 1 /*error*/;
}
static void checkArgumentCount(int count, int min, int max)
{
if (count < min) {
fputs(i18nc("@info:shell", "%1: Syntax error, not enough arguments\n", qAppName()).toLocal8Bit().constData(), stderr);
::exit(1);
}
if (max && (count > max)) {
fputs(i18nc("@info:shell", "%1: Syntax error, too many arguments\n", qAppName()).toLocal8Bit().constData(), stderr);
::exit(1);
}
}
#ifndef KIOCORE_ONLY
bool ClientApp::kde_open(const QString &url, const QString &mimeType, bool allowExec)
{
UrlInfo info(url);
if (!info.atStart()) {
QUrlQuery q;
q.addQueryItem(QStringLiteral("line"), QString::number(info.line));
q.addQueryItem(QStringLiteral("column"), QString::number(info.column));
info.url.setQuery(q);
}
auto *job = new KIO::OpenUrlJob(info.url, mimeType);
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, nullptr));
job->setRunExecutables(allowExec);
job->setFollowRedirections(false);
bool job_had_error = false;
QObject::connect(job, &KJob::result, this, [&](KJob *job) {
if (job->error()) {
job_had_error = true;
}
});
job->start();
qApp->exec();
return !job_had_error;
}
#endif
bool ClientApp::doCopy(const QStringList &urls)
{
QList<QUrl> srcLst(makeUrls(urls));
QUrl dest = srcLst.takeLast();
KIO::Job *job = KIO::copy(srcLst, dest, s_jobFlags);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KJob::result, this, &ClientApp::slotResult);
qApp->exec();
return m_ok;
}
void ClientApp::slotEntries(KIO::Job *, const KIO::UDSEntryList &list)
{
for (const auto &entry : list) {
// For each file...
std::cout << qPrintable(entry.stringValue(KIO::UDSEntry::UDS_NAME)) << '\n';
}
std::cout << std::endl;
}
bool ClientApp::doList(const QStringList &urls)
{
const QUrl dir = makeURL(urls.at(0));
KIO::ListJob *job = KIO::listDir(dir, KIO::HideProgressInfo);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KIO::ListJob::entries, this, &ClientApp::slotEntries);
connect(job, &KJob::result, this, &ClientApp::slotResult);
qApp->exec();
return m_ok;
}
bool ClientApp::doMove(const QStringList &urls)
{
QList<QUrl> srcLst(makeUrls(urls));
const QUrl dest = srcLst.takeLast();
KIO::Job *job = KIO::move(srcLst, dest, s_jobFlags);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KJob::result, this, &ClientApp::slotResult);
qApp->exec();
return m_ok;
}
bool ClientApp::doRemove(const QStringList &urls)
{
KIO::Job *job = KIO::del(makeUrls(urls), s_jobFlags);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KJob::result, this, &ClientApp::slotResult);
qApp->exec();
return m_ok;
}
bool ClientApp::doStat(const QStringList &urls)
{
KIO::Job *job = KIO::statDetails(makeURL(urls.first()),
KIO::StatJob::SourceSide,
(KIO::StatBasic | KIO::StatUser | KIO::StatTime | KIO::StatInode | KIO::StatMimeType | KIO::StatAcl),
s_jobFlags);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KJob::result, this, &ClientApp::slotStatResult);
qApp->exec();
return m_ok;
}
bool ClientApp::doIt(const QCommandLineParser &parser)
{
const int argc = parser.positionalArguments().count();
checkArgumentCount(argc, 1, 0);
if (parser.isSet(QStringLiteral("interactive"))) {
s_interactive = true;
} else {
// "noninteractive" is currently the default mode, so we don't check.
// The argument still needs to exist for compatibility
s_interactive = false;
s_jobFlags = KIO::HideProgressInfo;
}
#if !defined(KIOCLIENT_AS_KDEOPEN)
if (parser.isSet(QStringLiteral("overwrite"))) {
s_jobFlags |= KIO::Overwrite;
}
#endif
#ifdef KIOCLIENT_AS_KDEOPEN
return kde_open(parser.positionalArguments().at(0), QString(), false);
#elif defined(KIOCLIENT_AS_KDECP)
checkArgumentCount(argc, 2, 0);
return doCopy(parser.positionalArguments());
#elif defined(KIOCLIENT_AS_KDEMV)
checkArgumentCount(argc, 2, 0);
return doMove(parser.positionalArguments());
#else
// Normal kioclient mode
const QString command = parser.positionalArguments().at(0);
#ifndef KIOCORE_ONLY
if (command == QLatin1String("openProperties")) {
checkArgumentCount(argc, 2, 2); // openProperties <url>
const QUrl url = makeURL(parser.positionalArguments().constLast());
KPropertiesDialog *dlg = new KPropertiesDialog(url, nullptr /*no parent*/);
QObject::connect(dlg, &QObject::destroyed, qApp, &QCoreApplication::quit);
QObject::connect(dlg, &KPropertiesDialog::canceled, this, &ClientApp::slotDialogCanceled);
dlg->show();
qApp->exec();
return m_ok;
} else
#endif
if (command == QLatin1String("cat")) {
checkArgumentCount(argc, 2, 2); // cat <url>
const QUrl url = makeURL(parser.positionalArguments().constLast());
KIO::TransferJob *job = KIO::get(url, KIO::NoReload, s_jobFlags);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KIO::TransferJob::data, this, &ClientApp::slotPrintData);
connect(job, &KJob::result, this, &ClientApp::slotResult);
qApp->exec();
return m_ok;
}
#ifndef KIOCORE_ONLY
else if (command == QLatin1String("exec")) {
checkArgumentCount(argc, 2, 3);
return kde_open(parser.positionalArguments().at(1), argc == 3 ? parser.positionalArguments().constLast() : QString(), true);
} else if (command == QLatin1String("appmenu")) {
auto *job = new KIO::ApplicationLauncherJob();
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, nullptr));
connect(job, &KJob::result, this, &ClientApp::slotResult);
job->start();
qApp->exec();
return m_ok;
}
#endif
else if (command == QLatin1String("download")) {
checkArgumentCount(argc, 0, 0);
QStringList args = parser.positionalArguments();
args.removeFirst();
const QList<QUrl> srcLst = makeUrls(args);
if (srcLst.isEmpty()) {
return m_ok;
}
const QUrl dsturl = QFileDialog::getSaveFileUrl(nullptr, i18n("Destination where to download the files"), srcLst.at(0));
if (dsturl.isEmpty()) { // canceled
return m_ok; // AK - really okay?
}
KIO::Job *job = KIO::copy(srcLst, dsturl, s_jobFlags);
if (!s_interactive) {
job->setUiDelegate(nullptr);
job->setUiDelegateExtension(nullptr);
}
connect(job, &KJob::result, this, &ClientApp::slotResult);
qApp->exec();
return m_ok;
} else if (command == QLatin1String("copy") || command == QLatin1String("cp")) {
checkArgumentCount(argc, 3, 0); // cp <src> <dest>
QStringList args = parser.positionalArguments();
args.removeFirst();
return doCopy(args);
} else if (command == QLatin1String("move") || command == QLatin1String("mv")) {
checkArgumentCount(argc, 3, 0); // mv <src> <dest>
QStringList args = parser.positionalArguments();
args.removeFirst();
return doMove(args);
} else if (command == QLatin1String("list") || command == QLatin1String("ls")) {
checkArgumentCount(argc, 2, 2); // ls <url>
QStringList args = parser.positionalArguments();
args.removeFirst();
return doList(args);
} else if (command == QLatin1String("remove") || command == QLatin1String("rm")) {
checkArgumentCount(argc, 2, 0); // rm <url>
QStringList args = parser.positionalArguments();
args.removeFirst();
return doRemove(args);
} else if (command == QLatin1String("stat")) {
checkArgumentCount(argc, 2, 2); // stat <url>
QStringList args = parser.positionalArguments();
args.removeFirst();
return doStat(args);
} else {
fputs(i18nc("@info:shell", "%1: Syntax error, unknown command '%2'\n", qAppName(), command).toLocal8Bit().data(), stderr);
return false;
}
Q_UNREACHABLE();
#endif
}
void ClientApp::slotResult(KJob *job)
{
if (job->error()) {
#ifndef KIOCORE_ONLY
if (s_interactive) {
static_cast<KIO::Job *>(job)->uiDelegate()->showErrorMessage();
} else
#endif
{
fputs(qPrintable(i18nc("@info:shell", "%1: %2\n", qAppName(), job->errorString())), stderr);
}
}
m_ok = !job->error();
if (qApp->topLevelWindows().isEmpty()) {
qApp->quit();
} else {
qApp->setQuitOnLastWindowClosed(true);
}
}
void ClientApp::slotDialogCanceled()
{
m_ok = false;
qApp->quit();
}
void ClientApp::slotPrintData(KIO::Job *, const QByteArray &data)
{
if (!data.isEmpty()) {
std::cout.write(data.constData(), data.size());
}
}
static void showStatField(const KIO::UDSEntry &entry, uint field, const char *name)
{
if (!entry.contains(field))
return;
std::cout << qPrintable(QString::fromLocal8Bit(name).leftJustified(20, ' ')) << " ";
if (field == KIO::UDSEntry::UDS_ACCESS) {
std::cout << qPrintable(QString("0%1").arg(entry.numberValue(field), 3, 8, QLatin1Char('0')));
} else if (field == KIO::UDSEntry::UDS_FILE_TYPE) {
std::cout << qPrintable(QString("0%1").arg((entry.numberValue(field) & S_IFMT), 6, 8, QLatin1Char('0')));
} else if (field & KIO::UDSEntry::UDS_STRING) {
std::cout << qPrintable(entry.stringValue(field));
} else if ((field & KIO::UDSEntry::UDS_TIME) == KIO::UDSEntry::UDS_TIME) {
// The previous comparison is necessary because the value
// of UDS_TIME is 0x04000000|UDS_NUMBER which is 0x06000000.
// So simply testing with (field & KIO::UDSEntry::UDS_TIME)
// would be true for both UDS_TIME and UDS_NUMBER fields.
// The same would happen if UDS_NUMBER were tested first.
const QDateTime dt = QDateTime::fromSecsSinceEpoch(entry.numberValue(field));
if (dt.isValid())
std::cout << qPrintable(dt.toString(Qt::TextDate));
} else if (field & KIO::UDSEntry::UDS_NUMBER) {
std::cout << entry.numberValue(field);
}
std::cout << std::endl;
}
void ClientApp::slotStatResult(KJob *job)
{
if (!job->error()) {
KIO::StatJob *statJob = qobject_cast<KIO::StatJob *>(job);
Q_ASSERT(statJob != nullptr);
const KIO::UDSEntry &result = statJob->statResult();
showStatField(result, KIO::UDSEntry::UDS_NAME, "NAME");
showStatField(result, KIO::UDSEntry::UDS_DISPLAY_NAME, "DISPLAY_NAME");
showStatField(result, KIO::UDSEntry::UDS_COMMENT, "COMMENT");
showStatField(result, KIO::UDSEntry::UDS_SIZE, "SIZE");
// This is not requested for the StatJob, so should never be seen
showStatField(result, KIO::UDSEntry::UDS_RECURSIVE_SIZE, "RECURSIVE_SIZE");
showStatField(result, KIO::UDSEntry::UDS_FILE_TYPE, "FILE_TYPE");
showStatField(result, KIO::UDSEntry::UDS_USER, "USER");
showStatField(result, KIO::UDSEntry::UDS_GROUP, "GROUP");
showStatField(result, KIO::UDSEntry::UDS_HIDDEN, "HIDDEN");
showStatField(result, KIO::UDSEntry::UDS_DEVICE_ID, "DEVICE_ID");
showStatField(result, KIO::UDSEntry::UDS_INODE, "INODE");
showStatField(result, KIO::UDSEntry::UDS_LINK_DEST, "LINK_DEST");
showStatField(result, KIO::UDSEntry::UDS_URL, "URL");
showStatField(result, KIO::UDSEntry::UDS_LOCAL_PATH, "LOCAL_PATH");
showStatField(result, KIO::UDSEntry::UDS_TARGET_URL, "TARGET_URL");
showStatField(result, KIO::UDSEntry::UDS_MIME_TYPE, "MIME_TYPE");
showStatField(result, KIO::UDSEntry::UDS_GUESSED_MIME_TYPE, "GUESSED_MIME_TYPE");
showStatField(result, KIO::UDSEntry::UDS_ICON_NAME, "ICON_NAME");
showStatField(result, KIO::UDSEntry::UDS_ICON_OVERLAY_NAMES, "ICON_OVERLAY_NAMES");
showStatField(result, KIO::UDSEntry::UDS_ACCESS, "ACCESS");
showStatField(result, KIO::UDSEntry::UDS_EXTENDED_ACL, "EXTENDED_ACL");
showStatField(result, KIO::UDSEntry::UDS_ACL_STRING, "ACL_STRING");
showStatField(result, KIO::UDSEntry::UDS_DEFAULT_ACL_STRING, "DEFAULT_ACL_STRING");
showStatField(result, KIO::UDSEntry::UDS_MODIFICATION_TIME, "MODIFICATION_TIME");
showStatField(result, KIO::UDSEntry::UDS_ACCESS_TIME, "ACCESS_TIME");
showStatField(result, KIO::UDSEntry::UDS_CREATION_TIME, "CREATION_TIME");
showStatField(result, KIO::UDSEntry::UDS_XML_PROPERTIES, "XML_PROPERTIES");
showStatField(result, KIO::UDSEntry::UDS_DISPLAY_TYPE, "DISPLAY_TYPE");
}
slotResult(job);
}
ClientApp::ClientApp()
: QObject()
{
}

47
kioclient/kioclient.h Normal file
View File

@ -0,0 +1,47 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 1999-2006 David Faure <faure@kde.org>
SPDX-License-Identifier: LGPL-2.0-only
*/
#ifndef __kioclient_h
#define __kioclient_h
#include <QApplication>
#include <kio/udsentry.h>
class QCommandLineParser;
class KJob;
namespace KIO
{
class Job;
}
class ClientApp : public QObject
{
Q_OBJECT
public:
ClientApp();
/** Parse command-line arguments and "do it" */
bool doIt(const QCommandLineParser &parser);
private Q_SLOTS:
void slotPrintData(KIO::Job *job, const QByteArray &data);
void slotEntries(KIO::Job *job, const KIO::UDSEntryList &);
void slotResult(KJob *);
void slotStatResult(KJob *);
void slotDialogCanceled();
private:
bool kde_open(const QString &url, const QString &mimeType, bool allowExec);
bool doCopy(const QStringList &urls);
bool doMove(const QStringList &urls);
bool doList(const QStringList &urls);
bool doRemove(const QStringList &urls);
bool doStat(const QStringList &urls);
static bool m_ok;
};
#endif

107
kioclient/urlinfo.h Normal file
View File

@ -0,0 +1,107 @@
/* This file is part of the KDE project
SPDX-FileCopyrightText: 2015 Milian Wolff <mail@milianw.de>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#ifndef URLINFO_H
#define URLINFO_H
#include <QDir>
#include <QRegularExpression>
#include <QString>
#include <QUrl>
/**
* Represents a file to be opened, consisting of its URL and the cursor to jump to.
*/
class UrlInfo
{
public:
/**
* Parses an argument and determines its line number and column and full path
* @param pathOrUrl path passed on e.g. command line to parse into an URL or just an URL
*/
UrlInfo(const QString &pathOrUrl)
: line(0)
, column(0)
{
/**
* first try: just check if the path is an existing file
*/
if (QFile::exists(pathOrUrl)) {
/**
* create absolute file path, we will e.g. pass this over dbus to other processes
* and then we are done, no cursor can be detected here!
*/
url = QUrl::fromLocalFile(QDir::current().absoluteFilePath(pathOrUrl));
return;
}
/**
* if the path starts with http:// or any other scheme, except file://
* we also don't want to do anything with URL
*/
if (!QUrl::fromUserInput(pathOrUrl).isLocalFile()) {
url = QUrl::fromUserInput(pathOrUrl, QDir::currentPath(), QUrl::DefaultResolution);
// relative paths are not isLocalFile(), but not valid too, so we don't want them
if (url.isValid()) {
return;
}
}
/**
* ok, the path as is, is no existing file, now, cut away :xx:yy stuff as cursor
* this will make test:50 to test with line 50
*/
QString pathOrUrl2 = pathOrUrl;
const auto match = QRegularExpression(QStringLiteral(":(\\d+)(?::(\\d+))?:?$")).match(pathOrUrl2);
if (match.isValid()) {
/**
* cut away the line/column specification from the path
*/
pathOrUrl2.chop(match.capturedLength());
/**
* set right cursor position
*/
line = match.capturedRef(1).toUInt();
column = match.capturedRef(2).toUInt();
}
/**
* construct url:
* - make relative paths absolute using the current working directory
* - do not prefer local file, to be able to open things like foo.com in browser
*/
url = QUrl::fromUserInput(pathOrUrl2, QDir::currentPath(), QUrl::DefaultResolution);
/**
* in some cases, this will fail, e.g. if you have line/column specs like test.c:10:1
* => fallback: assume a local file and just convert it to an url
*/
if (!url.isValid()) {
/**
* create absolute file path, we will e.g. pass this over dbus to other processes
*/
url = QUrl::fromLocalFile(QDir::current().absoluteFilePath(pathOrUrl2));
}
}
bool atStart() const
{
return (line == 0 || line == 1) && (column == 0 || column == 1);
}
/**
* url computed out of the passed path or URL
*/
QUrl url;
/**
* initial cursor position, if any found inside the path as line/column specification at the end
*/
unsigned line, column;
};
#endif // URLINFO_H

View File

@ -0,0 +1,12 @@
add_executable(kmimetypefinder kmimetypefinder.cpp)
target_compile_definitions(kmimetypefinder PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
ecm_mark_nongui_executable(kmimetypefinder)
target_link_libraries(kmimetypefinder
KF5::CoreAddons # KAboutData
KF5::I18n # i18n
Qt::Core
)
install_compat_symlink(kmimetypefinder)
install(TARGETS kmimetypefinder DESTINATION ${KDE_INSTALL_FULL_BINDIR})

2
kmimetypefinder/Messages.sh Executable file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kmimetypefinder5.pot

View File

@ -0,0 +1,67 @@
/*
* SPDX-FileCopyrightText: 2002 David Faure <faure@kde.org>
* SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <KAboutData>
#include <KLocalizedString>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QFile>
#include <QMimeDatabase>
#include <QMimeType>
#include <stdio.h>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
KLocalizedString::setApplicationDomain("kmimetypefinder5");
KAboutData aboutData(QLatin1String("kmimetypefinder"), i18n("MIME Type Finder"), QLatin1String(PROJECT_VERSION));
aboutData.setShortDescription(i18n("Gives the MIME type for a given file"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("c") << QLatin1String("content"), i18n("Use only the file content for determining the MIME type.")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("f") << QLatin1String("filename-only"),
i18n("Whether use the file name only for determining the MIME type. Not used if -c is specified.")));
parser.addPositionalArgument(QLatin1String("filename"), i18n("The filename to test. '-' to read from stdin."));
parser.process(app);
aboutData.processCommandLine(&parser);
if (parser.positionalArguments().count() < 1) {
printf("No filename specified\n");
return 1;
}
const QString fileName = parser.positionalArguments().at(0);
QMimeDatabase db;
QMimeType mime;
if (fileName == QLatin1String("-")) {
QFile qstdin;
qstdin.open(stdin, QIODevice::ReadOnly);
const QByteArray data = qstdin.readAll();
mime = db.mimeTypeForData(data);
} else if (parser.isSet(QStringLiteral("c"))) {
mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchContent);
} else if (parser.isSet(QStringLiteral("f"))) {
mime = db.mimeTypeForFile(fileName, QMimeDatabase::MatchExtension);
} else {
mime = db.mimeTypeForFile(fileName);
}
if (!mime.isDefault()) {
printf("%s\n", mime.name().toLatin1().constData());
} else {
return 1; // error
}
return 0;
}

19
kstart/CMakeLists.txt Normal file
View File

@ -0,0 +1,19 @@
find_package(X11)
set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries"
URL "http://www.x.org"
TYPE REQUIRED
)
add_executable(kstart kstart.cpp)
target_compile_definitions(kstart PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(kstart
Qt::Widgets
Qt::X11Extras
KF5::I18n
KF5::KIOGui
KF5::Service
KF5::WindowSystem
${X11_X11_LIB})
install_compat_symlink(kstart)
install(TARGETS kstart DESTINATION ${KDE_INSTALL_FULL_BINDIR})

2
kstart/Messages.sh Normal file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/kstart5.pot

484
kstart/kstart.cpp Normal file
View File

@ -0,0 +1,484 @@
/*
* kstart.C. Part of the KDE project.
*
* SPDX-FileCopyrightText: 1997-2000 Matthias Ettrich <ettrich@kde.org>
* SPDX-FileCopyrightText: David Faure <faure@kde.org>
* SPDX-FileCopyrightText: Richard Moore <rich@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include <config-kde-cli-tools.h>
#include "kstart.h"
#include <ktoolinvocation.h>
#include <fcntl.h>
#include <iostream>
#include <stdlib.h>
#include <QApplication>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QDebug>
#include <QDesktopWidget>
#include <QRegExp>
#include <QScreen>
#include <QTimer>
#include <QUrl>
#include <kaboutdata.h>
#include <klocalizedstring.h>
#include <kprocess.h>
#include <kwindowsystem.h>
#include <kstartupinfo.h>
#include <kxmessages.h>
#include <KIO/ApplicationLauncherJob>
#include <KIO/CommandLauncherJob>
#include <QX11Info>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <netwm.h>
// some globals
static QString servicePath; // TODO KF6 remove
static QString serviceName;
static QString exe;
static QStringList exeArgs;
static QString url;
static QString windowtitle;
static QString windowclass;
static int desktop = 0;
static bool activate = false;
static bool iconify = false;
static bool fullscreen = false;
static NET::States state = {};
static NET::States mask = {};
static NET::WindowType windowtype = NET::Unknown;
KStart::KStart()
: QObject()
{
bool useRule = false;
#ifdef HAVE_X11
if (QX11Info::isPlatformX11()) {
NETRootInfo i(QX11Info::connection(), NET::Supported);
useRule = i.isSupported(NET::WM2KDETemporaryRules);
}
#endif
if (useRule) {
sendRule();
} else {
// connect to window add to get the NEW windows
connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, &KStart::windowAdded);
}
// propagate the app startup notification info to the started app
// We are not using KApplication, so the env remained set
KStartupInfoId id = KStartupInfo::currentStartupIdEnv();
// finally execute the comand
if (!servicePath.isEmpty()) { // TODO KF6 remove
QString error;
QString dbusService;
int pid;
if (KToolInvocation::startServiceByDesktopPath(exe, url, &error, &dbusService, &pid) == 0) {
printf("%s\n", qPrintable(dbusService));
} else {
qCritical() << error;
}
} else if (!serviceName.isEmpty()) {
KService::Ptr service = KService::serviceByDesktopName(serviceName);
if (!service) {
qCritical() << "No such service" << exe;
} else {
auto *job = new KIO::ApplicationLauncherJob(service);
if (!url.isEmpty()) {
job->setUrls({QUrl(url)}); // TODO use QUrl::fromUserInput(PreferLocalFile)?
}
job->exec();
if (job->error()) {
qCritical() << job->errorString();
} else {
std::cout << job->pid() << std::endl;
}
}
} else {
auto *job = new KIO::CommandLauncherJob(exe, exeArgs);
job->exec();
}
QTimer::singleShot(useRule ? 0 : 120 * 1000, qApp, SLOT(quit()));
}
void KStart::sendRule()
{
KXMessages msg;
QString message;
if (!windowtitle.isEmpty()) {
message += QStringLiteral("title=") + windowtitle + QStringLiteral("\ntitlematch=3\n"); // 3 = regexp match
}
if (!windowclass.isEmpty()) {
message += QStringLiteral("wmclass=") + windowclass + QStringLiteral("\nwmclassmatch=1\n") // 1 = exact match
+ QStringLiteral("wmclasscomplete=")
// if windowclass contains a space (i.e. 2 words, use whole WM_CLASS)
+ (windowclass.contains(QLatin1Char(' ')) ? QStringLiteral("true") : QStringLiteral("false")) + QLatin1Char('\n');
}
if ((!windowtitle.isEmpty()) || (!windowclass.isEmpty())) {
// always ignore these window types
message += QStringLiteral("types=")
+ QString().setNum(-1U & ~(NET::TopMenuMask | NET::ToolbarMask | NET::DesktopMask | NET::SplashMask | NET::MenuMask)) + QLatin1Char('\n');
} else {
// accept only "normal" windows
message += QStringLiteral("types=") + QString().setNum(NET::NormalMask | NET::DialogMask) + QLatin1Char('\n');
}
if ((desktop > 0 && desktop <= KWindowSystem::numberOfDesktops()) || desktop == NETWinInfo::OnAllDesktops) {
message += QStringLiteral("desktop=") + QString().setNum(desktop) + QStringLiteral("\ndesktoprule=3\n");
}
if (activate) {
message += QStringLiteral("fsplevel=0\nfsplevelrule=2\n");
}
if (iconify) {
message += QStringLiteral("minimize=true\nminimizerule=3\n");
}
if (windowtype != NET::Unknown) {
message += QStringLiteral("type=") + QString().setNum(windowtype) + QStringLiteral("\ntyperule=2");
}
if (state) {
if (state & NET::KeepAbove) {
message += QStringLiteral("above=true\naboverule=3\n");
}
if (state & NET::KeepBelow) {
message += QStringLiteral("below=true\nbelowrule=3\n");
}
if (state & NET::SkipTaskbar) {
message += QStringLiteral("skiptaskbar=true\nskiptaskbarrule=3\n");
}
if (state & NET::SkipPager) {
message += QStringLiteral("skippager=true\nskippagerrule=3\n");
}
if (state & NET::MaxVert) {
message += QStringLiteral("maximizevert=true\nmaximizevertrule=3\n");
}
if (state & NET::MaxHoriz) {
message += QStringLiteral("maximizehoriz=true\nmaximizehorizrule=3\n");
}
if (state & NET::FullScreen) {
message += QStringLiteral("fullscreen=true\nfullscreenrule=3\n");
}
}
msg.broadcastMessage("_KDE_NET_WM_TEMPORARY_RULES", message, -1);
}
const NET::WindowTypes SUPPORTED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask
| NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask;
void KStart::windowAdded(WId w)
{
KWindowInfo info(w, NET::WMWindowType | NET::WMName);
// always ignore these window types
if (info.windowType(SUPPORTED_WINDOW_TYPES_MASK) == NET::TopMenu || info.windowType(SUPPORTED_WINDOW_TYPES_MASK) == NET::Toolbar
|| info.windowType(SUPPORTED_WINDOW_TYPES_MASK) == NET::Desktop) {
return;
}
if (!windowtitle.isEmpty()) {
QString title = info.name().toLower();
QRegExp r(windowtitle.toLower());
if (!r.exactMatch(title)) {
return; // no match
}
}
if (!windowclass.isEmpty()) {
#ifdef __GNUC__
#warning "Porting required"
#endif
#if 0
XClassHint hint;
if( !XGetClassHint( QX11Info::display(), w, &hint ))
return;
Q3CString cls = windowclass.contains( ' ' )
? Q3CString( hint.res_name ) + ' ' + hint.res_class : Q3CString( hint.res_class );
cls = cls.toLower();
XFree( hint.res_name );
XFree( hint.res_class );
if( cls != windowclass )
return;
#endif
}
if (windowtitle.isEmpty() && windowclass.isEmpty()) {
// accept only "normal" windows
if (info.windowType(SUPPORTED_WINDOW_TYPES_MASK) != NET::Unknown && info.windowType(SUPPORTED_WINDOW_TYPES_MASK) != NET::Normal
&& info.windowType(SUPPORTED_WINDOW_TYPES_MASK) != NET::Dialog) {
return;
}
}
applyStyle(w);
QApplication::exit();
}
// extern Atom qt_wm_state; // defined in qapplication_x11.cpp
static bool wstate_withdrawn(WId winid)
{
Q_UNUSED(winid);
#ifdef __GNUC__
#warning "Porting required."
#endif
// Porting info: The Qt4 equivalent for qt_wm_state is qt_x11Data->atoms[QX11Data::WM_STATE]
// which can be accessed via the macro ATOM(WM_STATE). Unfortunately, neither of these seem
// to be exported out of the Qt environment. This value may have to be acquired from somewhere else.
/*
Atom type;
int format;
unsigned long length, after;
unsigned char *data;
int r = XGetWindowProperty( QX11Info::display(), winid, qt_wm_state, 0, 2,
false, AnyPropertyType, &type, &format,
&length, &after, &data );
bool withdrawn = true;
if ( r == Success && data && format == 32 ) {
quint32 *wstate = (quint32*)data;
withdrawn = (*wstate == WithdrawnState );
XFree( (char *)data );
}
return withdrawn;
*/
return true;
}
void KStart::applyStyle(WId w)
{
if (state || iconify || windowtype != NET::Unknown || desktop >= 1) {
XWithdrawWindow(QX11Info::display(), w, QX11Info::appScreen());
while (!wstate_withdrawn(w)) {
;
}
}
NETWinInfo info(QX11Info::connection(), w, QX11Info::appRootWindow(), NET::WMState, NET::Properties2());
if ((desktop > 0 && desktop <= KWindowSystem::numberOfDesktops()) || desktop == NETWinInfo::OnAllDesktops) {
info.setDesktop(desktop);
}
if (iconify) {
XWMHints *hints = XGetWMHints(QX11Info::display(), w);
if (hints) {
hints->flags |= StateHint;
hints->initial_state = IconicState;
XSetWMHints(QX11Info::display(), w, hints);
XFree(hints);
}
}
if (windowtype != NET::Unknown) {
info.setWindowType(windowtype);
}
if (state) {
info.setState(state, mask);
}
if (fullscreen) {
QRect r = QGuiApplication::primaryScreen()->geometry();
XMoveResizeWindow(QX11Info::display(), w, r.x(), r.y(), r.width(), r.height());
}
XSync(QX11Info::display(), False);
XMapWindow(QX11Info::display(), w);
XSync(QX11Info::display(), False);
if (activate) {
KWindowSystem::forceActiveWindow(w);
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain("kstart5");
KAboutData aboutData(QStringLiteral("kstart"),
i18n("KStart"),
QString::fromLatin1(PROJECT_VERSION),
i18n(""
"Utility to launch applications with special window properties \n"
"such as iconified, maximized, a certain virtual desktop, a special decoration\n"
"and so on."),
KAboutLicense::GPL,
i18n("(C) 1997-2000 Matthias Ettrich (ettrich@kde.org)"));
aboutData.addAuthor(i18n("Matthias Ettrich"), QString(), QStringLiteral("ettrich@kde.org"));
aboutData.addAuthor(i18n("David Faure"), QString(), QStringLiteral("faure@kde.org"));
aboutData.addAuthor(i18n("Richard J. Moore"), QString(), QStringLiteral("rich@kde.org"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("!+command"), i18n("Command to execute")));
// TODO KF6 remove
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("service"),
i18n("Alternative to <command>: desktop file path to start. D-Bus service will be printed to stdout. Deprecated: use --application"),
QLatin1String("desktopfile")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("application"),
i18n("Alternative to <command>: desktop file to start."),
QLatin1String("desktopfile")));
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("url"), i18n("Optional URL to pass <desktopfile>, when using --service"), QLatin1String("url")));
// "!" means: all options after command are treated as arguments to the command
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("window"), i18n("A regular expression matching the window title"), QLatin1String("regexp")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("windowclass"),
i18n("A string matching the window class (WM_CLASS property)\n"
"The window class can be found out by running\n"
"'xprop | grep WM_CLASS' and clicking on a window\n"
"(use either both parts separated by a space or only the right part).\n"
"NOTE: If you specify neither window title nor window class,\n"
"then the very first window to appear will be taken;\n"
"omitting both options is NOT recommended."),
QLatin1String("class")));
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("desktop"), i18n("Desktop on which to make the window appear"), QLatin1String("number")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("currentdesktop"),
i18n("Make the window appear on the desktop that was active\nwhen starting the application")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("alldesktops"), i18n("Make the window appear on all desktops")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("iconify"), i18n("Iconify the window")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("maximize"), i18n("Maximize the window")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("maximize-vertically"), i18n("Maximize the window vertically")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("maximize-horizontally"), i18n("Maximize the window horizontally")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("fullscreen"), i18n("Show window fullscreen")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("type"),
i18n("The window type: Normal, Desktop, Dock, Toolbar, \nMenu, Dialog, TopMenu or Override"),
QLatin1String("type")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("activate"),
i18n("Jump to the window even if it is started on a \n"
"different virtual desktop")));
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("ontop") << QLatin1String("keepabove"), i18n("Try to keep the window above other windows")));
parser.addOption(
QCommandLineOption(QStringList() << QLatin1String("onbottom") << QLatin1String("keepbelow"), i18n("Try to keep the window below other windows")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skiptaskbar"), i18n("The window does not get an entry in the taskbar")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skippager"), i18n("The window does not get an entry on the pager")));
parser.process(app);
aboutData.processCommandLine(&parser);
if (parser.isSet(QStringLiteral("service"))) {
servicePath = parser.value(QStringLiteral("service"));
url = parser.value(QStringLiteral("url"));
} else if (parser.isSet(QStringLiteral("application"))) {
serviceName = parser.value(QStringLiteral("application"));
url = parser.value(QStringLiteral("url"));
} else {
QStringList positionalArgs = parser.positionalArguments();
if (positionalArgs.isEmpty()) {
qCritical() << i18n("No command specified");
parser.showHelp(1);
}
exe = positionalArgs.takeFirst();
exeArgs = positionalArgs;
}
desktop = parser.value(QStringLiteral("desktop")).toInt();
if (parser.isSet(QStringLiteral("alldesktops"))) {
desktop = NETWinInfo::OnAllDesktops;
}
if (parser.isSet(QStringLiteral("currentdesktop"))) {
desktop = KWindowSystem::currentDesktop();
}
windowtitle = parser.value(QStringLiteral("window"));
windowclass = parser.value(QStringLiteral("windowclass"));
if (!windowclass.isEmpty()) {
windowclass = windowclass.toLower();
}
if (windowtitle.isEmpty() && windowclass.isEmpty()) {
qWarning() << "Omitting both --window and --windowclass arguments is not recommended";
}
QString s = parser.value(QStringLiteral("type"));
if (!s.isEmpty()) {
s = s.toLower();
if (s == QLatin1String("desktop")) {
windowtype = NET::Desktop;
} else if (s == QLatin1String("dock")) {
windowtype = NET::Dock;
} else if (s == QLatin1String("toolbar")) {
windowtype = NET::Toolbar;
} else if (s == QLatin1String("menu")) {
windowtype = NET::Menu;
} else if (s == QLatin1String("dialog")) {
windowtype = NET::Dialog;
} else if (s == QLatin1String("override")) {
windowtype = NET::Override;
} else if (s == QLatin1String("topmenu")) {
windowtype = NET::TopMenu;
} else {
windowtype = NET::Normal;
}
}
if (parser.isSet(QStringLiteral("keepabove"))) {
state |= NET::KeepAbove;
mask |= NET::KeepAbove;
} else if (parser.isSet(QStringLiteral("keepbelow"))) {
state |= NET::KeepBelow;
mask |= NET::KeepBelow;
}
if (parser.isSet(QStringLiteral("skiptaskbar"))) {
state |= NET::SkipTaskbar;
mask |= NET::SkipTaskbar;
}
if (parser.isSet(QStringLiteral("skippager"))) {
state |= NET::SkipPager;
mask |= NET::SkipPager;
}
activate = parser.isSet(QStringLiteral("activate"));
if (parser.isSet(QStringLiteral("maximize"))) {
state |= NET::Max;
mask |= NET::Max;
}
if (parser.isSet(QStringLiteral("maximize-vertically"))) {
state |= NET::MaxVert;
mask |= NET::MaxVert;
}
if (parser.isSet(QStringLiteral("maximize-horizontally"))) {
state |= NET::MaxHoriz;
mask |= NET::MaxHoriz;
}
iconify = parser.isSet(QStringLiteral("iconify"));
if (parser.isSet(QStringLiteral("fullscreen"))) {
NETRootInfo i(QX11Info::connection(), NET::Supported);
if (i.isSupported(NET::FullScreen)) {
state |= NET::FullScreen;
mask |= NET::FullScreen;
} else {
windowtype = NET::Override;
fullscreen = true;
}
}
fcntl(XConnectionNumber(QX11Info::display()), F_SETFD, 1);
KStart start;
return app.exec();
}

34
kstart/kstart.h Normal file
View File

@ -0,0 +1,34 @@
/*
* kstart.h Part of the KDE project.
*
* SPDX-FileCopyrightText: 1997-2000 Matthias Ettrich <ettrich@kde.org>
* SPDX-FileCopyrightText: David Faure <faure@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*
*/
#ifndef KSTART_H
#define KSTART_H
#include <QWidget>
class KStart : public QObject
{
Q_OBJECT
public:
KStart();
~KStart() override
{
}
public Q_SLOTS:
void windowAdded(WId);
private:
void applyStyle(WId);
void sendRule();
};
#endif

5
ksvgtopng/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
add_executable(ksvgtopng ksvgtopng.cpp)
ecm_mark_nongui_executable(ksvgtopng)
target_link_libraries(ksvgtopng Qt::Svg)
install_compat_symlink(ksvgtopng)
install(TARGETS ksvgtopng DESTINATION ${KDE_INSTALL_FULL_BINDIR})

55
ksvgtopng/ksvgtopng.cpp Normal file
View File

@ -0,0 +1,55 @@
#include <QApplication>
#include <QImage>
#include <QString>
#include <QPainter>
#include <QSvgRenderer>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char **argv)
{
// Initialize Qt application, otherwise for some svg files it can segfault with:
// ASSERT failure in QFontDatabase: "A QApplication object needs to be
// constructed before FontConfig is used."
QApplication app(argc, argv);
if (argc < 5) {
cout << "Usage : ksvgtopng width height svgfilename outputfilename" << endl;
cout << "Please use full path name for svgfilename" << endl;
return -1;
}
int width = atoi(argv[1]);
int height = atoi(argv[2]);
QImage img(width, height, QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QSvgRenderer renderer(QString::fromLocal8Bit(argv[3]));
if (renderer.isValid()) {
QPainter p(&img);
renderer.render(&p);
/*
// Apply icon sharpening
double factor = 0;
if(width == 16)
factor = 30;
else if(width == 32)
factor = 20;
else if(width == 48)
factor = 10;
else if(width == 64)
factor = 5;
*img = KImageEffect::sharpen(*img, factor); // use QImageBlitz::sharpen()
*/
}
img.save(QString::fromLatin1(argv[4]), "PNG");
return 0;
}

View File

@ -0,0 +1,12 @@
add_executable(ktraderclient5 ktraderclient.cpp)
target_compile_definitions(ktraderclient5 PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
ecm_mark_nongui_executable(ktraderclient5)
target_link_libraries(ktraderclient5
KF5::Service # KService, traders...
KF5::CoreAddons # KAboutData
KF5::I18n # i18n
Qt::Core
)
install(TARGETS ktraderclient5 ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

2
ktraderclient/Messages.sh Executable file
View File

@ -0,0 +1,2 @@
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/ktraderclient5.pot

View File

@ -0,0 +1,112 @@
/*
* SPDX-FileCopyrightText: 2002, 2003 David Faure <faure@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <kmimetypetrader.h>
#include <kservicetypetrader.h>
#include <KAboutData>
#include <KLocalizedString>
#include <QCommandLineOption>
#include <QCommandLineParser>
#include <QCoreApplication>
#include <stdio.h>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
KLocalizedString::setApplicationDomain("ktraderclient5");
KAboutData aboutData(QLatin1String("ktraderclient"), i18n("KTraderClient"), QLatin1String(PROJECT_VERSION));
aboutData.addAuthor(i18n("David Faure"), QString(), QStringLiteral("faure@kde.org"));
aboutData.setShortDescription(i18n("A command-line tool for querying the KDE trader system"));
KAboutData::setApplicationData(aboutData);
QCommandLineParser parser;
aboutData.setupCommandLine(&parser);
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("mimetype"), i18n("A MIME type"), QLatin1String("mimetype")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("servicetype"),
i18n("A servicetype, like KParts/ReadOnlyPart or KMyApp/Plugin"),
QLatin1String("servicetype")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("constraint"),
i18n("A constraint expressed in the trader query language"),
QLatin1String("constraint")));
parser.addOption(QCommandLineOption(QStringList() << QLatin1String("short"), i18n("Output only paths to desktop files")));
parser.process(app);
aboutData.processCommandLine(&parser);
const QString mimetype = parser.value(QStringLiteral("mimetype"));
QString servicetype = parser.value(QStringLiteral("servicetype"));
const QString constraint = parser.value(QStringLiteral("constraint"));
const bool outputProperties = !parser.isSet(QStringLiteral("short"));
if (mimetype.isEmpty() && servicetype.isEmpty()) {
parser.showHelp();
}
if (!mimetype.isEmpty()) {
printf("mimetype is : %s\n", qPrintable(mimetype));
}
if (!servicetype.isEmpty()) {
printf("servicetype is : %s\n", qPrintable(servicetype));
}
if (!constraint.isEmpty()) {
printf("constraint is : %s\n", qPrintable(constraint));
}
KService::List offers;
if (!mimetype.isEmpty()) {
if (servicetype.isEmpty()) {
servicetype = QStringLiteral("Application");
}
offers = KMimeTypeTrader::self()->query(mimetype, servicetype, constraint);
} else {
offers = KServiceTypeTrader::self()->query(servicetype, constraint);
}
printf("got %d offers.\n", offers.count());
int i = 0;
for (const auto &service : std::as_const(offers)) {
if (outputProperties) {
printf("---- Offer %d ----\n", i++);
const QStringList props = service->propertyNames();
for (const QString &propName : props) {
QVariant prop = service->property(propName);
if (!prop.isValid()) {
printf("Invalid property %s\n", propName.toLocal8Bit().data());
continue;
}
QString outp = propName;
outp += QStringLiteral(" : '");
switch (prop.type()) {
case QVariant::StringList:
outp += prop.toStringList().join(QStringLiteral(" - "));
break;
case QVariant::Bool:
outp += prop.toBool() ? QStringLiteral("TRUE") : QStringLiteral("FALSE");
break;
default:
outp += prop.toString();
break;
}
if (!outp.isEmpty()) {
printf("%s'\n", outp.toLocal8Bit().constData());
}
}
} else {
printf("%s\n", service->entryPath().toLocal8Bit().constData());
}
}
return 0;
}

View File

@ -0,0 +1,8 @@
# SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
add_executable(plasma-open-settings main.cpp)
target_compile_definitions(plasma-open-settings PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(plasma-open-settings Qt::Core KF5::CoreAddons KF5::KIOGui KF5::I18n)
install(TARGETS plasma-open-settings ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES org.kde.plasma.settings.open.desktop DESTINATION ${KDE_INSTALL_APPDIR})

View File

@ -0,0 +1,5 @@
#! /usr/bin/env bash
# SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
$XGETTEXT *.cpp -o $podir/plasma-open-settings.pot

View File

@ -0,0 +1,58 @@
/*
* SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <KAboutData>
#include <KIO/CommandLauncherJob>
#include <KLocalizedString>
#include <QGuiApplication>
#include <QProcess>
#include <QStandardPaths>
#include <QTextStream>
#include <QUrl>
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
KLocalizedString::setApplicationDomain("plasma-open-settings");
KAboutData aboutData(QStringLiteral("plasma-open-settings"), //
i18n("App to open Settings app"),
QLatin1String(PROJECT_VERSION),
i18n("A tool to start system settings"),
KAboutLicense::GPL,
i18n("(c) 2021, The KDE Developers"));
aboutData.addAuthor(QStringLiteral("Aleix Pol i Gonzalez"), {}, QStringLiteral("aleixpol@kde.org"));
const QUrl url(app.arguments().constLast());
QString moduleName = url.host().isEmpty() ? url.path() : url.host();
if (moduleName.startsWith('/')) {
moduleName = moduleName.mid(1);
}
KIO::CommandLauncherJob *job = nullptr;
int ret = 0;
if (!QStandardPaths::findExecutable("systemsettings").isEmpty()) {
job = new KIO::CommandLauncherJob(QStringLiteral("systemsettings"), {moduleName});
job->setDesktopName(QStringLiteral("org.kde.systemsettings"));
} else if (!QStandardPaths::findExecutable("plasma-settings").isEmpty()) {
job = new KIO::CommandLauncherJob(QStringLiteral("plasma-settings"), {"-m", moduleName});
job->setDesktopName(QStringLiteral("org.kde.plasma.settings"));
} else if (!QStandardPaths::findExecutable("kcmshell5").isEmpty()) {
job = new KIO::CommandLauncherJob(QStringLiteral("kcmshell5"), {moduleName});
} else if (!QStandardPaths::findExecutable("kdialog").isEmpty()) {
job = new KIO::CommandLauncherJob(QStringLiteral("kdialog"), {"--error", i18n("Could not open: %1", moduleName)});
ret = 1;
} else {
QTextStream err(stderr);
err << "Could not open:" << moduleName << url.toString() << Qt::endl;
return 32;
}
if (!qEnvironmentVariableIsEmpty("XDG_ACTIVATION_TOKEN")) {
job->setStartupId(qgetenv("XDG_ACTIVATION_TOKEN"));
}
return !job->exec() + ret;
}

View File

@ -0,0 +1,39 @@
# SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@kde.org>
# SPDX-License-Identifier: CC0-1.0
[Desktop Entry]
Name=Open System Settings
Name[az]=Sistem Ayarlarınıın
Name[ca]=Obre l'Arranjament del sistema
Name[ca@valencia]=Obri Configuració del sistema
Name[cs]=Otevřít nastavení systému
Name[de]=Systemeinstellungen öffnen
Name[el]=Άνοιγμα ρυθμίσεων συστήματος
Name[en_GB]=Open System Settings
Name[es]=Abrir las preferencias del sistema
Name[eu]=Ireki Sistemako ezarpenak
Name[fi]=Avaa järjestelmäasetukset
Name[fr]=Ouvrir la configuration du système
Name[hsb]=Systemowe nastajenja wočinić
Name[hu]=Rendszerbeállítások megnyitása
Name[ia]=Aperi Preferentias de Systema
Name[it]=Apri le impostazioni di sistema
Name[ko]=시스템 설정 열기
Name[nl]=Systeeminstellingen openen
Name[pl]=Otwórz ustawienia systemowe
Name[pt]=Abrir a Configuração do Sistema
Name[pt_BR]=Abrir configurações do sistema
Name[ru]=Открыть «Параметры системы»
Name[sk]=Otvoriť Systémové nastavenia
Name[sl]=Odpri sistemske nastavitve
Name[sv]=Öppna systeminställningar
Name[tr]=Sistem Ayarlarını
Name[uk]=Відкрити «Системні параметри»
Name[vi]=Mở Thiết lập hệ thống
Name[x-test]=xxOpen System Settingsxx
Name[zh_CN]=打开系统设置
MimeType=x-scheme-handler/systemsettings
Exec=plasma-open-settings %u
Icon=systemsettings
Type=Application
NoDisplay=true

565
po/af/kcm5_filetypes.po Normal file
View File

@ -0,0 +1,565 @@
# UTF-8 test:äëïöü
# Copyright (C) 2001 Free Software Foundation, Inc.
# Frikkie Thirion <frix@expertron.co.za>, 2001,2002,2005.
#
msgid ""
msgstr ""
"Project-Id-Version: filetypes stable\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2021-08-06 00:18+0000\n"
"PO-Revision-Date: 2005-11-22 11:27+0200\n"
"Last-Translator: Frikkie Thirion <frikkie.thirion@deneloptronics.co.za>\n"
"Language-Team: AFRIKAANS <AF@lia.org.za>\n"
"Language: af\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Frikkie Thirion"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "frikkie.thirion@deneloptronics.co.za"
#: filegroupdetails.cpp:22
#, kde-format
msgid "Left Click Action (only for Konqueror file manager)"
msgstr ""
#: filegroupdetails.cpp:26 filetypedetails.cpp:134
#, kde-format
msgid "Show file in embedded viewer"
msgstr "Vertoon lêer in ingelegde kyker"
#: filegroupdetails.cpp:27 filetypedetails.cpp:135
#, kde-format
msgid "Show file in separate viewer"
msgstr "Vertoon lêer in aparte kyker"
#: filegroupdetails.cpp:36
#, fuzzy, kde-format
#| msgid ""
#| "Here you can configure what the Konqueror file manager will do when you "
#| "click on a file belonging to this group. Konqueror can display the file "
#| "in an embedded viewer or start up a separate application. You can change "
#| "this setting for a specific file type in the 'Embedding' tab of the file "
#| "type configuration."
msgid ""
"Here you can configure what the Konqueror file manager will do when you "
"click on a file belonging to this group. Konqueror can display the file in "
"an embedded viewer or start up a separate application. You can change this "
"setting for a specific file type in the 'Embedding' tab of the file type "
"configuration. Dolphin shows files always in a separate viewer"
msgstr ""
"Hier jy kan konfigureer wat die Konqueror lêer bestuurder sal doen wanneer "
"jy kliek op 'n lêer behorende aan na hierdie groep. Konqueror kan vertoon "
"die lêer in 'n ingebedde aansig van begin begin 'n aparte aansoek. jy kan "
"verander hierdie opset vir 'n spesifieke lêer tipe in die 'Embedding' "
"oortjie van die lêer tipe opstelling."
#: filetypedetails.cpp:62
#, kde-format
msgid ""
"This button displays the icon associated with the selected file type. Click "
"on it to choose a different icon."
msgstr ""
"Hierdie knoppie vertoon die ikoon geassosieer met die gekose lêer tipe. "
"Kliek op dit na kies 'n ander ikoon."
#: filetypedetails.cpp:68
#, kde-format
msgid "Filename Patterns"
msgstr "Lêernaam Patrone"
#: filetypedetails.cpp:80
#, kde-format
msgid ""
"This box contains a list of patterns that can be used to identify files of "
"the selected type. For example, the pattern *.txt is associated with the "
"file type 'text/plain'; all files ending in '.txt' are recognized as plain "
"text files."
msgstr ""
"Hierdie boks bevat 'n lys van patrone wat kan wees gebruik word na "
"identifiseer lêers van die gekose tipe. Vir voorbeeld, die patroon *.txt is "
"geassosieer met die lêer tipe 'teks/eenvoudig'; alle lêers wat eindig in '."
"txt' word herken as eenvoudig teks lêers."
#: filetypedetails.cpp:88 filetypesview.cpp:102 kservicelistwidget.cpp:103
#, kde-format
msgid "Add..."
msgstr "Voeg by..."
#: filetypedetails.cpp:93
#, kde-format
msgid "Add a new pattern for the selected file type."
msgstr "Voeg by 'n nuwe patroon vir die gekose lêer tipe."
#: filetypedetails.cpp:95 kservicelistwidget.cpp:117
#, kde-format
msgid "Remove"
msgstr ""
#: filetypedetails.cpp:100
#, kde-format
msgid "Remove the selected filename pattern."
msgstr "Verwyder die gekiesde lêernaam patroon."
#: filetypedetails.cpp:111
#, fuzzy, kde-format
#| msgid "Description"
msgid "Description:"
msgstr "Beskrywing"
#: filetypedetails.cpp:116
#, kde-format
msgid ""
"You can enter a short description for files of the selected file type (e.g. "
"'HTML Page'). This description will be used by applications like Konqueror "
"to display directory content."
msgstr ""
"Jy kan invoer 'n kort beskrywing vir lêers van die gekose lêer tipe (e.g. "
"'HTML Page'). Hierdie beskrywing sal wees gebruik word deur programme hou "
"van Konqueror na vertoon gids inhoud."
#: filetypedetails.cpp:129
#, fuzzy, kde-format
#| msgid "Left Click Action"
msgid "Left Click Action in Konqueror"
msgstr "Links Kliek Aksie"
#: filetypedetails.cpp:138
#, fuzzy, kde-format
#| msgid "Ask whether to save to disk instead"
msgid "Ask whether to save to disk instead (only for Konqueror browser)"
msgstr "Vra om eerder op die hardeskryf te stoor"
#: filetypedetails.cpp:154
#, fuzzy, kde-format
#| msgid ""
#| "Here you can configure what the Konqueror file manager will do when you "
#| "click on a file of this type. Konqueror can display the file in an "
#| "embedded viewer or start up a separate application. If set to 'Use "
#| "settings for G group', Konqueror will behave according to the settings of "
#| "the group G this type belongs to, for instance 'image' if the current "
#| "file type is image/png."
msgid ""
"Here you can configure what the Konqueror file manager will do when you "
"click on a file of this type. Konqueror can either display the file in an "
"embedded viewer, or start up a separate application. If set to 'Use settings "
"for G group', the file manager will behave according to the settings of the "
"group G to which this type belongs; for instance, 'image' if the current "
"file type is image/png. Dolphin always shows files in a separate viewer."
msgstr ""
"Hier jy kan konfigureer wat die Konqueror lêer bestuurder sal doen wanneer "
"jy kliek op 'n lêer van hierdie tipe. Konqueror kan vertoon die lêer in 'n "
"ingebedde aansig van begin begin 'n aparte aansoek. As stel na 'Use "
"instellings vir G groep', Konqueror sal gedra volgens na die instellings van "
"die groep G hierdie tipe behoort na, vir voorbeeld 'beeld' As die huidige "
"lêer tipe is beeld/png."
#: filetypedetails.cpp:166
#, kde-format
msgid "&General"
msgstr "Algemeen"
#: filetypedetails.cpp:167
#, kde-format
msgid "&Embedding"
msgstr "Inbed"
#: filetypedetails.cpp:208
#, kde-format
msgid "Add New Extension"
msgstr "Voeg by Nuwe Uitbreiding"
#: filetypedetails.cpp:208
#, kde-format
msgid "Extension:"
msgstr "Uitbreiding:"
#: filetypedetails.cpp:326
#, fuzzy, kde-format
#| msgid "Edit File Type %1"
msgid "File type %1"
msgstr "Redigeer Lêer Tipe: %1"
#: filetypedetails.cpp:334
#, kde-format
msgid "Use settings for '%1' group"
msgstr "Gebruik instellings vir '%1' groep"
#: filetypesview.cpp:43
#, fuzzy, kde-format
#| msgid ""
#| "<h1>File Associations</h1> This module allows you to choose which "
#| "applications are associated with a given type of file. File types are "
#| "also referred to MIME types (MIME is an acronym which stands for "
#| "\"Multipurpose Internet Mail Extensions\".)<p> A file association "
#| "consists of the following: <ul><li>Rules for determining the MIME-type of "
#| "a file, for example the filename pattern *.kwd, which means 'all files "
#| "with names that end in .kwd', is associated with the MIME type \"x-kword"
#| "\";</li> <li>A short description of the MIME-type, for example the "
#| "description of the MIME type \"x-kword\" is simply 'KWord document';</li> "
#| "<li>An icon to be used for displaying files of the given MIME-type, so "
#| "that you can easily identify the type of file in, say, a Konqueror view "
#| "(at least for the types you use often);</li> <li>A list of the "
#| "applications which can be used to open files of the given MIME-type -- if "
#| "more than one application can be used then the list is ordered by "
#| "priority.</li></ul> You may be surprised to find that some MIME types "
#| "have no associated filename patterns; in these cases, Konqueror is able "
#| "to determine the MIME-type by directly examining the contents of the file."
msgid ""
"<p><h1>File Associations</h1> This module allows you to choose which "
"applications are associated with a given type of file. File types are also "
"referred to as MIME types (MIME is an acronym which stands for "
"\"Multipurpose Internet Mail Extensions\").</p><p> A file association "
"consists of the following: <ul><li>Rules for determining the MIME-type of a "
"file, for example the filename pattern *.png, which means 'all files with "
"names that end in .png', is associated with the MIME type \"image/png\";</"
"li> <li>A short description of the MIME-type, for example the description of "
"the MIME type \"image/png\" is simply 'PNG image';</li> <li>An icon to be "
"used for displaying files of the given MIME-type, so that you can easily "
"identify the type of file in a file manager or file-selection dialog (at "
"least for the types you use often);</li> <li>A list of the applications "
"which can be used to open files of the given MIME-type -- if more than one "
"application can be used then the list is ordered by priority.</li></ul> You "
"may be surprised to find that some MIME types have no associated filename "
"patterns; in these cases, KDE is able to determine the MIME-type by directly "
"examining the contents of the file.</p>"
msgstr ""
"<h1>Lêer Assosiasies</h1> Hierdie module laat jou toe om programme met lêer "
"tipes te assosieer. Daar word ook na lêer tipes verwys as MIME tipes. MIME "
"is 'n akroniem vir \"Multipurpose Internet Mail Extensions\". <p>'n Lêer "
"assosiasie bestaan uit die volgende items:<ul><li>Reëls om te bepaal wat die "
"MIME-tipe van 'n lêer is, bv. die patroon '*.kwd', wat beteken: 'alle lêers "
"wat eindig met .kwd is geassosieer met die MIME-tipe \"x-kword\"</li><li>'n "
"Kort beskrywing oor die MIME-tipe, bv. 'K Word dokument' vir \"x-kword"
"\"<li>'n Ikoon vir die MIME-tipe, sodat die tipe lêer maklik geidentifiseer "
"kan word in Konqueror</li><li>'n Lys van programme wat hierdie MIME-tipe kan "
"oopmaak. Die lys is volgens prioriteit gesorteer.</li></ul>Party programme "
"het geen MIME-tipe met hulle geassosieer nie. In so 'n geval sal Konquerer "
"probeer om die MIME-tipe te raai deur die inhoud van die lêer te ondersoek."
#: filetypesview.cpp:73
#, fuzzy, kde-format
#| msgid "F&ind filename pattern:"
msgid "Search for file type or filename pattern..."
msgstr "Soek lêernaam patroon:"
#: filetypesview.cpp:79
#, fuzzy, kde-format
#| msgid ""
#| "Enter a part of a filename pattern. Only file types with a matching file "
#| "pattern will appear in the list."
msgid ""
"Enter a part of a filename pattern, and only file types with a matching file "
"pattern will appear in the list. Alternatively, enter a part of a file type "
"name as it appears in the list."
msgstr ""
"Invoer 'n deel van 'n lêernaam patroon in. Slegs lêer tipes met 'n "
"ooreenstemmende lêer patroon sal in die lys verskyn."
#: filetypesview.cpp:87
#, kde-format
msgid "Known Types"
msgstr "Bekend Tipes"
#: filetypesview.cpp:93
#, kde-format
msgid ""
"Here you can see a hierarchical list of the file types which are known on "
"your system. Click on the '+' sign to expand a category, or the '-' sign to "
"collapse it. Select a file type (e.g. text/html for HTML files) to view/edit "
"the information for that file type using the controls on the right."
msgstr ""
"Hier jy kan sien 'n hiërargiese lys van die lêer tipes wat word bekend op "
"jou stelsel. Kliek op die '+' teken na vergroot 'n kategorie, of die '-' "
"teken na toevou dit. Kies 'n lêer tipe (e.g. teks/Html vir Html lêers) na "
"besigtig/redigeer die informasie vir wat lêer tipe te gebruik die kontroles "
"op die regterkant."
#: filetypesview.cpp:107
#, kde-format
msgid "Click here to add a new file type."
msgstr "Kliek hier na voeg by 'n nuwe lêer tipe."
#: filetypesview.cpp:109 filetypesview.cpp:375
#, kde-format
msgid "&Remove"
msgstr ""
#: filetypesview.cpp:133
#, kde-format
msgid "Select a file type by name or by extension"
msgstr "Kies 'n lêer tipe deur naam of deur uitbreiding"
#: filetypesview.cpp:368
#, kde-format
msgid "&Revert"
msgstr ""
#: filetypesview.cpp:369
#, kde-format
msgid "Revert this file type to its initial system-wide definition"
msgstr ""
#: filetypesview.cpp:371
#, kde-format
msgid ""
"Click here to revert this file type to its initial system-wide definition, "
"which undoes any changes made to the file type. Note that system-wide file "
"types cannot be deleted. You can however empty their pattern list, to "
"minimize the chances of them being used (but the file type determination "
"from file contents can still end up using them)."
msgstr ""
#: filetypesview.cpp:376
#, kde-format
msgid "Delete this file type definition completely"
msgstr ""
#: filetypesview.cpp:378
#, kde-format
msgid ""
"Click here to delete this file type definition completely. This is only "
"possible for user-defined file types. System-wide file types cannot be "
"deleted. You can however empty their pattern list, to minimize the chances "
"of them being used (but the file type determination from file contents can "
"still end up using them)."
msgstr ""
#: keditfiletype.cpp:122
#, fuzzy, kde-format
#| msgid "Edit File Type %1"
msgid "File Type Editor"
msgstr "Redigeer Lêer Tipe: %1"
#: keditfiletype.cpp:124
#, kde-format
msgid ""
"KDE file type editor - simplified version for editing a single file type"
msgstr ""
"KDE lêer tipe redigeerder - vereenvoudigde weergawe om 'n enkel lêer tipe te "
"redigeer"
#: keditfiletype.cpp:126
#, kde-format
msgid "(c) 2000, KDE developers"
msgstr "(c) 2000, KDE ontwikkelaars"
#: keditfiletype.cpp:127
#, kde-format
msgid "Preston Brown"
msgstr ""
#: keditfiletype.cpp:128
#, kde-format
msgid "David Faure"
msgstr ""
#: keditfiletype.cpp:134
#, kde-format
msgid "Makes the dialog transient for the window specified by winid"
msgstr "Maak dit 'n oorgang dialoog vir die venster gespesifiseer deur WinID"
#: keditfiletype.cpp:136
#, kde-format
msgid "File type to edit (e.g. text/html)"
msgstr "Lêer tipe om te redigeer (bv. teks/html)"
#: keditfiletype.cpp:167
#, kde-format
msgid "%1 File"
msgstr "%1 Lêer"
#: keditfiletype.cpp:194
#, kde-format
msgid "Edit File Type %1"
msgstr "Redigeer Lêer Tipe: %1"
#: keditfiletype.cpp:196
#, kde-format
msgid "Create New File Type %1"
msgstr "Skep Nuwe Lêer Tipe: %1"
#: kservicelistwidget.cpp:37
#, kde-format
msgid "%1 (%2)"
msgstr "%1 (%2)"
#: kservicelistwidget.cpp:50
#, kde-format
msgid "Application Preference Order"
msgstr "Aansoek Voorkeur Volgorde"
#: kservicelistwidget.cpp:50
#, kde-format
msgid "Services Preference Order"
msgstr "Dienste Voorkeur Volgorde"
#: kservicelistwidget.cpp:61
#, kde-format
msgid ""
"This is a list of applications associated with files of the selected file "
"type. This list is shown in Konqueror's context menus when you select \"Open "
"With...\". If more than one application is associated with this file type, "
"then the list is ordered by priority with the uppermost item taking "
"precedence over the others."
msgstr ""
"Hierdie is 'n lys van programme wat met die lêes van die gekose tipe "
"geassosieer is. Hierdie lys sal in Konqueror se konteks kieslyste vertoon "
"word wanneer jy \"Maak oop met...\"kies. As daar meer as een program met 'n "
"lêer tipe geassosieer is, sal die programme se prioriteit van bo na onder in "
"die lys bepaal word."
#: kservicelistwidget.cpp:66
#, fuzzy, kde-format
#| msgid ""
#| "This is a list of services associated with files of the selected file "
#| "type. This list is shown in Konqueror's context menus when you select a "
#| "\"Preview with...\" option. If more than one application is associated "
#| "with this file type, then the list is ordered by priority with the "
#| "uppermost item taking precedence over the others."
msgid ""
"This is a list of services associated with files of the selected file type. "
"This list is shown in Konqueror's context menus when you select a \"Preview "
"with...\" option. If more than one service is associated with this file "
"type, then the list is ordered by priority with the uppermost item taking "
"precedence over the others."
msgstr ""
"Hierdie is 'n lys van dienste wat met die lêes van die gekose tipe "
"geassosieer is. Hierdie lys sal in Konqueror se konteks kieslyste vertoon "
"word wanneer jy \"Voorskou met...\"kies. As daar meer as een program met 'n "
"lêer tipe geassosieer is, sal die programme se prioriteit van bo na onder in "
"die lys bepaal word."
#: kservicelistwidget.cpp:78
#, kde-format
msgid "Move &Up"
msgstr "Beweeg Begin"
#: kservicelistwidget.cpp:84
#, kde-format
msgid ""
"Assigns a higher priority to the selected\n"
"application, moving it up in the list. Note: This\n"
"only affects the selected application if the file type is\n"
"associated with more than one application."
msgstr ""
"Ken toe 'n hoër prioriteit na die gekose\n"
"aansoek, beweeg dit begin in die lys. Nota: Hierdie\n"
"slegs affekteer die gekose aansoek as die lêer tipe is\n"
"geassosieer met meer as een aansoek."
#: kservicelistwidget.cpp:88
#, kde-format
msgid ""
"Assigns a higher priority to the selected\n"
"service, moving it up in the list."
msgstr ""
"Ken toe 'n hoër prioriteit na die gekose\n"
"diens, beweeg dit begin in die lys."
#: kservicelistwidget.cpp:91
#, kde-format
msgid "Move &Down"
msgstr "Beweeg Ondertoe"
#: kservicelistwidget.cpp:96
#, kde-format
msgid ""
"Assigns a lower priority to the selected\n"
"application, moving it down in the list. Note: This \n"
"only affects the selected application if the file type is\n"
"associated with more than one application."
msgstr ""
"Ken toe 'n sagter prioriteit na die gekose\n"
"aansoek, beweeg dit ondertoe in die lys. Nota: Hierdie \n"
"slegs affekteer die gekose aansoek as die lêer tipe is\n"
"geassosieer met meer as een aansoek."
#: kservicelistwidget.cpp:100
#, kde-format
msgid ""
"Assigns a lower priority to the selected\n"
"service, moving it down in the list."
msgstr ""
"Ken toe 'n sagter prioriteit na die gekose\n"
"diens, beweeg dit ondertoe in die lys."
#: kservicelistwidget.cpp:108
#, kde-format
msgid "Add a new application for this file type."
msgstr "Voeg by 'n nuwe aansoek vir hierdie lêer tipe."
#: kservicelistwidget.cpp:110
#, kde-format
msgid "Edit..."
msgstr "Redigeer..."
#: kservicelistwidget.cpp:115
#, kde-format
msgid "Edit command line of the selected application."
msgstr "Redigeer opdrag lyn van die gekose aansoek."
#: kservicelistwidget.cpp:122
#, kde-format
msgid "Remove the selected application from the list."
msgstr "Verwyder die gekose aansoek van die lys."
#: kservicelistwidget.cpp:145
#, fuzzy, kde-format
#| msgid "None"
msgctxt "No applications associated with this file type"
msgid "None"
msgstr "Geen"
#: kservicelistwidget.cpp:147
#, fuzzy, kde-format
#| msgid "None"
msgctxt "No components associated with this file type"
msgid "None"
msgstr "Geen"
#: kserviceselectdlg.cpp:21
#, kde-format
msgid "Add Service"
msgstr "Voeg diens by"
#: kserviceselectdlg.cpp:25
#, kde-format
msgid "Select service:"
msgstr "Kies die diens:"
#: newtypedlg.cpp:28
#, kde-format
msgid "Create New File Type"
msgstr "Skep Nuwe Lêer Tipe"
#: newtypedlg.cpp:33
#, kde-format
msgid "Group:"
msgstr "Groep:"
#: newtypedlg.cpp:42
#, kde-format
msgid "Select the category under which the new file type should be added."
msgstr "Kies die kategorie onder wat die nuwe lêer tipe moet wees bygevoeg."
#: newtypedlg.cpp:47
#, kde-format
msgid "Type name:"
msgstr "Tipe naam:"
#: newtypedlg.cpp:53
#, kde-format
msgid ""
"Type the name of the file type. For instance, if you selected 'image' as "
"category and you type 'custom' here, the file type 'image/custom' will be "
"created."
msgstr ""

134
po/af/kcmshell5.po Normal file
View File

@ -0,0 +1,134 @@
# UTF-8 test:äëïöü
msgid ""
msgstr ""
"Project-Id-Version: kcmshell stable\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-01-18 02:09+0000\n"
"PO-Revision-Date: 2005-04-18 16:33+0200\n"
"Last-Translator: Frikkie Thirion <frix@expertron.co.za>\n"
"Language-Team: AFRIKAANS <translate-discuss-af@lists.sourceforge.net>\n"
"Language: af\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Frikkie Thirion"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "frix@expertron.co.za"
#: main.cpp:182
#, kde-format
msgid "System Settings Module"
msgstr ""
#: main.cpp:184
#, fuzzy, kde-format
#| msgid "A tool to start single KDE control modules"
msgid "A tool to start single system settings modules"
msgstr "'n Nuts program om enkel KDE beheer modules mee te begin"
#: main.cpp:186
#, fuzzy, kde-format
#| msgid "(c) 1999-2004, The KDE Developers"
msgid "(c) 1999-2016, The KDE Developers"
msgstr "(c) 1999-2004, The KDE Developers"
#: main.cpp:188
#, kde-format
msgid "Frans Englich"
msgstr ""
#: main.cpp:188
#, kde-format
msgid "Maintainer"
msgstr "Onderhouer"
#: main.cpp:189
#, kde-format
msgid "Daniel Molkentin"
msgstr ""
#: main.cpp:190
#, kde-format
msgid "Matthias Hoelzer-Kluepfel"
msgstr ""
#: main.cpp:191
#, kde-format
msgid "Matthias Elter"
msgstr ""
#: main.cpp:192
#, kde-format
msgid "Matthias Ettrich"
msgstr ""
#: main.cpp:193
#, kde-format
msgid "Waldo Bastian"
msgstr ""
#: main.cpp:199
#, kde-format
msgid "List all possible modules"
msgstr "Lys van alle moontlike modules"
#: main.cpp:200
#, kde-format
msgid "Configuration module to open"
msgstr "Opstel module om oop te maak"
#: main.cpp:201
#, kde-format
msgid "Specify a particular language"
msgstr "Spesifiseer 'n taal"
#: main.cpp:202
#, kde-format
msgid "Do not display main window"
msgstr "Moet nie die hoof venster vertoon nie"
#: main.cpp:203
#, kde-format
msgid "Arguments for the module"
msgstr ""
#: main.cpp:204
#, kde-format
msgid "Use a specific icon for the window"
msgstr ""
#: main.cpp:205
#, kde-format
msgid "Use a specific caption for the window"
msgstr ""
#: main.cpp:214
#, kde-format
msgid ""
"--lang is deprecated. Please set the LANGUAGE environment variable instead"
msgstr ""
#: main.cpp:218
#, kde-format
msgid "The following modules are available:"
msgstr "Die volgende modules is beskikbaar:"
#: main.cpp:237
#, kde-format
msgid "No description available"
msgstr "Geen beskywing beskikbaar"
#: main.cpp:296
#, kde-format
msgid ""
"Could not find module '%1'. See kcmshell5 --list for the full list of "
"modules."
msgstr ""

262
po/af/kdesu5.po Normal file
View File

@ -0,0 +1,262 @@
# UTF-8 test:äëïöü
# Copyright (C) 2001 Free Software Foundation, Inc.
# Frikkie Thirion <frix@expertron.co.za>, 2001,2002.
# Juanita Franz <juanita.franz@vr-web.de>, 2005.
msgid ""
msgstr ""
"Project-Id-Version: kdesu stable\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2021-08-06 00:18+0000\n"
"PO-Revision-Date: 2005-06-15 11:29+0200\n"
"Last-Translator: JUANITA FRANZ <JUANITA.FRANZ@VR-WEB.DE>\n"
"Language-Team: AFRIKAANS <translate-discuss-af@lists.sourceforge.net>\n"
"Language: af\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Frikkie Thirion, Juanita Franz"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "frix@expertron.co.za, juanita.franz@vr-web.de"
#: kdesu.cpp:105
#, kde-format
msgid "KDE su"
msgstr "Kde su"
#: kdesu.cpp:107
#, kde-format
msgid "Runs a program with elevated privileges."
msgstr "Loop 'n program met verhoogde voorregte."
#: kdesu.cpp:109
#, kde-format
msgid "Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"
msgstr ""
#: kdesu.cpp:110
#, kde-format
msgid "Geert Jansen"
msgstr ""
#: kdesu.cpp:110
#, kde-format
msgid "Maintainer"
msgstr "Onderhouer"
#: kdesu.cpp:111
#, kde-format
msgid "Pietro Iglio"
msgstr ""
#: kdesu.cpp:111
#, kde-format
msgid "Original author"
msgstr "Oorspronklike outeur"
#: kdesu.cpp:120
#, fuzzy, kde-format
#| msgid "Specifies the command to run"
msgid "Specifies the command to run as separate arguments"
msgstr "Spesifiseer die opdrag om te hardloop"
#: kdesu.cpp:121
#, fuzzy, kde-format
#| msgid "Specifies the command to run"
msgid "Specifies the command to run as one string"
msgstr "Spesifiseer die opdrag om te hardloop"
#: kdesu.cpp:122
#, kde-format
msgid "Run command under target uid if <file> is not writable"
msgstr "Hardloop opdrag onder teiken uid as <file> nie skryfbaar is nie"
#: kdesu.cpp:123
#, kde-format
msgid "Specifies the target uid"
msgstr "Spesifiseer die teiken uid"
#: kdesu.cpp:124
#, kde-format
msgid "Do not keep password"
msgstr "Hou nie wagwoord nie"
#: kdesu.cpp:125
#, kde-format
msgid "Stop the daemon (forgets all passwords)"
msgstr "Stop die bediener (vergeet alle wagwoorde)"
#: kdesu.cpp:126
#, kde-format
msgid "Enable terminal output (no password keeping)"
msgstr "Aktiveer terminaal uitset (geen wagwoord gehou)"
#: kdesu.cpp:128
#, kde-format
msgid "Set priority value: 0 <= prio <= 100, 0 is lowest"
msgstr "Stel prioriteit waarde: 0 <= prioriteit <= 100, 0 is laagste"
#: kdesu.cpp:129
#, kde-format
msgid "Use realtime scheduling"
msgstr "Gebruik intydse skedulering"
#: kdesu.cpp:130
#, kde-format
msgid "Do not display ignore button"
msgstr ""
#: kdesu.cpp:131
#, kde-format
msgid "Specify icon to use in the password dialog"
msgstr "Spesifiseer ikoon wat in die wagwoord dialoog gebruik moet word"
#: kdesu.cpp:132
#, kde-format
msgid "Do not show the command to be run in the dialog"
msgstr "Moenie die opdrag vertoon wat in die dialoog geloop moet word nie"
#: kdesu.cpp:139
#, kde-format
msgctxt ""
"Transient means that the kdesu app will be attached to the app specified by "
"the winid so that it is like a dialog box rather than some separate program"
msgid "Makes the dialog transient for an X app specified by winid"
msgstr ""
#: kdesu.cpp:141
#, kde-format
msgid "Embed into a window"
msgstr ""
#: kdesu.cpp:168
#, kde-format
msgid "Cannot execute command '%1'."
msgstr ""
#: kdesu.cpp:171
#, kde-format
msgid "Cannot execute command '%1'. It contains invalid characters."
msgstr ""
#: kdesu.cpp:245
#, kde-format
msgid "Illegal priority: %1"
msgstr "Onwettige prioriteit: %1"
#: kdesu.cpp:266
#, kde-format
msgid "No command specified."
msgstr "Geen opdrag gespesifiseer"
#: kdesu.cpp:372
#, kde-format
msgid "Su returned with an error.\n"
msgstr "Su teruggestuur met 'n fout.\n"
#: kdesu.cpp:400
#, kde-format
msgid "Command:"
msgstr "Opdrag:"
#: kdesu.cpp:409
#, kde-format
msgid "realtime: "
msgstr "intydse: "
#: kdesu.cpp:413
#, kde-format
msgid "Priority:"
msgstr "Prioriteit:"
#: sudlg.cpp:27
#, kde-format
msgid "Run as %1"
msgstr "Hardloop as %1"
#: sudlg.cpp:31
#, kde-format
msgid "Please enter your password below."
msgstr ""
#: sudlg.cpp:36
#, fuzzy, kde-format
msgid ""
"The action you requested needs <b>root privileges</b>. Please enter "
"<b>root's</b> password below or click Ignore to continue with your current "
"privileges."
msgstr ""
"Die aksie wat u versoek het, verlang root voorregte nodig. Voer asseblief "
"die root wagwoord in hieronder of kliek op Ignoreer om voort te gaan met u "
"huidige regte."
#: sudlg.cpp:42
#, fuzzy, kde-format
msgid ""
"The action you requested needs <b>root privileges</b>. Please enter "
"<b>root's</b> password below."
msgstr ""
"Die aksie wat u versoek het, verlang root voorregte nodig. Voer asseblief "
"die root wagwoord in hieronder of kliek op Ignoreer om voort te gaan met u "
"huidige regte."
#: sudlg.cpp:49
#, fuzzy, kde-format
msgid ""
"The action you requested needs additional privileges. Please enter the "
"password for <b>%1</b> below or click Ignore to continue with your current "
"privileges."
msgstr ""
"Die aksie wat u versoek het, verlang aditionele voorregte. Voer asseblief "
"die root wagwoord in vir \"%1\" onder of kliek Ignoreer om voort te gaan met "
"u huidige voorregte."
#: sudlg.cpp:56
#, fuzzy, kde-format
msgid ""
"The action you requested needs additional privileges. Please enter the "
"password for <b>%1</b> below."
msgstr ""
"Die aksie wat u versoek het, verlang aditionele voorregte. Voer asseblief "
"die root wagwoord in vir \"%1\" onder of kliek Ignoreer om voort te gaan met "
"u huidige voorregte."
#: sudlg.cpp:79
#, kde-format
msgid "Conversation with su failed."
msgstr "Gesprek met su het gevaal."
#: sudlg.cpp:86
#, fuzzy, kde-format
msgid ""
"The program 'su' could not be found.<br />Ensure your PATH is set correctly."
msgstr ""
"Die program 'su' is nie gevind nie;\n"
"Maak seker u Path korrek ingestel is."
#: sudlg.cpp:97
#, fuzzy, kde-format
#| msgid ""
#| "You are not allowed to use 'su';\n"
#| "on some systems, you need to be in a special group (often: wheel) to use "
#| "this program."
msgid ""
"Permission denied.<br />Possibly incorrect password, please try again.<br /"
">On some systems, you need to be in a special group (often: wheel) to use "
"this program."
msgstr ""
"U word nie toegelaat om te gebruik 'su';\n"
"op sommige sisteme, u benodig om in 'n spesiaal groep te wees (gereeld: "
"wiel) om hierdie program te gebruik."
#: sudlg.cpp:105
#, kde-format
msgid "Internal error: illegal return from SuProcess::checkInstall()"
msgstr "Interne fout: Onwettige terugkeer van Su-proses::Checkinstall()"

201
po/af/kstart5.po Normal file
View File

@ -0,0 +1,201 @@
# UTF-8 test:äëïöü
# Copyright (C) 2001 Free Software Foundation, Inc.
# Frikkie Thirion <frix@expertron.co.za>, 2001,2002.
# Juanita Franz <juanita.franz@vr-web.de>, 2005.
# Kobus Venter <kabousv@therugby.co.za>, 2005.
#
msgid ""
msgstr ""
"Project-Id-Version: kstart stable\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2021-08-06 00:18+0000\n"
"PO-Revision-Date: 2005-09-13 15:33+0200\n"
"Last-Translator: Kobus Venter <kabousv@therugby.co.za>\n"
"Language-Team: AFRIKAANS <translate-discuss-af@lists.sourceforge.net>\n"
"Language: af\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Frikkie Thirion, Juanita Franz, Kobus Venter"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "frix@expertron.co.za, juanita.franz@vr-web.de, kabousv@therugby.co.za"
#: kstart.cpp:312
#, kde-format
msgid "KStart"
msgstr "Kstart"
#: kstart.cpp:314
#, kde-format
msgid ""
"Utility to launch applications with special window properties \n"
"such as iconified, maximized, a certain virtual desktop, a special "
"decoration\n"
"and so on."
msgstr ""
"Program na lanseer programme met spesiaal venster eienskappe \n"
"soos as geïkonifiseer, maksimeerd, 'n sekere virtuele werkskerm, 'n spesiaal "
"versiering\n"
"en sodat op."
#: kstart.cpp:319
#, kde-format
msgid "(C) 1997-2000 Matthias Ettrich (ettrich@kde.org)"
msgstr ""
#: kstart.cpp:321
#, kde-format
msgid "Matthias Ettrich"
msgstr ""
#: kstart.cpp:322
#, kde-format
msgid "David Faure"
msgstr ""
#: kstart.cpp:323
#, kde-format
msgid "Richard J. Moore"
msgstr ""
#: kstart.cpp:328
#, kde-format
msgid "Command to execute"
msgstr "Opdrag om uit te voer"
#: kstart.cpp:332
#, kde-format
msgid ""
"Alternative to <command>: desktop file path to start. D-Bus service will be "
"printed to stdout. Deprecated: use --application"
msgstr ""
#: kstart.cpp:335
#, kde-format
msgid "Alternative to <command>: desktop file to start."
msgstr ""
#: kstart.cpp:338
#, kde-format
msgid "Optional URL to pass <desktopfile>, when using --service"
msgstr ""
#: kstart.cpp:341
#, kde-format
msgid "A regular expression matching the window title"
msgstr "'n Gewone uitdrukking passend tot die venster titel"
#: kstart.cpp:343
#, kde-format
msgid ""
"A string matching the window class (WM_CLASS property)\n"
"The window class can be found out by running\n"
"'xprop | grep WM_CLASS' and clicking on a window\n"
"(use either both parts separated by a space or only the right part).\n"
"NOTE: If you specify neither window title nor window class,\n"
"then the very first window to appear will be taken;\n"
"omitting both options is NOT recommended."
msgstr ""
"'n String passend tot die venster klas (WM_KLAS Waarskynlik)\n"
"Die venster klas kan uitgevind word deur loop\n"
"'xprop | grep WM_KLAS' en kliek op 'n venster\n"
"(gebruik of beide dele geskei deur 'n spasie of slegs die regter deel).\n"
"NOTEER: As jy spesifiseer nie die venster titel en ook nie die venster "
"klas,\n"
"dan sal die heel eerste venster wat verskyn geneem word;\n"
"weglating van beide opsies word nie aanbeveel nie."
#: kstart.cpp:352
#, kde-format
msgid "Desktop on which to make the window appear"
msgstr "Werkskerm waarop die venster gemaak verskyn word"
#: kstart.cpp:354
#, kde-format
msgid ""
"Make the window appear on the desktop that was active\n"
"when starting the application"
msgstr ""
"Maak die venster verskyn op die werkskerm wat was aktief\n"
"wanneer begin die aansoek"
#: kstart.cpp:355
#, kde-format
msgid "Make the window appear on all desktops"
msgstr "Maak die venster verskyn op alle werkskerms"
#: kstart.cpp:356
#, kde-format
msgid "Iconify the window"
msgstr "Ikoonifiseer die venster"
#: kstart.cpp:357
#, kde-format
msgid "Maximize the window"
msgstr "Maksimeer die venster"
#: kstart.cpp:358
#, kde-format
msgid "Maximize the window vertically"
msgstr "Maksimeer die venster vertikaal"
#: kstart.cpp:359
#, kde-format
msgid "Maximize the window horizontally"
msgstr "Maksimeer die venster horisontaal"
#: kstart.cpp:360
#, kde-format
msgid "Show window fullscreen"
msgstr "Vertoon venster volskerm"
#: kstart.cpp:362
#, fuzzy, kde-format
msgid ""
"The window type: Normal, Desktop, Dock, Toolbar, \n"
"Menu, Dialog, TopMenu or Override"
msgstr ""
"Die venster tipe: Normaal, Werkskerm, Koppel, Gereedskap, \n"
"Kieslys, Dialoog, BoonsteKieslys of Oorskryf"
#: kstart.cpp:365
#, kde-format
msgid ""
"Jump to the window even if it is started on a \n"
"different virtual desktop"
msgstr ""
"Spring na die venster al as dit is beginne op 'n \n"
"ander virtuele werkskerm"
#: kstart.cpp:368
#, kde-format
msgid "Try to keep the window above other windows"
msgstr "Probeer om die venster altyd bo ander vensters te hou"
#: kstart.cpp:370
#, kde-format
msgid "Try to keep the window below other windows"
msgstr "Probeer om die venster altyd onder ander venster te hou"
#: kstart.cpp:371
#, kde-format
msgid "The window does not get an entry in the taskbar"
msgstr "Die venster doen nie kry 'n inskrywing in Die kasbar"
#: kstart.cpp:372
#, kde-format
msgid "The window does not get an entry on the pager"
msgstr "Die venster doen nie kry 'n inskrywing op Die boodskapper"
#: kstart.cpp:386
#, kde-format
msgid "No command specified"
msgstr "Nee opdrag gespesifiseer"

527
po/ar/kcm5_filetypes.po Normal file
View File

@ -0,0 +1,527 @@
# translation of filetypes.po to Arabic
# translation of filetypes.po to
# محمد سعد Mohamed SAAD <metehyi@free.fr>, 2006.
# AbdulAziz AlSharif <a.a-a.s@hotmail.com>, 2007.
# Youssef Chahibi <chahibi@gmail.com>, 2007.
# محمد الحرقان <imksa@hotmail.com>, 2008.
# Anas Husseini <linux.anas@gmail.com>, 2008.
# zayed <zayed.alsaidi@gmail.com>, 2008.
# Abdalrahim Fakhouri <abdilra7eem@yahoo.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: filetypes\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2021-08-06 00:18+0000\n"
"PO-Revision-Date: 2012-02-09 14:36+0200\n"
"Last-Translator: Abdalrahim Fakhouri <abdilra7eem@yahoo.com>\n"
"Language-Team: Arabic <linuxac-kde-arabic-team@googlegroups.com>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"X-Generator: Translate Toolkit 1.10.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr " يوسف الشهيبي, أنس الحسيني , زايد السعيدي"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "chahibi@gmail.com, linux.anas@gmail.com,zayed.alsaidi@gmail.com"
#: filegroupdetails.cpp:22
#, kde-format
msgid "Left Click Action (only for Konqueror file manager)"
msgstr "حدث النقر بالزرّ الأيسر للفأرة (فقط لمدير الملفات)"
#: filegroupdetails.cpp:26 filetypedetails.cpp:134
#, kde-format
msgid "Show file in embedded viewer"
msgstr "أظهر الملف في عارض مضمن"
#: filegroupdetails.cpp:27 filetypedetails.cpp:135
#, kde-format
msgid "Show file in separate viewer"
msgstr "أظهر الملف في عارض منفصل"
#: filegroupdetails.cpp:36
#, fuzzy, kde-format
msgid ""
"Here you can configure what the Konqueror file manager will do when you "
"click on a file belonging to this group. Konqueror can display the file in "
"an embedded viewer or start up a separate application. You can change this "
"setting for a specific file type in the 'Embedding' tab of the file type "
"configuration. Dolphin shows files always in a separate viewer"
msgstr ""
"هنا يمكنك ضبط ما الذي يجب على مدير الملفات كونكيورر فعله عند النقر على ملف "
"يخص هذه المجموعة. كونكيورر يستطيع عرض الملف في عارض مضمّن أو بدء تشغيل تطبيق "
"منفصل. يمكنك تغيير هذه الإعدادات لنوع ملف محدّد في لسان 'مضمن' من تشكيل نوع "
"الملفات."
#: filetypedetails.cpp:62
#, kde-format
msgid ""
"This button displays the icon associated with the selected file type. Click "
"on it to choose a different icon."
msgstr ""
"هذا الزر يعرض الأيقونة المرتبطة بنوع الملف الذي اخترته. اضغط عليه لاختيار "
"أيقونة مختلفة."
#: filetypedetails.cpp:68
#, kde-format
msgid "Filename Patterns"
msgstr "أنماط أسماء الملفات"
#: filetypedetails.cpp:80
#, kde-format
msgid ""
"This box contains a list of patterns that can be used to identify files of "
"the selected type. For example, the pattern *.txt is associated with the "
"file type 'text/plain'; all files ending in '.txt' are recognized as plain "
"text files."
msgstr ""
"هذا مربّع يحتوي على قائمة نماذج يمكن استعمالها للتعرف على ملفات من نوع ما. "
"مثلا، النموذج *.txt مرتبط بنوع الملفات النصية ؛ تعتبر كل الملفات المنتهية بـ "
"'.txt' بأنها ملفات نصية."
#: filetypedetails.cpp:88 filetypesview.cpp:102 kservicelistwidget.cpp:103
#, kde-format
msgid "Add..."
msgstr "أضف..."
#: filetypedetails.cpp:93
#, kde-format
msgid "Add a new pattern for the selected file type."
msgstr "أضف نمط جديد لنوع الملف المختار."
#: filetypedetails.cpp:95 kservicelistwidget.cpp:117
#, kde-format
msgid "Remove"
msgstr "أزل"
#: filetypedetails.cpp:100
#, kde-format
msgid "Remove the selected filename pattern."
msgstr "أزل نمط اسم الملف المختار"
#: filetypedetails.cpp:111
#, kde-format
msgid "Description:"
msgstr "الوصف:"
#: filetypedetails.cpp:116
#, kde-format
msgid ""
"You can enter a short description for files of the selected file type (e.g. "
"'HTML Page'). This description will be used by applications like Konqueror "
"to display directory content."
msgstr ""
"يمكنك إدخال وصف قصير للملفات لنوع الملف المختار (مثلاً 'HTML صفحة'). هذا "
"الوصف سوف يستخدم عن طريق تطبيقات مثل كونكيورر لعرض محتوى الدليل."
#: filetypedetails.cpp:129
#, kde-format
msgid "Left Click Action in Konqueror"
msgstr "حدث النقر بزر الفأرة الأيسر في مدير الملفات"
#: filetypedetails.cpp:138
#, kde-format
msgid "Ask whether to save to disk instead (only for Konqueror browser)"
msgstr "اسأل عن إمكانية الحفظ إلى القرص بدلاً من ذلك (لمدير الملفات فقط)"
#: filetypedetails.cpp:154
#, fuzzy, kde-format
msgid ""
"Here you can configure what the Konqueror file manager will do when you "
"click on a file of this type. Konqueror can either display the file in an "
"embedded viewer, or start up a separate application. If set to 'Use settings "
"for G group', the file manager will behave according to the settings of the "
"group G to which this type belongs; for instance, 'image' if the current "
"file type is image/png. Dolphin always shows files in a separate viewer."
msgstr ""
"هنا يمكنك إعداد ماذا سيفعل مدير الملفات كونكيرور عندما تنقر على ملف من هذا "
"النوع. يمكن لكونكيرور أن يعرض الملف في عارض مضمّن أو يبدأه في تطبيق مستقل. إن "
"أعددته على 'استخدم إعدادات المجموعة G'، فسيتصرف كونكيرور وفقاً لإعدادات "
"المجموعة G التي ينتمي هذا النوع إليها. كمثال، ستكون المجموعة هي 'صورة' إن "
"كان نوع الملف الحالي هو صورة/png."
#: filetypedetails.cpp:166
#, kde-format
msgid "&General"
msgstr "&عام"
#: filetypedetails.cpp:167
#, kde-format
msgid "&Embedding"
msgstr "&تضمين"
#: filetypedetails.cpp:208
#, kde-format
msgid "Add New Extension"
msgstr "أضف امتداد جديد"
#: filetypedetails.cpp:208
#, kde-format
msgid "Extension:"
msgstr "الامتداد:"
#: filetypedetails.cpp:326
#, kde-format
msgid "File type %1"
msgstr "نوع الملف %1"
#: filetypedetails.cpp:334
#, kde-format
msgid "Use settings for '%1' group"
msgstr "استخدم الإعدادات للمجموعة '%1'"
#: filetypesview.cpp:43
#, kde-format
msgid ""
"<p><h1>File Associations</h1> This module allows you to choose which "
"applications are associated with a given type of file. File types are also "
"referred to as MIME types (MIME is an acronym which stands for "
"\"Multipurpose Internet Mail Extensions\").</p><p> A file association "
"consists of the following: <ul><li>Rules for determining the MIME-type of a "
"file, for example the filename pattern *.png, which means 'all files with "
"names that end in .png', is associated with the MIME type \"image/png\";</"
"li> <li>A short description of the MIME-type, for example the description of "
"the MIME type \"image/png\" is simply 'PNG image';</li> <li>An icon to be "
"used for displaying files of the given MIME-type, so that you can easily "
"identify the type of file in a file manager or file-selection dialog (at "
"least for the types you use often);</li> <li>A list of the applications "
"which can be used to open files of the given MIME-type -- if more than one "
"application can be used then the list is ordered by priority.</li></ul> You "
"may be surprised to find that some MIME types have no associated filename "
"patterns; in these cases, KDE is able to determine the MIME-type by directly "
"examining the contents of the file.</p>"
msgstr ""
"<p><h1>ارتباطات الملف</h1>هذه الوحدة تخوّلك أن تختار التطبيقات المرتبطة بنوع "
"معين من الملفات. يُرمز إلى أنواع الملفات أيضاً بأنواع MIME (MIME هو اختصار "
"يعني \"امتدادات بريد الإنترنت المتعددة الأغراض\").</p><p>تتضمّن ارتباط الملف "
"الأشياء التالية:<ul><li>قواعد لتحديد نوع MIME للملف. كمثال: اسم الملف *.png، "
"والتي تعني جميع الملفات التي ينتهي اسمها بـ .png، ترتبط بنوع MIME \"صورة/png"
"\";</li> <li>وصف قصير لنوع MIME. كمثال، الوصف القصير لنوع MIME \"صورة/png\" "
"هو ببساطة 'صورة PNG';</li> <li>أيقونة ستُستخدم عند عرض الملفات ذوي نوع MIME "
"المحدد، لتتمكن من تمييز نوع الملف في مدير الملفات أو نافذة اختيار الملفات "
"بسهولة;</li> <li>قائمة من التطبيقات التي يمكن استخدامها لفتح الملفات ذات نوع "
"MIME. إن اخترت أكثر من تطبيق فسيكون الترتيب حسب الأولوية.</li></ul>قد تتفاجأ "
"للعثور على أنواع MIME غير مرتبطة بأسماء ملفات. في هذه الحالة سيستطيع معرفة "
"نوع MIME من خلال فحص محتويات الملف.</p>"
#: filetypesview.cpp:73
#, fuzzy, kde-format
#| msgid "Find file type or filename pattern"
msgid "Search for file type or filename pattern..."
msgstr "ابحث عن نوع الملف أو عن نمط اسم الملف"
#: filetypesview.cpp:79
#, kde-format
msgid ""
"Enter a part of a filename pattern, and only file types with a matching file "
"pattern will appear in the list. Alternatively, enter a part of a file type "
"name as it appears in the list."
msgstr ""
"أدخل جزء من نمط اسم الملف، وستظهر أنواع الملفات المطابقة لنمط الملف فقط في "
"القائمة ؛ أو أدخل جزء من اسم نوع الملف كما يظهر في القائمة."
#: filetypesview.cpp:87
#, kde-format
msgid "Known Types"
msgstr "الأنواع المعروفة"
#: filetypesview.cpp:93
#, kde-format
msgid ""
"Here you can see a hierarchical list of the file types which are known on "
"your system. Click on the '+' sign to expand a category, or the '-' sign to "
"collapse it. Select a file type (e.g. text/html for HTML files) to view/edit "
"the information for that file type using the controls on the right."
msgstr ""
"يمكنك أن ترى هنا قائمة تراتبية من أنواع الملفات المعروفة في نظامك. اتقر على "
"رمز '+' لتوسيع فئة، أو الرمز '-' لتقليصها. اختر نوع الملف (مثال: نص/html "
"لملفات HTML) لرؤية/تعديل معلومات نوع الملف هذا باستخدام أزرار التحكم على "
"اليمين."
#: filetypesview.cpp:107
#, kde-format
msgid "Click here to add a new file type."
msgstr "انقر هنا لإضافة نوع ملف جديد."
#: filetypesview.cpp:109 filetypesview.cpp:375
#, kde-format
msgid "&Remove"
msgstr "أ&زل"
#: filetypesview.cpp:133
#, kde-format
msgid "Select a file type by name or by extension"
msgstr "اختر نوع الملف حسب الاسم أو الامتداد"
#: filetypesview.cpp:368
#, kde-format
msgid "&Revert"
msgstr "ا&سترجع"
#: filetypesview.cpp:369
#, kde-format
msgid "Revert this file type to its initial system-wide definition"
msgstr "استرجع نوع الملف هذا إلى تعريفه الافتراضي"
#: filetypesview.cpp:371
#, kde-format
msgid ""
"Click here to revert this file type to its initial system-wide definition, "
"which undoes any changes made to the file type. Note that system-wide file "
"types cannot be deleted. You can however empty their pattern list, to "
"minimize the chances of them being used (but the file type determination "
"from file contents can still end up using them)."
msgstr ""
"انقر هنا لاسترجاع حالة هذا النوع إلى تعريفه الافتراضي system-wide و إلغاء أي "
"تعديل عليه. لاحظ أن نوع ملف system-wide لا يمكن إزالته ، ولكن يمكن تفريغ "
"قائمة أنماطه لتقلل من احتمالية استخدمها (لكن تحديد نوع الملف من محتويات ملف "
"يمكن أن ينتهي باستخدامها على كل حال)."
#: filetypesview.cpp:376
#, kde-format
msgid "Delete this file type definition completely"
msgstr "احذف نوع ملف هذا بالكامل"
#: filetypesview.cpp:378
#, kde-format
msgid ""
"Click here to delete this file type definition completely. This is only "
"possible for user-defined file types. System-wide file types cannot be "
"deleted. You can however empty their pattern list, to minimize the chances "
"of them being used (but the file type determination from file contents can "
"still end up using them)."
msgstr ""
"انقر هنا لحذف هذا النوع بالكامل. هذا ممكن للأنواع المعرفة بواسطة المستخدم ، "
"أما نوع ملف system-wide لا يمكن إزالته ، ولكن يمكن تفريغ قائمة أنماطه لتقلل "
"من احتمالية استخدمها (لكن تحديد نوع الملف من محتويات ملف يمكن أن ينتهي "
"باستخدامها على كل حال)."
#: keditfiletype.cpp:122
#, fuzzy, kde-format
#| msgid "File type %1"
msgid "File Type Editor"
msgstr "نوع الملف %1"
#: keditfiletype.cpp:124
#, kde-format
msgid ""
"KDE file type editor - simplified version for editing a single file type"
msgstr "محرِّر نوع الملف لـِكدي - إصدار مبسّط لتحرير نوع ملف وحيد"
#: keditfiletype.cpp:126
#, kde-format
msgid "(c) 2000, KDE developers"
msgstr "(c) 2000, مطوري كدي"
#: keditfiletype.cpp:127
#, kde-format
msgid "Preston Brown"
msgstr "Preston Brown"
#: keditfiletype.cpp:128
#, kde-format
msgid "David Faure"
msgstr "David Faure"
#: keditfiletype.cpp:134
#, kde-format
msgid "Makes the dialog transient for the window specified by winid"
msgstr "يجعل الحوار عبارة عن نافذة يحددها winid"
#: keditfiletype.cpp:136
#, kde-format
msgid "File type to edit (e.g. text/html)"
msgstr "نوع الملف لكي يحرّر (مثال text/html)"
#: keditfiletype.cpp:167
#, kde-format
msgid "%1 File"
msgstr "ملف %1"
#: keditfiletype.cpp:194
#, kde-format
msgid "Edit File Type %1"
msgstr "حرّر نوع الملف %1"
#: keditfiletype.cpp:196
#, kde-format
msgid "Create New File Type %1"
msgstr "أنشئ نوع الملف الجديد %1"
#: kservicelistwidget.cpp:37
#, kde-format
msgid "%1 (%2)"
msgstr "%1 (%2)"
#: kservicelistwidget.cpp:50
#, kde-format
msgid "Application Preference Order"
msgstr "ترتيب تفضيلات التطبيقات"
#: kservicelistwidget.cpp:50
#, kde-format
msgid "Services Preference Order"
msgstr "ترتيب تفضيلات الخدمات"
#: kservicelistwidget.cpp:61
#, kde-format
msgid ""
"This is a list of applications associated with files of the selected file "
"type. This list is shown in Konqueror's context menus when you select \"Open "
"With...\". If more than one application is associated with this file type, "
"then the list is ordered by priority with the uppermost item taking "
"precedence over the others."
msgstr ""
"هذه قائمة من التطبيقات المرتبطة بالملفات ذات النوع المختار. تظهر هذه القائمة "
"في قوائم محتوى كونكيرور عندما تختار \"افتح باستخدام...\". إن كان هناك أكثر "
"من تطبيق واحد مرتبط بنوع الملف هذا، فستكون القائمة مرتبة حسب الأولوية حيث "
"يسبق العنصر الأهم البقية في الترتيب."
#: kservicelistwidget.cpp:66
#, kde-format
msgid ""
"This is a list of services associated with files of the selected file type. "
"This list is shown in Konqueror's context menus when you select a \"Preview "
"with...\" option. If more than one service is associated with this file "
"type, then the list is ordered by priority with the uppermost item taking "
"precedence over the others."
msgstr ""
"هذه قائمة من التطبيقات المرتبطة بالملفات ذات النوع المختار. تظهر هذه القائمة "
"في قوائم محتوى كونكيرور عندما تختار \"عاين باستخدام...\". إن كان هناك أكثر "
"من تطبيق واحد مرتبط بنوع الملف هذا، فستكون القائمة مرتبة حسب الأولوية حيث "
"يسبق العنصر الأهم البقية في الترتيب."
#: kservicelistwidget.cpp:78
#, kde-format
msgid "Move &Up"
msgstr "حرّك للأ&على"
#: kservicelistwidget.cpp:84
#, kde-format
msgid ""
"Assigns a higher priority to the selected\n"
"application, moving it up in the list. Note: This\n"
"only affects the selected application if the file type is\n"
"associated with more than one application."
msgstr ""
"يعطي أولوية أعلى للتطبيق المختار، \n"
"رافعاً إياه إلى أعلى القائمة. ملاحظة:\n"
"هذا يؤثر على التطبيق المحدد فقط في حال كان\n"
"نوع الملف مرتبطاً مع أكثر من تطبيق."
#: kservicelistwidget.cpp:88
#, kde-format
msgid ""
"Assigns a higher priority to the selected\n"
"service, moving it up in the list."
msgstr ""
"يعطي أولوية أعلى للخدمة المختارة،\n"
"رافعاً إياها إلى أعلى القائمة."
#: kservicelistwidget.cpp:91
#, kde-format
msgid "Move &Down"
msgstr "حرّك للأ&سفل"
#: kservicelistwidget.cpp:96
#, kde-format
msgid ""
"Assigns a lower priority to the selected\n"
"application, moving it down in the list. Note: This \n"
"only affects the selected application if the file type is\n"
"associated with more than one application."
msgstr ""
"يعطي أولوية أدنى للتطبيق المختار، \n"
"خافضاً إياه إلى أسفل القائمة. ملاحظة:\n"
"هذا يؤثر على التطبيق المحدد فقط في حال كان\n"
"نوع الملف مرتبطاً مع أكثر من تطبيق."
#: kservicelistwidget.cpp:100
#, kde-format
msgid ""
"Assigns a lower priority to the selected\n"
"service, moving it down in the list."
msgstr ""
"يعطي أولوية أدنى للخدمة المختارة،\n"
"خافضاً إياها إلى أسفل القائمة."
#: kservicelistwidget.cpp:108
#, kde-format
msgid "Add a new application for this file type."
msgstr "أضف تطبيق جديد لهذا النوع من الملفات."
#: kservicelistwidget.cpp:110
#, kde-format
msgid "Edit..."
msgstr "حرّر..."
#: kservicelistwidget.cpp:115
#, kde-format
msgid "Edit command line of the selected application."
msgstr "حرّر سطر الأمر للتطبيق المختار."
#: kservicelistwidget.cpp:122
#, kde-format
msgid "Remove the selected application from the list."
msgstr "أزل التطبيق المختار من القائمة."
#: kservicelistwidget.cpp:145
#, kde-format
msgctxt "No applications associated with this file type"
msgid "None"
msgstr "بدون"
#: kservicelistwidget.cpp:147
#, kde-format
msgctxt "No components associated with this file type"
msgid "None"
msgstr "بدون"
#: kserviceselectdlg.cpp:21
#, kde-format
msgid "Add Service"
msgstr "أضف خدمة"
#: kserviceselectdlg.cpp:25
#, kde-format
msgid "Select service:"
msgstr "اختر خدمة:"
#: newtypedlg.cpp:28
#, kde-format
msgid "Create New File Type"
msgstr "أنشئ نوع ملف جديد"
#: newtypedlg.cpp:33
#, kde-format
msgid "Group:"
msgstr "المجموعة:"
#: newtypedlg.cpp:42
#, kde-format
msgid "Select the category under which the new file type should be added."
msgstr "اختر الفئة التي ستضيف نوع الملف الجديد."
#: newtypedlg.cpp:47
#, kde-format
msgid "Type name:"
msgstr "اسم النوع:"
#: newtypedlg.cpp:53
#, kde-format
msgid ""
"Type the name of the file type. For instance, if you selected 'image' as "
"category and you type 'custom' here, the file type 'image/custom' will be "
"created."
msgstr ""
"أكتب اسم نوع الملف. فعلى سبيل المثال ، إذا كنت قد اخترت صورة 'كفئة وكتبت "
"'خاص' هنا سينشئ نوع الملف وسيكون 'صوره/خاص."

146
po/ar/kcmshell5.po Normal file
View File

@ -0,0 +1,146 @@
# translation of kcmshell.po to Arabic
# translation of kcmshell.po to
# محمد سعد Mohamed SAAD <metehyi@free.fr>, 2006.
# Youssef Chahibi <chahibi@gmail.com>, 2007.
# zayed <zayed.alsaidi@gmail.com>, 2008.
# Abdalrahim G. Fakhouri <abdilra7eem@yahoo.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: kcmshell\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-01-18 02:09+0000\n"
"PO-Revision-Date: 2011-12-28 20:40+0300\n"
"Last-Translator: Abdalrahim G. Fakhouri <abdilra7eem@yahoo.com>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"X-Generator: Translate Toolkit 1.10.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Mohamed SAAD محمد سعد,زايد السعيدي"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "metehyi@free.fr,zayed.alsaidi@gmail.com"
#: main.cpp:182
#, kde-format
msgid "System Settings Module"
msgstr ""
#: main.cpp:184
#, fuzzy, kde-format
#| msgid "A tool to start single KDE control modules"
msgid "A tool to start single system settings modules"
msgstr "أداة لبدء وحدات التحكم بالكيدي بشكل منفصل"
#: main.cpp:186
#, fuzzy, kde-format
#| msgid "(c) 1999-2004, The KDE Developers"
msgid "(c) 1999-2016, The KDE Developers"
msgstr "(c) 1999-2004, مطوري كيدي"
#: main.cpp:188
#, kde-format
msgid "Frans Englich"
msgstr "Frans Englich"
#: main.cpp:188
#, kde-format
msgid "Maintainer"
msgstr "المشرف على المشروع"
#: main.cpp:189
#, kde-format
msgid "Daniel Molkentin"
msgstr "Daniel Molkentin"
#: main.cpp:190
#, kde-format
msgid "Matthias Hoelzer-Kluepfel"
msgstr "Matthias Hoelzer-Kluepfel"
#: main.cpp:191
#, kde-format
msgid "Matthias Elter"
msgstr "Matthias Elter"
#: main.cpp:192
#, kde-format
msgid "Matthias Ettrich"
msgstr "Matthias Ettrich"
#: main.cpp:193
#, kde-format
msgid "Waldo Bastian"
msgstr "Waldo Bastian"
#: main.cpp:199
#, kde-format
msgid "List all possible modules"
msgstr "أعرض كل الوحدات النمطية الممكنة"
#: main.cpp:200
#, kde-format
msgid "Configuration module to open"
msgstr "تشكيل الوحدة النمطية للفتح"
#: main.cpp:201
#, kde-format
msgid "Specify a particular language"
msgstr "حدّد لغة معينة"
#: main.cpp:202
#, kde-format
msgid "Do not display main window"
msgstr "لا تعرض النافذة الرئيسية"
#: main.cpp:203
#, kde-format
msgid "Arguments for the module"
msgstr "معامِلات الوحدات"
#: main.cpp:204
#, kde-format
msgid "Use a specific icon for the window"
msgstr ""
#: main.cpp:205
#, kde-format
msgid "Use a specific caption for the window"
msgstr ""
#: main.cpp:214
#, kde-format
msgid ""
"--lang is deprecated. Please set the LANGUAGE environment variable instead"
msgstr ""
#: main.cpp:218
#, kde-format
msgid "The following modules are available:"
msgstr "الوحدات النمطية التالية هي متوفرة:"
#: main.cpp:237
#, kde-format
msgid "No description available"
msgstr "لا يوجد وصف متوفِر"
#: main.cpp:296
#, fuzzy, kde-format
#| msgid ""
#| "Could not find module '%1'. See kcmshell4 --list for the full list of "
#| "modules."
msgid ""
"Could not find module '%1'. See kcmshell5 --list for the full list of "
"modules."
msgstr ""
"تعذَّرَ إيجاد الوحدة '%1'. للحصول على القائمة الكاملة للوحدات، ألق نظرة على "
"مخرجات kcmshell4 --list."

263
po/ar/kdesu5.po Normal file
View File

@ -0,0 +1,263 @@
# translation of kdesu.po to Arabic
# translation of kdesu.po to
# Copyright (C) 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
# Mohammed Gamal <f2c2001@yahoo.com>, 2001.
# Isam Bayazidi <bayazidi@arabeyes.org>, 2002.
# Munzir Taha <munzir@kacst.edu.sa>, 2004.
# محمد سعد Mohamed SAAD <metehyi@free.fr>, 2006.
# AbdulAziz AlSharif <a.a-a.s@hotmail.com>, 2007.
# Youssef Chahibi <chahibi@gmail.com>, 2007.
# zayed <zayed.alsaidi@gmail.com>, 2008.
# Abdalrahim Fakhouri <abdilra7eem@yahoo.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: kdesu\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2021-08-06 00:18+0000\n"
"PO-Revision-Date: 2012-02-09 18:57+0200\n"
"Last-Translator: Abdalrahim Fakhouri <abdilra7eem@yahoo.com>\n"
"Language-Team: Arabic <linuxac-kde-arabic-team@googlegroups.com>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"X-Generator: Translate Toolkit 1.10.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr ""
"محمد جمال, عصام بايزيدي, محمد سعد Mohamed SAAD ,عبدالعزيز الشريف , زايد "
"السعيدي"
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr ""
"f2c2001@yahoo.com, bayazidi@arabeyes.org, metehyi@free.fr,a.a-a.s@hotmail."
"com,zayed.alsaidi@gmail.com"
#: kdesu.cpp:105
#, kde-format
msgid "KDE su"
msgstr "كدي su"
#: kdesu.cpp:107
#, kde-format
msgid "Runs a program with elevated privileges."
msgstr "ينفذ البرنامج مع امتيازات مرتفعة."
#: kdesu.cpp:109
#, kde-format
msgid "Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"
msgstr "حقوق النشر (c) 1998-2000 Geert Jansen, Pietro Iglio"
#: kdesu.cpp:110
#, kde-format
msgid "Geert Jansen"
msgstr "Geert Jansen"
#: kdesu.cpp:110
#, kde-format
msgid "Maintainer"
msgstr "المشرف على المشروع"
#: kdesu.cpp:111
#, kde-format
msgid "Pietro Iglio"
msgstr "Pietro Iglio"
#: kdesu.cpp:111
#, kde-format
msgid "Original author"
msgstr "المؤلف الأصلي"
#: kdesu.cpp:120
#, kde-format
msgid "Specifies the command to run as separate arguments"
msgstr "يحدد الأمر المطلوب تنفيذه كمعامل منفصل"
#: kdesu.cpp:121
#, kde-format
msgid "Specifies the command to run as one string"
msgstr "يحدد الأمر المطلوب تنفيذه كنصّ واحد"
#: kdesu.cpp:122
#, kde-format
msgid "Run command under target uid if <file> is not writable"
msgstr "نفّذ الأمر تحت uid الهدف إذا كان <ملف> غير قابل للكتابة."
#: kdesu.cpp:123
#, kde-format
msgid "Specifies the target uid"
msgstr "يحدد الـ uid الهدف."
#: kdesu.cpp:124
#, kde-format
msgid "Do not keep password"
msgstr "لا تحفظ كلمة السر."
#: kdesu.cpp:125
#, kde-format
msgid "Stop the daemon (forgets all passwords)"
msgstr "أوقف الرقيب (تنسى كلّ كلمات السر)"
#: kdesu.cpp:126
#, kde-format
msgid "Enable terminal output (no password keeping)"
msgstr "مكّن الخَرْج على الطرفية (لا تحفظ كلمة السر)"
#: kdesu.cpp:128
#, kde-format
msgid "Set priority value: 0 <= prio <= 100, 0 is lowest"
msgstr "عيّن قيمة الأولوية: 0<= الأولوية <=100, 0 هي الأدنى."
#: kdesu.cpp:129
#, kde-format
msgid "Use realtime scheduling"
msgstr "استخدم جدولة الزمن الحقيقي"
#: kdesu.cpp:130
#, kde-format
msgid "Do not display ignore button"
msgstr "لا تعرض زر تجاهل"
#: kdesu.cpp:131
#, kde-format
msgid "Specify icon to use in the password dialog"
msgstr "حدّد الأيقونة للاستخدام في حوار كلمة السر"
#: kdesu.cpp:132
#, kde-format
msgid "Do not show the command to be run in the dialog"
msgstr "لا تظهر الأمر للتنفيذ في الحوار"
#: kdesu.cpp:139
#, kde-format
msgctxt ""
"Transient means that the kdesu app will be attached to the app specified by "
"the winid so that it is like a dialog box rather than some separate program"
msgid "Makes the dialog transient for an X app specified by winid"
msgstr ""
"تجعل مربع حوار كجزء من التطبيق المحدد بواسطة winid بدلا أن يكون كتطبيق منفصل"
#: kdesu.cpp:141
#, kde-format
msgid "Embed into a window"
msgstr ""
#: kdesu.cpp:168
#, kde-format
msgid "Cannot execute command '%1'."
msgstr "لا يمكن تنفيذ الأمر '%1'."
#: kdesu.cpp:171
#, fuzzy, kde-format
#| msgid "Cannot execute command '%1'."
msgid "Cannot execute command '%1'. It contains invalid characters."
msgstr "لا يمكن تنفيذ الأمر '%1'."
#: kdesu.cpp:245
#, kde-format
msgid "Illegal priority: %1"
msgstr "أولوية غير شرعية: %1"
#: kdesu.cpp:266
#, kde-format
msgid "No command specified."
msgstr "لم يتم تحديد أمر."
#: kdesu.cpp:372
#, kde-format
msgid "Su returned with an error.\n"
msgstr "تم استرجاع خطأ من su \n"
#: kdesu.cpp:400
#, kde-format
msgid "Command:"
msgstr "الأمر:"
#: kdesu.cpp:409
#, kde-format
msgid "realtime: "
msgstr "الزمن الحقيقي: "
#: kdesu.cpp:413
#, kde-format
msgid "Priority:"
msgstr "الأولوية:"
#: sudlg.cpp:27
#, kde-format
msgid "Run as %1"
msgstr "نفّذ كـ %1"
#: sudlg.cpp:31
#, kde-format
msgid "Please enter your password below."
msgstr "من فضلك أدخل كلمة السر في الأسفل."
#: sudlg.cpp:36
#, kde-format
msgid ""
"The action you requested needs <b>root privileges</b>. Please enter "
"<b>root's</b> password below or click Ignore to continue with your current "
"privileges."
msgstr ""
"الإجراء الذي طلبته يحتاج إلى <b>صلاحية جذر</b>.الرجاء إدخال كلمة سر "
"<b>الجذر</b> في الأسفل أو انقر على تجاهل وتابع بصلاحيات حسابك."
#: sudlg.cpp:42
#, kde-format
msgid ""
"The action you requested needs <b>root privileges</b>. Please enter "
"<b>root's</b> password below."
msgstr ""
"الإجراء الذي طلبته يحتاج إلى <b>صلاحيات الجذر</b>. الرجاء إدخال كلمة سر "
"<b>الجذر</b> في الأسفل."
#: sudlg.cpp:49
#, kde-format
msgid ""
"The action you requested needs additional privileges. Please enter the "
"password for <b>%1</b> below or click Ignore to continue with your current "
"privileges."
msgstr ""
"الإجراء الذي طلبته يحتاج إلى امتيازات إضافية. من فضلك أدخل كلمة السر لـ "
"\"%1\" بالأسفل أو انقر تجاهل للمتابعة مع امتيازاتك الحالية."
#: sudlg.cpp:56
#, kde-format
msgid ""
"The action you requested needs additional privileges. Please enter the "
"password for <b>%1</b> below."
msgstr ""
"الإجراء الذي طلبته يحتاج إلى امتيازات إضافية. من فضلك أدخل كلمة سر <b>%1</b> "
"بالأسفل."
#: sudlg.cpp:79
#, kde-format
msgid "Conversation with su failed."
msgstr "فشلت المحادثة مع su."
#: sudlg.cpp:86
#, kde-format
msgid ""
"The program 'su' could not be found.<br />Ensure your PATH is set correctly."
msgstr ""
"لا يمكن إيجاد البرنامج 'su' .<br /> تأكد من أن المسار PATH مضبوط بشكل صحيح."
#: sudlg.cpp:97
#, kde-format
msgid ""
"Permission denied.<br />Possibly incorrect password, please try again.<br /"
">On some systems, you need to be in a special group (often: wheel) to use "
"this program."
msgstr ""
#: sudlg.cpp:105
#, kde-format
msgid "Internal error: illegal return from SuProcess::checkInstall()"
msgstr "خطأ داخلي: نتيجة غير شرعية من SuProcess::checkInstall()"

428
po/ar/kioclient.po Normal file
View File

@ -0,0 +1,428 @@
# translation of kioclient.po to Arabic
# translation of kioclient.po to
# Copyright (C) YEAR This_file_is_part_of_KDE
# This file is distributed under the same license as the PACKAGE package.
# Youssef Chahibi <chahibi@gmail.com>, 2007.
# Abdulaziz AlSharif <a.a-a.s@hotmail.com>, 2007.
# zayed <zayed.alsaidi@gmail.com>, 2008.
# Abdalrahim G. Fakhouri <abdilra7eem@yahoo.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: kioclient\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
"POT-Creation-Date: 2022-01-14 02:21+0000\n"
"PO-Revision-Date: 2012-01-12 21:41+0300\n"
"Last-Translator: Abdalrahim G. Fakhouri <abdilra7eem@yahoo.com>\n"
"Language-Team: Arabic <doc@arabeyes.org>\n"
"Language: ar\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
"X-Generator: Translate Toolkit 1.10.0\n"
#, kde-format
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr ""
#, kde-format
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr ""
#: kioclient.cpp:55
#, kde-format
msgid ""
"\n"
"Syntax:\n"
msgstr ""
"\n"
"الجملة:\n"
#: kioclient.cpp:56
#, fuzzy, kde-format
#| msgid ""
#| " kioclient openProperties 'url'\n"
#| " # Opens a properties menu\n"
#| "\n"
msgid ""
" kioclient openProperties 'url'\n"
" # Opens a properties menu\n"
"\n"
msgstr ""
" kioclient openProperties 'url'\n"
" # يفتح قائمة الخصائص\n"
"\n"
#: kioclient.cpp:60
#, fuzzy, kde-format
#| msgid ""
#| " kioclient exec 'url' ['mimetype']\n"
#| " # Tries to open the document pointed to by 'url', in the "
#| "application\n"
#| " # associated with it in KDE. You may omit 'mimetype'.\n"
#| " # In this case the mimetype is determined\n"
#| " # automatically. Of course URL may be the URL of a\n"
#| " # document, or it may be a *.desktop file.\n"
#| " # 'url' can be an executable, too.\n"
msgid ""
" kioclient exec 'url' ['mimetype']\n"
" # Tries to open the document pointed to by 'url', in the "
"application\n"
" # associated with it in KDE. You may omit 'mimetype'.\n"
" # In this case the mimetype is determined\n"
" # automatically. Of course URL may be the URL of a\n"
" # document, or it may be a *.desktop file.\n"
" # 'url' can be an executable, too.\n"
msgstr ""
" kioclient exec 'url' ['mimetype']\n"
" # يحاول فتح المستند ذو العنوان 'url'، في التطبيق\n"
" # الملحق به في الكيدي. يمكن حذف 'mimetype'.\n"
" # في هذه الحالة سيتم التعرف على mimetype\n"
" # تلقائي. بطبيعة الحال العنوان قد يكون عنوان مسند\n"
" # أو قد يكون *.desktop file.\n"
" # يمكن أن يكون المسار 'url' تنفيذيًّا أيضاً.\n"
#: kioclient.cpp:69
#, fuzzy, kde-format
#| msgid ""
#| " kioclient move 'src' 'dest'\n"
#| " # Moves the URL 'src' to 'dest'.\n"
#| " # 'src' may be a list of URLs.\n"
msgid ""
" kioclient move 'src' 'dest'\n"
" # Moves the URL 'src' to 'dest'.\n"
" # 'src' may be a list of URLs.\n"
msgstr ""
" kioclient move 'src' 'dest'\n"
" # ينقل عنوان 'src' إلى 'dest'.\n"
" # قد تكون'src' قائمة عناوين.\n"
#: kioclient.cpp:74
#, kde-format
msgid ""
" # 'dest' may be \"trash:/\" to move the files\n"
" # to the trash.\n"
msgstr ""
" # يمكن لـ'dest' أن تكون \"trash:/\" لنقل الملفات\n"
" # إلى المهملات.\n"
#: kioclient.cpp:78
#, fuzzy, kde-format
#| msgid ""
#| " # the short version kioclient mv\n"
#| " # is also available.\n"
#| "\n"
msgid ""
" # the short version kioclient mv\n"
" # is also available.\n"
"\n"
msgstr ""
" # الاختصار kioclient mv\n"
" # متوفّرٌ أيضاً.\n"
"\n"
#: kioclient.cpp:82
#, fuzzy, kde-format
#| msgid ""
#| " kioclient download ['src']\n"
#| " # Copies the URL 'src' to a user-specified location'.\n"
#| " # 'src' may be a list of URLs, if not present then\n"
#| " # a URL will be requested.\n"
#| "\n"
msgid ""
" kioclient download ['src']\n"
" # Copies the URL 'src' to a user-specified location'.\n"
" # 'src' may be a list of URLs, if not present then\n"
" # a URL will be requested.\n"
"\n"
msgstr ""
" kioclient download ['src']\n"
" # ينسخ عنوان 'src' إلى الموقع الذي يحدده المستخدم'.\n"
" # قد يكون 'src' قائمة عناوين ، إذا لم يحدد سيتم طلب\n"
" # عنوان.\n"
"\n"
#: kioclient.cpp:88
#, fuzzy, kde-format
#| msgid ""
#| " kioclient copy 'src' 'dest'\n"
#| " # Copies the URL 'src' to 'dest'.\n"
#| " # 'src' may be a list of URLs.\n"
msgid ""
" kioclient copy 'src' 'dest'\n"
" # Copies the URL 'src' to 'dest'.\n"
" # 'src' may be a list of URLs.\n"
msgstr ""
" kioclient copy 'src' 'dest'\n"
" # تنسخ عنوان 'src' إلى 'dest'.\n"
" # قد يكون 'src' قائمة عناوين.\n"
#: kioclient.cpp:93
#, fuzzy, kde-format
#| msgid ""
#| " # the short version kioclient cp\n"
#| " # is also available.\n"
#| "\n"
msgid ""
" # the short version kioclient cp\n"
" # is also available.\n"
"\n"
msgstr ""
" # الاختصار kioclient cp\n"
" # متوفّرٌ أيضاً.\n"
"\n"
#: kioclient.cpp:97
#, fuzzy, kde-format
#| msgid ""
#| " kioclient cat 'url'\n"
#| " # Writes out the contents of 'url' to stdout\n"
#| "\n"
msgid ""
" kioclient cat 'url'\n"
" # Writes out the contents of 'url' to stdout\n"
"\n"
msgstr ""
" kioclient cat 'url'\n"
" # تكتب محتويات 'url' إلى stdout\n"
"\n"
#: kioclient.cpp:101
#, fuzzy, kde-format
msgid ""
" kioclient ls 'url'\n"
" # Lists the contents of the directory 'url' to stdout\n"
"\n"
msgstr ""
" kioclient cat 'url'\n"
" # تكتب محتويات 'url' إلى stdout\n"
"\n"
#: kioclient.cpp:105
#, fuzzy, kde-format
#| msgid ""
#| " kioclient remove 'url'\n"
#| " # Removes the URL\n"
#| " # 'url' may be a list of URLs.\n"
msgid ""
" kioclient remove 'url'\n"
" # Removes the URL\n"
" # 'url' may be a list of URLs.\n"
msgstr ""
" kioclient remove 'url'\n"
" # ينقل العنوان URL\n"
" # قد تكون 'src' قائمة عناوين.\n"
#: kioclient.cpp:110
#, fuzzy, kde-format
#| msgid ""
#| " # the short version kioclient rm\n"
#| " # is also available.\n"
#| "\n"
msgid ""
" # the short version kioclient rm\n"
" # is also available.\n"
"\n"
msgstr ""
" # الاختصار kioclient rm\n"
" # متوفّرٌ أيضاً.\n"
"\n"
#: kioclient.cpp:114
#, fuzzy, kde-format
#| msgid ""
#| " kioclient cat 'url'\n"
#| " # Writes out the contents of 'url' to stdout\n"
#| "\n"
msgid ""
" kioclient stat 'url'\n"
" # Shows all of the available information for 'url'\n"
"\n"
msgstr ""
" kioclient cat 'url'\n"
" # تكتب محتويات 'url' إلى stdout\n"
"\n"
#: kioclient.cpp:118
#, fuzzy, kde-format
#| msgid ""
#| " kioclient openProperties 'url'\n"
#| " # Opens a properties menu\n"
#| "\n"
msgid ""
" kioclient appmenu\n"
" # Opens a basic application launcher.\n"
"\n"
msgstr ""
" kioclient openProperties 'url'\n"
" # يفتح قائمة الخصائص\n"
"\n"
#: kioclient.cpp:123
#, kde-format
msgid "*** Examples:\n"
msgstr ""
#: kioclient.cpp:124
#, fuzzy, kde-format
#| msgid ""
#| " kioclient exec file:/home/weis/data/test.html\n"
#| " // Opens the file with default binding\n"
#| "\n"
msgid ""
" kioclient exec file:/home/weis/data/test.html\n"
" // Opens the file with default binding\n"
"\n"
msgstr ""
" kioclient exec file:/home/weis/data/test.html\n"
" //تفتح الملف بربط المبدئي\n"
"\n"
#: kioclient.cpp:128
#, fuzzy, kde-format
#| msgid ""
#| " kioclient exec ftp://localhost/\n"
#| " // Opens new window with URL\n"
#| "\n"
msgid ""
" kioclient exec ftp://localhost/\n"
" // Opens new window with URL\n"
"\n"
msgstr ""
" kioclient exec ftp://localhost/\n"
" // تفتح نافذة جديدة فيها العنوان\n"
"\n"
#: kioclient.cpp:132
#, fuzzy, kde-format
#| msgid ""
#| " kioclient exec file:/root/Desktop/emacs.desktop\n"
#| " // Starts emacs\n"
#| "\n"
msgid ""
" kioclient exec file:/root/Desktop/emacs.desktop\n"
" // Starts emacs\n"
"\n"
msgstr ""
" kioclient exec file:/root/Desktop/emacs.desktop\n"
" // تبدأ emacs\n"
"\n"
#: kioclient.cpp:136
#, fuzzy, kde-format
#| msgid ""
#| " kioclient exec .\n"
#| " // Opens the current directory. Very convenient.\n"
#| "\n"
msgid ""
" kioclient exec .\n"
" // Opens the current directory. Very convenient.\n"
"\n"
msgstr ""
" kioclient exec .\n"
" // تفتح المجلد الحالي. مريحة جدا.\n"
"\n"
#: kioclient.cpp:154
#, kde-format
msgid "KIO Client"
msgstr "عميل KIO"
#: kioclient.cpp:155
#, kde-format
msgid "Command-line tool for network-transparent operations"
msgstr "أداة سطر أوامر لعمليات العابرة للشبكة."
#: kioclient.cpp:162
#, kde-format
msgid "Use message boxes and other native notifications"
msgstr ""
#: kioclient.cpp:165
#, kde-format
msgid ""
"Non-interactive use: no message boxes. If you don't want a graphical "
"connection, use --platform offscreen"
msgstr ""
#: kioclient.cpp:169
#, kde-format
msgid "Overwrite destination if it exists (for copy and move)"
msgstr "استبدال الهدف إذا كان موجوداً (لأوامر النسخ والنقل)"
#: kioclient.cpp:173
#, fuzzy, kde-format
msgid "file or URL"
msgstr "عنوان أو عناوين URL"
#: kioclient.cpp:173 kioclient.cpp:175 kioclient.cpp:178 kioclient.cpp:183
#, kde-format
msgid "urls..."
msgstr ""
#: kioclient.cpp:175 kioclient.cpp:178
#, kde-format
msgid "Source URL or URLs"
msgstr "مصدر العنوان أو العناوين"
#: kioclient.cpp:176 kioclient.cpp:179
#, kde-format
msgid "Destination URL"
msgstr "وجهة العنوان"
#: kioclient.cpp:176 kioclient.cpp:179
#, kde-format
msgid "url"
msgstr ""
#: kioclient.cpp:181
#, kde-format
msgid "Show available commands"
msgstr "أظهر الأوامر المتوفرة"
#: kioclient.cpp:182
#, kde-format
msgid "Command (see --commands)"
msgstr "الأمر (انظر --الأوامر)"
#: kioclient.cpp:182
#, kde-format
msgid "command"
msgstr ""
#: kioclient.cpp:183
#, kde-format
msgid "Arguments for command"
msgstr "معطيات الأمر"
#: kioclient.cpp:207
#, fuzzy, kde-format
msgctxt "@info:shell"
msgid "%1: Syntax error, not enough arguments\n"
msgstr "خطأ في الصياغة: المتحولات ليست كافية\n"
#: kioclient.cpp:211
#, fuzzy, kde-format
msgctxt "@info:shell"
msgid "%1: Syntax error, too many arguments\n"
msgstr "خطأ في الصياغة: المتحولات كثيرة\n"
#: kioclient.cpp:416
#, kde-format
msgid "Destination where to download the files"
msgstr ""
#: kioclient.cpp:458
#, fuzzy, kde-format
msgctxt "@info:shell"
msgid "%1: Syntax error, unknown command '%2'\n"
msgstr "صيغة خاطئة: الأمر غير معروف '%1'\n"
#: kioclient.cpp:474
#, kde-format
msgctxt "@info:shell"
msgid "%1: %2\n"
msgstr ""

Some files were not shown because too many files have changed in this diff Show More