Import Upstream version 5.24.6
This commit is contained in:
commit
850d7e45e3
|
@ -0,0 +1,2 @@
|
|||
# clang-format
|
||||
24192da4d63dc5026d4da5285cfcad698767bae4
|
|
@ -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
|
|
@ -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
|
|
@ -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'
|
|
@ -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()
|
|
@ -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.
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
|
@ -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>.
|
|
@ -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!
|
|
@ -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!
|
|
@ -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!
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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}
|
|
@ -0,0 +1,2 @@
|
|||
ecm_optional_add_subdirectory(kcontrol5)
|
||||
ecm_optional_add_subdirectory(kdesu)
|
|
@ -0,0 +1 @@
|
|||
ecm_optional_add_subdirectory(filetypes)
|
|
@ -0,0 +1,2 @@
|
|||
########### install files ###############
|
||||
kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR kcontrol5/filetypes)
|
|
@ -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>
|
|
@ -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})
|
|
@ -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 <-> &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:
|
||||
-->
|
||||
|
|
@ -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>
|
|
@ -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})
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kbroadcastnotification.pot
|
|
@ -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();
|
||||
}
|
|
@ -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})
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kcmshell5.pot
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
install(PROGRAMS kdeeject DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF5})
|
|
@ -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
|
|
@ -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})
|
|
@ -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
|
||||
}
|
|
@ -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})
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kdesu5.pot
|
|
@ -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>
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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__
|
|
@ -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} )
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kcm5_filetypes.pot
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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]=檔案關聯
|
||||
|
|
@ -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
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
)
|
|
@ -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"
|
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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()
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kioclient.pot
|
|
@ -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()
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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})
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kmimetypefinder5.pot
|
|
@ -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;
|
||||
}
|
|
@ -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})
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/kstart5.pot
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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})
|
|
@ -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;
|
||||
}
|
|
@ -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})
|
|
@ -0,0 +1,2 @@
|
|||
#! /usr/bin/env bash
|
||||
$XGETTEXT *.cpp -o $podir/ktraderclient5.pot
|
|
@ -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;
|
||||
}
|
|
@ -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})
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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ı açı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ı Aç
|
||||
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
|
|
@ -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 ""
|
|
@ -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 ""
|
|
@ -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()"
|
|
@ -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"
|
|
@ -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 ""
|
||||
"أكتب اسم نوع الملف. فعلى سبيل المثال ، إذا كنت قد اخترت صورة 'كفئة وكتبت "
|
||||
"'خاص' هنا سينشئ نوع الملف وسيكون 'صوره/خاص."
|
|
@ -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."
|
|
@ -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()"
|
|
@ -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
Loading…
Reference in New Issue