pax_global_header00006660000000000000000000000064136104364710014517gustar00rootroot0000000000000052 comment=4261e23c65a69bb59a2455648d8331a9fd6c1f79 fcitx5-chinese-addons-0.0~git20200117.4261e23/000077500000000000000000000000001361043647100200665ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/.clang-format000066400000000000000000000033211361043647100224400ustar00rootroot00000000000000--- Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -4 ConstructorInitializerIndentWidth: 4 AlignEscapedNewlinesLeft: false AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AllowShortFunctionsOnASingleLine: All AlwaysBreakTemplateDeclarations: true AlwaysBreakBeforeMultilineStrings: false BreakBeforeBinaryOperators: false BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BinPackParameters: true ColumnLimit: 80 ConstructorInitializerAllOnOneLineOrOnePerLine: false DerivePointerAlignment: false ExperimentalAutoDetectBinPacking: false IndentCaseLabels: false IndentWrappedFunctionNames: false IndentFunctionDeclarationAfterType: false MaxEmptyLinesToKeep: 1 KeepEmptyLinesAtTheStartOfBlocks: true NamespaceIndentation: None ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakComment: 300 PenaltyBreakString: 1000 PenaltyBreakFirstLessLess: 120 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right SpacesBeforeTrailingComments: 1 Cpp11BracedListStyle: true Standard: Cpp11 IndentWidth: 4 TabWidth: 4 UseTab: Never BreakBeforeBraces: Attach SpacesInParentheses: false SpacesInAngles: false SpaceInEmptyParentheses: false SpacesInCStyleCastParentheses: false SpacesInContainerLiterals: true SpaceBeforeAssignmentOperators: true ContinuationIndentWidth: 4 CommentPragmas: '^ IWYU pragma:' ForEachMacros: [ Q_FOREACH, BOOST_FOREACH ] SpaceBeforeParens: ControlStatements DisableFormat: false SortIncludes: true ... fcitx5-chinese-addons-0.0~git20200117.4261e23/.gitignore000066400000000000000000000001651361043647100220600ustar00rootroot00000000000000build*/ .* !.git* .git/ *.tar.* *.kdev4 *.kate-swp *.orig tags astyle.sh cscope.* *.part XF86keysym.h keysymdef.h *~ fcitx5-chinese-addons-0.0~git20200117.4261e23/CMakeLists.txt000066400000000000000000000045321361043647100226320ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.6.0) project(fcitx5-chinese-addons VERSION 0.0.1) find_package(ECM REQUIRED 1.0.0) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) include(FeatureSummary) include(GNUInstallDirs) include(ECMSetupVersion) include(ECMUninstallTarget) find_package(Fcitx5Core REQUIRED) find_package(Fcitx5Module REQUIRED COMPONENTS Notifications QuickPhrase Spell) find_package(LibIntl REQUIRED) find_package(Pthread REQUIRED) find_package(PkgConfig REQUIRED) find_package(Gettext REQUIRED) find_package(fmt REQUIRED) if (TARGET fmt::fmt-header-only) set(FMT_TARGET fmt::fmt-header-only) else() set(FMT_TARGET fmt::fmt) endif () pkg_check_modules(Curl REQUIRED IMPORTED_TARGET "libcurl") include("${FCITX_INSTALL_CMAKECONFIG_DIR}/Fcitx5Utils/Fcitx5CompilerSettings.cmake") ####################################################################### # Options ####################################################################### option(ENABLE_TEST "Build Test" On) option(ENABLE_OPENCC "Enable OpenCC for chttrans" On) option(ENABLE_GUI "Enable Configure Gui" On) if (ENABLE_OPENCC) find_package(OpenCC REQUIRED) endif() if (ENABLE_GUI) find_package(Qt5 REQUIRED COMPONENTS DBus WebEngineWidgets Concurrent) find_package(Fcitx5Qt5WidgetsAddons REQUIRED) find_package(Fcitx5Qt5DBusAddons REQUIRED) endif() find_package(Boost 1.61 REQUIRED COMPONENTS iostreams) find_package(LibIMEPinyin REQUIRED) find_package(LibIMETable REQUIRED) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_definitions(-DFCITX_GETTEXT_DOMAIN=\"fcitx5-chinese-addons\") add_subdirectory(modules) add_subdirectory(im) add_subdirectory(po) add_subdirectory(tools) if (ENABLE_GUI) add_subdirectory(gui) endif() if (ENABLE_TEST) enable_testing() add_subdirectory(test) if (ENABLE_COVERAGE) add_custom_target(coverage COMMAND "${CMAKE_CTEST_COMMAND}" COMMAND lcov --capture --directory ./ --output-file coverage.info COMMAND genhtml coverage.info --output-directory "coverage_pages" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) endif() endif () feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) fcitx5-chinese-addons-0.0~git20200117.4261e23/COPYING000066400000000000000000000636421361043647100211340ustar00rootroot00000000000000 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. GNU LESSER GENERAL PUBLIC LICENSE 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. Copyright (C) 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. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! fcitx5-chinese-addons-0.0~git20200117.4261e23/Messages.sh000077500000000000000000000026741361043647100222050ustar00rootroot00000000000000#!/bin/bash DOMAIN=$(basename $PWD) POT_FILE=po/$DOMAIN.pot set -x XGETTEXT="xgettext --package-name=$DOMAIN --add-comments --sort-output --msgid-bugs-address=fcitx-dev@googlegroups.com" source_files=$(find . -name \*.cpp -o -name \*.h) $XGETTEXT --keyword=_ --keyword=N_ --language=C++ -o ${POT_FILE} $source_files desktop_files=$(find . -name \*.conf.in -o -name \*.conf.in.in -o -name \*.desktop) $XGETTEXT --language=Desktop -k --keyword=Name --keyword=GenericName --keyword=Comment --keyword=Keywords $desktop_files -j -o ${POT_FILE} ui_files=$(find . -name \*.ui) extractrc $ui_files > rc.cpp $XGETTEXT --kde --language=C++ --add-comments --sort-output -j -o ${POT_FILE} rc.cpp rm -f rc.cpp sed -i 's|^"Content-Type: text/plain; charset=CHARSET\\n"|"Content-Type: text/plain; charset=utf-8\\n"|g' ${POT_FILE} # Due to transifex problem, delete the date. #sed -i '/^"PO-Revision-Date/d' ${POT_FILE} #sed -i '/^"PO-Revision-Date/d' ${POT_FILE} sed -i '/^# FIRST AUTHOR/d' ${POT_FILE} sed -i '/^#, fuzzy/d' ${POT_FILE} sed -i 's|^"Language: \\n"|"Language: LANG\\n"|g' ${POT_FILE} echo > po/LINGUAS for pofile in $(ls po/*.po | sort); do pofilebase=$(basename $pofile) pofilebase=${pofilebase/.po/} msgmerge -U --backup=none $pofile ${POT_FILE} project_line=$(grep "Project-Id-Version" ${POT_FILE} | head -n 1 | tr --delete '\n' | sed -e 's/[\/&]/\\&/g') sed -i "s|.*Project-Id-Version.*|$project_line|g" $pofile echo $pofilebase >> po/LINGUAS done fcitx5-chinese-addons-0.0~git20200117.4261e23/README.md000066400000000000000000000007561361043647100213550ustar00rootroot00000000000000Chinese related addon for fcitx5 ================================================ This provides pinyin and table input method support for fcitx5. Released under LGPL-2.1+. [![Jenkins Build Status](https://img.shields.io/jenkins/s/https/jenkins.fcitx-im.org/job/fcitx5-chinese-addons.svg)](https://jenkins.fcitx-im.org/job/fcitx5-chinese-addons/) [![Coverity Scan Status](https://img.shields.io/coverity/scan/11995.svg)](https://scan.coverity.com/projects/fcitx-fcitx5-chinese-addons) fcitx5-chinese-addons-0.0~git20200117.4261e23/cmake/000077500000000000000000000000001361043647100211465ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/cmake/FindLibIntl.cmake000066400000000000000000000024101361043647100243030ustar00rootroot00000000000000# - find where dlopen and friends are located. # LIBINTL_FOUND - system has dynamic linking interface available # LIBINTL_INCLUDE_DIR - where dlfcn.h is located. # LIBINTL_LIBRARY - libraries needed to use dlopen include(CheckFunctionExists) find_path(LIBINTL_INCLUDE_DIR NAMES libintl.h) find_library(LIBINTL_LIBRARY NAMES intl) if(LIBINTL_LIBRARY) set(LIBINTL_FOUND TRUE) else(LIBINTL_LIBRARY) check_function_exists(dgettext LIBINTL_FOUND) # If dlopen can be found without linking in dl then dlopen is part # of libc, so don't need to link extra libs. set(LIBINTL_LIBRARY "") endif(LIBINTL_LIBRARY) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBINTL FOUND_VAR LIBINTL_FOUND REQUIRED_VARS LIBINTL_INCLUDE_DIR ) mark_as_advanced(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARY) if(LIBINTL_FOUND AND NOT TARGET LibIntl::LibIntl) if (LIBINTL_LIBRARY) add_library(LibIntl::LibIntl UNKNOWN IMPORTED) set_target_properties(LibIntl::LibIntl PROPERTIES IMPORTED_LOCATION "${LIBINTL_LIBRARY}") else() add_library(LibIntl::LibIntl INTERFACE IMPORTED ) endif() set_target_properties(LibIntl::LibIntl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBINTL_INCLUDE_DIR}" ) endif() fcitx5-chinese-addons-0.0~git20200117.4261e23/cmake/FindOpenCC.cmake000066400000000000000000000021211361043647100240540ustar00rootroot00000000000000find_package(PkgConfig) pkg_check_modules(PKG_OPENCC QUIET opencc) set(OPENCC_DEFINITIONS ${PKG_OPENCC_CFLAGS_OTHER}) set(OPENCC_VERSION ${PKG_OPENCC_VERSION}) find_path(OPENCC_INCLUDE_DIR NAMES opencc.h HINTS ${PKG_OPENCC_INCLUDE_DIRS} ) find_library(OPENCC_LIBRARY NAMES opencc HINTS ${PKG_OPENCC_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(OpenCC FOUND_VAR OPENCC_FOUND REQUIRED_VARS OPENCC_LIBRARY OPENCC_INCLUDE_DIR VERSION_VAR OPENCC_VERSION ) if(OPENCC_FOUND AND NOT TARGET OpenCC::OpenCC) add_library(OpenCC::OpenCC UNKNOWN IMPORTED) set_target_properties(OpenCC::OpenCC PROPERTIES IMPORTED_LOCATION "${OPENCC_LIBRARY}" INTERFACE_COMPILE_OPTIONS "${OPENCC_DEFINITIONS}" INTERFACE_INCLUDE_DIRECTORIES "${OPENCC_INCLUDE_DIR}" ) endif() mark_as_advanced(OPENCC_INCLUDE_DIR OPENCC_LIBRARY) include(FeatureSummary) set_package_properties(OPENCC PROPERTIES URL "https://github.com/BYVoid/OpenCC/" DESCRIPTION "Library for Open Chinese Convert" ) fcitx5-chinese-addons-0.0~git20200117.4261e23/cmake/FindPthread.cmake000066400000000000000000000040751361043647100243460ustar00rootroot00000000000000# Try to find Pthread functionality # Once done this will define # # PTHREAD_FOUND - system has Pthread # PTHREAD_INCLUDE_DIR - Pthread include directory # PTHREAD_LIBRARIES - Libraries needed to use Pthread # # TODO: This will enable translations only if Gettext functionality is # present in libc. Must have more robust system for release, where Gettext # functionality can also reside in standalone Gettext library, or the one # embedded within kdelibs (cf. gettext.m4 from Gettext source). # # Copyright (c) 2006, Chusslove Illich, # Copyright (c) 2007, Alexander Neundorf, # Copyright (c) 2016, Xuetian Weng # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. find_path(PTHREAD_INCLUDE_DIR NAMES pthread.h) if(PTHREAD_INCLUDE_DIR) include(CheckFunctionExists) check_function_exists(pthread_create PTHREAD_LIBC_HAS_PTHREAD_CREATE) if (PTHREAD_LIBC_HAS_PTHREAD_CREATE) set(PTHREAD_LIBRARIES) set(PTHREAD_LIB_FOUND TRUE) else (PTHREAD_LIBC_HAS_PTHREAD_CREATE) find_library(PTHREAD_LIBRARIES NAMES pthread libpthread ) if(PTHREAD_LIBRARIES) set(PTHREAD_LIB_FOUND TRUE) endif(PTHREAD_LIBRARIES) endif (PTHREAD_LIBC_HAS_PTHREAD_CREATE) endif(PTHREAD_INCLUDE_DIR) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Pthread FOUND_VAR PTHREAD_FOUND REQUIRED_VARS PTHREAD_INCLUDE_DIR PTHREAD_LIB_FOUND ) if(PTHREAD_FOUND AND NOT TARGET Pthread::Pthread) if (PTHREAD_LIBRARIES) add_library(Pthread::Pthread UNKNOWN IMPORTED) set_target_properties(Pthread::Pthread PROPERTIES IMPORTED_LOCATION "${PTHREAD_LIBRARIES}") else() add_library(Pthread::Pthread INTERFACE IMPORTED ) endif() set_target_properties(Pthread::Pthread PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${PTHREAD_INCLUDE_DIR}" ) endif() mark_as_advanced(PTHREAD_INCLUDE_DIR PTHREAD_LIBRARIES PTHREAD_LIBC_HAS_PTHREAD_CREATE PTHREAD_LIB_FOUND) fcitx5-chinese-addons-0.0~git20200117.4261e23/config.h.in000066400000000000000000000020131361043647100221050ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _FCITX5_CHINESE_ADDONS_CONFIG_H_IN_ #define _FCITX5_CHINESE_ADDONS_CONFIG_H_IN_ #cmakedefine ENABLE_OPENCC #define LIBIME_INSTALL_PKGDATADIR "@LIBIME_INSTALL_PKGDATADIR@" #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #endif // _FCITX5_CHINESE_ADDONS_CONFIG_H_IN_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/000077500000000000000000000000001361043647100206525ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/CMakeLists.txt000066400000000000000000000000441361043647100234100ustar00rootroot00000000000000add_subdirectory(pinyindictmanager) fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/000077500000000000000000000000001361043647100243575ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/CMakeLists.txt000066400000000000000000000011061361043647100271150ustar00rootroot00000000000000add_library(pinyindictmanager MODULE main.cpp pinyindictmanager.cpp processrunner.cpp pipeline.cpp pipelinejob.cpp log.cpp renamefile.cpp filelistmodel.cpp browserdialog.cpp filedownloader.cpp ) target_link_libraries(pinyindictmanager Fcitx5Qt5::WidgetsAddons Fcitx5Qt5::DBusAddons Qt5::DBus Qt5::WebEngineWidgets Qt5::Concurrent) set_target_properties(pinyindictmanager PROPERTIES AUTOMOC TRUE AUTOUIC TRUE AUTOUIC_OPTIONS "-tr=fcitx::tr2fcitx;--include=fcitxqti18nhelper.h") install(TARGETS pinyindictmanager DESTINATION ${CMAKE_INSTALL_LIBDIR}/fcitx5/qt5) fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/browserdialog.cpp000066400000000000000000000072521361043647100277340ustar00rootroot00000000000000// // Copyright (C) 2013~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include #include #include #include #include #include #include #include #include "browserdialog.h" #include "filedownloader.h" #include "guicommon.h" #include "ui_browserdialog.h" #include namespace fcitx { /* * a typical link looks like this. * http://download.pinyin.sogou.com/dict/download_cell.php?id=15207&name=%D6%B2%CE%EF%B4%CA%BB%E3%B4%F3%C8%AB%A1%BE%B9%D9%B7%BD%CD%C6%BC%F6%A1%BF */ class WebPage : public QWebEnginePage { public: WebPage(BrowserDialog *dialog) : QWebEnginePage(dialog), dialog_(dialog) {} protected: bool acceptNavigationRequest(const QUrl &url, NavigationType, bool) override { return dialog_->linkClicked(url); } QWebEnginePage *createWindow(QWebEnginePage::WebWindowType) override { return this; } private: BrowserDialog *dialog_; }; BrowserDialog::BrowserDialog(QWidget *parent) : QDialog(parent), page_(new WebPage(this)) { setupUi(this); webView_->setPage(page_); setWindowIcon(QIcon::fromTheme("internet-web-browser")); setWindowTitle(_("Browse Sogou Cell Dict repository")); connect(webView_, &QWebEngineView::loadProgress, progressBar_, &QProgressBar::setValue); connect(webView_, &QWebEngineView::loadStarted, progressBar_, &QProgressBar::show); connect(webView_, &QWebEngineView::loadFinished, progressBar_, &QProgressBar::hide); webView_->load(QUrl(URL_BASE)); } BrowserDialog::~BrowserDialog() {} QString BrowserDialog::decodeName(const QByteArray &in) { QTextCodec *codec = QTextCodec::codecForName("UTF-8"); if (!codec) { return QString(); } QByteArray out = QByteArray::fromPercentEncoding(in); return codec->toUnicode(out); } bool BrowserDialog::linkClicked(const QUrl &url) { do { if (url.host() != DOWNLOAD_HOST_BASE && url.host() != HOST_BASE) { break; } // Now the site seems to have "d/dict/download_cell.php", just to make // it works with both. if (!url.path().endsWith("/dict/download_cell.php")) { break; } QUrlQuery query(url); QString id = query.queryItemValue("id"); QByteArray name = query.queryItemValue("name", QUrl::FullyEncoded).toLatin1(); QString sname = decodeName(name); name_ = sname; url_ = url; if (!id.isEmpty() && !sname.isEmpty()) { accept(); return false; } } while (0); if (url.host() != HOST_BASE) { QMessageBox::information(this, _("Wrong Link"), _("No browsing outside pinyin.sogou.com, now " "redirect to home page.")); webView_->load(QUrl(URL_BASE)); return false; } else { return true; } } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/browserdialog.h000066400000000000000000000027161361043647100274010ustar00rootroot00000000000000// // Copyright (C) 2013~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_BROWSERDIALOG_H_ #define _PINYINDICTMANAGER_BROWSERDIALOG_H_ #include "ui_browserdialog.h" #include #include #include namespace fcitx { class WebPage; class BrowserDialog : public QDialog, public Ui::BrowserDialog { friend class WebPage; Q_OBJECT public: explicit BrowserDialog(QWidget *parent = nullptr); virtual ~BrowserDialog(); const QUrl &url() const { return url_; } const QString &name() const { return name_; } private: bool linkClicked(const QUrl &url); QString decodeName(const QByteArray &in); QString name_; QUrl url_; WebPage *page_; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_BROWSERDIALOG_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/browserdialog.ui000066400000000000000000000020001361043647100275510ustar00rootroot00000000000000 BrowserDialog 0 0 1200 600 Dialog about:blank 24 QWebEngineView QWidget
QtWebEngineWidgets/QWebEngineView
fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/filedownloader.cpp000066400000000000000000000055361361043647100300720ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include #include "filedownloader.h" #include "guicommon.h" #include namespace fcitx { FileDownloader::FileDownloader(const QUrl &url, const QString &dest, QObject *parent) : PipelineJob(parent), url_(url), file_(dest), progress_(0) {} void FileDownloader::start() { if (!file_.open(QIODevice::WriteOnly)) { emit message(QMessageBox::Warning, _("Create temporary file failed.")); emit finished(false); return; } else { emit message(QMessageBox::Information, _("Temporary file created.")); } QNetworkRequest request(url_); request.setRawHeader( "Referer", QString("%1://%2").arg(url_.scheme()).arg(url_.host()).toLatin1()); reply_ = nam_.get(request); if (!reply_) { emit message(QMessageBox::Warning, _("Failed to create request.")); emit finished(false); return; } emit message(QMessageBox::Information, _("Download started.")); connect(reply_, &QNetworkReply::readyRead, this, &FileDownloader::readyToRead); connect(reply_, &QNetworkReply::finished, this, &FileDownloader::downloadFinished); connect(reply_, &QNetworkReply::downloadProgress, this, &FileDownloader::updateProgress); } void FileDownloader::abort() { reply_->abort(); delete reply_; reply_ = nullptr; } void FileDownloader::cleanUp() { file_.remove(); } void FileDownloader::readyToRead() { file_.write(reply_->readAll()); } void FileDownloader::updateProgress(qint64 downloaded, qint64 total) { if (total <= 0) { return; } int percent = (int)(((qreal)downloaded / total) * 100); if (percent > 100) { percent = 100; } if (percent >= progress_ + 10) { emit message(QMessageBox::Information, QString::fromUtf8(_("%1% Downloaded.")).arg(percent)); progress_ = percent; } } void FileDownloader::downloadFinished() { file_.close(); emit message(QMessageBox::Information, _("Download Finished")); emit finished(true); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/filedownloader.h000066400000000000000000000031661361043647100275340ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_FILEDOWNLOADER_H_ #define _PINYINDICTMANAGER_FILEDOWNLOADER_H_ #include "pipelinejob.h" #include #include #include #include #include #include #include namespace fcitx { class FileDownloader : public PipelineJob { Q_OBJECT public: explicit FileDownloader(const QUrl &url, const QString &dest, QObject *parent = nullptr); void start() override; void abort() override; void cleanUp() override; public slots: void readyToRead(); void downloadFinished(); void updateProgress(qint64, qint64); private: QUrl url_; QFile file_; QNetworkAccessManager nam_; QNetworkReply *reply_ = nullptr; int progress_; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_FILEDOWNLOADER_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/filelistmodel.cpp000066400000000000000000000042111361043647100277150ustar00rootroot00000000000000// // Copyright (C) 2013~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "filelistmodel.h" #include #include namespace fcitx { FileListModel::FileListModel(QObject *parent) : QAbstractListModel(parent) { loadFileList(); } FileListModel::~FileListModel() {} int FileListModel::rowCount(const QModelIndex &) const { return fileList_.size(); } QVariant FileListModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() >= fileList_.size()) return QVariant(); switch (role) { case Qt::DisplayRole: { auto name = fileList_[index.row()]; if (name.endsWith(".dict")) { name = name.left(name.size() - 5); } return name; } case Qt::UserRole: return fileList_[index.row()]; default: break; } return QVariant(); } void FileListModel::loadFileList() { beginResetModel(); fileList_.clear(); auto files = StandardPath::global().multiOpen( StandardPath::Type::PkgData, "pinyin/dictionaries", O_RDONLY, filter::Suffix(".dict")); for (const auto &file : files) { fileList_.append( QString::fromLocal8Bit(file.first.data(), file.first.size())); } endResetModel(); } int FileListModel::findFile(const QString &lastFileName) { int idx = fileList_.indexOf(lastFileName); if (idx < 0) { return 0; } return idx; } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/filelistmodel.h000066400000000000000000000026441361043647100273720ustar00rootroot00000000000000// // Copyright (C) 2013~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_FILELISTMODEL_H_ #define _PINYINDICTMANAGER_FILELISTMODEL_H_ #include #include namespace fcitx { class FileListModel : public QAbstractListModel { Q_OBJECT public: explicit FileListModel(QObject *parent = nullptr); ~FileListModel() override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; void loadFileList(); int findFile(const QString &lastFileName); private: QStringList fileList_; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_FILELISTMODEL_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/guicommon.h000066400000000000000000000017031361043647100265260ustar00rootroot00000000000000// // Copyright (C) 2013~2020 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef GUICOMMON_H #define GUICOMMON_H #define DOWNLOAD_HOST_BASE "download.pinyin.sogou.com" #define HOST_BASE "pinyin.sogou.com" #define URL_BASE "http://" HOST_BASE "/dict/" #endif // GUICOMMON_H fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/log.cpp000066400000000000000000000015431361043647100256470ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "log.h" namespace fcitx { Q_LOGGING_CATEGORY(dictmanager, "dictmanager") } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/log.h000066400000000000000000000017201361043647100253110ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_LOG_H_ #define _PINYINDICTMANAGER_LOG_H_ #include namespace fcitx { Q_DECLARE_LOGGING_CATEGORY(dictmanager) } // namespace fcitx #endif // _PINYINDICTMANAGER_LOG_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/main.cpp000066400000000000000000000021131361043647100260040ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "main.h" #include "pinyindictmanager.h" namespace fcitx { PinyinDictManagerPlugin::PinyinDictManagerPlugin(QObject *parent) : FcitxQtConfigUIPlugin(parent) {} FcitxQtConfigUIWidget *PinyinDictManagerPlugin::create(const QString &key) { Q_UNUSED(key); return new PinyinDictManager(nullptr); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/main.h000066400000000000000000000023751361043647100254630ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_MAIN_H_ #define _PINYINDICTMANAGER_MAIN_H_ #include "fcitxqtconfiguiplugin.h" namespace fcitx { class PinyinDictManagerPlugin : public FcitxQtConfigUIPlugin { Q_OBJECT public: Q_PLUGIN_METADATA(IID FcitxQtConfigUIFactoryInterface_iid FILE "pinyindictmanager.json") explicit PinyinDictManagerPlugin(QObject *parent = nullptr); FcitxQtConfigUIWidget *create(const QString &key) override; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_MAIN_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pinyindictmanager.cpp000066400000000000000000000303251361043647100305730ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pinyindictmanager.h" #include "browserdialog.h" #include "filedownloader.h" #include "log.h" #include "processrunner.h" #include "renamefile.h" #include #include #include #include #include #include #include namespace fcitx { PinyinDictManager::PinyinDictManager(QWidget *parent) : FcitxQtConfigUIWidget(parent), model_(new FileListModel(this)), pipeline_(new Pipeline(this)) { setupUi(this); QMenu *menu = new QMenu(this); importFromFileAction_ = new QAction(_("From &File"), this); importFromSogou_ = new QAction(_("From &Sogou Cell Dictionary File"), this); importFromSogouOnline_ = new QAction(_("&Browse Sogou Cell Dictionary Online"), this); menu->addAction(importFromFileAction_); menu->addAction(importFromSogou_); menu->addAction(importFromSogouOnline_); importButton_->setMenu(menu); menu = new QMenu(this); clearUserDictAction_ = new QAction(_("&Clear User Data"), this); clearAllDataAction_ = new QAction(_("Clear &All Data"), this); menu->addAction(clearUserDictAction_); menu->addAction(clearAllDataAction_); clearDictButton_->setMenu(menu); listView_->setModel(model_); connect(importFromFileAction_, &QAction::triggered, this, &PinyinDictManager::importFromFile); connect(importFromSogou_, &QAction::triggered, this, &PinyinDictManager::importFromSogou); connect(importFromSogouOnline_, &QAction::triggered, this, &PinyinDictManager::importFromSogouOnline); connect(clearUserDictAction_, &QAction::triggered, this, &PinyinDictManager::clearUserDict); connect(clearAllDataAction_, &QAction::triggered, this, &PinyinDictManager::clearAllDict); connect(removeButton_, &QPushButton::clicked, this, &PinyinDictManager::removeDict); connect(removeAllButton_, &QPushButton::clicked, this, &PinyinDictManager::removeAllDict); connect(pipeline_, &Pipeline::finished, this, [this]() { setEnabled(true); reload(); }); model_->loadFileList(); } void PinyinDictManager::load() {} void PinyinDictManager::save() {} QString PinyinDictManager::title() { return _("Pinyin dictionary manager"); } bool PinyinDictManager::asyncSave() { return true; } QString PinyinDictManager::confirmImportFileName(const QString &defaultName) { bool ok; auto importName = QInputDialog::getText( this, _("Input Dictionary Name"), _("New Dictionary Name:"), QLineEdit::Normal, defaultName, &ok); if (!ok) { return QString(); } return importName; } QString PinyinDictManager::prepareDirectory() { auto directory = stringutils::joinPath( StandardPath::global().userDirectory(StandardPath::Type::PkgData), "pinyin/dictionaries"); if (!fs::makePath(directory)) { QMessageBox::warning(this, _("Failed to create directory"), _("Create directory failed. Please check the " "permission or disk space.")); return ""; } return QString::fromLocal8Bit(directory.data()); } QString PinyinDictManager::prepareTempFile(const QString &tempFileTemplate) { QTemporaryFile tempFile(tempFileTemplate); if (!tempFile.open()) { QMessageBox::warning(this, _("Failed to create temp file"), _("Creating temp file failed. Please check the " "permission or disk space.")); return QString(); } tempFile.setAutoRemove(false); return tempFile.fileName(); } QString PinyinDictManager::checkOverwriteFile(const QString &dirName, const QString &importName) { QDir dir(dirName); auto fullname = dir.filePath(importName + ".dict"); if (QFile::exists(fullname)) { auto button = QMessageBox::warning( this, _("Dictionary already exists"), QString(_("%1 already exists, do you want to overwrite this " "dictionary?")) .arg(importName), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (button == QMessageBox::No) { return QString(); } } return fullname; } void PinyinDictManager::reload() { model_->loadFileList(); saveSubConfig("fcitx://config/addon/pinyin/dictmanager"); } void PinyinDictManager::importFromFile() { QString name = QFileDialog::getOpenFileName(this, _("Select Dictionary File")); if (name.isEmpty()) { return; } QFileInfo info(name); QString importName = info.fileName(); if (importName.endsWith(".txt")) { importName = importName.left(importName.size() - 4); } importName = confirmImportFileName(importName); if (importName.isEmpty()) { return; } auto directory = prepareDirectory(); if (directory.isEmpty()) { return; } QDir dir(directory); auto fullname = dir.filePath(importName + ".dict"); auto tempFile = prepareTempFile(fullname + "_XXXXXX"); if (tempFile.isEmpty()) { return; } setEnabled(false); pipeline_->reset(); auto runner = new ProcessRunner( "libime_pinyindict", QStringList() << info.fileName() << tempFile, tempFile); auto rename = new RenameFile(tempFile, fullname); pipeline_->addJob(runner); pipeline_->addJob(rename); pipeline_->start(); } void PinyinDictManager::importFromSogou() { QString name = QFileDialog::getOpenFileName( this, _("Select scel file"), QString(), _("Scel file (*.scel)")); if (name.isEmpty()) { return; } QFileInfo info(name); QString importName = info.fileName(); if (importName.endsWith(".scel")) { importName = importName.left(importName.size() - 5); } importName = confirmImportFileName(importName); if (importName.isEmpty()) { return; } auto directory = prepareDirectory(); if (directory.isEmpty()) { return; } auto runtimeDirectory = StandardPath::global().userDirectory(StandardPath::Type::Runtime); if (runtimeDirectory.empty()) { QMessageBox::warning(this, _("Failed to get runtime directory"), _("Create directory failed. Please check the " "permission or disk space.")); return; } auto fullname = checkOverwriteFile(directory, importName); if (fullname.isEmpty()) { return; } auto tempFile = prepareTempFile(fullname + "_XXXXXX"); QDir runtimeDir(QString::fromLocal8Bit(runtimeDirectory.data(), runtimeDirectory.size())); auto txtFile = prepareTempFile(runtimeDir.filePath("scel_txt_XXXXXX")); if (tempFile.isEmpty() || txtFile.isEmpty()) { if (!tempFile.isEmpty()) { QFile::remove(tempFile); } return; } setEnabled(false); pipeline_->reset(); auto scelrunner = new ProcessRunner( "scel2org5", QStringList() << info.absoluteFilePath() << "-o" << txtFile, txtFile); pipeline_->addJob(scelrunner); auto dictrunner = new ProcessRunner( "libime_pinyindict", QStringList() << txtFile << tempFile, tempFile); pipeline_->addJob(dictrunner); auto rename = new RenameFile(tempFile, fullname); pipeline_->addJob(rename); pipeline_->start(); } void PinyinDictManager::importFromSogouOnline() { BrowserDialog dialog(this); int result = dialog.exec(); if (result != QDialog::Accepted) { return; } QString importName = dialog.name(); importName = confirmImportFileName(importName); if (importName.isEmpty()) { return; } auto directory = prepareDirectory(); if (directory.isEmpty()) { return; } auto runtimeDirectory = StandardPath::global().userDirectory(StandardPath::Type::Runtime); if (runtimeDirectory.empty()) { QMessageBox::warning(this, _("Failed to get runtime directory"), _("Create directory failed. Please check the " "permission or disk space.")); return; } auto fullname = checkOverwriteFile(directory, importName); if (fullname.isEmpty()) { return; } QDir runtimeDir(QString::fromLocal8Bit(runtimeDirectory.data(), runtimeDirectory.size())); auto tempFile = prepareTempFile(fullname + "_XXXXXX"); auto txtFile = prepareTempFile(runtimeDir.filePath("scel_txt_XXXXXX")); auto scelFile = prepareTempFile(runtimeDir.filePath("scel_XXXXXX")); QStringList list; list << tempFile << txtFile << scelFile; for (const auto &file : list) { if (file.isEmpty()) { for (const auto &file : list) { if (!file.isEmpty()) { QFile::remove(file); } } return; } } setEnabled(false); pipeline_->reset(); auto fileDownloader = new FileDownloader(dialog.url(), scelFile); pipeline_->addJob(fileDownloader); auto scelrunner = new ProcessRunner( "scel2org5", QStringList() << scelFile << "-o" << txtFile, txtFile); pipeline_->addJob(scelrunner); auto dictrunner = new ProcessRunner( "libime_pinyindict", QStringList() << txtFile << tempFile, tempFile); pipeline_->addJob(dictrunner); auto rename = new RenameFile(tempFile, fullname); pipeline_->addJob(rename); pipeline_->start(); } void PinyinDictManager::removeAllDict() { int ret = QMessageBox::question( this, _("Confirm deletion"), QString::fromUtf8(_("Are you sure to delete all dictionaries?")), QMessageBox::Ok | QMessageBox::Cancel); if (ret != QMessageBox::Ok) { return; } for (int i = 0; i < model_->rowCount(); i++) { QModelIndex index = model_->index(i); std::string fileName = index.data(Qt::UserRole).toString().toLocal8Bit().constData(); auto fullPath = StandardPath::global().locate( StandardPath::Type::PkgData, "pinyin/dictionaries/" + fileName); QFile::remove(QString::fromLocal8Bit(fullPath.data(), fullPath.size())); } reload(); } void PinyinDictManager::removeDict() { QModelIndex index = listView_->currentIndex(); if (!index.isValid()) { return; } QString curName = index.data(Qt::DisplayRole).toString(); std::string fileName = index.data(Qt::UserRole).toString().toLocal8Bit().constData(); auto fullPath = StandardPath::global().locate( StandardPath::Type::PkgData, "pinyin/dictionaries/" + fileName); int ret = QMessageBox::question( this, _("Confirm deletion"), QString::fromUtf8(_("Are you sure to delete %1?")).arg(curName), QMessageBox::Ok | QMessageBox::Cancel); if (ret == QMessageBox::Ok) { bool ok = QFile::remove( QString::fromLocal8Bit(fullPath.data(), fullPath.size())); if (!ok) { QMessageBox::warning( this, _("File Operation Failed"), QString::fromUtf8(_("Error while deleting %1.")).arg(curName)); } else { reload(); } } } void PinyinDictManager::clearUserDict() { emit saveSubConfig("fcitx://config/addon/pinyin/clearuserdict"); } void PinyinDictManager::clearAllDict() { emit saveSubConfig("fcitx://config/addon/pinyin/clearalldict"); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pinyindictmanager.h000066400000000000000000000040541361043647100302400ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_PINYINDICTMANAGER_H_ #define _PINYINDICTMANAGER_PINYINDICTMANAGER_H_ #include "filelistmodel.h" #include "pipeline.h" #include "ui_pinyindictmanager.h" #include namespace fcitx { class PinyinDictManager : public FcitxQtConfigUIWidget, public Ui::PinyinDictManager { Q_OBJECT public: PinyinDictManager(QWidget *widget); void load() override; void save() override; QString title() override; bool asyncSave() override; private slots: void importFromFile(); void importFromSogou(); void importFromSogouOnline(); void removeDict(); void removeAllDict(); void clearUserDict(); void clearAllDict(); private: QString confirmImportFileName(const QString &defaultName); QString prepareDirectory(); QString prepareTempFile(const QString &tempFileTemplate); QString checkOverwriteFile(const QString &dirName, const QString &importName); void reload(); QAction *importFromFileAction_; QAction *importFromSogou_; QAction *importFromSogouOnline_; QAction *clearUserDictAction_; QAction *clearAllDataAction_; FileListModel *model_; Pipeline *pipeline_; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_PINYINDICTMANAGER_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pinyindictmanager.json000066400000000000000000000000701361043647100307540ustar00rootroot00000000000000{ "addon": "pinyin", "files": ["dictmanager"] } fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pinyindictmanager.ui000066400000000000000000000041471361043647100304310ustar00rootroot00000000000000 PinyinDictManager 0 0 371 419 &Import .. &Remove .. Remove &All .. &Clear Dict .. Qt::Vertical 20 40 fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pipeline.cpp000066400000000000000000000033741361043647100266770ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pipeline.h" namespace fcitx { Pipeline::Pipeline(QObject *parent) : QObject(parent) {} void Pipeline::addJob(PipelineJob *job) { job->setParent(this); jobs_.push_back(job); connect(job, &PipelineJob::finished, this, [this](bool success) { if (success) { startNext(); } else { emitFinished(false); } }); } void Pipeline::abort() { if (index_ < 0) { return; } jobs_[index_]->abort(); index_ = -1; } void Pipeline::reset() { abort(); for (auto job : jobs_) { delete job; } jobs_.clear(); } void Pipeline::start() { Q_ASSERT(!jobs_.isEmpty()); index_ = -1; startNext(); } void Pipeline::startNext() { if (index_ + 1 == jobs_.size()) { emitFinished(true); return; } index_ += 1; jobs_[index_]->start(); } void Pipeline::emitFinished(bool result) { for (auto job : jobs_) { job->cleanUp(); } emit finished(result); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pipeline.h000066400000000000000000000025321361043647100263370ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_PIPELINE_H_ #define _PINYINDICTMANAGER_PIPELINE_H_ #include "pipelinejob.h" #include #include namespace fcitx { class Pipeline : public QObject { Q_OBJECT public: Pipeline(QObject *parent = nullptr); void addJob(PipelineJob *job); void start(); void abort(); void reset(); signals: void finished(bool); void messages(const QString &message); private: void startNext(); void emitFinished(bool); QVector jobs_; int index_ = -1; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_PIPELINE_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pipelinejob.cpp000066400000000000000000000015721361043647100273700ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pipelinejob.h" namespace fcitx { PipelineJob::PipelineJob(QObject *parent) : QObject(parent) {} } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/pipelinejob.h000066400000000000000000000024011361043647100270250ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_PIPELINEJOB_H_ #define _PINYINDICTMANAGER_PIPELINEJOB_H_ #include #include namespace fcitx { class PipelineJob : public QObject { Q_OBJECT public: PipelineJob(QObject *parent = nullptr); virtual void start() = 0; virtual void abort() = 0; virtual void cleanUp() = 0; signals: void finished(bool success); void message(QMessageBox::Icon icon, const QString &message); }; } // namespace fcitx #endif // _PINYINDICTMANAGER_PIPELINEJOB_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/processrunner.cpp000066400000000000000000000042121361043647100277720ustar00rootroot00000000000000// // Copyright (C) 2013~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "processrunner.h" #include "guicommon.h" #include "log.h" #include #include #include #include #include namespace fcitx { ProcessRunner::ProcessRunner(const QString &bin, const QStringList &args, const QString &file, QObject *parent) : PipelineJob(parent), bin_(bin), args_(args), file_(file) { connect(&process_, qOverload(&QProcess::finished), this, &ProcessRunner::processFinished); } void ProcessRunner::start() { if (process_.state() != QProcess::NotRunning) { process_.kill(); } qCDebug(dictmanager) << bin_ << args_; process_.start(bin_, args_); process_.closeReadChannel(QProcess::StandardError); process_.closeReadChannel(QProcess::StandardOutput); } void ProcessRunner::abort() { process_.kill(); } void ProcessRunner::cleanUp() { QFile::remove(file_); } void ProcessRunner::processFinished(int exitCode, QProcess::ExitStatus status) { if (status == QProcess::CrashExit) { emit message(QMessageBox::Critical, _("Converter crashed.")); emit finished(false); return; } if (exitCode != 0) { emit message(QMessageBox::Warning, _("Convert failed.")); emit finished(false); return; } emit finished(true); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/processrunner.h000066400000000000000000000027671361043647100274540ustar00rootroot00000000000000// // Copyright (C) 2013~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_PROCESSRUNNER_H_ #define _PINYINDICTMANAGER_PROCESSRUNNER_H_ #include "pipelinejob.h" #include #include #include #include namespace fcitx { class ProcessRunner : public PipelineJob { Q_OBJECT public: explicit ProcessRunner(const QString &bin, const QStringList &args, const QString &file, QObject *parent = nullptr); void start() override; void abort() override; void cleanUp() override; private slots: void processFinished(int exitCode, QProcess::ExitStatus status); private: QProcess process_; QString bin_; QStringList args_; QString file_; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_PROCESSRUNNER_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/renamefile.cpp000066400000000000000000000031671361043647100272010ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "renamefile.h" #include "guicommon.h" #include "log.h" #include #include #include #include #include namespace fcitx { RenameFile::RenameFile(const QString &from, const QString &to, QObject *parent) : PipelineJob(parent), from_(from), to_(to) {} void RenameFile::start() { bool result = ::rename(from_.toLocal8Bit().constData(), to_.toLocal8Bit().constData()) >= 0; QMetaObject::invokeMethod(this, "emitFinished", Qt::QueuedConnection, Q_ARG(bool, result)); } void RenameFile::abort() {} void RenameFile::cleanUp() {} void RenameFile::emitFinished(bool result) { if (!result) { emit message(QMessageBox::Critical, _("Converter crashed.")); return; } emit finished(result); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/gui/pinyindictmanager/renamefile.h000066400000000000000000000026411361043647100266420ustar00rootroot00000000000000// // Copyright (C) 2018~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINDICTMANAGER_RENAMEFILE_H_ #define _PINYINDICTMANAGER_RENAMEFILE_H_ #include "pipelinejob.h" #include #include #include #include #include #include namespace fcitx { class RenameFile : public PipelineJob { Q_OBJECT public: explicit RenameFile(const QString &from, const QString &to, QObject *parent = nullptr); void start() override; void abort() override; void cleanUp() override; private slots: void emitFinished(bool result); private: QString from_, to_; }; } // namespace fcitx #endif // _PINYINDICTMANAGER_RENAMEFILE_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/im/000077500000000000000000000000001361043647100204735ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/im/CMakeLists.txt000066400000000000000000000000611361043647100232300ustar00rootroot00000000000000add_subdirectory(pinyin) add_subdirectory(table) fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/000077500000000000000000000000001361043647100220015ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/CMakeLists.txt000066400000000000000000000016711361043647100245460ustar00rootroot00000000000000set(PINYIN_SOURCES pinyin.cpp ) add_library(pinyin MODULE ${PINYIN_SOURCES}) target_link_libraries(pinyin Fcitx5::Core Fcitx5::Config LibIME::Pinyin Boost::iostreams Fcitx5::Module::Punctuation Fcitx5::Module::QuickPhrase Fcitx5::Module::CloudPinyin Fcitx5::Module::Notifications Fcitx5::Module::Spell Fcitx5::Module::PinyinHelper ${FMT_TARGET}) set_target_properties(pinyin PROPERTIES PREFIX "") install(TARGETS pinyin DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(pinyin.conf.in pinyin.conf) fcitx5_translate_desktop_file(shuangpin.conf.in shuangpin.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pinyin.conf" "${CMAKE_CURRENT_BINARY_DIR}/shuangpin.conf" DESTINATION "${CMAKE_INSTALL_DATADIR}/fcitx5/inputmethod") fcitx5_translate_desktop_file(pinyin-addon.conf.in pinyin-addon.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pinyin-addon.conf" RENAME pinyin.conf DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon") fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/pinyin-addon.conf.in000066400000000000000000000004101361043647100256410ustar00rootroot00000000000000[Addon] Name=Pinyin Category=InputMethod Library=pinyin Type=SharedLibrary OnDemand=True Configurable=True [Addon/Dependencies] 0=punctuation [Addon/OptionalDependencies] 0=fullwidth 1=quickphrase 2=cloudpinyin 3=notifications 4=spell 5=pinyinhelper 6=chttrans fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/pinyin.conf.in000066400000000000000000000001441361043647100245620ustar00rootroot00000000000000[InputMethod] Name=Pinyin Icon=fcitx-pinyin Label=拼 LangCode=zh_CN Addon=pinyin Configurable=True fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/pinyin.cpp000066400000000000000000001165111361043647100240200ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pinyin.h" #include "cloudpinyin_public.h" #include "config.h" #include "notifications_public.h" #include "pinyinhelper_public.h" #include "punctuation_public.h" #include "spell_public.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace fcitx { FCITX_DEFINE_LOG_CATEGORY(pinyin, "pinyin"); #define PINYIN_DEBUG() FCITX_LOGC(pinyin, Debug) #define PINYIN_ERROR() FCITX_LOGC(pinyin, Error) bool consumePreifx(std::string_view &view, std::string_view prefix) { if (boost::starts_with(view, prefix)) { view.remove_prefix(prefix.size()); return true; } return false; } class PinyinState : public InputContextProperty { public: PinyinState(PinyinEngine *engine) : context_(engine->ime()) {} libime::PinyinContext context_; bool lastIsPunc_ = false; std::unique_ptr cancelLastEvent_; std::vector predictWords_; }; class PinyinPredictCandidateWord : public CandidateWord { public: PinyinPredictCandidateWord(PinyinEngine *engine, std::string word) : CandidateWord(Text(word)), engine_(engine), word_(std::move(word)) {} void select(InputContext *inputContext) const override { inputContext->commitString(word_); auto state = inputContext->propertyFor(&engine_->factory()); state->predictWords_.push_back(word_); // Max history size. constexpr size_t maxHistorySize = 5; if (state->predictWords_.size() > maxHistorySize) { state->predictWords_.erase(state->predictWords_.begin(), state->predictWords_.begin() + state->predictWords_.size() - maxHistorySize); } engine_->updatePredict(inputContext); } PinyinEngine *engine_; std::string word_; }; class StrokeCandidateWord : public CandidateWord { public: StrokeCandidateWord(PinyinEngine *engine, const std::string &hz, const std::string &py) : CandidateWord(), engine_(engine), hz_(std::move(hz)) { if (py.empty()) { setText(Text(hz_)); } else { setText(Text(fmt::format(_("{0} ({1})"), hz_, py))); } } void select(InputContext *inputContext) const override { inputContext->commitString(hz_); engine_->doReset(inputContext); } private: PinyinEngine *engine_; std::string hz_; }; class SpellCandidateWord : public CandidateWord { public: SpellCandidateWord(PinyinEngine *engine, const std::string &word) : CandidateWord(), engine_(engine), word_(std::move(word)) { setText(Text(word_)); } void select(InputContext *inputContext) const override { auto state = inputContext->propertyFor(&engine_->factory()); auto &context = state->context_; inputContext->commitString(context.selectedSentence() + word_); engine_->doReset(inputContext); } private: PinyinEngine *engine_; std::string word_; }; class PinyinCandidateWord : public CandidateWord { public: PinyinCandidateWord(PinyinEngine *engine, Text text, size_t idx) : CandidateWord(std::move(text)), engine_(engine), idx_(idx) {} void select(InputContext *inputContext) const override { auto state = inputContext->propertyFor(&engine_->factory()); auto &context = state->context_; if (idx_ >= context.candidates().size()) { return; } context.select(idx_); engine_->updateUI(inputContext); } PinyinEngine *engine_; size_t idx_; }; std::unique_ptr PinyinEngine::predictCandidateList(const std::vector &words) { if (words.empty()) { return nullptr; } auto candidateList = std::make_unique(); for (const auto &word : words) { candidateList->append(new PinyinPredictCandidateWord(this, word)); } candidateList->setSelectionKey(selectionKeys_); candidateList->setPageSize(*config_.pageSize); candidateList->setGlobalCursorIndex(0); return candidateList; } void PinyinEngine::initPredict(InputContext *inputContext) { inputContext->inputPanel().reset(); auto state = inputContext->propertyFor(&factory_); auto &context = state->context_; auto lmState = context.state(); state->predictWords_ = context.selectedWords(); auto words = prediction_.predict(lmState, context.selectedWords(), *config_.predictionSize); if (auto candidateList = predictCandidateList(words)) { auto &inputPanel = inputContext->inputPanel(); inputPanel.setCandidateList(std::move(candidateList)); } inputContext->updatePreedit(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); } void PinyinEngine::updatePredict(InputContext *inputContext) { inputContext->inputPanel().reset(); auto state = inputContext->propertyFor(&factory_); auto words = prediction_.predict(state->predictWords_, *config_.pageSize); if (auto candidateList = predictCandidateList(words)) { auto &inputPanel = inputContext->inputPanel(); inputPanel.setCandidateList(std::move(candidateList)); } inputContext->updatePreedit(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); } int englishNess(const std::string &input, bool sp) { auto pys = stringutils::split(input, " "); constexpr int fullWeight = -2, shortWeight = 3, invalidWeight = 6; int weight = 0; for (auto iter = pys.begin(), end = pys.end(); iter != end; ++iter) { if (sp) { if (iter->size() == 2) { weight += fullWeight; } else { if (std::next(iter) == end) { weight += shortWeight; } else { weight += invalidWeight; } } } else { if (*iter == "ng") { weight += fullWeight; } else { auto firstChr = (*iter)[0]; if (firstChr == '\'') { return 0; } else if (firstChr == 'i' || firstChr == 'u' || firstChr == 'v') { weight += invalidWeight; } else if (iter->size() <= 2) { weight += shortWeight; } else if (iter->find_first_of("aeiou") != std::string::npos) { weight += fullWeight; } else { weight += shortWeight; } } } } if (weight < 0) { return 0; } return (weight + 3) / 10; } bool isStroke(const std::string &input) { static const std::unordered_set py{'h', 'p', 's', 'z', 'n'}; return std::all_of(input.begin(), input.end(), [](char c) { return py.count(c); }); } void PinyinEngine::updateUI(InputContext *inputContext) { inputContext->inputPanel().reset(); auto state = inputContext->propertyFor(&factory_); auto &context = state->context_; if (context.selected()) { auto sentence = context.sentence(); if (!inputContext->capabilityFlags().testAny( CapabilityFlag::PasswordOrSensitive)) { context.learn(); } inputContext->updatePreedit(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); inputContext->commitString(sentence); if (*config_.predictionEnabled) { initPredict(inputContext); } context.clear(); return; } if (context.userInput().size()) { auto &candidates = context.candidates(); auto &inputPanel = inputContext->inputPanel(); if (context.candidates().size()) { auto candidateList = std::make_unique(); size_t idx = 0; candidateList->setPageSize(*config_.pageSize); candidateList->setCursorPositionAfterPaging( CursorPositionAfterPaging::ResetToFirst); std::unique_ptr cloud; if (*config_.cloudPinyinEnabled && cloudpinyin() && !inputContext->capabilityFlags().testAny( CapabilityFlag::PasswordOrSensitive)) { using namespace std::placeholders; auto fullPinyin = context.useShuangpin() ? context.candidateFullPinyin(0) : context.userInput().substr(context.selectedLength()); cloud = std::make_unique( cloudpinyin(), fullPinyin, context.selectedSentence(), inputContext, std::bind(&PinyinEngine::cloudPinyinSelected, this, _1, _2, _3)); } for (const auto &candidate : candidates) { auto candidateString = candidate.toString(); if (cloud && cloud->filled() && cloud->word() == candidateString) { cloud.reset(); } candidateList->append(new PinyinCandidateWord( this, Text(std::move(candidateString)), idx)); idx++; } int engNess; auto parsedPy = context.preedit().substr(context.selectedSentence().size()); if (spell() && (engNess = englishNess(parsedPy, context.useShuangpin()))) { auto py = context.userInput().substr(context.selectedLength()); auto results = spell()->call( "en", SpellProvider::Custom, py, engNess); int idx = 1; for (auto &result : results) { auto actualIdx = idx; if (actualIdx > candidateList->totalSize()) { actualIdx = candidateList->totalSize(); } if (cloud && cloud->filled() && cloud->word() == result) { cloud.reset(); } candidateList->insert(actualIdx, new SpellCandidateWord(this, result)); idx++; } } // if we didn't got it from cache or whatever, and not empty // otherwise we can throw it away. if (cloud && (!cloud->filled() || !cloud->word().empty())) { auto index = *config_.cloudPinyinIndex; if (index >= candidateList->totalSize()) { index = candidateList->totalSize(); } candidateList->insert(index - 1, cloud.release()); } if (pinyinhelper() && context.selectedLength() == 0 && isStroke(context.userInput())) { int limit = (context.userInput().size() + 4) / 5; if (limit > 3) { limit = 3; } auto results = pinyinhelper()->call( context.userInput(), limit); int desiredPos = *config_.pageSize - static_cast(results.size()); if (desiredPos < 0) { desiredPos = 0; } for (auto &result : results) { utf8::getChar(result.first); auto py = pinyinhelper()->call( utf8::getChar(result.first)); auto pystr = stringutils::join(py, " "); if (desiredPos > candidateList->size()) { desiredPos = candidateList->size(); } candidateList->insert( desiredPos, new StrokeCandidateWord(this, result.first, pystr)); } } candidateList->setSelectionKey(selectionKeys_); candidateList->setGlobalCursorIndex(0); inputPanel.setCandidateList(std::move(candidateList)); } auto preeditWithCursor = context.preeditWithCursor(); Text preedit(preeditWithCursor.first); preedit.setCursor(preeditWithCursor.second); if (config_.showPreeditInApplication.value() && inputContext->capabilityFlags().test(CapabilityFlag::Preedit)) { inputPanel.setClientPreedit(preedit); } else { inputPanel.setPreedit(preedit); inputPanel.setClientPreedit( Text(context.sentence(), TextFormatFlag::Underline)); } } inputContext->updatePreedit(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); } PinyinEngine::PinyinEngine(Instance *instance) : instance_(instance), factory_([this](InputContext &) { return new PinyinState(this); }) { ime_ = std::make_unique( std::make_unique(), std::make_unique( libime::DefaultLanguageModelResolver::instance() .languageModelFileForLanguage("zh_CN"))); ime_->dict()->load(libime::PinyinDictionary::SystemDict, LIBIME_INSTALL_PKGDATADIR "/sc.dict", libime::PinyinDictFormat::Binary); prediction_.setUserLanguageModel(ime_->model()); auto &standardPath = StandardPath::global(); do { auto file = standardPath.openUser(StandardPath::Type::PkgData, "pinyin/user.dict", O_RDONLY); if (file.fd() < 0) { break; } try { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(file.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); ime_->dict()->load(libime::PinyinDictionary::UserDict, in, libime::PinyinDictFormat::Binary); } catch (const std::exception &e) { PINYIN_ERROR() << "Failed to load pinyin dict: " << e.what(); } } while (0); do { auto file = standardPath.openUser(StandardPath::Type::PkgData, "pinyin/user.history", O_RDONLY); try { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(file.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); ime_->model()->load(in); } catch (const std::exception &e) { PINYIN_ERROR() << "Failed to load pinyin history: " << e.what(); } } while (0); ime_->setScoreFilter(1); reloadConfig(); instance_->inputContextManager().registerProperty("pinyinState", &factory_); KeySym syms[] = { FcitxKey_1, FcitxKey_2, FcitxKey_3, FcitxKey_4, FcitxKey_5, FcitxKey_6, FcitxKey_7, FcitxKey_8, FcitxKey_9, FcitxKey_0, }; KeyStates states; for (auto sym : syms) { selectionKeys_.emplace_back(sym, states); } predictionAction_.setShortText(_("Prediction")); predictionAction_.setLongText(_("Show prediction words")); predictionAction_.setIcon(*config_.predictionEnabled ? "fcitx-remind-active" : "fcitx-remind-inactive"); predictionAction_.connect( [this](InputContext *ic) { config_.predictionEnabled.setValue(!(*config_.predictionEnabled)); predictionAction_.setIcon(*config_.predictionEnabled ? "fcitx-remind-active" : "fcitx-remind-inactive"); predictionAction_.update(ic); }); instance_->userInterfaceManager().registerAction("pinyin-prediction", &predictionAction_); } PinyinEngine::~PinyinEngine() {} void PinyinEngine::loadExtraDict() { auto &standardPath = StandardPath::global(); auto files = standardPath.multiOpen(StandardPath::Type::PkgData, "pinyin/dictionaries", O_RDONLY, filter::Suffix(".dict")); ime_->dict()->removeAll(); for (const auto &file : files) { try { if (file.second.fd() < 0) { continue; } PINYIN_DEBUG() << "Loading extra dictionary: " << file.first; boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(file.second.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); ime_->dict()->addEmptyDict(); ime_->dict()->load(ime_->dict()->dictSize() - 1, in, libime::PinyinDictFormat::Binary); } catch (const std::exception &e) { PINYIN_ERROR() << "Failed to load pinyin dict " << file.first << ": " << e.what(); } } } void PinyinEngine::reloadConfig() { readAsIni(config_, "conf/pinyin.conf"); ime_->setNBest(*config_.nbest); if (*config_.shuangpinProfile == ShuangpinProfileEnum::Custom) { auto file = StandardPath::global().open(StandardPath::Type::PkgConfig, "pinyin/sp.dat", O_RDONLY); try { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(file.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); ime_->setShuangpinProfile( std::make_shared(in)); } catch (const std::exception &) { } } else { libime::ShuangpinBuiltinProfile profile; #define TRANS_SP_PROFILE(PROFILE) \ case ShuangpinProfileEnum::PROFILE: \ profile = libime::ShuangpinBuiltinProfile::PROFILE; \ break; switch (*config_.shuangpinProfile) { TRANS_SP_PROFILE(Ziranma) TRANS_SP_PROFILE(MS) TRANS_SP_PROFILE(Ziguang) TRANS_SP_PROFILE(ABC) TRANS_SP_PROFILE(Zhongwenzhixing) TRANS_SP_PROFILE(PinyinJiajia) TRANS_SP_PROFILE(Xiaohe) default: profile = libime::ShuangpinBuiltinProfile::Ziranma; break; } ime_->setShuangpinProfile( std::make_shared(profile)); } libime::PinyinFuzzyFlags flags; const auto &fuzzyConfig = *config_.fuzzyConfig; #define SET_FUZZY_FLAG(VAR, ENUM) \ if (*fuzzyConfig.VAR) { \ flags |= libime::PinyinFuzzyFlag::ENUM; \ } SET_FUZZY_FLAG(ue, VE_UE) SET_FUZZY_FLAG(ng, NG_GN) SET_FUZZY_FLAG(inner, Inner) SET_FUZZY_FLAG(v, V_U) SET_FUZZY_FLAG(an, AN_ANG) SET_FUZZY_FLAG(en, EN_ENG) SET_FUZZY_FLAG(ian, IAN_IANG) SET_FUZZY_FLAG(in, IN_ING) SET_FUZZY_FLAG(ou, U_OU) SET_FUZZY_FLAG(uan, UAN_UANG) SET_FUZZY_FLAG(c, C_CH) SET_FUZZY_FLAG(f, F_H) SET_FUZZY_FLAG(l, L_N) SET_FUZZY_FLAG(s, S_SH) SET_FUZZY_FLAG(z, Z_ZH) ime_->setFuzzyFlags(flags); loadExtraDict(); } void PinyinEngine::activate(const fcitx::InputMethodEntry &entry, fcitx::InputContextEvent &event) { auto inputContext = event.inputContext(); // Request full width. fullwidth(); chttrans(); for (auto actionName : {"chttrans", "punctuation", "fullwidth"}) { if (auto action = instance_->userInterfaceManager().lookupAction(actionName)) { inputContext->statusArea().addAction(StatusGroup::InputMethod, action); } } inputContext->statusArea().addAction(StatusGroup::InputMethod, &predictionAction_); auto state = inputContext->propertyFor(&factory_); state->context_.setUseShuangpin(entry.uniqueName() == "shuangpin"); } void PinyinEngine::deactivate(const fcitx::InputMethodEntry &entry, fcitx::InputContextEvent &event) { auto inputContext = event.inputContext(); inputContext->statusArea().clearGroup(StatusGroup::InputMethod); if (event.type() == EventType::InputContextSwitchInputMethod) { auto state = inputContext->propertyFor(&factory_); if (state->context_.size()) { inputContext->commitString(state->context_.userInput()); } } reset(entry, event); } void PinyinEngine::keyEvent(const InputMethodEntry &entry, KeyEvent &event) { FCITX_UNUSED(entry); PINYIN_DEBUG() << "Pinyin receive key: " << event.key() << " " << event.isRelease(); // by pass all key release if (event.isRelease()) { return; } // and by pass all modifier if (event.key().isModifier()) { return; } if (cloudpinyin() && event.key().checkKeyList( cloudpinyin()->call())) { config_.cloudPinyinEnabled.setValue(!*config_.cloudPinyinEnabled); safeSaveAsIni(config_, "conf/pinyin.conf"); notifications()->call( "fcitx-cloudpinyin-toggle", "fcitx", "", _("Cloud Pinyin Status"), *config_.cloudPinyinEnabled ? _("Cloud Pinyin is enabled.") : _("Cloud Pinyin is disabled."), -1); if (*config_.cloudPinyinEnabled) { cloudpinyin()->call(); } event.filterAndAccept(); return; } auto inputContext = event.inputContext(); auto state = inputContext->propertyFor(&factory_); bool lastIsPunc = state->lastIsPunc_; state->lastIsPunc_ = false; // check if we can select candidate. auto candidateList = inputContext->inputPanel().candidateList(); if (candidateList) { int idx = event.key().keyListIndex(selectionKeys_); if (idx >= 0) { event.filterAndAccept(); if (idx < candidateList->size()) { candidateList->candidate(idx)->select(inputContext); } return; } if (event.key().checkKeyList(*config_.prevPage)) { auto pageable = candidateList->toPageable(); if (!pageable->hasPrev()) { if (pageable->usedNextBefore()) { event.filterAndAccept(); return; } } else { event.filterAndAccept(); pageable->prev(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); return; } } if (event.key().checkKeyList(*config_.nextPage)) { event.filterAndAccept(); candidateList->toPageable()->next(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); return; } if (auto movable = candidateList->toCursorMovable()) { if (event.key().checkKeyList(*config_.nextCandidate)) { movable->nextCandidate(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); return event.filterAndAccept(); } else if (event.key().checkKeyList(*config_.prevCandidate)) { movable->prevCandidate(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); return event.filterAndAccept(); } } } // In prediction, as long as it's not candidate selection, clear, then // fallback // to remaining operation. if (!state->predictWords_.empty()) { state->predictWords_.clear(); inputContext->inputPanel().reset(); inputContext->updatePreedit(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); } auto checkSp = [this](const KeyEvent &event, PinyinState *state) { auto shuangpinProfile = ime_->shuangpinProfile(); return state->context_.useShuangpin() && shuangpinProfile && event.key().isSimple() && shuangpinProfile->validInput().count( Key::keySymToUnicode(event.key().sym())); }; if (event.key().isLAZ() || (event.key().check(FcitxKey_apostrophe) && state->context_.size()) || (state->context_.size() && checkSp(event, state))) { // first v, use it to trigger quickphrase if (!state->context_.useShuangpin() && quickphrase() && event.key().check(FcitxKey_v) && !state->context_.size()) { quickphrase()->call( inputContext, "", "v", "", "", Key(FcitxKey_None)); event.filterAndAccept(); return; } state->context_.type(Key::keySymToUTF8(event.key().sym())); event.filterAndAccept(); } else if (state->context_.size()) { // key to handle when it is not empty. if (event.key().check(FcitxKey_BackSpace)) { if (state->context_.selectedLength()) { state->context_.cancel(); } else { state->context_.backspace(); } event.filterAndAccept(); } else if (event.key().check(FcitxKey_Delete)) { state->context_.del(); event.filterAndAccept(); } else if (event.key().check(FcitxKey_Home)) { state->context_.setCursor(state->context_.selectedLength()); event.filterAndAccept(); } else if (event.key().check(FcitxKey_End)) { state->context_.setCursor(state->context_.size()); event.filterAndAccept(); } else if (event.key().check(FcitxKey_Left)) { if (state->context_.cursor() == state->context_.selectedLength()) { state->context_.cancel(); } auto cursor = state->context_.cursor(); if (cursor > 0) { state->context_.setCursor(cursor - 1); } event.filterAndAccept(); } else if (event.key().check(FcitxKey_Right)) { auto cursor = state->context_.cursor(); if (cursor < state->context_.size()) { state->context_.setCursor(cursor + 1); } event.filterAndAccept(); } else if (event.key().check(FcitxKey_Left, KeyState::Ctrl)) { if (state->context_.cursor() == state->context_.selectedLength()) { state->context_.cancel(); } auto cursor = state->context_.pinyinBeforeCursor(); if (cursor >= 0) { state->context_.setCursor(cursor); } event.filterAndAccept(); } else if (event.key().check(FcitxKey_Right, KeyState::Ctrl)) { auto cursor = state->context_.pinyinAfterCursor(); if (cursor >= 0 && static_cast(cursor) <= state->context_.size()) { state->context_.setCursor(cursor); } event.filterAndAccept(); } else if (event.key().check(FcitxKey_Escape)) { state->context_.clear(); event.filterAndAccept(); } else if (event.key().check(FcitxKey_Return)) { inputContext->commitString(state->context_.userInput()); state->context_.clear(); event.filterAndAccept(); } else if (event.key().check(FcitxKey_space)) { auto candidateList = inputContext->inputPanel().candidateList(); if (candidateList && candidateList->size()) { event.filterAndAccept(); int idx = candidateList->cursorIndex(); if (idx < 0) { idx = 0; } inputContext->inputPanel() .candidateList() ->candidate(idx) ->select(inputContext); return; } } } else { if (event.key().check(FcitxKey_BackSpace)) { if (lastIsPunc) { auto puncStr = punctuation()->call( "zh_CN", inputContext); if (!puncStr.empty()) { // forward the original key is the best choice. // forward the original key is the best choice. auto ref = inputContext->watch(); state->cancelLastEvent_ = instance()->eventLoop().addTimeEvent( CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 300, 0, [this, ref, puncStr](EventSourceTime *, uint64_t) { if (auto inputContext = ref.get()) { inputContext->commitString(puncStr); auto state = inputContext->propertyFor(&factory_); state->cancelLastEvent_.reset(); } return true; }); event.filter(); return; } } } } if (!event.filtered()) { if (event.key().states().testAny(KeyState::SimpleMask)) { return; } // if it gonna commit something auto c = Key::keySymToUnicode(event.key().sym()); if (c) { if (inputContext->inputPanel().candidateList() && inputContext->inputPanel().candidateList()->size()) { inputContext->inputPanel() .candidateList() ->candidate(0) ->select(inputContext); } auto punc = punctuation()->call( "zh_CN", inputContext, c); if (event.key().check(FcitxKey_semicolon) && quickphrase()) { auto keyString = utf8::UCS4ToUTF8(c); // s is punc or key auto output = punc.size() ? punc : keyString; // alt is key or empty auto altOutput = punc.size() ? keyString : ""; // if no punc: key -> key (s = key, alt = empty) // if there's punc: key -> punc, return -> key (s = punc, alt = // key) std::string text; if (!output.empty()) { if (!altOutput.empty()) { text = boost::str( boost::format( _("Press %1% for %2% and %3% for %4%")) % keyString % output % _("Return") % altOutput); } else { text = boost::str(boost::format(_("Press %1% for %2%")) % keyString % altOutput); } } quickphrase()->call( inputContext, text, "", output, altOutput, Key(FcitxKey_semicolon)); event.filterAndAccept(); return; } if (punc.size()) { event.filterAndAccept(); inputContext->commitString(punc); } state->lastIsPunc_ = true; } } if (event.filtered() && event.accepted()) { updateUI(inputContext); } } void PinyinEngine::setSubConfig(const std::string &path, const RawConfig &) { if (path == "dictmanager") { loadExtraDict(); } else if (path == "clearuserdict") { ime_->dict()->clear(libime::PinyinDictionary::UserDict); } else if (path == "clearalldict") { ime_->dict()->clear(libime::PinyinDictionary::UserDict); ime_->model()->history().clear(); ; } } void PinyinEngine::reset(const InputMethodEntry &, InputContextEvent &event) { auto inputContext = event.inputContext(); doReset(inputContext); } void PinyinEngine::doReset(InputContext *inputContext) { auto state = inputContext->propertyFor(&factory_); state->context_.clear(); state->predictWords_.clear(); inputContext->inputPanel().reset(); inputContext->updatePreedit(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); // state->lastIsPunc_ = false; } void PinyinEngine::save() { safeSaveAsIni(config_, "conf/pinyin.conf"); auto &standardPath = StandardPath::global(); standardPath.safeSave( StandardPath::Type::PkgData, "pinyin/user.dict", [this](int fd) { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_sink> buffer(fd, boost::iostreams::file_descriptor_flags:: never_close_handle); std::ostream out(&buffer); try { ime_->dict()->save(libime::PinyinDictionary::UserDict, out, libime::PinyinDictFormat::Binary); return static_cast(out); } catch (const std::exception &e) { PINYIN_ERROR() << "Failed to save pinyin dict: " << e.what(); return false; } }); standardPath.safeSave( StandardPath::Type::PkgData, "pinyin/user.history", [this](int fd) { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_sink> buffer(fd, boost::iostreams::file_descriptor_flags:: never_close_handle); std::ostream out(&buffer); try { ime_->model()->save(out); return true; } catch (const std::exception &e) { PINYIN_ERROR() << "Failed to save pinyin history: " << e.what(); return false; } }); } void PinyinEngine::cloudPinyinSelected(InputContext *inputContext, const std::string &selected, const std::string &word) { auto state = inputContext->propertyFor(&factory_); auto words = state->context_.selectedWords(); auto preedit = state->context_.preedit(); do { if (!stringutils::startsWith(preedit, selected)) { break; } preedit = preedit.substr(selected.size()); auto pinyins = stringutils::split(preedit, " '"); std::string_view wordView = word; if (pinyins.empty() || pinyins.size() != utf8::length(word)) { break; } const auto &candidates = state->context_.candidates(); auto pinyinsIter = pinyins.begin(); auto pinyinsEnd = pinyins.end(); if (candidates.size()) { const auto &bestSentence = candidates[0].sentence(); auto iter = bestSentence.begin(); auto end = bestSentence.end(); while (iter != end) { auto consumed = wordView; if (!consumePreifx(consumed, (*iter)->word())) { break; } if ((*iter)->word().size()) { words.push_back((*iter)->word()); PINYIN_DEBUG() << "Cloud Pinyin can reuse segment " << (*iter)->word(); auto pinyinNode = static_cast(*iter); auto pinyinSize = pinyinNode->encodedPinyin().size() / 2; if (pinyinSize && static_cast(std::distance( pinyinsIter, pinyinsEnd)) >= pinyinSize) { pinyinsIter += pinyinSize; } else { break; } } wordView = consumed; iter++; } } // if pinyin is not valid, it may throw try { if (utf8::length(wordView) == 1 && std::all_of(words.begin(), words.end(), [](const std::string &w) { return utf8::length(w) == 1; })) { words = state->context_.selectedWords(); auto joined = stringutils::join(pinyins.begin(), pinyins.end(), "'"); words.push_back(word); ime_->dict()->addWord(libime::PinyinDictionary::UserDict, joined, word); } else { auto joined = stringutils::join(pinyinsIter, pinyinsEnd, "'"); ime_->dict()->addWord(libime::PinyinDictionary::UserDict, joined, wordView); words.push_back(std::string{wordView}); } ime_->model()->history().add(words); } catch (const std::exception &e) { } } while (0); state->context_.clear(); inputContext->commitString(selected + word); inputContext->inputPanel().reset(); if (*config_.predictionEnabled) { state->predictWords_ = words; updatePredict(inputContext); } inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); } } // namespace fcitx FCITX_ADDON_FACTORY(fcitx::PinyinEngineFactory) fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/pinyin.h000066400000000000000000000161001361043647100234560ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYIN_PINYIN_H_ #define _PINYIN_PINYIN_H_ #include #include #include #include #include #include #include #include #include #include #include #include namespace fcitx { FCITX_CONFIG_ENUM(ShuangpinProfileEnum, Ziranma, MS, Ziguang, ABC, Zhongwenzhixing, PinyinJiajia, Xiaohe, Custom) FCITX_CONFIGURATION( FuzzyConfig, Option ue{this, "VE_UE", _("ue -> ve"), true}; Option ng{this, "NG_GN", _("gn -> ng"), true}; Option inner{this, "Inner", _("Inner Segment (xian -> xi'an)"), true}; Option v{this, "V_U", _("u <-> v"), false}; Option an{this, "AN_ANG", _("an <-> ang"), false}; Option en{this, "EN_ENG", _("en <-> eng"), false}; Option ian{this, "IAN_IANG", _("ian <-> iang"), false}; Option in{this, "IN_ING", _("in <-> ing"), false}; Option ou{this, "U_OU", _("u <-> ou"), false}; Option uan{this, "UAN_UANG", _("uan <-> uang"), false}; Option c{this, "C_CH", _("c <-> ch"), false}; Option f{this, "F_H", _("f <-> h"), false}; Option l{this, "L_N", _("l <-> n"), false}; Option s{this, "S_SH", _("s <-> sh"), false}; Option z{this, "Z_ZH", _("z <-> zh"), false};) FCITX_CONFIGURATION( PinyinEngineConfig, Option pageSize{this, "PageSize", _("Page size"), 5, IntConstrain(3, 10)}; Option predictionSize{ this, "PredictionSize", _("Prediction Size"), 10, IntConstrain(3, 20)}; Option predictionEnabled{this, "Prediction", _("Enable Prediction"), false}; Option cloudPinyinEnabled{this, "CloudPinyinEnabled", _("Enable Cloud Pinyin"), true}; Option cloudPinyinIndex{this, "CloudPinyinIndex", _("Cloud Pinyin Index"), 2, IntConstrain(1, 10)}; Option showPreeditInApplication{ this, "PreeditInApplicaation", _("Use preedit in application when possible"), false}; KeyListOption prevPage{ this, "PrevPage", _("Prev Page"), {Key(FcitxKey_minus), Key(FcitxKey_Up)}, KeyListConstrain({KeyConstrainFlag::AllowModifierLess})}; KeyListOption nextPage{ this, "NextPage", _("Next Page"), {Key(FcitxKey_equal), Key(FcitxKey_Down)}, KeyListConstrain({KeyConstrainFlag::AllowModifierLess})}; KeyListOption prevCandidate{ this, "PrevCandidate", _("Prev Candidate"), {Key("Shift+Tab")}, KeyListConstrain({KeyConstrainFlag::AllowModifierLess})}; KeyListOption nextCandidate{ this, "NextCandidate", _("Next Candidate"), {Key("Tab")}, KeyListConstrain({KeyConstrainFlag::AllowModifierLess})}; Option nbest{this, "Number of sentence", _("Number of Sentence"), 2, IntConstrain(1, 3)}; Option shuangpinProfile{ this, "ShuangpinProfile", _("Shuangpin Profile"), ShuangpinProfileEnum::Ziranma}; Option fuzzyConfig{this, "Fuzzy", _("Fuzzy Pinyin Settings")}; ExternalOption dictmanager{this, "DictManager", _("Dictionaries"), "fcitx://config/addon/pinyin/dictmanager"};); class PinyinState; class EventSourceTime; class CandidateList; class PinyinEngine final : public InputMethodEngine { public: PinyinEngine(Instance *instance); ~PinyinEngine(); Instance *instance() { return instance_; } void activate(const InputMethodEntry &entry, InputContextEvent &event) override; void deactivate(const InputMethodEntry &entry, InputContextEvent &event) override; void keyEvent(const InputMethodEntry &entry, KeyEvent &keyEvent) override; void reloadConfig() override; void reset(const InputMethodEntry &entry, InputContextEvent &event) override; void setSubConfig(const std::string &path, const fcitx::RawConfig &) override; void doReset(InputContext *ic); void save() override; auto &factory() { return factory_; } const Configuration *getConfig() const override { return &config_; } void setConfig(const RawConfig &config) override { config_.load(config, true); safeSaveAsIni(config_, "conf/pinyin.conf"); reloadConfig(); } libime::PinyinIME *ime() { return ime_.get(); } void initPredict(InputContext *ic); void updatePredict(InputContext *ic); std::unique_ptr predictCandidateList(const std::vector &words); void updateUI(InputContext *inputContext); private: void cloudPinyinSelected(InputContext *inputContext, const std::string &selected, const std::string &word); void loadExtraDict(); Instance *instance_; PinyinEngineConfig config_; std::unique_ptr ime_; KeyList selectionKeys_; FactoryFor factory_; SimpleAction predictionAction_; libime::Prediction prediction_; FCITX_ADDON_DEPENDENCY_LOADER(quickphrase, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(cloudpinyin, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(fullwidth, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(chttrans, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(punctuation, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(notifications, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(pinyinhelper, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(spell, instance_->addonManager()); }; class PinyinEngineFactory : public AddonFactory { public: AddonInstance *create(AddonManager *manager) override { return new PinyinEngine(manager->instance()); } }; } // namespace fcitx #endif // _PINYIN_PINYIN_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/im/pinyin/shuangpin.conf.in000066400000000000000000000001521361043647100252470ustar00rootroot00000000000000[InputMethod] Name=Shuangpin Icon=fcitx-shuangpin Label=双 LangCode=zh_CN Addon=pinyin Configurable=True fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/000077500000000000000000000000001361043647100215625ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/CMakeLists.txt000066400000000000000000000022611361043647100243230ustar00rootroot00000000000000set(TABLE_SOURCES engine.cpp state.cpp ime.cpp context.cpp ) add_library(table MODULE ${TABLE_SOURCES}) target_link_libraries(table Fcitx5::Core Fcitx5::Config LibIME::Table Boost::iostreams Fcitx5::Module::Punctuation Fcitx5::Module::QuickPhrase Fcitx5::Module::PinyinHelper LibIME::Pinyin ${FMT_TARGET}) set_target_properties(table PROPERTIES PREFIX "") target_compile_definitions(table PRIVATE FCITX_STRINGUTILS_ENABLE_BOOST_STRING_VIEW) install(TARGETS table DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(table.conf.in table.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/table.conf" DESTINATION "${CMAKE_INSTALL_DATADIR}/fcitx5/addon") file(GLOB TABLE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.conf.in.in) foreach(TABLE_ORIG ${TABLE_FILES}) get_filename_component(TABLE_NAME "${TABLE_ORIG}" NAME_WE) configure_file(${TABLE_NAME}.conf.in.in "${CMAKE_CURRENT_BINARY_DIR}/${TABLE_NAME}.conf.in" @ONLY) fcitx5_translate_desktop_file("${CMAKE_CURRENT_BINARY_DIR}/${TABLE_NAME}.conf.in" ${TABLE_NAME}.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${TABLE_NAME}.conf" DESTINATION "${CMAKE_INSTALL_DATADIR}/fcitx5/inputmethod") endforeach() fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/cangjie.conf.in.in000066400000000000000000000005551361043647100250500ustar00rootroot00000000000000[InputMethod] Name=Cangjie Icon=fcitx-cangjie Label=仓 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/cj.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=0 Hint=False MatchingKey=? OrderPolicy=No UseFullWidth=True QuickPhraseKey=semicolon [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/context.cpp000066400000000000000000000033431361043647100237550ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) 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; see the file COPYING. If not, // see . // #include "context.h" namespace fcitx { TableContext::TableContext(libime::TableBasedDictionary &dict, const TableConfig &config, libime::UserLanguageModel &model) : libime::TableContext(dict, model), config_(config) {} Text TableContext::preeditText() const { Text text; for (size_t i = 0, e = selectedSize(); i < e; i++) { auto seg = selectedSegment(i); if (std::get(seg)) { text.append(std::get(seg), {TextFormatFlag::Underline}); } else { text.append( stringutils::concat("(", std::get(seg), ")"), {TextFormatFlag::DontCommit, TextFormatFlag::Strike, TextFormatFlag::Underline}); } } text.setCursor(text.textLength()); text.append(currentCode(), {TextFormatFlag::Underline, TextFormatFlag::HighLight}); return text; } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/context.h000066400000000000000000000026541361043647100234260ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) 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; see the file COPYING. If not, // see . // #ifndef _TABLE_CONTEXT_H_ #define _TABLE_CONTEXT_H_ #include "ime.h" #include #include namespace fcitx { class TableContext : public libime::TableContext { public: TableContext(libime::TableBasedDictionary &dict, const TableConfig &config, libime::UserLanguageModel &model); const TableConfig &config() { return config_; } std::string customHint(const std::string &code) { if (*config_.displayCustomHint) { return dict().hint(code); } return code; } Text preeditText() const; private: const TableConfig &config_; }; } // namespace fcitx #endif // _TABLE_CONTEXT_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/db.conf.in.in000066400000000000000000000006401361043647100240300ustar00rootroot00000000000000[InputMethod] Name=Dianbaoma Icon=fcitx-dianbaoma Label=电 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/db.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=-1 Hint=True OrderPolicy=Freq UseFullWidth=True QuickPhraseKey=semicolon [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal [Table/Selection] 0=q 1=w 2=e 3=r 4=t 5=y 6=u 7=i 8=o 9=p fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/engine.cpp000066400000000000000000000146641361043647100235460ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) 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; see the file COPYING. If not, // see . // #include "engine.h" #include "config.h" #include "context.h" #include "punctuation_public.h" #include "state.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace fcitx { TableEngine::TableEngine(Instance *instance) : instance_(instance), factory_([this](InputContext &ic) { return new TableState(&ic, this); }) { ime_ = std::make_unique( &libime::DefaultLanguageModelResolver::instance()); reloadConfig(); instance_->inputContextManager().registerProperty("tableState", &factory_); event_ = instance_->watchEvent( EventType::InputMethodGroupChanged, EventWatcherPhase::Default, [this](Event &) { instance_->inputContextManager().foreach([this](InputContext *ic) { auto state = ic->propertyFor(&factory_); state->release(); return true; }); std::unordered_set names; for (const auto &im : instance_->inputMethodManager() .currentGroup() .inputMethodList()) { names.insert(im.name()); } ime_->releaseUnusedDict(names); }); } TableEngine::~TableEngine() {} void TableEngine::reloadConfig() { readAsIni(config_, "conf/table.conf"); } void TableEngine::activate(const fcitx::InputMethodEntry &entry, fcitx::InputContextEvent &event) { auto inputContext = event.inputContext(); auto state = inputContext->propertyFor(&factory_); auto context = state->context(&entry); if (stringutils::startsWith(entry.languageCode(), "zh_")) { chttrans(); for (auto actionName : {"chttrans", "punctuation"}) { if (auto action = instance_->userInterfaceManager().lookupAction( actionName)) { inputContext->statusArea().addAction(StatusGroup::InputMethod, action); } } } if (context && *context->config().useFullWidth && fullwidth()) { if (auto action = instance_->userInterfaceManager().lookupAction("fullwidth")) { inputContext->statusArea().addAction(StatusGroup::InputMethod, action); } } } void TableEngine::deactivate(const fcitx::InputMethodEntry &entry, fcitx::InputContextEvent &event) { auto inputContext = event.inputContext(); inputContext->statusArea().clearGroup(StatusGroup::InputMethod); reset(entry, event); } std::string TableEngine::subMode(const fcitx::InputMethodEntry &entry, fcitx::InputContext &ic) { auto state = ic.propertyFor(&factory_); if (!state->context(&entry)) { return _("Not available"); } return {}; } void TableEngine::keyEvent(const InputMethodEntry &entry, KeyEvent &event) { FCITX_UNUSED(entry); TABLE_DEBUG() << "Table receive key: " << event.key() << " " << event.isRelease(); // by pass all key release and by pass all modifier if (event.isRelease() || event.key().isModifier()) { return; } auto inputContext = event.inputContext(); auto state = inputContext->propertyFor(&factory_); state->keyEvent(entry, event); } void TableEngine::reset(const InputMethodEntry &entry, InputContextEvent &event) { TABLE_DEBUG() << "TableEngine::reset"; auto inputContext = event.inputContext(); auto state = inputContext->propertyFor(&factory_); // The reason that we do not commit here is we want to force the behavior. // When client get unfocused, the framework will try to commit the string. state->commitBuffer(true, event.type() == EventType::InputContextFocusOut); state->reset(&entry); } void TableEngine::save() { ime_->saveAll(); } const libime::PinyinDictionary &TableEngine::pinyinDict() { if (!pinyinLoaded_) { try { pinyinDict_.load(libime::PinyinDictionary::SystemDict, LIBIME_INSTALL_PKGDATADIR "/sc.dict", libime::PinyinDictFormat::Binary); } catch (const std::exception &) { } pinyinLoaded_ = true; } return pinyinDict_; } const libime::LanguageModel &TableEngine::pinyinModel() { if (!pinyinLM_) { pinyinLM_ = std::make_unique( libime::DefaultLanguageModelResolver::instance() .languageModelFileForLanguage("zh_CN")); } return *pinyinLM_; } const Configuration * TableEngine::getConfigForInputMethod(const InputMethodEntry &entry) const { auto dict = ime_->requestDict(entry.uniqueName()); return std::get<2>(dict); } void TableEngine::setConfigForInputMethod(const InputMethodEntry &entry, const RawConfig &config) { ime_->updateConfig(entry.uniqueName(), config); } } // namespace fcitx FCITX_ADDON_FACTORY(fcitx::TableEngineFactory) fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/engine.h000066400000000000000000000104211361043647100231760ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) 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; see the file COPYING. If not, // see . // #ifndef _TABLE_TABLE_H_ #define _TABLE_TABLE_H_ #include "ime.h" #include #include #include #include #include #include #include #include #include namespace fcitx { class TableState; FCITX_CONFIGURATION(TableGlobalConfig, KeyListOption modifyDictionary{this, "ModifyDictionaryKey", _("Modify dictionary"), {Key("Control+8")}, KeyListConstrain()}; KeyListOption lookupPinyin{this, "LookupPinyinKey", _("Lookup pinyin"), {Key("Control+Alt+E")}, KeyListConstrain()};); class TableEngine final : public InputMethodEngine { public: TableEngine(Instance *instance); ~TableEngine(); Instance *instance() { return instance_; } void activate(const InputMethodEntry &entry, InputContextEvent &event) override; void deactivate(const InputMethodEntry &entry, InputContextEvent &event) override; void keyEvent(const InputMethodEntry &entry, KeyEvent &keyEvent) override; std::string subMode(const InputMethodEntry &entry, InputContext &event) override; void reloadConfig() override; void reset(const InputMethodEntry &entry, InputContextEvent &event) override; void save() override; auto &factory() { return factory_; } TableIME *ime() { return ime_.get(); } auto &config() { return config_; } const Configuration *getConfig() const override { return &config_; } void setConfig(const RawConfig &config) override { config_.load(config, true); safeSaveAsIni(config_, "conf/table.conf"); } const Configuration * getConfigForInputMethod(const InputMethodEntry &) const override; void setConfigForInputMethod(const InputMethodEntry &, const RawConfig &) override; const libime::PinyinDictionary &pinyinDict(); const libime::LanguageModel &pinyinModel(); FCITX_ADDON_DEPENDENCY_LOADER(fullwidth, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(punctuation, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(quickphrase, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(pinyinhelper, instance_->addonManager()); FCITX_ADDON_DEPENDENCY_LOADER(chttrans, instance_->addonManager()); private: void cloudTableSelected(InputContext *inputContext, const std::string &selected, const std::string &word); Instance *instance_; std::unique_ptr ime_; std::unique_ptr> event_; FactoryFor factory_; TableGlobalConfig config_; libime::PinyinDictionary pinyinDict_; bool pinyinLoaded_ = false; std::unique_ptr pinyinLM_; }; class TableEngineFactory : public AddonFactory { public: AddonInstance *create(AddonManager *manager) override { return new TableEngine(manager->instance()); } }; } // namespace fcitx #endif // _TABLE_TABLE_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/erbi.conf.in.in000066400000000000000000000006731361043647100243720ustar00rootroot00000000000000[InputMethod] Name=Erbi Icon=fcitx-erbi Label=二 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/erbi.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=0 Hint=False OrderPolicy=Freq UseFullWidth=True QuickPhraseKey=semicolon PinyinKey=[ MatchingKey=? AutoPhraseLength=4 SaveAutoPhraseAfter=-1 [Table/AutoRuleSet] 0=e2 [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/ime.cpp000066400000000000000000000220661361043647100230460ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) 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; see the file COPYING. If not, // see . // #include "ime.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include namespace fcitx { FCITX_DEFINE_LOG_CATEGORY(table_logcategory, "table") namespace { libime::OrderPolicy converOrderPolicy(fcitx::OrderPolicy policy) { switch (policy) { #define POLICY_CONVERT(NAME) \ case fcitx::OrderPolicy::NAME: \ return libime::OrderPolicy::NAME; POLICY_CONVERT(No) POLICY_CONVERT(Freq) POLICY_CONVERT(Fast) } return libime::OrderPolicy::Freq; } void populateOptions(libime::TableBasedDictionary *dict, const TableConfigRoot &root) { libime::TableOptions options; options.setOrderPolicy(converOrderPolicy(*root.config->orderPolicy)); options.setNoSortInputLength(*root.config->noSortInputLength); options.setAutoSelect(*root.config->autoSelect); options.setAutoSelectLength(*root.config->autoSelectLength); options.setNoMatchAutoSelectLength(*root.config->noMatchAutoSelectLength); options.setCommitRawInput(*root.config->commitRawInput); options.setMatchingKey( Key::keySymToUnicode(root.config->matchingKey->sym())); std::set endKeys; TABLE_DEBUG() << "End key" << *root.config->endKey; for (const auto &key : *root.config->endKey) { auto chr = Key::keySymToUnicode(key.sym()); if (chr) { endKeys.insert(chr); } } options.setEndKey(endKeys); options.setExactMatch(*root.config->exactMatch); options.setLearning(*root.config->learning); options.setAutoPhraseLength(*root.config->autoPhraseLength); options.setSaveAutoPhraseAfter(*root.config->saveAutoPhraseAfter); options.setAutoRuleSet(std::unordered_set( root.config->autoRuleSet->begin(), root.config->autoRuleSet->end())); options.setLanguageCode(*root.im->languageCode); dict->setTableOptions(options); } } // namespace TableIME::TableIME(libime::LanguageModelResolver *lm) : lm_(lm) {} std::tuple TableIME::requestDict(const std::string &name) { auto iter = tables_.find(name); if (iter == tables_.end()) { TABLE_DEBUG() << "Load table config for: " << name; std::string filename = "inputmethod/"; filename.append(name.begin(), name.end()); filename += ".conf"; auto files = StandardPath::global().openAll(StandardPath::Type::PkgData, filename, O_RDONLY); RawConfig rawConfig; // reverse the order, so we end up parse user file at last. for (const auto &file : files | boost::adaptors::reversed) { readFromIni(rawConfig, file.fd()); } iter = tables_ .emplace(std::piecewise_construct, std::make_tuple(name), std::make_tuple()) .first; auto &root = iter->second.root; root.load(rawConfig); try { auto dict = std::make_unique(); auto dictFile = StandardPath::global().open( StandardPath::Type::PkgData, *root.config->file, O_RDONLY); FCITX_LOG(Debug) << "Load table at: " << *root.config->file; if (dictFile.fd() < 0) { throw std::runtime_error("Couldn't open file"); } boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(dictFile.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); dict->load(in); iter->second.dict = std::move(dict); } catch (const std::exception &) { } if (auto dict = iter->second.dict.get()) { try { auto dictFile = StandardPath::global().openUser( StandardPath::Type::PkgData, stringutils::concat("table/", name, ".user.dict"), O_RDONLY); boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(dictFile.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); dict->loadUser(in); } catch (const std::exception &e) { TABLE_ERROR() << e.what(); } populateOptions(dict, iter->second.root); auto lmFile = lm_->languageModelFileForLanguage( dict->tableOptions().languageCode()); iter->second.model = std::make_unique(lmFile); try { auto dictFile = StandardPath::global().openUser( StandardPath::Type::PkgData, stringutils::concat("table/", name, ".history"), O_RDONLY); boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(dictFile.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); iter->second.model->load(in); } catch (const std::exception &e) { TABLE_ERROR() << e.what(); } } } return {iter->second.dict.get(), iter->second.model.get(), &(*iter->second.root.config)}; } void TableIME::saveAll() { for (const auto &p : tables_) { saveDict(p.first); } } void TableIME::updateConfig(const std::string &name, const RawConfig &config) { auto iter = tables_.find(name); if (iter == tables_.end()) { return; } iter->second.root.load(config, true); if (iter->second.dict) { populateOptions(iter->second.dict.get(), iter->second.root); } safeSaveAsIni(iter->second.root, stringutils::concat("inputmethod/", name, ".conf")); } void TableIME::releaseUnusedDict(const std::unordered_set &names) { for (auto iter = tables_.begin(); iter != tables_.end();) { if (names.count(iter->first) == 0) { TABLE_DEBUG() << "Release unused table: " << iter->first; saveDict(iter->first); iter = tables_.erase(iter); } else { ++iter; } } } void TableIME::saveDict(const std::string &name) { auto iter = tables_.find(name); if (iter == tables_.end()) { return; } libime::TableBasedDictionary *dict = iter->second.dict.get(); libime::UserLanguageModel *lm = iter->second.model.get(); auto fileName = stringutils::joinPath("table", name); StandardPath::global().safeSave( StandardPath::Type::PkgData, fileName + ".user.dict", [dict](int fd) { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_sink> buffer(fd, boost::iostreams::file_descriptor_flags:: never_close_handle); std::ostream out(&buffer); try { dict->saveUser(out); return static_cast(out); } catch (const std::exception &) { return false; } }); StandardPath::global().safeSave( StandardPath::Type::PkgData, fileName + ".history", [lm](int fd) { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_sink> buffer(fd, boost::iostreams::file_descriptor_flags:: never_close_handle); std::ostream out(&buffer); try { lm->save(out); return static_cast(out); } catch (const std::exception &) { return false; } }); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/ime.h000066400000000000000000000127551361043647100225170ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) 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; see the file COPYING. If not, // see . // #ifndef _TABLE_TABLEDICTRESOLVER_H_ #define _TABLE_TABLEDICTRESOLVER_H_ #include #include #include #include #include #include #include namespace fcitx { FCITX_CONFIG_ENUM(OrderPolicy, No, Freq, Fast); FCITX_CONFIGURATION( TableConfig, HiddenOption file{this, "File", _("File")}; Option prevPage{ this, "PrevPage", _("Prev page"), {Key(FcitxKey_Up)}}; Option nextPage{ this, "NextPage", _("Next page"), {Key(FcitxKey_Down)}}; Option prevCandidate{ this, "PrevCandidate", "Prev Candidate", {Key("Left")}}; Option nextCandidate{ this, "NextCandidate", "Next Candidate", {Key("Right")}}; HiddenOption selection{ this, "Selection", _("Selection"), {Key(FcitxKey_1), Key(FcitxKey_2), Key(FcitxKey_3), Key(FcitxKey_4), Key(FcitxKey_5), Key(FcitxKey_6), Key(FcitxKey_7), Key(FcitxKey_8), Key(FcitxKey_9), Key(FcitxKey_0)}}; Option pageSize{this, "PageSize", "Page size", 5, IntConstrain(3, 10)}; Option useFullWidth{this, "UseFullWidth", _("Use full width"), true}; Option quickphrase{this, "QuickPhraseKey", _("Key to trigger quickphrase")}; HiddenOption icon{this, "Icon", _("Icon")}; Option noSortInputLength{this, "NoSortInputLength", _("Don't sort word shorter")}; Option pinyinKey{this, "PinyinKey", _("Prefix key to trigger Pinyin")}; Option autoSelect{this, "AutoSelect", _("Auto select candidate")}; Option autoSelectLength{this, "AutoSelectLength", _("Auto select candidate Length")}; Option noMatchAutoSelectLength{ this, "NoMatchAutoSelectLength", _("Auto select last candidate when there is no new match")}; Option commitRawInput{ this, "CommitRawInput", _("Commit raw input when there is no candidate")}; Option orderPolicy{this, "OrderPolicy", _("Order policy")}; HiddenOption endKey{this, "EndKey", _("End key")}; Option matchingKey{this, "MatchingKey", _("Wildcard matching Key")}; Option autoPhraseLength{this, "AutoPhraseLength", _("Auto phrase length"), -1}; Option saveAutoPhraseAfter{this, "SaveAutoPhraseAfter", _("Save auto phrase"), -1}; Option exactMatch{this, "ExactMatch", _("Exact Match")}; Option learning{this, "Learning", _("Learning"), true}; Option hint{this, "Hint", _("Display Hint for word")}; Option displayCustomHint{this, "DisplayCustomHint", _("Display custom hint")}; HiddenOption> autoRuleSet{this, "AutoRuleSet", _("Auto rule set")};); FCITX_CONFIGURATION(PartialIMInfo, HiddenOption languageCode{ this, "LangCode", "Language Code"};); struct NoSaveAnnotation { bool skipDescription() const { return true; } bool skipSave() const { return true; } void dumpDescription(RawConfig &) const {} }; FCITX_CONFIGURATION(TableConfigRoot, Option config{this, "Table", "Table"}; Option, DefaultMarshaller, NoSaveAnnotation> im{this, "InputMethod", "InputMethod"};); struct TableData { TableConfigRoot root; std::unique_ptr dict; std::unique_ptr model; }; class TableIME { public: TableIME(libime::LanguageModelResolver *lmResolver); const TableConfig &config(const std::string &name); public: std::tuple requestDict(const std::string &name); void saveDict(const std::string &name); void saveAll(); void updateConfig(const std::string &name, const RawConfig &config); void releaseUnusedDict(const std::unordered_set &names); private: libime::LanguageModelResolver *lm_; std::unordered_map tables_; }; FCITX_DECLARE_LOG_CATEGORY(table_logcategory); #define TABLE_DEBUG() FCITX_LOGC(::fcitx::table_logcategory, Debug) #define TABLE_ERROR() FCITX_LOGC(::fcitx::table_logcategory, Error) } // namespace fcitx #endif // _TABLE_TABLEDICTRESOLVER_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/qxm.conf.in.in000066400000000000000000000006651361043647100242570ustar00rootroot00000000000000[InputMethod] Name=Bingchan Icon=fcitx-bingchan Label=冰 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/qxm.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=-1 Hint=True MatchingKey=# OrderPolicy=Fast UseFullWidth=True QuickPhraseKey=semicolon AutoPhraseLength=4 SaveAutoPhraseAfter=3 [Table/AutoRuleSet] 0=e2 [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/state.cpp000066400000000000000000000626211361043647100234150ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "state.h" #include "pinyinhelper_public.h" #include "punctuation_public.h" #include "quickphrase_public.h" #include #include #include #include #include #include #include namespace fcitx { namespace { class TableCandidateWord : public CandidateWord { public: TableCandidateWord(TableEngine *engine, Text text, size_t idx) : CandidateWord(std::move(text)), engine_(engine), idx_(idx) {} void select(InputContext *inputContext) const override { auto state = inputContext->propertyFor(&engine_->factory()); // nullptr means use the last requested entry. auto *context = state->context(nullptr); if (!context || idx_ >= context->candidates().size()) { return; } context->select(idx_); state->updateUI(); } TableEngine *engine_; size_t idx_; }; class TablePinyinCandidateWord : public CandidateWord { public: TablePinyinCandidateWord(TableEngine *engine, std::string word, const libime::TableBasedDictionary &dict, bool customHint) : CandidateWord(), engine_(engine), word_(std::move(word)) { Text text; text.append(word_); if (utf8::lengthValidated(word_) == 1) { auto code = dict.reverseLookup(word_); if (!code.empty()) { text.append(" ~ "); if (customHint) { text.append(dict.hint(code)); } else { text.append(code); } } } setText(std::move(text)); } void select(InputContext *inputContext) const override { auto state = inputContext->propertyFor(&engine_->factory()); inputContext->commitString(word_); state->pushLastCommit(word_); state->reset(); } TableEngine *engine_; std::string word_; }; } // namespace TableContext *TableState::context(const InputMethodEntry *entry) { if (!entry || lastContext_ == entry->uniqueName()) { return context_.get(); } auto dict = engine_->ime()->requestDict(entry->uniqueName()); if (!std::get<0>(dict)) { return nullptr; } context_ = std::make_unique( *std::get<0>(dict), *std::get<2>(dict), *std::get<1>(dict)); lastContext_ = entry->uniqueName(); return context_.get(); } void TableState::release() { reset(); lastContext_.clear(); context_.reset(); } void TableState::pushLastCommit(const std::string &lastSegment) { if (lastSegment.empty() || ic_->capabilityFlags().testAny(CapabilityFlag::PasswordOrSensitive)) { return; } lastCommit_ += lastSegment; constexpr size_t limit = 10; auto length = utf8::length(lastCommit_); TABLE_DEBUG() << "TableState::pushLastCommit " << lastSegment << " length: " << utf8::length(lastSegment); if (utf8::length(lastSegment) == 1) { lastSingleCharCommit_.push_back(lastSegment); while (lastSingleCharCommit_.size() > 10) { lastSingleCharCommit_.pop_front(); } auto singleCharString = stringutils::join(lastSingleCharCommit_, ""); TABLE_DEBUG() << "learnAutoPhrase " << singleCharString; context_->learnAutoPhrase(singleCharString); } else { lastSingleCharCommit_.clear(); } if (length > limit) { auto iter = lastCommit_.begin(); while (length > limit) { iter = utf8::nextChar(iter); length--; } lastCommit_ = lastCommit_.substr(std::distance(lastCommit_.begin(), iter)); } lastSegment_ = lastSegment; } void TableState::reset(const InputMethodEntry *entry) { auto context = this->context(entry); if (context) { context->clear(); } ic_->inputPanel().reset(); ic_->updatePreedit(); ic_->updateUserInterface(UserInterfaceComponent::InputPanel); // lastIsPunc_ = false; mode_ = TableMode::Normal; pinyinModePrefix_.clear(); pinyinModeBuffer_.clear(); } bool TableState::handleCandidateList(const TableConfig &config, KeyEvent &event) { auto inputContext = event.inputContext(); // check if we can select candidate. auto candidateList = inputContext->inputPanel().candidateList(); if (!candidateList) { return false; } int idx = event.key().keyListIndex(*config.selection); if (idx >= 0) { event.filterAndAccept(); if (idx < candidateList->size()) { candidateList->candidate(idx)->select(inputContext); } return true; } if (event.key().checkKeyList(*config.prevPage)) { auto pageable = candidateList->toPageable(); if (!pageable->hasPrev()) { if (pageable->usedNextBefore()) { event.filterAndAccept(); return true; } } else { event.filterAndAccept(); pageable->prev(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); return true; } } if (event.key().checkKeyList(*config.nextPage)) { event.filterAndAccept(); candidateList->toPageable()->next(); inputContext->updateUserInterface(UserInterfaceComponent::InputPanel); return true; } if (auto movable = candidateList->toCursorMovable()) { if (event.key().checkKeyList(*config.nextCandidate)) { movable->nextCandidate(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); event.filterAndAccept(); return true; } else if (event.key().checkKeyList(*config.prevCandidate)) { movable->prevCandidate(); inputContext->updateUserInterface( UserInterfaceComponent::InputPanel); event.filterAndAccept(); return true; } } return false; } bool TableState::handlePinyinMode(KeyEvent &event) { auto context = context_.get(); const auto &pinyinKey = *context->config().pinyinKey; if (pinyinKey.sym() == FcitxKey_None) { return false; } bool needUpdate = false; if (mode_ == TableMode::Normal && event.key().check(pinyinKey)) { if (context->size() != 0) { commitBuffer(false); } mode_ = TableMode::Pinyin; event.filterAndAccept(); if (!event.key().hasModifier()) { pinyinModePrefix_ = Key::keySymToUTF8(event.key().sym()); needUpdate = true; } } else if (mode_ != TableMode::Pinyin) { return false; } else { event.filterAndAccept(); if (event.key().isLAZ() || event.key().check(FcitxKey_apostrophe)) { pinyinModeBuffer_.type(Key::keySymToUTF8(event.key().sym())); needUpdate = true; } else if (event.key().check(FcitxKey_BackSpace)) { if (pinyinModeBuffer_.size()) { pinyinModeBuffer_.backspace(); needUpdate = true; } else { reset(); return true; } } else if (event.key().check(FcitxKey_space)) { auto candidateList = ic_->inputPanel().candidateList(); if (candidateList && candidateList->size()) { int idx = candidateList->cursorIndex(); if (idx < 0) { idx = 0; } candidateList->candidate(idx)->select(ic_); return true; } else if (!pinyinModeBuffer_.size()) { if (!lastSegment_.empty()) { ic_->commitString(lastSegment_); } reset(); } } else if (event.key().check(FcitxKey_Return)) { auto commit = pinyinModePrefix_ + pinyinModeBuffer_.userInput(); if (!commit.empty()) { ic_->commitString(commit); } reset(); } } if (needUpdate) { auto &inputPanel = ic_->inputPanel(); ic_->inputPanel().reset(); if (pinyinModeBuffer_.size()) { auto &dict = engine_->pinyinDict(); auto &lm = engine_->pinyinModel(); auto pinyin = libime::PinyinEncoder::encodeOneUserPinyin( pinyinModeBuffer_.userInput()); auto candidateList = std::make_unique(); candidateList->setSelectionKey(*context_->config().selection); candidateList->setPageSize(*context_->config().pageSize); std::vector> pinyinWords; dict.matchWords(pinyin.data(), pinyin.size(), [&pinyinWords, &lm](std::string_view, std::string_view hanzi, float) { pinyinWords.emplace_back( hanzi, lm.singleWordScore(hanzi)); return true; }); std::sort(pinyinWords.begin(), pinyinWords.end(), [](const auto &lhs, const auto &rhs) { return lhs.second > rhs.second; }); for (auto &p : pinyinWords) { candidateList->append(new TablePinyinCandidateWord( engine_, std::move(p.first), context_->dict(), *context_->config().displayCustomHint)); } if (candidateList->size()) { inputPanel.setCandidateList(std::move(candidateList)); } } else { if (!lastSegment_.empty()) { inputPanel.setAuxDown(Text(lastSegment_)); } } Text preeditText; preeditText.append(pinyinModePrefix_); preeditText.append(pinyinModeBuffer_.userInput()); if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) { preeditText.setCursor(0); inputPanel.setClientPreedit(preeditText); } else { preeditText.setCursor(preeditText.textLength()); inputPanel.setPreedit(preeditText); } ic_->updatePreedit(); ic_->updateUserInterface(UserInterfaceComponent::InputPanel); } return true; } bool TableState::handleLookupPinyinOrModifyDictionaryMode(KeyEvent &event) { // Lookup pinyin and addPhrase may share some code. auto context = context_.get(); bool needUpdate = false; if (mode_ == TableMode::Normal) { if (event.key().checkKeyList(*engine_->config().lookupPinyin)) { mode_ = TableMode::LookupPinyin; } else if (event.key().checkKeyList( *engine_->config().modifyDictionary)) { mode_ = TableMode::ModifyDictionary; } if (mode_ == TableMode::Normal) { return false; } if (context->size() != 0) { commitBuffer(false); } lookupPinyinIndex_ = 0; lookupPinyinString_ = lastCommit_; if (ic_->capabilityFlags().test(CapabilityFlag::SurroundingText) && ic_->surroundingText().isValid()) { auto text = ic_->surroundingText().selectedText(); if (!text.empty()) { lookupPinyinString_ = std::move(text); } } needUpdate = true; } else if (mode_ != TableMode::LookupPinyin && mode_ != TableMode::ModifyDictionary) { return false; } event.filterAndAccept(); if (event.key().check(FcitxKey_Left)) { needUpdate = true; auto length = utf8::length(lookupPinyinString_); if (length != 0) { lookupPinyinIndex_ += 1; if (lookupPinyinIndex_ >= length) { lookupPinyinIndex_ = length - 1; } } } else if (event.key().check(FcitxKey_Right)) { needUpdate = true; auto length = utf8::length(lookupPinyinString_); if (length != 0) { if (lookupPinyinIndex_ >= length) { lookupPinyinIndex_ = length - 1; } else if (lookupPinyinIndex_ > 0) { lookupPinyinIndex_ -= 1; } } } auto length = utf8::length(lookupPinyinString_); auto getSubString = [&]() { if (lookupPinyinIndex_ >= length) { lookupPinyinIndex_ = length - 1; } auto idx = length - lookupPinyinIndex_ - 1; auto iter = utf8::nextNChar(lookupPinyinString_.begin(), idx); return std::string(iter, lookupPinyinString_.end()); }; if (length != 0 && length != utf8::INVALID_LENGTH) { if (event.key().check(FcitxKey_space) && mode_ == TableMode::ModifyDictionary) { auto subString = getSubString(); std::string result; if (context_->dict().generate(subString, result)) { if (context_->dict().wordExists(result, subString) == libime::PhraseFlag::Invalid) { context_->mutableDict().insert(subString); reset(); return true; } } } else if (event.key().checkKeyList(std::initializer_list{ Key(FcitxKey_BackSpace), Key(FcitxKey_Delete)}) && mode_ == TableMode::ModifyDictionary) { auto subString = getSubString(); std::string result; if (context_->dict().generate(subString, result)) { auto flag = context_->dict().wordExists(result, subString); if (flag != libime::PhraseFlag::Invalid) { if (flag == libime::PhraseFlag::User && event.key().check(FcitxKey_Delete)) { context_->mutableDict().removeWord(result, subString); } context_->mutableModel().history().forget(subString); reset(); return true; } } } } if (needUpdate) { auto &inputPanel = ic_->inputPanel(); inputPanel.reset(); if (length == 0 || length == utf8::INVALID_LENGTH) { inputPanel.setAuxUp(Text( _("Please use this functionality after typing some text."))); } else { auto subString = getSubString(); auto chr = utf8::getChar(subString); if (mode_ == TableMode::LookupPinyin) { Text auxUp(_("Use Left and Right to select character: ")); auxUp.append(utf8::UCS4ToUTF8(chr)); inputPanel.setAuxUp(auxUp); auto result = engine_->pinyinhelper()->call(chr); if (!result.empty()) { inputPanel.setAuxDown(Text(stringutils::join(result, " "))); } else { inputPanel.setAuxDown(Text(_("Could not find pinyin."))); } } else { Text auxUp(_("Use Left and Right to select text. ")); Text auxDown; if (lookupPinyinIndex_ >= 1) { std::string result; if (context_->dict().generate(subString, result)) { auxDown.append( fmt::format(_("{0}: {1}"), subString, context_->customHint(result))); auto flag = context_->dict().wordExists(result, subString); if (flag == libime::PhraseFlag::Invalid) { auxUp.append(_("Press space to insert.")); } if (flag != libime::PhraseFlag::Invalid) { auxUp.append(_("Press Backspace to forget.")); } if (flag == libime::PhraseFlag::User) { auxUp.append(_("Press Delete to remove.")); } } else { auxDown.append(fmt::format( _("{0}: No corresponding code."), subString)); } auxDown.append(" "); } auto chrString = utf8::UCS4ToUTF8(chr); auto chrCode = context_->dict().reverseLookup(chrString); if (!chrCode.empty()) { auxDown.append( fmt::format(_("{0}: {1}"), chrString, chrCode)); } else { auxDown.append( fmt::format(_("{0} is not in table."), chrString)); } inputPanel.setAuxUp(auxUp); inputPanel.setAuxDown(auxDown); } } ic_->updatePreedit(); ic_->updateUserInterface(UserInterfaceComponent::InputPanel); } return true; } void TableState::keyEvent(const InputMethodEntry &entry, KeyEvent &event) { bool needUpdate = false; auto inputContext = event.inputContext(); bool lastIsPunc = lastIsPunc_; auto context = this->context(&entry); if (!context) { return; } if ((mode_ != TableMode::Normal || context_->size()) && event.key().check(FcitxKey_Escape)) { reset(); return event.filterAndAccept(); } lastIsPunc_ = false; auto &config = context->config(); if (handleCandidateList(config, event)) { return; } if (handlePinyinMode(event)) { return; } if (handleLookupPinyinOrModifyDictionaryMode(event)) { return; } auto chr = Key::keySymToUnicode(event.key().sym()); if (!event.key().hasModifier() && chr && context->isValidInput(chr)) { auto str = utf8::UCS4ToUTF8(chr); context->type(str); if (context->candidates().empty() && context->currentCode() == str) { // This means it is not a valid start, make it go through the punc. context->backspace(); } else { event.filterAndAccept(); } } else if (context->size()) { if (event.key().check(FcitxKey_Return, KeyState::Shift)) { inputContext->commitString(context->userInput()); context->clear(); event.filterAndAccept(); } else if (event.key().check(FcitxKey_Tab)) { // if it gonna commit something context->autoSelect(); if (context->selected()) { commitBuffer(false); } event.filterAndAccept(); } else if (event.key().check(FcitxKey_Return) && !context->selected()) { commitBuffer(true); event.filterAndAccept(); } else if (event.key().check(FcitxKey_BackSpace)) { // Discard the last segement if it is selected. if (context->selected()) { auto length = context->selectedSegmentLength(context->selectedSize() - 1); context->erase(context->size() - length, context->size()); } else { context->backspace(); } event.filterAndAccept(); } else if (event.key().isCursorMove() || event.key().check(FcitxKey_Delete)) { // if it gonna commit something commitBuffer(true); needUpdate = true; event.filter(); } else if (!context->selected()) { // key to handle when it is not empty. if (event.key().check(FcitxKey_space)) { auto candidateList = ic_->inputPanel().candidateList(); if (candidateList && candidateList->size()) { int idx = candidateList->cursorIndex(); if (idx < 0) { idx = 0; } candidateList->candidate(idx)->select(ic_); return event.filterAndAccept(); } } } } else if (event.key().check(FcitxKey_BackSpace) && lastIsPunc) { auto puncStr = engine_->punctuation()->call( entry.languageCode(), inputContext); if (!puncStr.empty()) { // forward the original key is the best choice. auto ref = inputContext->watch(); cancelLastEvent_ = engine_->instance()->eventLoop().addTimeEvent( CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 300, 0, [this, ref, puncStr](EventSourceTime *, uint64_t) { if (auto inputContext = ref.get()) { inputContext->commitString(puncStr); } cancelLastEvent_.reset(); return true; }); event.filter(); return; } } if (!event.filtered()) { if (event.key().hasModifier() || !chr) { return; } // if it gonna commit something context->autoSelect(); if (context->selected()) { commitBuffer(false); needUpdate = true; } auto punc = engine_->punctuation()->call( entry.languageCode(), inputContext, chr); if (event.key().check(*config.quickphrase) && engine_->quickphrase()) { auto s = punc.size() ? punc : utf8::UCS4ToUTF8(chr); auto alt = punc.size() ? utf8::UCS4ToUTF8(chr) : ""; std::string text; if (s.size()) { text += alt + _(" for ") + s; } if (alt.size()) { text += _(" Return for ") + alt; } engine_->quickphrase()->call( inputContext, text, "", s, alt, Key(FcitxKey_semicolon)); event.filterAndAccept(); return; } if (punc.size()) { event.filterAndAccept(); inputContext->commitString(punc); } lastIsPunc_ = true; } if ((event.filtered() && event.accepted()) || needUpdate) { updateUI(); } } void TableState::commitBuffer(bool commitCode, bool noRealCommit) { auto context = context_.get(); if (!context) { return; } auto sentence = context->selectedSentence(); TABLE_DEBUG() << "TableState::commitBuffer " << sentence << " " << context->selectedSize(); for (size_t i = 0; i < context->selectedSize(); i++) { auto seg = context->selectedSegment(i); if (std::get(seg)) { pushLastCommit(std::get(seg)); } } if (commitCode) { sentence += context->currentCode(); } if (!noRealCommit) { ic_->commitString(sentence); } if (!ic_->capabilityFlags().testAny(CapabilityFlag::PasswordOrSensitive)) { context->learn(); } context->clear(); } void TableState::updateUI() { ic_->inputPanel().reset(); auto context = context_.get(); if (!context) { return; } auto &config = context->config(); if (context->userInput().size()) { auto candidates = context->candidates(); auto &inputPanel = ic_->inputPanel(); if (context->candidates().size()) { auto candidateList = std::make_unique(); size_t idx = 0; candidateList->setCursorPositionAfterPaging( CursorPositionAfterPaging::ResetToFirst); for (const auto &candidate : candidates) { auto candidateString = candidate.toString(); Text text; text.append(candidateString); std::string hint; if (*config.hint) { hint = context->candidateHint(idx, *config.displayCustomHint); } if (!hint.empty()) { text.append(" ~ "); text.append(hint); } candidateList->append( new TableCandidateWord(engine_, std::move(text), idx)); idx++; } candidateList->setSelectionKey(*config.selection); candidateList->setPageSize(*config.pageSize); candidateList->setGlobalCursorIndex(0); inputPanel.setCandidateList(std::move(candidateList)); } Text preeditText = context->preeditText(); if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) { inputPanel.setClientPreedit(preeditText); } else { inputPanel.setPreedit(preeditText); } } ic_->updatePreedit(); ic_->updateUserInterface(UserInterfaceComponent::InputPanel); } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/state.h000066400000000000000000000045311361043647100230560ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _TABLE_STATE_H_ #define _TABLE_STATE_H_ #include "context.h" #include "engine.h" #include namespace fcitx { enum class TableMode { Normal, ModifyDictionary, Pinyin, LookupPinyin, }; class EventSourceTime; class TableState : public InputContextProperty { public: TableState(InputContext *ic, TableEngine *engine) : ic_(ic), engine_(engine) {} InputContext *ic_; TableEngine *engine_; bool lastIsPunc_ = false; std::unique_ptr cancelLastEvent_; TableContext *context(const InputMethodEntry *entry); void release(); void reset(const InputMethodEntry *entry = nullptr); void keyEvent(const InputMethodEntry &entry, KeyEvent &event); void commitBuffer(bool commitCode, bool noRealCommit = false); void updateUI(); void pushLastCommit(const std::string &lastSegment); private: bool handleCandidateList(const TableConfig &config, KeyEvent &event); bool handlePinyinMode(KeyEvent &event); bool handleLookupPinyinOrModifyDictionaryMode(KeyEvent &event); bool handleAddPhraseMode(KeyEvent &event); TableMode mode_ = TableMode::Normal; std::string pinyinModePrefix_; InputBuffer pinyinModeBuffer_{ {InputBufferOption::AsciiOnly, InputBufferOption::FixedCursor}}; size_t lookupPinyinIndex_ = 0; std::string lookupPinyinString_; std::string lastContext_; std::string lastCommit_; std::string lastSegment_; std::list lastSingleCharCommit_; std::unique_ptr context_; }; } // namespace fcitx #endif // _TABLE_STATE_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/table.conf.in000066400000000000000000000003031361043647100241210ustar00rootroot00000000000000[Addon] Name=Table Category=InputMethod Library=table Type=SharedLibrary OnDemand=True [Addon/Dependencies] 0=punctuation 1=pinyinhelper [Addon/OptionalDependencies] 0=fullwidth 1=quickphrase fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/wanfeng.conf.in.in000066400000000000000000000006551361043647100250760ustar00rootroot00000000000000[InputMethod] Name=Wanfeng Icon=fcitx-wanfeng Label=晚 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/wanfeng.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=1 Hint=True OrderPolicy=No UseFullWidth=True QuickPhraseKey=semicolon AutoPhraseLength=-1 [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal [Table/EndKey] 0=comma 1=semicolon 2=slash 3=period fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/wbpy.conf.in.in000066400000000000000000000006761361043647100244350ustar00rootroot00000000000000[InputMethod] Name=Wubi Pinyin Icon=fcitx-wubi Label=五 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/wbpy.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=-1 NoSortInputLength=2 Hint=True MatchingKey=* OrderPolicy=Freq UseFullWidth=True QuickPhraseKey=semicolon AutoPhraseLength=4 SaveAutoPhraseAfter=3 AutoRuleSet=e2 [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/wbx.conf.in.in000066400000000000000000000007151361043647100242460ustar00rootroot00000000000000[InputMethod] Name=Wubi Icon=fcitx-wubi Label=五 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/wbx.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=-1 NoSortInputLength=2 Hint=True MatchingKey=* PinyinKey=z OrderPolicy=Freq UseFullWidth=True QuickPhraseKey=semicolon AutoPhraseLength=4 SaveAutoPhraseAfter=3 [Table/AutoRuleSet] 0=e2 [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal fcitx5-chinese-addons-0.0~git20200117.4261e23/im/table/zrm.conf.in.in000066400000000000000000000005431361043647100242550ustar00rootroot00000000000000[InputMethod] Name=Ziranma Icon=fcitx-ziranma Label=自 LangCode=zh_CN Addon=table Configurable=True [Table] File=@LIBIME_INSTALL_PKGDATADIR@/zrm.main.dict AutoSelect=True AutoSelectLength=-1 NoMatchAutoSelectLength=-1 Hint=True OrderPolicy=Fast UseFullWidth=True QuickPhraseKey=semicolon [Table/PrevPage] 0=Up 1=minus [Table/NextPage] 0=Down 1=equal fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/000077500000000000000000000000001361043647100215365ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/CMakeLists.txt000066400000000000000000000002221361043647100242720ustar00rootroot00000000000000add_subdirectory(chttrans) add_subdirectory(punctuation) add_subdirectory(fullwidth) add_subdirectory(cloudpinyin) add_subdirectory(pinyinhelper) fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/000077500000000000000000000000001361043647100233645ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/CMakeLists.txt000066400000000000000000000013651361043647100261310ustar00rootroot00000000000000set(CHTTRANS_SOURCES chttrans.cpp chttrans-native.cpp ) if (ENABLE_OPENCC) set(CHTTRANS_SOURCES ${CHTTRANS_SOURCES} chttrans-opencc.cpp) endif() add_library(chttrans MODULE ${CHTTRANS_SOURCES}) target_link_libraries(chttrans Fcitx5::Core Fcitx5::Config Fcitx5::Module::Notifications Boost::iostreams) if (ENABLE_OPENCC) target_link_libraries(chttrans OpenCC::OpenCC) endif() set_target_properties(chttrans PROPERTIES PREFIX "") install(TARGETS chttrans DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(chttrans.conf.in chttrans.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/chttrans.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon") install(FILES gbks2t.tab DESTINATION "${CMAKE_INSTALL_DATADIR}/fcitx5/data") fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans-native.cpp000066400000000000000000000063211361043647100272040ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "chttrans-native.h" #include "config.h" #include #include #include #include #include #define TABLE_GBKS2T "data/gbks2t.tab" using namespace fcitx; typedef std::unique_ptr ScopedFILE; bool NativeBackend::loadOnce() { auto file = StandardPath::global().open(StandardPath::Type::PkgData, TABLE_GBKS2T, O_RDONLY); if (file.fd() < 0) { return false; } boost::iostreams::stream_buffer buffer(file.fd(), boost::iostreams::file_descriptor_flags::never_close_handle); std::istream in(&buffer); std::string strBuf; while (std::getline(in, strBuf)) { // Get two char. auto simpStart = strBuf.begin(); uint32_t simp, trad; auto tradStart = utf8::getNextChar(simpStart, strBuf.end(), &simp); auto end = utf8::getNextChar(tradStart, strBuf.end(), &trad); if (!utf8::isValidChar(simp) || !utf8::isValidChar(trad)) { continue; } if (!s2tMap_.count(simp)) { s2tMap_.emplace(std::piecewise_construct, std::forward_as_tuple(simp), std::forward_as_tuple(tradStart, end)); } if (!t2sMap_.count(trad)) { t2sMap_.emplace(std::piecewise_construct, std::forward_as_tuple(trad), std::forward_as_tuple(simpStart, tradStart)); } } return true; } std::string convert(const std::unordered_map &transMap, const std::string &strHZ) { auto len = utf8::length(strHZ); std::string result; auto ps = strHZ.c_str(); for (size_t i = 0; i < len; ++i) { uint32_t wc; char *nps; nps = fcitx_utf8_get_char(ps, &wc); int chr_len = nps - ps; auto iter = transMap.find(wc); if (iter != transMap.end()) { result.append(iter->second); } else { result.append(ps, chr_len); } ps = nps; } return result; } std::string NativeBackend::convertSimpToTrad(const std::string &strHZ) { return convert(s2tMap_, strHZ); } std::string NativeBackend::convertTradToSimp(const std::string &strHZ) { return convert(t2sMap_, strHZ); } fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans-native.h000066400000000000000000000023711361043647100266520ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _CHTTRANS_CHTTRANS_NATIVE_H_ #define _CHTTRANS_CHTTRANS_NATIVE_H_ #include "chttrans.h" #include class NativeBackend : public ChttransBackend { public: std::string convertSimpToTrad(const std::string &) override; std::string convertTradToSimp(const std::string &) override; protected: bool loadOnce() override; private: std::unordered_map s2tMap_; std::unordered_map t2sMap_; }; #endif // _CHTTRANS_CHTTRANS_NATIVE_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans-opencc.cpp000066400000000000000000000030441361043647100271640ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "chttrans-opencc.h" bool OpenCCBackend::loadOnce() { try { s2t_ = std::make_unique( OPENCC_DEFAULT_CONFIG_SIMP_TO_TRAD); t2s_ = std::make_unique( OPENCC_DEFAULT_CONFIG_TRAD_TO_SIMP); } catch (const std::exception &e) { return false; } return true; } std::string OpenCCBackend::convertSimpToTrad(const std::string &str) { if (s2t_) { try { return s2t_->Convert(str); } catch (const std::exception &e) { } } return str; } std::string OpenCCBackend::convertTradToSimp(const std::string &str) { if (t2s_) { try { return t2s_->Convert(str); } catch (const std::exception &e) { } } return str; } fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans-opencc.h000066400000000000000000000023541361043647100266340ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _CHTTRANS_CHTTRANS_OPENCC_H_ #define _CHTTRANS_CHTTRANS_OPENCC_H_ #include "chttrans.h" #include class OpenCCBackend : public ChttransBackend { public: std::string convertSimpToTrad(const std::string &) override; std::string convertTradToSimp(const std::string &) override; protected: bool loadOnce() override; private: std::unique_ptr s2t_; std::unique_ptr t2s_; }; #endif // _CHTTRANS_CHTTRANS_OPENCC_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans.conf.in000066400000000000000000000002761361043647100264730ustar00rootroot00000000000000[Addon] Name=Simplified and Traditional Chinese Translation Category=Module Library=chttrans Type=SharedLibrary Configurable=True OnDemand=True [Addon/OptionalDependencies] 0=notifications fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans.cpp000066400000000000000000000207711361043647100257250ustar00rootroot00000000000000// // Copyright (C) 2016~2016 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "chttrans.h" #include "config.h" #include #include #include #include #include #include #include #include #ifdef ENABLE_OPENCC #include "chttrans-opencc.h" #endif #include "chttrans-native.h" #include #include using namespace fcitx; static ChttransIMType inputMethodType(const InputMethodEntry &entry) { if (entry.languageCode() == "zh_CN") { return ChttransIMType::Simp; } else if (entry.languageCode() == "zh_HK" || entry.languageCode() == "zh_TW") { return ChttransIMType::Trad; } return ChttransIMType::Other; } Chttrans::Chttrans(fcitx::Instance *instance) : instance_(instance) { instance_->userInterfaceManager().registerAction("chttrans", &toggleAction_); reloadConfig(); #ifdef ENABLE_OPENCC backends_.emplace(ChttransEngine::OpenCC, std::make_unique()); #endif backends_.emplace(ChttransEngine::Native, std::make_unique()); eventHandler_ = instance_->watchEvent( EventType::InputContextKeyEvent, EventWatcherPhase::Default, [this](Event &event) { auto &keyEvent = static_cast(event); if (keyEvent.isRelease()) { return; } auto ic = keyEvent.inputContext(); auto engine = instance_->inputMethodEngine(ic); auto entry = instance_->inputMethodEntry(ic); if (!engine || !entry || !toggleAction_.isParent(&ic->statusArea())) { return; } auto type = inputMethodType(*entry); if (type == ChttransIMType::Other) { return; } if (keyEvent.key().checkKeyList(config_.hotkey.value())) { toggle(ic); bool tradEnabled = convertType(ic) == ChttransIMType::Trad; if (notifications()) { notifications()->call( "fcitx-chttrans-toggle", "fcitx", tradEnabled ? "fcitx-chttrans-active" : "fcitx-chttrans-inactive", tradEnabled ? _("Traditional Chinese") : _("Simplified Chinese"), tradEnabled ? _("Traditional Chinese is enabled.") : _("Simplified Chinese is enabled."), -1); } keyEvent.filterAndAccept(); ic->updateUserInterface(UserInterfaceComponent::InputPanel); } }); outputFilterConn_ = instance_->connect( [this](InputContext *inputContext, Text &text) { if (!toggleAction_.isParent(&inputContext->statusArea()) || !needConvert(inputContext)) { return; } auto type = convertType(inputContext); auto oldString = text.toString(); auto oldLength = utf8::lengthValidated(oldString); if (oldLength == utf8::INVALID_LENGTH) { return; } auto newString = convert(type, oldString); auto newLength = utf8::lengthValidated(newString); if (newLength == utf8::INVALID_LENGTH) { return; } Text newText; size_t off = 0; size_t remainLength = newLength; for (size_t i = 0; i < text.size(); i++) { auto segmentLength = utf8::length(text.stringAt(i)); if (remainLength < segmentLength) { segmentLength = remainLength; } remainLength -= segmentLength; size_t segmentByteLength = utf8::ncharByteLength( newString.begin() + off, segmentLength); newText.append(newString.substr(off, segmentByteLength), text.formatAt(i)); off = off + segmentByteLength; } if (text.cursor() >= 0) { auto length = utf8::length(oldString, 0, text.cursor()); if (length > newLength) { length = newLength; } newText.setCursor( utf8::ncharByteLength(newText.toString().begin(), length)); } else { newText.setCursor(text.cursor()); } text = std::move(newText); }); commitFilterConn_ = instance_->connect( [this](InputContext *inputContext, std::string &str) { if (!toggleAction_.isParent(&inputContext->statusArea()) || !needConvert(inputContext)) { return; } auto type = convertType(inputContext); str = convert(type, str); }); } void Chttrans::toggle(InputContext *ic) { auto engine = instance_->inputMethodEngine(ic); auto entry = instance_->inputMethodEntry(ic); if (!engine || !entry || !toggleAction_.isParent(&ic->statusArea())) { return; } auto type = inputMethodType(*entry); if (type == ChttransIMType::Other) { return; } if (enabledIM_.count(entry->uniqueName())) { enabledIM_.erase(entry->uniqueName()); } else { enabledIM_.insert(entry->uniqueName()); } toggleAction_.update(ic); } void Chttrans::reloadConfig() { readAsIni(config_, "conf/chttrans.conf"); enabledIM_.clear(); enabledIM_.insert(config_.enabledIM.value().begin(), config_.enabledIM.value().end()); } void Chttrans::save() { std::vector values_; for (const auto &id : enabledIM_) { values_.push_back(id); } config_.enabledIM.setValue(std::move(values_)); safeSaveAsIni(config_, "conf/chttrans.conf"); } std::string Chttrans::convert(ChttransIMType type, const std::string &str) { auto iter = backends_.find(config_.engine.value()); if (iter == backends_.end()) { iter = backends_.find(ChttransEngine::Native); } if (iter == backends_.end() || !iter->second->load()) { return str; } if (type == ChttransIMType::Trad) { return iter->second->convertSimpToTrad(str); } else { return iter->second->convertTradToSimp(str); } } bool Chttrans::needConvert(fcitx::InputContext *inputContext) { auto engine = instance_->inputMethodEngine(inputContext); auto entry = instance_->inputMethodEntry(inputContext); if (!engine || !entry) { return false; } auto type = inputMethodType(*entry); if (type == ChttransIMType::Other) { return false; } return enabledIM_.count(entry->uniqueName()); } ChttransIMType Chttrans::convertType(fcitx::InputContext *inputContext) { auto engine = instance_->inputMethodEngine(inputContext); auto entry = instance_->inputMethodEntry(inputContext); if (!engine || !entry) { return ChttransIMType::Other; } auto type = inputMethodType(*entry); if (type == ChttransIMType::Other) { return ChttransIMType::Other; } if (!enabledIM_.count(entry->uniqueName())) { return type; } return type == ChttransIMType::Simp ? ChttransIMType::Trad : ChttransIMType::Simp; } class ChttransModuleFactory : public AddonFactory { AddonInstance *create(AddonManager *manager) override { return new Chttrans(manager->instance()); } }; FCITX_ADDON_FACTORY(ChttransModuleFactory) fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/chttrans.h000066400000000000000000000104221361043647100253620ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _CHTTRANS_CHTTRANS_H_ #define _CHTTRANS_CHTTRANS_H_ #include "notifications_public.h" #include #include #include #include #include #include #include #include #include FCITX_CONFIG_ENUM(ChttransEngine, Native, OpenCC); FCITX_CONFIGURATION( ChttransConfig, fcitx::Option engine{this, "Engine", _("Translate engine"), ChttransEngine::OpenCC}; fcitx::Option hotkey{ this, "Hotkey", _("Toggle key"), {fcitx::Key("Control+Shift+F")}}; fcitx::HiddenOption> enabledIM{ this, "EnabledIM", _("Enabled Input Methods")};); enum class ChttransIMType { Simp, Trad, Other }; class ChttransBackend { public: virtual ~ChttransBackend() {} bool load() { if (!loaded_) { loadResult_ = loadOnce(); loaded_ = true; } return loadResult_; } virtual std::string convertSimpToTrad(const std::string &) = 0; virtual std::string convertTradToSimp(const std::string &) = 0; protected: virtual bool loadOnce() = 0; private: bool loaded_ = false; bool loadResult_ = false; }; class Chttrans final : public fcitx::AddonInstance { class ToggleAction : public fcitx::Action { public: ToggleAction(Chttrans *parent) : parent_(parent) {} std::string shortText(fcitx::InputContext *ic) const override { return parent_->convertType(ic) == ChttransIMType::Trad ? _("Traditional Chinese") : _("Simplified Chinese"); } std::string icon(fcitx::InputContext *ic) const override { return parent_->convertType(ic) == ChttransIMType::Trad ? "fcitx-chttrans-active" : "fcitx-chttrans-inactive"; } void activate(fcitx::InputContext *ic) override { return parent_->toggle(ic); } private: Chttrans *parent_; }; public: Chttrans(fcitx::Instance *instance); void reloadConfig() override; void save() override; const fcitx::Configuration *getConfig() const override { return &config_; } void setConfig(const fcitx::RawConfig &config) override { config_.load(config, true); fcitx::safeSaveAsIni(config_, "conf/chttrans.conf"); reloadConfig(); } bool needConvert(fcitx::InputContext *inputContext); ChttransIMType convertType(fcitx::InputContext *inputContext); std::string convert(ChttransIMType type, const std::string &str); void toggle(fcitx::InputContext *inputContext); fcitx::AddonInstance *notifications() { if (!notifications_) { notifications_ = instance_->addonManager().addon("notifications", true); } return notifications_; } private: fcitx::Instance *instance_; ChttransConfig config_; fcitx::AddonInstance *notifications_ = nullptr; std::unique_ptr> eventHandler_; std::unordered_map, fcitx::EnumHash> backends_; std::unordered_set enabledIM_; fcitx::ScopedConnection outputFilterConn_; fcitx::ScopedConnection commitFilterConn_; ToggleAction toggleAction_{this}; }; #endif // _CHTTRANS_CHTTRANS_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/chttrans/gbks2t.tab000066400000000000000000000570111361043647100252540ustar00rootroot00000000000000篓簍 卢盧 娄婁 掳擄 滩灘 炉爐 颅顱 驴驢 谈談 赂賂 台臺 台檯 台颱 台台 芦蘆 禄祿 搂摟 庐廬 陇隴 垄壟 拢攏 楼樓 卤滷 卤鹵 侪儕 职職 执執 只只 只隻 只祇 纸紙 志志 志誌 挚摯 㤘㥮 玚瑒 觍覥 阘闒 鸴鷽 阇闍 鸮鴞 硚礄 唡啢 觃覎 阓闠 鸰鴒 襕襴 篯籛 蟏蠨 闿闓 鸧鶬 䙌䙡 瘆瘮 硙磑 锧鑕 霡霢 馌饁 鳣鱣 㘎㘚 闬閈 鸤鳲 䜣訢 䜩讌 䞍䝼 䥺釾 䥽鏺 䦂䥇 䦃鐯 䦅鐥 䦆钁 䦶䦛 䦷䦟 䲟鮣 䲠鰆 䲡鰌 䲢鰧 䲣䱷 䴓鳾 䴔鵁 䴕鴷 䴖鶄 䴗鶪 䴘鷈 䴙鷿 䶮龑 万萬 万万 与與 丑醜 丑丑 丛叢 东東 丝絲 丢丟 两兩 严嚴 丧喪 个個 个箇 丰豐 丰丰 临臨 丽麗 举舉 义義 乌烏 乐樂 乔喬 乡鄉 书書 买買 乱亂 了了 了瞭 争爭 于於 于于 亏虧 云雲 云云 亚亞 产產 亲親 亵褻 亸嚲 亿億 仅僅 仆僕 仆仆 仇仇 仇讎 从從 仑侖 仑崙 仓倉 仪儀 们們 价價 价价 仿仿 仿彷 众衆 优優 伙夥 伙伙 会會 伛傴 伞傘 传傳 伡俥 伣俔 伤傷 伥倀 伦倫 伧傖 伫佇 体體 余餘 余余 佛佛 佛彿 佥僉 侠俠 侣侶 侥僥 侦偵 侧側 侨僑 侩儈 侬儂 俊俊 俊儁 俣俁 俦儔 俨儼 俩倆 俪儷 俭儉 修修 修脩 借借 借藉 倾傾 偬傯 偻僂 偾僨 偿償 傥儻 傧儐 储儲 傩儺 僵僵 僵殭 儿兒 克克 克剋 兑兌 兖兗 党黨 党党 兰蘭 关關 兴興 兹茲 养養 兽獸 冁囅 内內 冈岡 册冊 军軍 冬冬 冬鼕 冯馮 冲衝 冲沖 决決 况況 冻凍 净淨 凄悽 凄淒 准準 准准 凉涼 凌凌 凌淩 减減 凑湊 凛凜 几幾 几几 几機 凤鳳 凫鳧 凭憑 凯凱 凶兇 凶凶 出出 出齣 击擊 凿鑿 刍芻 划劃 划划 刘劉 则則 刚剛 创創 删刪 别別 别彆 刭剄 刮刮 刮颳 制制 制製 刹剎 刽劊 刿劌 剀剴 剂劑 剐剮 剑劍 剥剝 剧劇 办辦 务務 劢勱 动動 励勵 劲勁 劳勞 势勢 勋勳 勚勩 匀勻 匦匭 匮匱 区區 升升 升昇 华華 单單 卖賣 卜卜 卜蔔 卧臥 卫衛 却卻 卷卷 卷捲 卺巹 厂廠 厂厂 厅廳 历歷 历曆 厉厲 压壓 厌厭 厍厙 厐龎 厕廁 厘釐 厘厘 厢廂 厣厴 厦廈 厨廚 厩廄 厮廝 县縣 叁叄 参參 参蔘 叆靉 双雙 发發 发髮 变變 叙敘 叠疊 号號 叹嘆 叹歎 叽嘰 吁籲 吁吁 合合 合閤 吊吊 吊弔 同同 同衕 后後 后后 向向 向嚮 向曏 吓嚇 吕呂 吗嗎 吣唚 吨噸 听聽 启啓 吴吳 呐吶 呒嘸 呓囈 呖嚦 呗唄 呙咼 呜嗚 周周 周週 周賙 咏詠 咙嚨 咛嚀 咝噝 咤吒 咨諮 咨咨 咸鹹 咸咸 咽咽 咽嚥 哄哄 哄鬨 响響 哑啞 哒噠 哓嘵 哔嗶 哕噦 哗譁 哗嘩 哙噲 哜嚌 哝噥 唇脣 唛嘜 唠嘮 唢嗩 唤喚 啧嘖 啬嗇 啭囀 啮齧 啯嘓 啰囉 啴嘽 喷噴 喽嘍 喾嚳 嗫囁 嗳噯 嘘噓 嘤嚶 嘱囑 噜嚕 噪噪 噪譟 嚣囂 回回 回迴 团團 团糰 园園 困困 困睏 囱囪 囵圇 国國 图圖 圣聖 圹壙 场場 坂阪 坏壞 坐坐 坐座 块塊 坚堅 坛壇 坛罈 坜壢 坝壩 坞塢 坟墳 坠墜 垅壠 垆壚 垒壘 垦墾 垩堊 垫墊 垭埡 垯墶 垱壋 垲塏 垴堖 埘塒 埙塤 埚堝 埯垵 堕墮 壮壯 声聲 壳殼 壶壺 壸壺 处處 备備 复復 复複 复覆 够夠 夫夫 夫伕 头頭 夸誇 夸夸 夹夾 夺奪 奁奩 奂奐 奋奮 奖獎 奥奧 奸奸 奸姦 妆妝 妇婦 妈媽 妩嫵 妪嫗 妫嬀 姗姍 姜姜 姜薑 姹奼 娅婭 娆嬈 娇嬌 娈孌 娘娘 娘孃 娱娛 娲媧 娴嫻 婵嬋 婶嬸 媪媼 媭嬃 嫒嬡 嫔嬪 嫱嬙 嬷嬤 孙孫 学學 孪孿 宁寧 宁甯 宝寶 实實 宠寵 审審 宪憲 宫宮 家家 家傢 宽寬 宾賓 寝寢 对對 寻尋 导導 寿壽 将將 尔爾 尘塵 尝嘗 尝嚐 尴尷 尸屍 尸尸 尽盡 尽儘 局局 局侷 层層 屃屓 屉屜 届屆 属屬 屡屢 屦屨 屿嶼 岁歲 岂豈 岖嶇 岗崗 岘峴 岙嶴 岚嵐 岛島 岩巖 岩岩 岭嶺 岳嶽 岳岳 岽崬 岿巋 峄嶧 峡峽 峤嶠 峥崢 峦巒 峰峯 崂嶗 崃崍 崄嶮 嵘嶸 嵚嶔 嵝嶁 巅巔 巨巨 巨鉅 巩鞏 巯巰 币幣 布布 布佈 帅帥 师師 帏幃 帐帳 帘簾 帘帘 帜幟 带帶 帧幀 帮幫 帱幬 帻幘 帼幗 幂冪 幞襆 干幹 干乾 干干 并並 并併 幸幸 幸倖 广廣 广广 庄莊 庆慶 床牀 庑廡 库庫 庙廟 庞龐 废廢 庵庵 庵菴 廪廩 开開 异異 弃棄 弑弒 张張 弥彌 弥瀰 弦弦 弦絃 弪弳 弯彎 弹彈 归歸 当當 当噹 彝彝 彟彠 彦彥 彨彲 彩彩 彩綵 彻徹 征徵 征征 径徑 徕徠 御御 御禦 忆憶 忏懺 忧憂 念念 念唸 忾愾 怀懷 态態 怂慫 怃憮 怄慪 怅悵 怆愴 怜憐 总總 怼懟 怿懌 恋戀 恒恆 恤恤 恤卹 恳懇 恶惡 恶噁 恸慟 恹懨 恺愷 恻惻 恼惱 恽惲 悦悅 悫愨 悬懸 悭慳 悮悞 悯憫 惊驚 惧懼 惨慘 惩懲 惫憊 惬愜 惭慚 惮憚 惯慣 愈愈 愈癒 愠慍 愤憤 愦憒 慑懾 懑懣 懒懶 懔懍 戆戇 戋戔 戏戲 戗戧 戚戚 戚慼 戚鏚 戬戩 戯戱 户戶 才才 才纔 扎扎 扎紮 扑撲 托託 托托 扣扣 扣釦 扩擴 扪捫 扫掃 扬揚 扰擾 折折 折摺 抚撫 抛拋 抟摶 抠摳 抡掄 抢搶 护護 报報 抬擡 抵抵 抵牴 担擔 拐拐 拐柺 拟擬 拣揀 拦攔 拨撥 择擇 挂掛 挂挂 挛攣 挜掗 挝撾 挞撻 挠撓 挡擋 挢撟 挣掙 挤擠 挥揮 挦撏 挨挨 挨捱 挽挽 挽輓 捝挩 捞撈 损損 捡撿 换換 捣搗 据據 据据 掴摑 掷擲 掸撣 掺摻 掼摜 揽攬 揿撳 搀攙 搁擱 搅攪 搜搜 搜蒐 摄攝 摅攄 摆擺 摆襬 摈擯 摊攤 撄攖 撑撐 撵攆 撷擷 撸擼 撺攛 擞擻 攒攢 敌敵 教教 敛斂 敩斆 数數 斓斕 斗鬥 斗斗 断斷 无無 旧舊 时時 旷曠 昆昆 昆崑 昙曇 昼晝 显顯 晋晉 晒曬 晓曉 晔曄 晕暈 晖暉 暂暫 暗暗 暗闇 暧曖 曲曲 曲麴 术術 术朮 朱朱 朱硃 朴樸 朴朴 机機 杀殺 杂雜 杆杆 杆桿 杠槓 杠杠 条條 来來 杨楊 杩榪 杯杯 杯盃 杰傑 杰杰 松鬆 松松 板板 板闆 极極 极极 构構 枞樅 枢樞 枣棗 枥櫪 枧梘 枨棖 枫楓 枭梟 柜櫃 柜柜 柠檸 查查 柽檉 栀梔 标標 栉櫛 栊櫳 栋棟 栌櫨 栎櫟 栏欄 树樹 栖棲 栗慄 栗栗 样樣 核核 核覈 栾欒 桠椏 桡橈 桢楨 档檔 桤榿 桥橋 桦樺 桧檜 桨槳 桩樁 梁樑 梁梁 梦夢 梼檮 梾棶 梿槤 检檢 棁梲 棂欞 棱棱 椁槨 椝槼 椟櫝 椠槧 椢槶 椤欏 椫樿 椭橢 榄欖 榇櫬 榈櫚 榉櫸 槚檟 槛檻 槟檳 槠櫧 横橫 樯檣 橥櫫 橱櫥 橹櫓 橼櫞 檩檁 欢歡 欤歟 欲欲 欲慾 歼殲 殁歿 殇殤 残殘 殒殞 殓殮 殚殫 殡殯 毁毀 毁燬 毁譭 毂轂 毕畢 毙斃 毵毿 氇氌 气氣 氢氫 氩氬 氲氳 汇匯 汇彙 汉漢 污污 汤湯 汹洶 沈沈 沈瀋 沟溝 沣灃 沥瀝 沦淪 沧滄 沩潙 沪滬 泛泛 泛氾 泛汎 泪淚 泶澩 泷瀧 泸瀘 泺濼 泼潑 泽澤 泾涇 洁潔 洒灑 洼窪 浃浹 浆漿 浇澆 浈湞 浉溮 浊濁 测測 浍澮 济濟 浏瀏 浐滻 浑渾 浒滸 浔潯 浕濜 涂塗 涂涂 涌涌 涛濤 涝澇 涞淶 涟漣 涠潿 涡渦 涢溳 涣渙 涤滌 润潤 涧澗 涨漲 涩澀 淀澱 淀淀 渊淵 渌淥 渍漬 渎瀆 渐漸 渑澠 渔漁 渖瀋 渗滲 温溫 游遊 游游 湾灣 湿溼 溃潰 溅濺 溆漵 溇漊 滗潷 滚滾 滞滯 滟灩 滠灄 满滿 滢瀅 滤濾 滥濫 滦灤 滨濱 滪澦 漓漓 漓灕 漤灠 潆瀠 潇瀟 潋瀲 潴瀦 澛瀂 澜瀾 濑瀨 濒瀕 灏灝 灭滅 灯燈 灵靈 灶竈 灾災 灿燦 炀煬 炖燉 炜煒 炝熗 点點 炼煉 炼鍊 炽熾 烁爍 烂爛 烃烴 烛燭 烟煙 烟菸 烦煩 烧燒 烨燁 烩燴 烫燙 烬燼 热熱 焕煥 焖燜 焘燾 煴熅 熏薰 熏燻 爱愛 牍牘 牦氂 牺犧 犊犢 状狀 犷獷 犸獁 犹猶 狈狽 狞獰 独獨 狭狹 狮獅 狯獪 狰猙 狱獄 狲猻 猃獫 猎獵 猕獼 猡玀 猪豬 猬蝟 献獻 獭獺 玑璣 玛瑪 玮瑋 环環 现現 玺璽 珐琺 珑瓏 珰璫 珲琿 琏璉 琐瑣 琼瓊 瑶瑤 瑷璦 璎瓔 瓒瓚 瓮甕 瓯甌 电電 画畫 畅暢 畴疇 疖癤 疗療 疠癘 疡瘍 疬癧 疮瘡 疯瘋 疱皰 疴痾 症症 症癥 痉痙 痒癢 痖瘂 痨癆 痪瘓 痫癇 痴癡 瘅癉 瘗瘞 瘘瘻 瘪癟 瘫癱 瘾癮 瘿癭 癞癩 癣癬 癫癲 皂皁 皂皂 皑皚 皱皺 皲皸 盐鹽 监監 盖蓋 盗盜 盘盤 眍瞘 眦眥 眬矓 睁睜 睐睞 睑瞼 瞒瞞 瞩矚 矩矩 矩榘 矫矯 矶磯 矾礬 矿礦 砀碭 码碼 砗硨 砚硯 砜碸 砺礪 砻礱 砾礫 础礎 硕碩 硖硤 硗磽 确確 确确 硵磠 硷鹼 碍礙 碛磧 碜磣 碱鹼 礼禮 祢禰 祯禎 祷禱 祸禍 禀稟 禅禪 离離 私私 私俬 秃禿 秆稈 秋秋 秋鞦 种種 种种 秘祕 积積 称稱 秽穢 秾穠 稆穭 税稅 稣穌 稳穩 穑穡 穗穗 穗繐 穷窮 窃竊 窍竅 窎窵 窜竄 窝窩 窥窺 窦竇 窭窶 竖豎 竞競 笃篤 笋筍 笔筆 笕筧 笺箋 笼籠 笾籩 筑築 筑筑 筚篳 筛篩 筝箏 筹籌 简簡 箓籙 箦簀 箧篋 箨籜 箩籮 箪簞 箫簫 篑簣 篮籃 篱籬 簖籪 籁籟 籴糴 类類 籼秈 粜糶 粝糲 粤粵 粪糞 粮糧 粽糉 糁糝 糇餱 糍餈 系系 系係 系繫 紧緊 累累 絷縶 纟糹 纠糾 纡紆 红紅 纣紂 纤纖 纤縴 纥紇 级級 纨紈 纩纊 纪紀 纫紉 纭紜 纮紘 纯純 纰紕 纱紗 纲綱 纳納 纴紝 纵縱 纶綸 纷紛 纹紋 纺紡 纻紵 纼紖 纾紓 线線 绀紺 绁紲 绂紱 练練 组組 绅紳 细細 织織 终終 绉縐 绊絆 绋紼 绌絀 绍紹 绎繹 经經 绐紿 绑綁 绒絨 结結 绔絝 绕繞 绖絰 绗絎 绘繪 给給 绚絢 绛絳 络絡 绝絕 绞絞 统統 绠綆 绡綃 绢絹 绣繡 绤綌 绥綏 绦絛 继繼 绨綈 绩績 绪緒 绫綾 绬緓 续續 绮綺 绯緋 绰綽 绱鞝 绲緄 绳繩 绵綿 绶綬 绷繃 绸綢 绹綯 绺綹 绻綣 综綜 绽綻 绾綰 绿綠 缀綴 缁緇 缂緙 缃緗 缄緘 缅緬 缆纜 缇緹 缈緲 缉緝 缊縕 缋繢 缌緦 缍綞 缎緞 缏緶 缑緱 缒縋 缓緩 缔締 缕縷 编編 缗緡 缙縉 缚縛 缛縟 缜縝 缝縫 缞縗 缟縞 缠纏 缡縭 缢縊 缣縑 缤繽 缥縹 缦縵 缧縲 缩縮 缪繆 缫繅 缬纈 缭繚 缮繕 缯繒 缰繮 缱繾 缲繰 缳繯 缴繳 缵纘 罂罌 网網 罗羅 罚罰 罢罷 罴羆 羁羈 羟羥 羡羨 群羣 翘翹 翙翽 翚翬 耢耮 耧耬 耸聳 耻恥 聂聶 聋聾 聍聹 联聯 聩聵 聪聰 肃肅 肠腸 肤膚 肮骯 肴餚 肾腎 肿腫 胀脹 胆膽 背背 背揹 胜勝 胜胜 胡胡 胡鬍 胡衚 胧朧 胨腖 胪臚 胫脛 胶膠 脉脈 脍膾 脏髒 脏臟 脐臍 脑腦 脔臠 脚腳 脱脫 脶腡 脸臉 腊臘 腊腊 腌醃 腌腌 腭齶 腻膩 腼靦 腽膃 腾騰 膑臏 膻羶 膻膻 致致 致緻 舆輿 舍舍 舍捨 舣艤 舰艦 舱艙 舻艫 艰艱 艳豔 艺藝 节節 芈羋 芗薌 芜蕪 芸芸 芸蕓 苁蓯 苈藶 苋莧 苌萇 苍蒼 苎苧 苏蘇 苏甦 苏囌 苔苔 苔薹 苘檾 苹蘋 苹苹 范範 范范 茎莖 茏蘢 茑蔦 茔塋 茕煢 茧繭 荆荊 荐薦 荐荐 荚莢 荛蕘 荜蓽 荞蕎 荟薈 荠薺 荡蕩 荡盪 荣榮 荤葷 荥滎 荦犖 荨蕁 荩藎 荪蓀 荫蔭 荫廕 荬蕒 荭葒 荮葤 莅蒞 莱萊 莲蓮 莳蒔 莴萵 莶薟 获獲 获穫 莸蕕 莺鶯 莼蓴 萝蘿 萦縈 萧蕭 萨薩 葱蔥 蒇蕆 蒉蕢 蒋蔣 蒌蔞 蒙蒙 蒙矇 蒙濛 蒙懞 蓝藍 蓟薊 蓠蘺 蓣蕷 蓥鎣 蓦驀 蔑蔑 蔑衊 蔹蘞 蔺藺 蔼藹 蕰薀 蕲蘄 蕴蘊 薮藪 藓蘚 蘖櫱 虑慮 虚虛 虫蟲 虫虫 虬虯 虮蟣 虱蝨 虽雖 虾蝦 虿蠆 蚀蝕 蚁蟻 蚂螞 蚕蠶 蚝蠔 蚝蚝 蚬蜆 蛊蠱 蛎蠣 蛏蟶 蛮蠻 蛰蟄 蛱蛺 蛲蟯 蛳螄 蛴蠐 蜕蛻 蜗蝸 蜡蠟 蜡蜡 蝈蟈 蝉蟬 蝼螻 蝾蠑 螀螿 螨蟎 衅釁 衔銜 补補 表表 表錶 衬襯 衮袞 袄襖 袅嫋 袅裊 袜襪 装裝 裆襠 裢褳 裣襝 裤褲 裥襇 褛褸 褴襤 见見 观觀 规規 觅覓 视視 觇覘 览覽 觉覺 觊覬 觋覡 觌覿 觎覦 觏覯 觐覲 觑覷 觞觴 触觸 觯觶 誉譽 誊謄 讠訁 计計 订訂 讣訃 认認 讥譏 讦訐 讧訌 讨討 让讓 讪訕 讫訖 训訓 议議 讯訊 记記 讲講 讳諱 讵詎 讶訝 讷訥 许許 讹訛 论論 讼訟 讽諷 设設 访訪 诀訣 证證 诂詁 诃訶 评評 诅詛 识識 诉訴 诊診 诋詆 诌謅 词詞 诎詘 译譯 诒詒 诓誆 诔誄 试試 诖詿 诗詩 诘詰 诙詼 诚誠 诛誅 诜詵 话話 诞誕 诟詬 诠詮 诡詭 询詢 诣詣 该該 详詳 诧詫 诨諢 诩詡 诫誡 诬誣 语語 诮誚 误誤 诰誥 诱誘 诲誨 诳誑 说說 诵誦 诶誒 请請 诸諸 诹諏 读讀 诼諑 诽誹 课課 诿諉 谀諛 谁誰 谂諗 调調 谄諂 谅諒 谆諄 谇誶 谊誼 谌諶 谍諜 谎謊 谏諫 谑謔 谒謁 谔諤 谕諭 谖諼 谗讒 谘諮 谙諳 谚諺 谛諦 谜謎 谝諞 谟謨 谠讜 谡謖 谤謗 谥諡 谥謚 谧謐 谨謹 谪謫 谫譾 谬謬 谭譚 谮譖 谯譙 谰讕 谱譜 谲譎 谳讞 谵譫 谶讖 谷谷 谷穀 贝貝 贞貞 负負 贡貢 财財 责責 贤賢 败敗 账賬 货貨 质質 贩販 贪貪 贬貶 购購 贮貯 贯貫 贰貳 贱賤 贲賁 贳貰 贴貼 贵貴 贶貺 贷貸 费費 贺賀 贻貽 贼賊 贽贄 贾賈 贿賄 赀貲 赁賃 赃贓 资資 赅賅 赆贐 赇賕 赈賑 赉賚 赊賒 赋賦 赌賭 赍齎 赎贖 赏賞 赐賜 赓賡 赔賠 赕賧 赖賴 赘贅 赙賻 赚賺 赛賽 赜賾 赝贗 赞贊 赞讚 赠贈 赡贍 赣贛 赵趙 赶趕 趋趨 趱趲 趸躉 跄蹌 跞躒 践踐 跷蹺 跸蹕 跹躚 跻躋 踊踊 踌躊 踪蹤 踬躓 踯躑 蹑躡 蹒蹣 蹰躕 蹿躥 躏躪 躜躦 躯軀 车車 轧軋 轨軌 轩軒 轫軔 轭軛 轮輪 软軟 轰轟 轱軲 轲軻 轳轤 轴軸 轵軹 轶軼 轷軤 轸軫 轹轢 轺軺 轻輕 轼軾 载載 轾輊 轿轎 辁輇 辂輅 较較 辄輒 辅輔 辆輛 辇輦 辈輩 辉輝 辊輥 辋輞 辍輟 辎輜 辏輳 辐輻 辑輯 输輸 辔轡 辕轅 辖轄 辘轆 辙轍 辚轔 辞辭 辟闢 辟辟 辩辯 辫辮 边邊 辽遼 达達 过過 迈邁 运運 还還 这這 进進 连連 迟遲 迩邇 迳逕 迹跡 迹蹟 适適 适适 选選 逊遜 递遞 逦邐 逻邏 遗遺 邓鄧 邝鄺 邬鄔 邮郵 邹鄒 邺鄴 邻鄰 郁鬱 郁郁 郏郟 郐鄶 郑鄭 郓鄆 郦酈 郧鄖 郸鄲 酂酇 酝醞 酰醯 酱醬 酸酸 酸痠 酽釅 酾釃 酿釀 采採 采采 采寀 释釋 里裏 里里 鉴鑑 鉴鑒 銮鑾 錾鏨 钅釒 钆釓 钇釔 针針 针鍼 钉釘 钊釗 钋釙 钌釕 钍釷 钏釧 钐釤 钑鈒 钒釩 钓釣 钔鍆 钕釹 钖鍚 钗釵 钘鈃 钙鈣 钚鈈 钛鈦 钜鉅 钝鈍 钞鈔 钟鍾 钟鐘 钠鈉 钡鋇 钢鋼 钣鈑 钤鈐 钦欽 钧鈞 钨鎢 钩鉤 钪鈧 钫鈁 钬鈥 钭鈄 钯鈀 钰鈺 钲鉦 钴鈷 钵鉢 钶鈳 钷鉕 钸鈽 钹鈸 钺鉞 钻鑽 钼鉬 钽鉭 钾鉀 钿鈿 铀鈾 铁鐵 铂鉑 铃鈴 铄鑠 铇鉋 铈鈰 铉鉉 铊鉈 铋鉍 铌鈮 铍鈹 铎鐸 铏鉶 铐銬 铑銠 铒鉺 铓鋩 铔錏 铕銪 铖鋮 铗鋏 铘鋣 铙鐃 铚銍 铛鐺 铜銅 铝鋁 铞銱 铟銦 铠鎧 铢銖 铤鋌 铥銩 铦銛 铧鏵 铨銓 铩鎩 铪鉿 铫銚 铬鉻 铭銘 铮錚 铯銫 铰鉸 铲鏟 铲剷 铳銃 铴鐋 铵銨 银銀 铷銣 铸鑄 铹鐒 铺鋪 铻鋙 铼錸 铽鋱 链鏈 链鍊 铿鏗 销銷 锁鎖 锂鋰 锃鋥 锄鋤 锅鍋 锆鋯 锇鋨 锈鏽 锉銼 锊鋝 锋鋒 锍鋶 锎鐦 锏鐧 锐銳 锑銻 锒鋃 锓鋟 锔鋦 锕錒 锖錆 锗鍺 锘鍩 错錯 锛錛 锜錡 锝鍀 锞錁 锟錕 锠錩 锡錫 锢錮 锣鑼 锤錘 锥錐 锦錦 锨杴 锩錈 锪鍃 锫錇 锬錟 锭錠 键鍵 锯鋸 锰錳 锱錙 锲鍥 锴鍇 锵鏘 锶鍶 锷鍔 锸鍤 锹鍬 锺鍾 锻鍛 锼鎪 锾鍰 锿鎄 镀鍍 镂鏤 镄鐨 镅鎇 镆鏌 镇鎮 镉鎘 镊鑷 镌鐫 镍鎳 镎鎿 镏鎦 镐鎬 镑鎊 镒鎰 镓鎵 镔鑌 镖鏢 镗鏜 镘鏝 镙鏍 镛鏞 镜鏡 镝鏑 镞鏃 镟鏇 镡鐔 镢钁 镣鐐 镤鏷 镥鑥 镦鐓 镧鑭 镨鐠 镩鑹 镪鏹 镫鐙 镬鑊 镭鐳 镯鐲 镰鐮 镰鎌 镱鐿 镲鑔 镳鑣 镶鑲 长長 门門 闩閂 闪閃 闫閆 闭閉 问問 闯闖 闰閏 闱闈 闲閒 闲閑 闳閎 间間 闵閔 闶閌 闷悶 闹鬧 闺閨 闻聞 闼闥 闽閩 闾閭 阀閥 阁閣 阂閡 阃閫 阄鬮 阅閱 阆閬 阈閾 阉閹 阊閶 阋鬩 阌閿 阍閽 阎閻 阏閼 阐闡 阑闌 阒闃 阔闊 阕闋 阖闔 阗闐 阙闕 阚闞 队隊 阳陽 阴陰 阵陣 阶階 际際 陈陳 陉陘 陕陝 陧隉 陨隕 险險 随隨 隐隱 隶隸 隽雋 难難 雇僱 雏雛 雕雕 雕鵰 雠讎 雳靂 雾霧 霁霽 霭靄 靓靚 静靜 面面 面麪 靥靨 鞑韃 鞒鞽 鞯韉 鞲韝 韧韌 韨韍 韩韓 韪韙 韫韞 韬韜 韵韻 顶頂 顷頃 顸頇 项項 顺順 须須 须鬚 顼頊 顽頑 顾顧 顿頓 颀頎 颁頒 颂頌 颃頏 预預 领領 颇頗 颈頸 颉頡 颊頰 颌頜 颍潁 颏頦 颐頤 颓頹 颔頷 颗顆 题題 颚顎 颛顓 颜顏 额額 颞顳 颟顢 颠顛 颡顙 颢顥 颤顫 颥顬 颦顰 风風 飑颮 飒颯 飓颶 飕颼 飘飄 飙飆 飚飈 飞飛 飨饗 餍饜 饣飠 饤飣 饥飢 饥饑 饦飥 饧餳 饨飩 饩餼 饪飪 饫飫 饬飭 饭飯 饮飲 饯餞 饰飾 饱飽 饲飼 饳飿 饴飴 饵餌 饶饒 饷餉 饸餄 饹餎 饺餃 饻餏 饼餅 饽餑 饾餖 饿餓 馀餘 馁餒 馂餕 馃餜 馄餛 馅餡 馆館 馇餷 馈饋 馉餶 馊餿 馋饞 馍饃 馏餾 馐饈 馑饉 馒饅 馓饊 馔饌 馕饢 马馬 驭馭 驮馱 驯馴 驰馳 驱驅 驳駁 驵駔 驶駛 驷駟 驸駙 驹駒 驺騶 驼駝 驽駑 驾駕 驿驛 骀駘 骁驍 骂罵 骄驕 骅驊 骆駱 骇駭 骈駢 骊驪 骋騁 验驗 骏駿 骐騏 骑騎 骒騍 骓騅 骖驂 骗騙 骘騭 骚騷 骛騖 骜驁 骝騮 骞騫 骟騸 骠驃 骡騾 骢驄 骣驏 骤驟 骥驥 骧驤 髅髏 髋髖 髌髕 鬓鬢 魇魘 魉魎 鱼魚 鱽魛 鱾魢 鱿魷 鲀魨 鲂魴 鲃䰾 鲄魺 鲅鮁 鲆鮃 鲇鯰 鲈鱸 鲉鮋 鲊鮓 鲋鮒 鲌鮊 鲍鮑 鲎鱟 鲏鮍 鲐鮐 鲑鮭 鲒鮚 鲓鮳 鲔鮪 鲕鮞 鲖鮦 鲗鰂 鲘鮜 鲙鱠 鲚鱭 鲛鮫 鲜鮮 鲝鮺 鲞鯗 鲟鱘 鲠鯁 鲡鱺 鲢鰱 鲣鰹 鲤鯉 鲥鰣 鲦鰷 鲧鯀 鲨鯊 鲩鯇 鲪鮶 鲫鯽 鲬鯒 鲭鯖 鲮鯪 鲯鯕 鲰鯫 鲱鯡 鲲鯤 鲳鯧 鲴鯝 鲵鯢 鲶鯰 鲷鯛 鲸鯨 鲹鰺 鲺鯴 鲻鯔 鲼鱝 鲽鰈 鲾鰏 鲿鱨 鳀鯷 鳁鰮 鳂鰃 鳃鰓 鳄鱷 鳅鰍 鳆鰒 鳇鰉 鳈鰁 鳉鱂 鳊鯿 鳋鰠 鳌鰲 鳍鰭 鳎鰨 鳏鰥 鳐鰩 鳑鰟 鳒鰜 鳓鰳 鳔鰾 鳕鱈 鳖鱉 鳗鰻 鳘鰵 鳙鱅 鳚䲁 鳛鰼 鳜鱖 鳝鱔 鳞鱗 鳟鱒 鳠鱯 鳡鱤 鳢鱧 鸟鳥 鸠鳩 鸡雞 鸢鳶 鸣鳴 鸦鴉 鸨鴇 鸩鴆 鸪鴣 鸫鶇 鸬鸕 鸭鴨 鸯鴦 鸱鴟 鸲鴝 鸳鴛 鸵鴕 鸶鷥 鸷鷙 鸸鴯 鸹鴰 鸺鵂 鸽鴿 鸾鸞 鸿鴻 鹁鵓 鹂鸝 鹃鵑 鹄鵠 鹅鵝 鹆鵒 鹇鷳 鹈鵜 鹉鵡 鹊鵲 鹋鶓 鹌鵪 鹎鵯 鹏鵬 鹑鶉 鹕鶘 鹗鶚 鹘鶻 鹚鶿 鹛鶥 鹜鶩 鹞鷂 鹣鶼 鹤鶴 鹦鸚 鹧鷓 鹨鷚 鹩鷯 鹪鷦 鹫鷲 鹬鷸 鹭鷺 鹱鸌 鹳鸛 鹾鹺 麦麥 麸麩 麽麼 黄黃 黉黌 黩黷 黪黲 黾黽 鼋黿 鼍鼉 鼗鞀 鼹鼴 齄齇 齐齊 齑齏 齿齒 龀齔 龁齕 龂齗 龃齟 龄齡 龅齙 龆齠 龇齜 龈齦 龉齬 龊齪 龋齲 龌齷 龙龍 龚龔 龛龕 龟龜 录錄 录彔 陆陸 㛠𡢃 㟆㠏 𢫊𢷮 𢫞𢶫 𨱀𨥛 𨱊𨧱 𨱔鐏 𨸂閍 𨸌𨶮 㖊噚 㚯㜄 㛿𡠹 𥮋𥸠 𨱁鈠 𨱋錂 𨱕𨮂 𨸃閐 㔉劚 㟜𡾱 𢬦𢹿 𥬀䉙 𥬞籋 𥱔𥵃 𨱂鈋 𨱌鏆 𨱖䥩 𨸄䦘 𨸎𨷲 𨸘𨽏 㛣㜏 𢭏擣 𨱃鈲 𨱍鎯 𨸅𨴗 㛤孋 𢫬摋 𥧂𥨐 𥬠篘 𨱄鈯 𨱎鍮 𨸆𨵩 𥭉𥵊 𨱅鉁 𨱏鎝 𨸇𨵸 㓥劏 𨱆龯 𨱐𨫒 𨱇銶 𨱑鐄 𨷿䦳 𨸉𨶀 㛀媰 𥮜䉲 𨰾鎷 𨱈鋉 𨱒鏉 𨸀𨳕 𨸊𨶏 㛟𡞵 𨰿釳 𨱉鍄 𨱓鐎 𨸁𨳑 𨸋𨶲 𨸟䧢 㱩殰 𦈐縺 𦈚縬 㶶燶 𥹥𥼽 𦈑緸 𦈛繓 𦈈𥿊 𦈒𦂅 𦈜䌖 𥺅䊭 𦈉緷 𦈓䋿 𦈝繏 𢽾斅 𦈔縎 𦈞䌟 㭴樫 㲿瀇 𥺇𥽖 𦈋綇 𦈕緰 𦈟䌝 㳔濧 㶉鸂 𦈌綀 𦈖䌈 𦈠䌥 㳕灡 𦈗𦃄 𦈡繻 㨫㩜 㭏椲 㭣𣙎 㳡濄 㶽煱 𦈎繟 𦈘䌋 㧑撝 㧰擽 㭤樢 㳢𣾷 𦈏緍 𦈙䌰 虏虜 䌺䋙 𠆲儣 𦛨朥 𩏼䪏 𩖖顃 𩙨𩘹 𩠂𩛆 𩠌餸 𩠠𩠴 㻘𤪺 䌻䋚 𩏽𩏪 𩖗䫴 𩙩𩘀 𩠃𩛩 㻅璯 㻏𤫩 䌼綐 𩏾𩎢 𩙪颷 𩠎𩞄 䇲筴 䌽綵 𠆿𠌥 𣍯腪 𩏿䪘 𩙫颾 𩠅𩟐 𩠏𩞦 䀥䁻 䌾䋻 𠉂㒓 𣆐曥 𣍰脥 𣐤欍 𩐀䪗 𩙬𩘺 𩠆𩜦 䅉稏 𠉗𠏢 𩙭𩘝 𩠇䭀 㺍獱 䍀繿 𣍨𦢈 𣑶𣠲 𩙮䬘 𩠈䭃 䂵碽 䅪𥢢 䉤籔 䌶䊷 䍁繸 𣎑臗 𣗋欓 𩙥颰 𩙯䬝 𩟿𩚛 𩠉𩜇 䌸縳 𩙦𩗀 𩙰𩙈 𩠀𩚥 𩠊𩜵 䌹絅 𣘓𣞻 𩖕𩓣 𩙧𩗡 𩠁𩚵 𩠋𩝔 鲁魯 䑽𦪙 䙊𧜵 䞐賰 𠛆𠞆 𩧬𩢡 𩧶𩣏 𩨀騔 𩨊騚 𠚳𠠎 𩧭䭿 𩨁䮞 𩨋𩥄 𩬣𩭙 䟢躎 𣘴檭 𩧮𩢾 𩨌𩥑 𩬤𩰀 䘛𧝞 𦨩𦪽 𩧯驋 𩨃騝 𩨍𩥇 䗖螮 𩧦𩡺 𩧰䮝 𩧺駶 𩨄騪 𩨎龭 𣘷𣝕 𩧱𩥉 𩧻𩣵 𩨅𩤸 𩨏䮳 䘞𧜗 䜥𧩙 𦰴䕳 𩧨駎 𩧲駧 𩧼𩣺 𩨆𩤙 𩨐𩧆 𩯒𩯳 䝙貙 䞌𧵳 𩧩𩤊 𩧳𩢸 𩨇䮫 䓕薳 䙓襬 䜧譅 䞎𧶧 𦝼膢 𩧪䮾 𩧴駩 𩨈騟 𩲒𩳤 𠛅剾 𦟗𦣎 𩧫駚 𩧵𩢴 𩧿䮠 𩨉𩤲 䢀𨊰 𠵾㗲 𣭤𣯴 𩾂䲖 𩾌鱇 𪉈鴜 𪉒𪄕 䢁𨊸 䥾䥱 䩄靦 䲝䱽 𣶩澅 𩽹魥 𩾃鮸 𪉉𪁈 䢂𨋢 䥿𨯅 䲞𩶘 𩽺𩵩 𩾄𩷰 𩾎𩽇 𪉊鷨 𪉔𪄆 䦀𨦫 𠲥𡅏 𣶫𣿉 𣸣濆 𣽷瀃 𩽻𩵹 𩾅𩸃 𪉋𪀾 𪉕𪇳 䦁𨧜 䯃𩣑 𠮶嗰 𠵸𡄣 𩽼鯶 𩾆𩸦 𪉂䲰 𪉌𪁖 䭪𩞯 䯄騧 𠯟哯 𩽽𩶱 𩾇鯱 𪉃鳼 𪉍鵚 䯅䯀 𠯠噅 𣺼灙 𩽾鮟 𩾈䱙 𪉄𩿪 𪉎𪂆 𣺽𤁣 𩽿𩶰 𪉅𪀦 𪉏𪃏 𠴢𡄔 𩾀鮕 𩾊䱬 𪉆鴲 𪉐𪃍 𩾁鯄 𩾋䱰 𪉑鷔 𤊀𤒎 𪎈䴬 𤇃爄 𪎉麲 𪔭𪔵 𤇄熌 𪎊麨 𪎋䴴 𧉞䗿 𪎌麳 𧒭𧔥 𪎍𪋿 𪚏𪘀 𡋀𡓾 𤈶熉 𪚐𪘯 𤆡熓 𤈷㷿 𡋗𡑭 𤋏熡 𡝠㜷 棡 𡞱㜢 𤦀瓕 𪡏嗹 𪞝凙 𤞤玁 𪨊㞞 𡒄壈 𪢮圞 𤠋㺏 𪨗屩 𡭜𡮉 𧳕𧳟 𧹑䞈 𧮪詀 𤶧𤸫 𧹓𧶔 𡭬𡮣 𧹕䝻 𤳄𤳸 𧹖賟 𧿈𨇁 𪻐瑽 𪾢睍 𫂈䉬 𧹗贃 𫁡鴗 𡶴嵼 𥅘𥌃 𨁴𨅍 𨂺𨈊 𫌀襀 𫌨覼 𫐄軏 𫗮餭 𤽯㿧 𫍰諰 𫐆轣 𫐐輗 𫗦餔 𨀱𨄣 𨉗軉 𨐅軗 𫏋蹻 𫗧餗 𨄄𨈌 𨐆𨊻 𫄸纁 𫍲謏 𨐇𨏠 𫍟𧦧 𫐉軨 𫐓輮 𨐈輄 𫔎鐍 𫗠餦 𫗴饘 𨅫𨇞 𨐉𨎮 𫓧鈇 𤾀皟 𥅴䀹 𥇢䁪 𨅬躝 𨐊𨏥 𫄨絺 𫍢譊 𥆧瞤 𨑹䢨 𫍙訑 𫓩鏦 㐽偑 㑈倲 𢋈㢝 𫛞鴃 𥐟礒 𫚙鯆 㑔㑯 㑩儸 𢘝𢣚 𢛯㦎 𫘣駻 𢘞𢣭 𫘤騃 𫚈鱮 𫚒鮄 𫛢鸋 𫛶鶒 𫚉魟 𨤰𨤻 𫚔鮰 𫛸鶗 𢙓懀 𥐯𥖅 𫘝駃 𫚕鰤 𫛛鳷 𥐰𥕥 𫘨騠 𥐻碙 轪軑 阛闤 鸻鴴 狝獮 锳鍈 馎餺 谩謾 呛嗆 颧顴 墙牆 牵牽 㧏掆 辀輈 鸼鵃 袯襏 锽鍠 㧟擓 辌輬 鹀鵐 镃鎡 辒轀 鹍鵾 黡黶 旸暘 桪樳 镈鎛 浅淺 潜潛 㧐㩳 鹐鵮 镋鎲 猫貓 锚錨 权權 鹒鶊 镕鎔 颋頲 俫倈 鹓鵷 镚鏰 颎熲 堑塹 谴譴 千千 千韆 铅鉛 钎釺 蔂虆 揾搵 沨渢 鬶鬹 鹔鷫 臜臢 镠鏐 颒頮 㱮殨 刬剗 峣嶢 鹖鶡 镮鐶 颕頴 铆鉚 谋謀 㳠澾 鹙鶖 蚃蠁 镴鑞 颙顒 豮豶 鹝鷊 镵鑱 颣纇 签籤 签簽 迁遷 亩畝 祃禡 鹟鶲 鹠鶹 麺麪 硁硜 鹡鶺 腘膕 酦醱 枪槍 䁖瞜 昽曨 玱瑲 筼篔 鹢鷁 婳嫿 贠貟 贸貿 么麼 劝勸 强強 蔷薔 谦謙 刾㓨 鹥鷖 赑贔 鹮䴉 琎璡 荙薘 赒賙 跶躂 䌷紬 苧薴 飏颺 鹯鸇 荝萴 赗賵 驲馹 飐颭 鹲鸏 疭瘲 赟贇 骃駰 拧擰 祎禕 飔颸 鹴鸘 裈褌 骉驫 钮鈕 脓膿 纽紐 纽鈕 泞濘 飖颻 骍騂 霉黴 没沒 疟瘧 农農 浓濃 飗飀 骎駸 赪赬 骔騌 诺諾 榅榲 骕驌 唝嗊 筜簹 骙騤 欧歐 鸥鷗 㖞喎 瞆瞶 骦驦 殴毆 沤漚 呕嘔 贫貧 频頻 镁鎂 钳鉗 钱錢 亘亙 亘亘 讴謳 诏詔 诤諍 讬託 讱訒 讻訩 诇詗 诐詖 诪譸 谞諝 注注 注註 驻駐 专專 砖磚 转轉 伪僞 维維 纬緯 苇葦 喂喂 喂餵 铣銑 为爲 习習 谓謂 韦韋 袭襲 席席 席蓆 违違 潍濰 伟偉 围圍 胁脅 谐諧 佣傭 佣佣 写寫 詟讋 袆褘 訚誾 鹰鷹 婴嬰 樱櫻 泻瀉 摇搖 谢謝 遥遙 尧堯 谣謠 窑窯 缨纓 应應 萤螢 荧熒 莹瑩 营營 锌鋅 业業 颖穎 赢贏 爷爺 啸嘯 页頁 药藥 药葯 拥擁 哟喲 叶葉 叶叶 医醫 铱銥 蝎蠍 痈癰 协協 蝇蠅 挟挾 携攜 铡鍘 员員 闸閘 圆圓 栅柵 缘緣 远遠 愿願 愿愿 诈詐 斋齋 约約 债債 跃躍 钥鑰 毡氈 盏盞 斩斬 辗輾 崭嶄 栈棧 占佔 占占 战戰 fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/000077500000000000000000000000001361043647100240735ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/CMakeLists.txt000066400000000000000000000013771361043647100266430ustar00rootroot00000000000000set(CLOUDPINYIN_SOURCES cloudpinyin.cpp fetch.cpp ) add_library(cloudpinyin MODULE ${CLOUDPINYIN_SOURCES}) target_link_libraries(cloudpinyin Fcitx5::Core Fcitx5::Config PkgConfig::Curl Pthread::Pthread) set_target_properties(cloudpinyin PROPERTIES PREFIX "") install(TARGETS cloudpinyin DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(cloudpinyin.conf.in cloudpinyin.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cloudpinyin.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon") install(FILES ${CLOUDPINYIN_DATA_FILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/fcitx5/cloudpinyin") fcitx5_export_module(CloudPinyin TARGET cloudpinyin BUILD_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}" HEADERS cloudpinyin_public.h INSTALL) fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/cloudpinyin.conf.in000066400000000000000000000001621361043647100277030ustar00rootroot00000000000000[Addon] Name=Cloud Pinyin Category=Module Library=cloudpinyin Type=SharedLibrary OnDemand=True Configurable=True fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/cloudpinyin.cpp000066400000000000000000000155261361043647100271450ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "cloudpinyin.h" #include #include #include #include #include #include #include #include #include #include using namespace fcitx; FCITX_DEFINE_LOG_CATEGORY(cloudpinyin, "cloudpinyin"); #define CLOUDPINYIN_DEBUG() FCITX_LOGC(cloudpinyin, Debug) class GoogleBackend : public Backend { public: void prepareRequest(CurlQueue *queue, const std::string &pinyin) override { std::string url = "https://www.google.com/inputtools/request?ime=pinyin&text="; std::unique_ptr escaped( curl_escape(pinyin.c_str(), pinyin.size()), &curl_free); url += escaped.get(); CLOUDPINYIN_DEBUG() << "Request URL: " << url; curl_easy_setopt(queue->curl(), CURLOPT_URL, url.c_str()); } std::string parseResult(CurlQueue *queue) override { std::string result(queue->result().begin(), queue->result().end()); CLOUDPINYIN_DEBUG() << "Request result: " << result; auto start = result.find("\",[\""); std::string hanzi; if (start != std::string::npos) { start += strlen("\",[\""); auto end = result.find("\"", start); if (end != std::string::npos && end > start) { hanzi = result.substr(start, end - start); } } return hanzi; } }; class BaiduBackend : public Backend { public: void prepareRequest(CurlQueue *queue, const std::string &pinyin) override { std::string url = "https://olime.baidu.com/py?rn=0&pn=1&ol=1&py="; std::unique_ptr escaped( curl_escape(pinyin.c_str(), pinyin.size()), &curl_free); url += escaped.get(); CLOUDPINYIN_DEBUG() << "Request URL: " << url; curl_easy_setopt(queue->curl(), CURLOPT_URL, url.c_str()); } std::string parseResult(CurlQueue *queue) override { std::string result(queue->result().begin(), queue->result().end()); CLOUDPINYIN_DEBUG() << "Request result: " << result; auto start = result.find("[[\""); std::string hanzi; if (start != std::string::npos) { start += strlen("[[\""); auto end = result.find("\",", start); if (end != std::string::npos && end > start) { hanzi = result.substr(start, end - start); } } return hanzi; } }; constexpr int MAX_ERROR = 10; constexpr int minInUs = 60000000; CloudPinyin::CloudPinyin(fcitx::AddonManager *manager) : eventLoop_(manager->eventLoop()) { curl_global_init(CURL_GLOBAL_ALL); UnixFD pipe1Fd[2]; int pipe1[2]; if (pipe2(pipe1, O_NONBLOCK) < 0) { throw std::runtime_error("Failed to create pipe"); } pipe1Fd[0].give(pipe1[0]); pipe1Fd[1].give(pipe1[1]); recvFd_.give(pipe1Fd[0].release()); backends_.emplace(CloudPinyinBackend::Google, std::make_unique()); backends_.emplace(CloudPinyinBackend::Baidu, std::make_unique()); event_ = eventLoop_->addIOEvent( recvFd_.fd(), IOEventFlag::In, [this](EventSourceIO *, int, IOEventFlags) { char c; while (fs::safeRead(recvFd_.fd(), &c, sizeof(char)) > 0) ; CurlQueue *item; auto backend = config_.backend.value(); auto iter = backends_.find(backend); Backend *b = nullptr; if (iter != backends_.end()) { b = iter->second.get(); } while ((item = thread_->popFinished())) { if (item->httpCode() != 200) { errorCount_ += 1; if (errorCount_ == MAX_ERROR && resetError_) { FCITX_ERROR() << "Cloud pinyin reaches max error. " "Retry in 5 minutes."; resetError_->setNextInterval(minInUs * 5); resetError_->setOneShot(); } } std::string hanzi; if (b) { hanzi = b->parseResult(item); } else { hanzi = ""; } item->callback()(item->pinyin(), hanzi); if (hanzi.size()) { cache_.insert(item->pinyin(), hanzi); } item->release(); } return true; }); resetError_ = eventLoop_->addTimeEvent(CLOCK_MONOTONIC, now(CLOCK_MONOTONIC), minInUs, [this](EventSourceTime *, uint64_t) { resetError(); return true; }); if (resetError_) { resetError_->setEnabled(false); } thread_ = std::make_unique(std::move(pipe1Fd[1])); reloadConfig(); } CloudPinyin::~CloudPinyin() {} void CloudPinyin::reloadConfig() { readAsIni(config_, "conf/cloudpinyin.conf"); } void CloudPinyin::request(const std::string &pinyin, CloudPinyinCallback callback) { if (static_cast(pinyin.size()) < config_.minimumLength.value()) { callback(pinyin, ""); return; } if (auto value = cache_.find(pinyin)) { callback(pinyin, *value); } else { auto backend = config_.backend.value(); auto iter = backends_.find(backend); if (iter == backends_.end() || errorCount_ >= MAX_ERROR) { callback(pinyin, ""); return; } auto b = iter->second.get(); if (!thread_->addRequest([b, &pinyin, &callback](CurlQueue *queue) { b->prepareRequest(queue, pinyin); queue->setPinyin(pinyin); queue->setBusy(); queue->setCallback(callback); })) { callback(pinyin, ""); }; } } FCITX_ADDON_FACTORY(CloudPinyinFactory); fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/cloudpinyin.h000066400000000000000000000066401361043647100266070ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _CLOUDPINYIN_CLOUDPINYIN_H_ #define _CLOUDPINYIN_CLOUDPINYIN_H_ #include "cloudpinyin_public.h" #include "fetch.h" #include "lrucache.h" #include #include #include #include #include #include #include #include #include FCITX_CONFIG_ENUM(CloudPinyinBackend, Google, Baidu); FCITX_CONFIGURATION( CloudPinyinConfig, fcitx::Option toggleKey{ this, "Toggle Key", _("Toggle Key"), {fcitx::Key("Control+Alt+Shift+C")}}; fcitx::Option minimumLength{this, "MinimumPinyinLength", _("Minimum Pinyin Length"), 4}; fcitx::Option backend{this, "Backend", _("Backend"), CloudPinyinBackend::Google};); class Backend { public: virtual void prepareRequest(CurlQueue *queue, const std::string &pinyin) = 0; virtual std::string parseResult(CurlQueue *queue) = 0; }; class CloudPinyin : public fcitx::AddonInstance { public: CloudPinyin(fcitx::AddonManager *manager); ~CloudPinyin(); void reloadConfig() override; const fcitx::Configuration *getConfig() const override { return &config_; } void setConfig(const fcitx::RawConfig &config) override { config_.load(config, true); fcitx::safeSaveAsIni(config_, "conf/cloudpinyin.conf"); reloadConfig(); } void request(const std::string &pinyin, CloudPinyinCallback callback); const fcitx::KeyList &toggleKey() { return config_.toggleKey.value(); } void resetError() { errorCount_ = 0; resetError_->setEnabled(false); } private: FCITX_ADDON_EXPORT_FUNCTION(CloudPinyin, request); FCITX_ADDON_EXPORT_FUNCTION(CloudPinyin, toggleKey); FCITX_ADDON_EXPORT_FUNCTION(CloudPinyin, resetError); fcitx::UnixFD recvFd_, notifyFd_; std::unique_ptr thread_; fcitx::EventLoop *eventLoop_; std::unique_ptr event_; std::unique_ptr resetError_; LRUCache cache_{2048}; std::unordered_map, fcitx::EnumHash> backends_; CloudPinyinConfig config_; int errorCount_ = 0; }; class CloudPinyinFactory : public fcitx::AddonFactory { public: fcitx::AddonInstance *create(fcitx::AddonManager *manager) override { return new CloudPinyin(manager); } }; #endif // _CLOUDPINYIN_CLOUDPINYIN_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/cloudpinyin_public.h000066400000000000000000000120631361043647100301410ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _CLOUDPINYIN_CLOUDPINYIN_PUBLIC_H_ #define _CLOUDPINYIN_CLOUDPINYIN_PUBLIC_H_ #include #include #include #include #include #include #include #include #include typedef std::function CloudPinyinCallback; typedef std::function CloudPinyinSelectedCallback; FCITX_ADDON_DECLARE_FUNCTION(CloudPinyin, request, void(const std::string &pinyin, CloudPinyinCallback)); FCITX_ADDON_DECLARE_FUNCTION(CloudPinyin, toggleKey, const fcitx::KeyList &()); FCITX_ADDON_DECLARE_FUNCTION(CloudPinyin, resetError, void()); class CloudPinyinCandidateWord : public fcitx::CandidateWord, public fcitx::TrackableObject { public: CloudPinyinCandidateWord(fcitx::AddonInstance *cloudpinyin_, const std::string &pinyin, const std::string &selectedSentence, fcitx::InputContext *inputContext, CloudPinyinSelectedCallback callback) : CandidateWord(fcitx::Text{}), selectedSentence_(selectedSentence), inputContext_(inputContext), callback_(callback) { // use cloud unicode char setText(fcitx::Text("\xe2\x98\x81")); auto ref = watch(); cloudpinyin_->call( pinyin, [ref](const std::string &pinyin, const std::string &hanzi) { FCITX_UNUSED(pinyin); auto self = ref.get(); if (self) { self->fill(hanzi); } }); constructor_ = false; } void select(fcitx::InputContext *inputContext) const override { if (!filled_ || word_.empty()) { // not filled, do nothing return; } callback_(inputContext, selectedSentence_, word_); } bool filled() const { return filled_; } const std::string &word() { return word_; } private: static constexpr long int LOADING_TIME_QUICK_THRESHOLD = 300; void fill(const std::string &hanzi) { setText(fcitx::Text(hanzi)); word_ = hanzi; filled_ = true; if (!constructor_) { update(); } } void update() { auto inputContext = inputContext_; auto candidateList = inputContext_->inputPanel().candidateList(); if (!candidateList) { return; } auto modifiable = candidateList->toModifiable(); if (!modifiable) { return; } int idx = -1; bool dup = false; for (auto i = 0, e = modifiable->totalSize(); i < e; i++) { auto &candidate = modifiable->candidateFromAll(i); if (static_cast(this) == &candidate) { idx = i; } else { if (!dup && text().toString() == candidate.text().toString()) { dup = true; } } } if (idx >= 0 && (dup || word_.empty())) { auto ms = std::chrono::duration_cast( std::chrono::high_resolution_clock::now() - timestamp_) .count(); if (ms > LOADING_TIME_QUICK_THRESHOLD) { setText(fcitx::Text("\xe2\x98\x81")); word_ = std::string(); } else { modifiable->remove(idx); } } // use stack variable inputContext, because it may be removed already inputContext->updateUserInterface( fcitx::UserInterfaceComponent::InputPanel); } std::chrono::high_resolution_clock::time_point timestamp_ = std::chrono::high_resolution_clock::now(); bool filled_ = false; std::string word_; std::string selectedSentence_; fcitx::InputContext *inputContext_; bool constructor_ = true; CloudPinyinSelectedCallback callback_; }; #endif // _CLOUDPINYIN_CLOUDPINYIN_PUBLIC_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/fetch.cpp000066400000000000000000000176271361043647100257050ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "fetch.h" #include #include #include #include using namespace fcitx; FetchThread::FetchThread(fcitx::UnixFD notifyFd) : notifyFd_(std::move(notifyFd)) { int pipefd[2]; if (pipe2(pipefd, O_NONBLOCK) < 0) { throw std::runtime_error("Failed to create pipe"); } selfPipeFd_[0].give(pipefd[0]); selfPipeFd_[1].give(pipefd[1]); curlm_ = curl_multi_init(); curl_multi_setopt(curlm_, CURLMOPT_MAXCONNECTS, MAX_HANDLE); curl_multi_setopt(curlm_, CURLMOPT_SOCKETFUNCTION, &FetchThread::curlCallback); curl_multi_setopt(curlm_, CURLMOPT_SOCKETDATA, this); curl_multi_setopt(curlm_, CURLMOPT_TIMERFUNCTION, &FetchThread::curlTimerCallback); curl_multi_setopt(curlm_, CURLMOPT_TIMERDATA, this); thread_ = std::make_unique(&FetchThread::runThread, this); } FetchThread::~FetchThread() { quit(); thread_->join(); while (workingQueue.size()) { auto queue = &workingQueue.front(); workingQueue.pop_front(); curl_multi_remove_handle(curlm_, queue->curl()); queue->release(); } while (pendingQueue.size()) { auto queue = &pendingQueue.front(); pendingQueue.pop_front(); queue->release(); } while (finishingQueue.size()) { auto queue = &finishingQueue.front(); finishingQueue.pop_front(); queue->release(); } curl_multi_cleanup(curlm_); } void FetchThread::runThread(FetchThread *self) { self->run(); } int FetchThread::curlCallback(CURL *, curl_socket_t s, int action, void *userp, void *) { FetchThread *self = static_cast(userp); self->curl(s, action); return 0; } void FetchThread::handleIO(int fd, IOEventFlags flags) { int mask = 0; if (flags & IOEventFlag::In) { mask |= CURL_CSELECT_IN; } if (flags & IOEventFlag::Out) { mask |= CURL_CSELECT_OUT; } if (flags & IOEventFlag::Err) { mask |= CURL_CSELECT_ERR; } int still_running = 0; CURLMcode mcode; do { mcode = curl_multi_socket_action(curlm_, fd, mask, &still_running); } while (mcode == CURLM_CALL_MULTI_PERFORM); processMessages(); } void FetchThread::processMessages() { int num_messages = 0; CURLMsg *curl_message = curl_multi_info_read(curlm_, &num_messages); while (curl_message != NULL) { if (curl_message->msg == CURLMSG_DONE) { int curl_result = curl_message->data.result; void *p = nullptr; curl_easy_getinfo(curl_message->easy_handle, CURLINFO_PRIVATE, &p); auto queue = static_cast(p); curl_multi_remove_handle(curlm_, queue->curl()); queue->finish(curl_result); queue->remove(); finished(queue); } curl_message = curl_multi_info_read(curlm_, &num_messages); } } void FetchThread::curl(curl_socket_t s, int action) { // if loop is gone, don't bother do anything if (!loop_) { return; } if (action == CURL_POLL_REMOVE) { events_.erase(s); } else { auto iter = events_.find(s); if (iter == events_.end()) { auto that_ = this; auto p = events_.emplace( s, loop_->addIOEvent( s, IOEventFlags(0), [that_](EventSourceIO *, int fd, IOEventFlags flags) { auto that = that_; // make sure "that" is valid since io handler may // free itself. that->handleIO(fd, flags); return true; })); iter = p.first; } IOEventFlags flags(0); if (action == CURL_POLL_IN) { flags = IOEventFlag::In; } else if (action == CURL_POLL_OUT) { flags = IOEventFlag::Out; } else if (action == CURL_POLL_INOUT) { flags |= IOEventFlag::In; flags |= IOEventFlag::Out; } iter->second->setEvents(flags); } } int FetchThread::curlTimerCallback(CURLM *, long timeout_ms, void *user) { auto self = static_cast(user); self->curlTimer(timeout_ms); return 0; } void FetchThread::curlTimer(long timeout_ms) { if (!loop_) { return; } if (!timer_) { timer_ = loop_->addTimeEvent( CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + timeout_ms * 1000, 0, [this](EventSourceTime *, uint64_t) { CURLMcode mcode; int still_running; do { mcode = curl_multi_socket_action( curlm_, CURL_SOCKET_TIMEOUT, 0, &still_running); } while (mcode == CURLM_CALL_MULTI_PERFORM); processMessages(); return true; }); timer_->setOneShot(); } else { timer_->setNextInterval(timeout_ms * 1000); timer_->setOneShot(); } } void FetchThread::finished(CurlQueue *queue) { std::lock_guard lock(finishQueueLock); finishingQueue.push_back(*queue); char c = 0; fs::safeWrite(notifyFd_.fd(), &c, sizeof(char)); } bool FetchThread::addRequest(SetupRequestCallback callback) { CurlQueue *queue = nullptr; for (auto &handle : handles_) { if (!handle.busy()) { queue = &handle; break; } } if (!queue) { return false; } callback(queue); std::lock_guard lock(pendingQueueLock); pendingQueue.push_back(*queue); char c = 0; fs::safeWrite(selfPipeFd_[1].fd(), &c, sizeof(c)); return true; } void FetchThread::quit() { char c = 1; fs::safeWrite(selfPipeFd_[1].fd(), &c, sizeof(c)); } CurlQueue *FetchThread::popFinished() { std::lock_guard lock(finishQueueLock); CurlQueue *result = nullptr; if (finishingQueue.size()) { result = &finishingQueue.front(); finishingQueue.pop_front(); } return result; } void FetchThread::run() { loop_.reset(new fcitx::EventLoop); std::unique_ptr event(loop_->addIOEvent( selfPipeFd_[0].fd(), IOEventFlag::In, [this](EventSourceIO *, int, IOEventFlags) { char c; int r = 0; bool endflag = false; while ((r = fs::safeRead(selfPipeFd_[0].fd(), &c, sizeof(char))) > 0) { if (c == 1) { endflag = true; } } if (r == 0 || endflag) { loop_->quit(); return true; } std::lock_guard lock(pendingQueueLock); while (pendingQueue.size()) { auto queue = &pendingQueue.front(); pendingQueue.pop_front(); curl_multi_add_handle(curlm_, queue->curl()); workingQueue.push_back(*queue); } return true; })); loop_->exec(); // free events ahead of time timer_.reset(); events_.clear(); loop_.reset(); } fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/fetch.h000066400000000000000000000130731361043647100253410ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _CLOUDPINYIN_FETCH_H_ #define _CLOUDPINYIN_FETCH_H_ #include "cloudpinyin_public.h" #include #include #include #include #include #include #include #include #include #include #define MAX_HANDLE 100l #define MAX_BUFFER_SIZE 2048 class CurlQueue : public fcitx::IntrusiveListNode { public: CurlQueue(bool keep = true) : keep_(keep), curl_(curl_easy_init()) { curl_easy_setopt(curl_, CURLOPT_PRIVATE, this); curl_easy_setopt(curl_, CURLOPT_WRITEDATA, this); curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, &CurlQueue::curlWriteFunction); curl_easy_setopt(curl_, CURLOPT_TIMEOUT, 10l); curl_easy_setopt(curl_, CURLOPT_NOSIGNAL, 1); } ~CurlQueue() { curl_easy_cleanup(curl_); } void release() { busy_ = false; if (!keep_) { delete this; } else { data_.clear(); pinyin_.clear(); // make sure lambda is free'd callback_ = CloudPinyinCallback(); httpCode_ = 0; } } const auto &pinyin() const { return pinyin_; } void setPinyin(const std::string &pinyin) { pinyin_ = pinyin; } auto curl() { return curl_; } void finish(int result) { curlResult_ = result; curl_easy_getinfo(curl_, CURLINFO_RESPONSE_CODE, &httpCode_); } bool busy() const { return busy_; } void setBusy() { busy_ = true; } const std::vector &result() { return data_; } CloudPinyinCallback callback() { return callback_; } void setCallback(CloudPinyinCallback callback) { callback_ = callback; } int httpCode() const { return httpCode_; } private: static size_t curlWriteFunction(char *ptr, size_t size, size_t nmemb, void *userdata) { auto self = static_cast(userdata); return self->curlWrite(ptr, size, nmemb); } size_t curlWrite(char *ptr, size_t size, size_t nmemb) { size_t realsize = size * nmemb; /* * We know that it isn't possible to overflow during multiplication if * neither operand uses any of the most significant half of the bits in * a size_t. */ if ((unsigned long long)((nmemb | size) & ((unsigned long long)SIZE_MAX << (sizeof(size_t) << 2))) && (realsize / size != nmemb)) return 0; if (SIZE_MAX - data_.size() < realsize) { realsize = SIZE_MAX - data_.size(); } // make sure we won't be hacked if (data_.size() + realsize > MAX_BUFFER_SIZE) { return 0; } data_.reserve(data_.size() + realsize); std::copy(ptr, ptr + realsize, std::back_inserter(data_)); return realsize; } bool keep_ = true; bool busy_ = false; CURL *curl_ = nullptr; int curlResult_ = 0; long httpCode_ = 0; std::vector data_; std::string pinyin_; CloudPinyinCallback callback_; }; typedef std::function SetupRequestCallback; class FetchThread { public: FetchThread(fcitx::UnixFD notifyFd); ~FetchThread(); bool addRequest(SetupRequestCallback); CurlQueue *popFinished(); private: static void runThread(FetchThread *self); static int curlCallback(CURL *easy, /* easy handle */ curl_socket_t s, /* socket */ int action, /* see values below */ void *userp, /* private callback pointer */ void *socketp); static int curlTimerCallback(CURLM *multi, /* multi handle */ long timeout_ms, /* see above */ void *userp); /* private callback pointer */ void curl(curl_socket_t s, /* socket */ int action); void curlTimer(long timeout_ms); void handleIO(int fd, fcitx::IOEventFlags flags); void processMessages(); void run(); void finished(CurlQueue *queue); void quit(); std::unique_ptr thread_; std::unique_ptr loop_; std::unordered_map> events_; std::unique_ptr timer_; CURLM *curlm_; fcitx::UnixFD selfPipeFd_[2]; fcitx::UnixFD notifyFd_; CurlQueue handles_[MAX_HANDLE]; fcitx::IntrusiveList pendingQueue; fcitx::IntrusiveList workingQueue; fcitx::IntrusiveList finishingQueue; std::mutex pendingQueueLock; std::mutex finishQueueLock; }; #endif // _CLOUDPINYIN_FETCH_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/cloudpinyin/lrucache.h000066400000000000000000000060541361043647100260370ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _FCITX_LIBIME_LRU_H_ #define _FCITX_LIBIME_LRU_H_ #include #include template class LRUCache { typedef K key_type; typedef V value_type; typedef std::unordered_map::iterator>> dict_type; dict_type dict_; std::list order_; size_t sz_; public: LRUCache(size_t sz = 80) : sz_(sz) {} size_t size() const { return dict_.size(); } size_t capacity() const { return sz_; } bool empty() const { return dict_.empty(); } bool contains(const key_type &key) { return dict_.find(key) != dict_.end(); } template value_type *insert(const key_type &key, Args &&... args) { auto iter = dict_.find(key); if (iter == dict_.end()) { if (size() >= sz_) { evict(); } order_.push_front(key); auto r = dict_.emplace( key, std::make_pair(value_type(std::forward(args)...), order_.begin())); return &r.first->second.first; } return nullptr; } void erase(const key_type &key) { auto i = dict_.find(key); if (i == dict_.end()) { return; } order_.erase(i->second.second); dict_.erase(i); } value_type *find(const key_type &key) { // lookup value in the cache auto i = dict_.find(key); return find_helper(i); } void clear() { dict_.clear(); order_.clear(); } private: void evict() { // evict item from the end of most recently used list auto i = std::prev(order_.end()); dict_.erase(*i); order_.erase(i); } value_type *find_helper(typename dict_type::iterator i) { if (i == dict_.end()) { // value not in cache return nullptr; } // return the value, but first update its place in the most // recently used list auto j = i->second.second; if (j != order_.begin()) { order_.splice(order_.begin(), order_, j, std::next(j)); j = order_.begin(); i->second.second = j; } return &i->second.first; } }; #endif // _FCITX_LIBIME_LRU_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/fullwidth/000077500000000000000000000000001361043647100235405ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/fullwidth/CMakeLists.txt000066400000000000000000000007421361043647100263030ustar00rootroot00000000000000set(FULLWIDTH_SOURCES fullwidth.cpp ) add_library(fullwidth MODULE ${FULLWIDTH_SOURCES}) target_link_libraries(fullwidth Fcitx5::Core Fcitx5::Config Fcitx5::Module::Notifications) set_target_properties(fullwidth PROPERTIES PREFIX "") install(TARGETS fullwidth DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(fullwidth.conf.in fullwidth.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/fullwidth.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon") fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/fullwidth/fullwidth.conf.in000066400000000000000000000002231361043647100270130ustar00rootroot00000000000000[Addon] Name=Full width character Category=Module Library=fullwidth Type=SharedLibrary OnDemand=True [Addon/OptionalDependencies] 0=notifications fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/fullwidth/fullwidth.cpp000066400000000000000000000122251361043647100262500ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "fullwidth.h" #include "notifications_public.h" #include #include #include #include #include #include #include #include #include #include using namespace fcitx; const char *sCornerTrans[] = { " ", "!", """, "#", "¥", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", }; Fullwidth::Fullwidth(Instance *instance) : instance_(instance) { instance_->userInterfaceManager().registerAction("fullwidth", &toggleAction_); auto filterKey = [this](Event &event) { if (!enabled_) { return; } auto &keyEvent = static_cast(event); if (!inWhiteList(keyEvent.inputContext())) { return; } if (keyEvent.key().states() || keyEvent.isRelease()) { return; } auto key = static_cast(keyEvent.key().sym()); if (key >= 32 && key - 32 < FCITX_ARRAY_SIZE(sCornerTrans)) { keyEvent.accept(); keyEvent.inputContext()->commitString(sCornerTrans[key - 32]); } }; eventHandlers_.emplace_back(instance->watchEvent( EventType::InputContextKeyEvent, EventWatcherPhase::Default, [this, filterKey](Event &event) { auto &keyEvent = static_cast(event); if (keyEvent.isRelease()) { return; } if (!inWhiteList(keyEvent.inputContext())) { return; } if (keyEvent.key().checkKeyList(config_.hotkey.value())) { setEnabled(!enabled_, keyEvent.inputContext()); if (notifications()) { notifications()->call( "fcitx-fullwidth-toggle", "fcitx", enabled_ ? "fcitx-fullwidth-active" : "fcitx-fullwidth-inactive", _("Full width Character"), enabled_ ? _("Full width Character is enabled.") : _("Full width Character is disabled."), -1); } keyEvent.filterAndAccept(); return; } return filterKey(event); })); commitFilterConn_ = instance_->connect( [this](InputContext *inputContext, std::string &str) { if (!enabled_ || !inWhiteList(inputContext)) { return; } auto len = utf8::length(str); std::string result; auto ps = str.c_str(); for (size_t i = 0; i < len; ++i) { uint32_t wc; char *nps; nps = fcitx_utf8_get_char(ps, &wc); int chr_len = nps - ps; if (wc > 32 && wc - 32 < FCITX_ARRAY_SIZE(sCornerTrans)) { result.append(sCornerTrans[wc - 32]); } else { result.append(ps, chr_len); } ps = nps; } str = std::move(result); }); reloadConfig(); } void Fullwidth::reloadConfig() { readAsIni(config_, "conf/fullwidth.conf"); } void Fullwidth::save() { safeSaveAsIni(config_, "conf/fullwidth.conf"); } bool Fullwidth::inWhiteList(InputContext *inputContext) const { return toggleAction_.isParent(&inputContext->statusArea()); } class FullwidthModuleFactory : public AddonFactory { AddonInstance *create(AddonManager *manager) override { return new Fullwidth(manager->instance()); } }; FCITX_ADDON_FACTORY(FullwidthModuleFactory) fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/fullwidth/fullwidth.h000066400000000000000000000054111361043647100257140ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _FULLWIDTH_FULLWIDTH_H_ #define _FULLWIDTH_FULLWIDTH_H_ #include #include #include #include #include #include FCITX_CONFIGURATION(FullWidthConfig, fcitx::Option hotkey{ this, "Hotkey", _("Toggle key")};) class ToggleAction; class Fullwidth final : public fcitx::AddonInstance { class ToggleAction : public fcitx::Action { public: ToggleAction(Fullwidth *parent) : parent_(parent) {} std::string shortText(fcitx::InputContext *) const override { return parent_->enabled_ ? _("Full width Character") : _("Half width Character"); } std::string icon(fcitx::InputContext *) const override { return parent_->enabled_ ? "fcitx-fullwidth-active" : "fcitx-fullwidth-inactive"; } void activate(fcitx::InputContext *ic) override { return parent_->setEnabled(!parent_->enabled_, ic); } private: Fullwidth *parent_; }; public: Fullwidth(fcitx::Instance *instance); void reloadConfig() override; void save() override; FCITX_ADDON_DEPENDENCY_LOADER(notifications, instance_->addonManager()); bool inWhiteList(fcitx::InputContext *inputContext) const; void setEnabled(bool enabled, fcitx::InputContext *ic) { if (enabled != enabled_) { enabled_ = enabled; toggleAction_.update(ic); } } private: bool enabled_ = false; fcitx::Instance *instance_; FullWidthConfig config_; fcitx::AddonInstance *notifications_ = nullptr; std::vector>> eventHandlers_; fcitx::ScopedConnection commitFilterConn_; std::unordered_set whiteList_; ToggleAction toggleAction_{this}; }; #endif // _FULLWIDTH_FULLWIDTH_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/000077500000000000000000000000001361043647100242445ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/CMakeLists.txt000066400000000000000000000034431361043647100270100ustar00rootroot00000000000000set(PINYINHELPER_SOURCES pinyinhelper.cpp pinyinlookup.cpp stroke.cpp ) add_library(pinyinhelper MODULE ${PINYINHELPER_SOURCES}) target_link_libraries(pinyinhelper Fcitx5::Core Fcitx5::Config LibIME::Core Boost::iostreams) set_target_properties(pinyinhelper PROPERTIES PREFIX "") install(TARGETS pinyinhelper DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(pinyinhelper.conf.in pinyinhelper.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pinyinhelper.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon") fcitx5_export_module(PinyinHelper TARGET pinyinhelper BUILD_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}" HEADERS pinyinhelper_public.h INSTALL) set(PY_STROKE_VER 20121124) set(PY_STROKE_TGT "${CMAKE_CURRENT_BINARY_DIR}/py_stroke.mb") set(PY_STROKE_TAR "py_stroke-${PY_STROKE_VER}.tar.gz") set(PY_STROKE_URL "http://download.fcitx-im.org/data/py_stroke-${PY_STROKE_VER}.tar.gz") fcitx5_download(py-stroke-download "${PY_STROKE_URL}" "${PY_STROKE_TAR}" 8eb128a9bfa43952e67cf2fcee1fd134c6f4cfd317bc2f6c38a615f5eb64e248) fcitx5_extract(py-stroke-extract "${PY_STROKE_TAR}" DEPENDS py-stroke-download OUTPUT ${PY_STROKE_TGT}) install(FILES "${PY_STROKE_TGT}" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/pinyinhelper") set(PY_TABLE_VER 20121124) set(PY_TABLE_TGT "${CMAKE_CURRENT_BINARY_DIR}/py_table.mb") set(PY_TABLE_TAR "py_table-${PY_TABLE_VER}.tar.gz") set(PY_TABLE_URL "http://download.fcitx-im.org/data/py_table-${PY_TABLE_VER}.tar.gz") fcitx5_download(py-table-download "${PY_TABLE_URL}" "${PY_TABLE_TAR}" 42146ac97de6c13d55f9e99ed873915f4c66739e9c11532a34556badf9792c04) fcitx5_extract(py-table-extract "${PY_TABLE_TAR}" DEPENDS py-table-download OUTPUT ${PY_TABLE_TGT}) install(FILES "${PY_TABLE_TGT}" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/pinyinhelper") fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/pinyinhelper.conf.in000066400000000000000000000001561361043647100302300ustar00rootroot00000000000000[Addon] Name=Extra Pinyin functionality Category=Module Library=pinyinhelper Type=SharedLibrary OnDemand=True fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/pinyinhelper.cpp000066400000000000000000000053161361043647100274630ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pinyinhelper.h" #include #include #include #include #include #include #include #include #include #include namespace fcitx { PinyinHelper::PinyinHelper(Instance *instance) : instance_(instance) { lookup_.load(); stroke_.load(); reloadConfig(); } void PinyinHelper::reloadConfig() {} std::vector PinyinHelper::lookup(uint32_t chr) { return lookup_.lookup(chr); } std::vector> PinyinHelper::lookupStroke(const std::string &input, int limit) { static const std::set num{'1', '2', '3', '4', '5'}; static const std::map py{ {'h', '1'}, {'s', '2'}, {'p', '3'}, {'n', '4'}, {'z', '5'}}; if (input.empty()) { return {}; } if (num.count(input[0])) { if (!std::all_of(input.begin(), input.end(), [&](char c) { return num.count(c); })) { return {}; } return stroke_.lookup(input, limit); } if (py.count(input[0])) { if (!std::all_of(input.begin(), input.end(), [&](char c) { return py.count(c); })) { return {}; } std::string converted; std::transform(input.begin(), input.end(), std::back_inserter(converted), [&](char c) { return py.find(c)->second; }); return stroke_.lookup(converted, limit); } return {}; } std::string PinyinHelper::prettyStrokeString(const std::string &input) { return stroke_.prettyString(input); } class PinyinHelperModuleFactory : public AddonFactory { AddonInstance *create(AddonManager *manager) override { return new PinyinHelper(manager->instance()); } }; } // namespace fcitx FCITX_ADDON_FACTORY(fcitx::PinyinHelperModuleFactory) fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/pinyinhelper.h000066400000000000000000000033641361043647100271310ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINHELPER_PINYINHELPER_H_ #define _PINYINHELPER_PINYINHELPER_H_ #include "pinyinhelper_public.h" #include "pinyinlookup.h" #include "stroke.h" #include #include #include #include #include namespace fcitx { class PinyinHelper final : public AddonInstance { public: PinyinHelper(Instance *instance); void reloadConfig() override; std::vector lookup(uint32_t); std::vector> lookupStroke(const std::string &input, int limit); std::string prettyStrokeString(const std::string &input); FCITX_ADDON_EXPORT_FUNCTION(PinyinHelper, lookup); FCITX_ADDON_EXPORT_FUNCTION(PinyinHelper, lookupStroke); FCITX_ADDON_EXPORT_FUNCTION(PinyinHelper, prettyStrokeString); private: Instance *instance_; PinyinLookup lookup_; Stroke stroke_; }; } // namespace fcitx #endif // _PINYINHELPER_PINYINHELPER_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/pinyinhelper_public.h000066400000000000000000000026101361043647100304600ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINHELPER_PINYINHELPER_PUBLIC_H_ #define _PINYINHELPER_PINYINHELPER_PUBLIC_H_ #include #include #include FCITX_ADDON_DECLARE_FUNCTION(PinyinHelper, lookup, std::vector(uint32_t)); FCITX_ADDON_DECLARE_FUNCTION(PinyinHelper, lookupStroke, std::vector>( const std::string &, int limit)); FCITX_ADDON_DECLARE_FUNCTION(PinyinHelper, prettyStrokeString, std::string(const std::string &)); #endif // _PINYINHELPER_PINYINHELPER_PUBLIC_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/pinyinlookup.cpp000066400000000000000000000131521361043647100275120ustar00rootroot00000000000000// // Copyright (C) 2012~2012 by Yichao Yu // yyc1992@gmail.com // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pinyinlookup.h" #include #include #include #include #include #include #include namespace fcitx { namespace { std::string_view py_enhance_get_vokal(int index, int tone) { static const std::string_view vokals_table[][5] = { {"", "", "", "", ""}, {"a", "ā", "á", "ǎ", "à"}, {"ai", "āi", "ái", "ǎi", "ài"}, {"an", "ān", "án", "ǎn", "àn"}, {"ang", "āng", "áng", "ǎng", "àng"}, {"ao", "āo", "áo", "ǎo", "ào"}, {"e", "ē", "é", "ě", "è"}, {"ei", "ēi", "éi", "ěi", "èi"}, {"en", "ēn", "én", "ěn", "èn"}, {"eng", "ēng", "éng", "ěng", "èng"}, {"er", "ēr", "ér", "ěr", "èr"}, {"i", "ī", "í", "ǐ", "ì"}, {"ia", "iā", "iá", "iǎ", "ià"}, {"ian", "iān", "ián", "iǎn", "iàn"}, {"iang", "iāng", "iáng", "iǎng", "iàng"}, {"iao", "iāo", "iáo", "iǎo", "iào"}, {"ie", "iē", "ié", "iě", "iè"}, {"in", "īn", "ín", "ǐn", "ìn"}, {"ing", "īng", "íng", "ǐng", "ìng"}, {"iong", "iōng", "ióng", "iǒng", "iòng"}, {"iu", "iū", "iú", "iǔ", "iù"}, {"m", "m", "m", "m", "m"}, {"n", "n", "ń", "ň", "ǹ"}, {"ng", "ng", "ńg", "ňg", "ǹg"}, {"o", "ō", "ó", "ǒ", "ò"}, {"ong", "ōng", "óng", "ǒng", "òng"}, {"ou", "ōu", "óu", "ǒu", "òu"}, {"u", "ū", "ú", "ǔ", "ù"}, {"ua", "uā", "uá", "uǎ", "uà"}, {"uai", "uāi", "uái", "uǎi", "uài"}, {"uan", "uān", "uán", "uǎn", "uàn"}, {"uang", "uāng", "uáng", "uǎng", "uàng"}, {"ue", "uē", "ué", "uě", "uè"}, {"ueng", "uēng", "uéng", "uěng", "uèng"}, {"ui", "uī", "uí", "uǐ", "uì"}, {"un", "ūn", "ún", "ǔn", "ùn"}, {"uo", "uō", "uó", "uǒ", "uò"}, {"ü", "ǖ", "ǘ", "ǚ", "ǜ"}, {"üan", "üān", "üán", "üǎn", "üàn"}, {"üe", "üē", "üé", "üě", "üè"}, {"ün", "ǖn", "ǘn", "ǚn", "ǜn"}}; static const int8_t vokals_count = FCITX_ARRAY_SIZE(vokals_table); if (index < 0 || index >= vokals_count) { return ""; } if (tone < 0 || tone > 4) tone = 0; return vokals_table[index][tone]; } std::string_view py_enhance_get_konsonant(int index) { static const std::string_view konsonants_table[] = { "", "b", "c", "ch", "d", "f", "g", "h", "j", "k", "l", "m", "n", "ng", "p", "q", "r", "s", "sh", "t", "w", "x", "y", "z", "zh"}; static const int8_t konsonants_count = FCITX_ARRAY_SIZE(konsonants_table); if (index < 0 || index >= konsonants_count) { return ""; } return konsonants_table[index]; } } // namespace PinyinLookup::PinyinLookup() {} std::vector PinyinLookup::lookup(uint32_t hz) { auto iter = data_.find(hz); if (iter == data_.end()) { return {}; } std::vector result; for (const auto &data : iter->second) { auto c = py_enhance_get_konsonant(data.consonant); auto v = py_enhance_get_vokal(data.vocal, data.tone); if (c.empty() && v.empty()) { continue; } result.emplace_back(); auto &str = result.back(); str.reserve(c.size() + v.size()); str.append(c.begin(), c.end()); str.append(v.begin(), v.end()); } return result; } bool PinyinLookup::load() { auto file = StandardPath::global().open( StandardPath::Type::PkgData, "pinyinhelper/py_table.mb", O_RDONLY); if (file.fd() < 0) { return false; } /** * Format: * uint8_t word_l; * char word[word_l]; * uint8_t count; * int8_t py[count][3]; **/ while (true) { char word[FCITX_UTF8_MAX_LENGTH + 1]; uint8_t wordLen; auto res = read(file.fd(), &wordLen, 1); if (res == 0) { return true; } if (res < 0 || wordLen > FCITX_UTF8_MAX_LENGTH) { return false; } if (read(file.fd(), word, wordLen) != wordLen) { return false; } word[wordLen] = '\0'; std::string_view view(word); if (utf8::lengthValidated(view) != 1) { return false; } uint32_t chr = utf8::getChar(view); uint8_t count; if (read(file.fd(), &count, 1) != 1) { return false; } if (count == 0) continue; auto &data = data_[chr]; while (count--) { uint8_t buf[3]; if (read(file.fd(), buf, 3) != 3) { return false; } data.push_back({buf[0], buf[1], buf[2]}); } } } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/pinyinlookup.h000066400000000000000000000023701361043647100271570ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINHELPER_PINYINLOOKUP_H_ #define _PINYINHELPER_PINYINLOOKUP_H_ #include #include #include namespace fcitx { struct PinyinLookupData { uint8_t consonant; uint8_t vocal; uint8_t tone; }; class PinyinLookup { public: PinyinLookup(); bool load(); std::vector lookup(uint32_t hz); private: std::unordered_map> data_; }; } // namespace fcitx #endif // _PINYINHELPER_PINYINLOOKUP_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/stroke.cpp000066400000000000000000000142571361043647100262700ustar00rootroot00000000000000// // Copyright (C) 2012~2012 by Yichao Yu // yyc1992@gmail.com // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "stroke.h" #include #include #include #include #include #include #include #include namespace fcitx { Stroke::Stroke() {} bool Stroke::load() { auto file = StandardPath::global().open( StandardPath::Type::PkgData, "pinyinhelper/py_stroke.mb", O_RDONLY); if (file.fd() < 0) { return false; } boost::iostreams::stream_buffer buffer(file.fd(), boost::iostreams::file_descriptor_flags::never_close_handle); std::istream in(&buffer); std::string buf; auto isSpaceCheck = boost::is_any_of(" \n\t\r\v\f"); while (!in.eof()) { if (!std::getline(in, buf)) { break; } // Validate everything first, so it's easier to process. if (!utf8::validate(buf)) { continue; } boost::trim_if(buf, isSpaceCheck); if (buf.empty() || buf[0] == '#') { continue; } std::vector tokens; boost::split(tokens, buf, isSpaceCheck); if (tokens.size() != 2 || utf8::length(tokens[1]) != 1 || tokens[0].find_first_not_of("12345") != std::string::npos) { continue; } std::string token = tokens[0] + '|' + tokens[1]; dict_.set(token, 1); } return true; } #define DELETION_WEIGHT 5 #define INSERTION_WEIGHT 5 #define SUBSTITUTION_WEIGHT 5 #define TRANSPOSITION_WEIGHT 5 std::vector> Stroke::lookup(std::string_view input, int limit) { std::vector> result; using position_type = decltype(dict_)::position_type; struct LookupItem { position_type pos; std::string_view remain; int weight; int length; bool operator>(const LookupItem &other) const { return weight > other.weight; } }; std::priority_queue, std::greater> q; auto pushQueue = [&q](LookupItem &&item) { if (item.weight >= 10) { return; } q.push(std::move(item)); }; pushQueue(LookupItem{0, input, 0, 0}); while (!q.empty()) { auto current = q.top(); q.pop(); if (current.remain.empty()) { if (!dict_.foreach( "|", [this, &result, ¤t, limit](int32_t, size_t len, uint64_t pos) { std::string buf; dict_.suffix(buf, current.length + 1 + len, pos); result.emplace_back(buf.substr(current.length + 1), buf.substr(0, current.length)); if (limit > 0 && result.size() >= static_cast(limit)) { return false; } return true; }, current.pos)) { break; } } // Deletion if (current.remain.size() >= 1) { pushQueue(LookupItem{current.pos, current.remain.substr(1), current.weight + DELETION_WEIGHT, current.length}); } for (char i = '1'; i <= '5'; i++) { auto pos = current.pos; auto v = dict_.traverse(&i, 1, pos); if (dict_.isNoPath(v)) { continue; } if (!current.remain.empty() && current.remain[0] == i) { pushQueue(LookupItem{pos, current.remain.substr(1), current.weight, current.length + 1}); } else { pushQueue(LookupItem{pos, current.remain, current.weight + INSERTION_WEIGHT, current.length + 1}); if (!current.remain.empty()) { pushQueue(LookupItem{pos, current.remain.substr(1), current.weight + SUBSTITUTION_WEIGHT, current.length + 1}); } } if (current.remain.size() >= 2 && current.remain[1] == i) { auto nextPos = pos; auto nextV = dict_.traverse(¤t.remain[0], 1, nextPos); if (!dict_.isNoPath(nextV)) { pushQueue(LookupItem{nextPos, current.remain.substr(2), current.weight + TRANSPOSITION_WEIGHT, current.length + 2}); } } } } return result; } std::string Stroke::prettyString(const std::string &input) const { std::string result; static const std::string_view stroke_table[] = {"一", "丨", "丿", "㇏", "𠃍", ""}; for (auto c : input) { if (c < '1' || c > '5') { return {}; } auto v = stroke_table[c - '1']; result.append(v.begin(), v.end()); } return result; } } // namespace fcitx fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/pinyinhelper/stroke.h000066400000000000000000000023461361043647100257310ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PINYINHELPER_STROKE_H_ #define _PINYINHELPER_STROKE_H_ #include #include #include #include namespace fcitx { class Stroke { public: Stroke(); bool load(); std::vector> lookup(std::string_view input, int limit); std::string prettyString(const std::string &input) const; private: libime::DATrie dict_; }; } // namespace fcitx #endif // _PINYINHELPER_STROKE_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/000077500000000000000000000000001361043647100241075ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/CMakeLists.txt000066400000000000000000000015141361043647100266500ustar00rootroot00000000000000set(PUNCTUATION_SOURCES punctuation.cpp ) set(PUNCTUATION_DATA_FILES punc.mb.zh_CN punc.mb.zh_HK punc.mb.zh_TW ) add_library(punctuation MODULE ${PUNCTUATION_SOURCES}) target_link_libraries(punctuation Fcitx5::Core Fcitx5::Config Boost::iostreams Fcitx5::Module::Notifications) set_target_properties(punctuation PROPERTIES PREFIX "") install(TARGETS punctuation DESTINATION "${CMAKE_INSTALL_LIBDIR}/fcitx5") fcitx5_translate_desktop_file(punctuation.conf.in punctuation.conf) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/punctuation.conf" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/addon") install(FILES ${PUNCTUATION_DATA_FILES} DESTINATION "${CMAKE_INSTALL_DATADIR}/fcitx5/punctuation") fcitx5_export_module(Punctuation TARGET punctuation BUILD_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}" HEADERS punctuation_public.h INSTALL) fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punc.mb.zh_CN000066400000000000000000000002101361043647100263650ustar00rootroot00000000000000. 。 , , ? ? " “ ” : : ; ; ' ‘ ’ < 《 > 》 \ 、 ! ! $ ¥ ^ …… * × _ —— ( ( ) ) [ · ] 「 」 ~ ~ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punc.mb.zh_HK000066400000000000000000000002101361043647100263670ustar00rootroot00000000000000. 。 , , ? ? " “ ” : : ; ; ' ‘ ’ < 《 > 》 \ 、 ! ! $ $ ^ …… * × _ —— ( ( ) ) [ · ] 「 」 ~ ~ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punc.mb.zh_TW000066400000000000000000000002051361043647100264230ustar00rootroot00000000000000. 。 , , ? ? : : ; ; < 《 》 > 〈 〉 \ 、 ! ! $ $ ^ …… * × _ —— ( ( ) ) [ 「 ] 」 { 『 } 』 ~ ~ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punctuation.conf.in000066400000000000000000000001761361043647100277400ustar00rootroot00000000000000[Addon] Name=Punctuation Category=Module Library=punctuation Type=SharedLibrary [Addon/OptionalDependencies] 0=notifications fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punctuation.cpp000066400000000000000000000336761361043647100272030ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "punctuation.h" #include "notifications_public.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace fcitx; namespace { static const std::string emptyString; static const std::pair emptyStringPair; } // namespace bool dontConvertWhenEn(uint32_t c) { return c == '.' || c == ','; } class PunctuationState : public InputContextProperty { public: std::unordered_map lastPuncStack_; char lastIsEngOrDigit_ = 0; uint32_t notConverted_ = 0; bool mayRebuildStateFromSurroundingText_ = false; std::unordered_map lastPuncStackBackup_; uint32_t notConvertedBackup_ = 0; }; PunctuationProfile::PunctuationProfile(std::istream &in) { std::string strBuf; while (std::getline(in, strBuf)) { auto pair = stringutils::trimInplace(strBuf); std::string::size_type start = pair.first, end = pair.second; if (start == end) { continue; } std::string text(strBuf.begin() + start, strBuf.begin() + end); auto tokens = stringutils::split(strBuf, FCITX_WHITESPACE); if (tokens.size() != 2 && tokens.size() != 3) { continue; } if (!std::any_of( tokens.begin(), tokens.end(), [](const std::string &s) { return utf8::validate(s); })) { continue; } // we don't make # as comment here, # would be consider as a valid char if (utf8::lengthValidated(tokens[0]) != 1) { continue; } auto c = utf8::getChar(tokens[0]); decltype(puncMap_)::mapped_type p; p.first = tokens[1]; if (tokens.size() > 2) { p.second = tokens[2]; } puncMap_.emplace(c, std::move(p)); } } const std::pair & PunctuationProfile::getPunctuation(uint32_t unicode) const { auto iter = puncMap_.find(unicode); if (iter == puncMap_.end()) { return emptyStringPair; } return iter->second; } Punctuation::Punctuation(Instance *instance) : instance_(instance), factory_([](InputContext &) { return new PunctuationState; }) { reloadConfig(); if (!instance_) { return; } instance_->inputContextManager().registerProperty("punctuationState", &factory_); instance_->userInterfaceManager().registerAction("punctuation", &toggleAction_); commitConn_ = instance_->connect( [this](InputContext *ic, const std::string &sentence) { auto state = ic->propertyFor(&factory_); // Though sentence is utf8, we only check ascii. if (sentence.size() && (charutils::isupper(sentence.back()) || charutils::islower(sentence.back()) || charutils::isdigit(sentence.back()))) { state->lastIsEngOrDigit_ = sentence.back(); } else { state->lastIsEngOrDigit_ = '\0'; } }); keyEventConn_ = instance_->connect( [this](const KeyEvent &event) { auto state = event.inputContext()->propertyFor(&factory_); if (event.isRelease()) { return; } if (!event.accepted()) { if (event.key().isUAZ() || event.key().isLAZ() || event.key().isDigit()) { state->lastIsEngOrDigit_ = Key::keySymToUnicode(event.key().sym()); } else { state->lastIsEngOrDigit_ = '\0'; } } }); eventWatchers_.emplace_back(instance_->watchEvent( EventType::InputContextKeyEvent, EventWatcherPhase::PostInputMethod, [this](Event &event) { auto &keyEvent = static_cast(event); if (keyEvent.isRelease()) { return; } if (inWhiteList(keyEvent.inputContext()) && keyEvent.key().checkKeyList(config_.hotkey.value())) { setEnabled(!enabled(), keyEvent.inputContext()); if (notifications()) { notifications()->call( "fcitx-punc-toggle", "fcitx", enabled() ? "fcitx-punc-active" : "fcitx-punc-inactive", _("Punctuation"), enabled() ? _("Full width punctuation is enabled.") : _("Full width punctuation is disabled."), -1); } return keyEvent.filterAndAccept(); } })); eventWatchers_.emplace_back(instance_->watchEvent( EventType::InputContextFocusIn, EventWatcherPhase::PostInputMethod, [this](Event &event) { auto &icEvent = static_cast(event); auto ic = icEvent.inputContext(); auto state = ic->propertyFor(&factory_); if (ic->capabilityFlags().test(CapabilityFlag::SurroundingText)) { state->mayRebuildStateFromSurroundingText_ = true; } })); eventWatchers_.emplace_back(instance_->watchEvent( EventType::InputContextReset, EventWatcherPhase::PostInputMethod, [this](Event &event) { auto &icEvent = static_cast(event); auto ic = icEvent.inputContext(); auto state = ic->propertyFor(&factory_); state->lastIsEngOrDigit_ = 0; // Backup the state. state->notConvertedBackup_ = state->notConverted_; state->notConverted_ = 0; // Backup the state. state->lastPuncStackBackup_ = state->lastPuncStack_; state->lastPuncStack_.clear(); if (ic->capabilityFlags().test(CapabilityFlag::SurroundingText)) { state->mayRebuildStateFromSurroundingText_ = true; } })); eventWatchers_.emplace_back(instance_->watchEvent( EventType::InputContextSurroundingTextUpdated, EventWatcherPhase::PostInputMethod, [this](Event &event) { auto &icEvent = static_cast(event); auto ic = icEvent.inputContext(); auto state = ic->propertyFor(&factory_); // Enable to rebuild punctuation state from surrounding text. if (state->mayRebuildStateFromSurroundingText_) { state->mayRebuildStateFromSurroundingText_ = false; } else { state->notConvertedBackup_ = 0; state->lastPuncStackBackup_.clear(); return; } if (!ic->capabilityFlags().test(CapabilityFlag::SurroundingText) || !ic->surroundingText().isValid()) { return; } // We need text before the cursor. auto &text = ic->surroundingText().text(); auto cursor = ic->surroundingText().cursor(); auto length = utf8::lengthValidated(text); if (length == utf8::INVALID_LENGTH) { return; } if (cursor <= 0 && cursor > length) { return; } uint32_t lastCharBeforeCursor; auto start = utf8::nextNChar(text.begin(), cursor - 1); auto end = utf8::getNextChar(start, text.end(), &lastCharBeforeCursor); if (lastCharBeforeCursor == utf8::INVALID_CHAR || lastCharBeforeCursor == utf8::NOT_ENOUGH_SPACE) { return; } // Need to make sure we have ascii. if (std::distance(start, end) == 1 && (charutils::isupper(lastCharBeforeCursor) || charutils::islower(lastCharBeforeCursor) || charutils::isdigit(lastCharBeforeCursor))) { state->lastIsEngOrDigit_ = lastCharBeforeCursor; } // Restore the not converted state if we still after the same chr. if (lastCharBeforeCursor == state->notConvertedBackup_ && state->notConverted_ == 0) { state->notConverted_ = state->notConvertedBackup_; } state->notConvertedBackup_ = 0; // Scan through the surrounding text if (!state->lastPuncStackBackup_.empty() && state->lastPuncStack_.empty()) { auto range = utf8::MakeUTF8CharRange(MakeIterRange(text.begin(), end)); for (auto iter = std::begin(range); iter != std::end(range); iter++) { auto charRange = iter.charRange(); std::string_view chr( &*charRange.first, std::distance(charRange.first, charRange.second)); auto puncIter = std::find_if( state->lastPuncStackBackup_.begin(), state->lastPuncStackBackup_.end(), [chr](auto &p) { return p.second == chr; }); if (puncIter != state->lastPuncStackBackup_.end()) { state->lastPuncStack_.insert(*puncIter); } } } state->lastPuncStackBackup_.clear(); })); } Punctuation::~Punctuation() {} void Punctuation::reloadConfig() { readAsIni(config_, "conf/punctuation.conf"); auto files = StandardPath::global().multiOpen(StandardPath::Type::PkgData, "punctuation", O_RDONLY, filter::Prefix("punc.mb.")); auto iter = profiles_.begin(); while (iter != profiles_.end()) { if (!files.count("punc.mb." + iter->first)) { iter = profiles_.erase(iter); } else { iter++; } } for (const auto &file : files) { if (file.first.size() <= 8) { continue; } auto lang = file.first.substr(8); try { boost::iostreams::stream_buffer< boost::iostreams::file_descriptor_source> buffer(file.second.fd(), boost::iostreams::file_descriptor_flags:: never_close_handle); std::istream in(&buffer); PunctuationProfile newProfile(in); profiles_[lang] = std::move(newProfile); } catch (const std::exception &e) { FCITX_LOG(Warn) << "Error when load profile " << file.first << ": " << e.what(); } } } bool Punctuation::inWhiteList(fcitx::InputContext *inputContext) const { return toggleAction_.isParent(&inputContext->statusArea()); } const std::string &Punctuation::pushPunctuation(const std::string &language, InputContext *ic, uint32_t unicode) { if (!enabled()) { return emptyString; } auto state = ic->propertyFor(&factory_); if (state->lastIsEngOrDigit_ && dontConvertWhenEn(unicode)) { state->notConverted_ = unicode; return emptyString; } else { auto iter = profiles_.find(language); if (iter == profiles_.end()) { return emptyString; } auto &result = getPunctuation(language, unicode); state->notConverted_ = 0; if (result.second.empty()) { return result.first; } else { auto iter = state->lastPuncStack_.find(unicode); if (iter != state->lastPuncStack_.end()) { state->lastPuncStack_.erase(iter); return result.second; } else { state->lastPuncStack_.emplace(unicode, result.first); return result.first; } } } } const std::string &Punctuation::cancelLast(const std::string &language, InputContext *ic) { if (!enabled()) { return emptyString; } auto state = ic->propertyFor(&factory_); if (dontConvertWhenEn(state->notConverted_)) { auto &result = getPunctuation(language, state->notConverted_); state->notConverted_ = 0; return result.first; } return emptyString; } const std::pair & Punctuation::getPunctuation(const std::string &language, uint32_t unicode) { if (!*config_.enabled) { return emptyStringPair; } auto iter = profiles_.find(language); if (iter == profiles_.end()) { return emptyStringPair; } return iter->second.getPunctuation(unicode); } FCITX_ADDON_FACTORY(PunctuationFactory); fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punctuation.h000066400000000000000000000106251361043647100266350ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PUNCTUATION_PUNCTUATION_H_ #define _PUNCTUATION_PUNCTUATION_H_ #include "punctuation_public.h" #include #include #include #include #include #include #include #include #include FCITX_CONFIGURATION( PunctuationConfig, fcitx::Option hotkey{ this, "Hotkey", _("Toggle key"), {fcitx::Key("Control+period")}}; fcitx::Option enabled{this, "Enabled", "Enabled", true};); class PunctuationProfile { public: PunctuationProfile() {} PunctuationProfile(std::istream &in); PunctuationProfile(PunctuationProfile &&) = default; PunctuationProfile(const PunctuationProfile &) = default; PunctuationProfile &operator=(PunctuationProfile &&) = default; PunctuationProfile &operator=(const PunctuationProfile &) = default; const std::pair & getPunctuation(uint32_t unicode) const; private: std::unordered_map> puncMap_; }; class PunctuationState; class Punctuation final : public fcitx::AddonInstance { class ToggleAction : public fcitx::Action { public: ToggleAction(Punctuation *parent) : parent_(parent) {} std::string shortText(fcitx::InputContext *) const override { return parent_->enabled() ? _("Full width punctuation") : _("Half width punctuation"); } std::string icon(fcitx::InputContext *) const override { return parent_->enabled() ? "fcitx-punc-active" : "fcitx-punc-inactive"; } void activate(fcitx::InputContext *ic) override { return parent_->setEnabled(!parent_->enabled(), ic); } private: Punctuation *parent_; }; public: Punctuation(fcitx::Instance *instance); ~Punctuation(); const std::pair & getPunctuation(const std::string &language, uint32_t unicode); const std::string &pushPunctuation(const std::string &language, fcitx::InputContext *ic, uint32_t unicode); const std::string &cancelLast(const std::string &language, fcitx::InputContext *ic); void reloadConfig() override; FCITX_ADDON_EXPORT_FUNCTION(Punctuation, getPunctuation); FCITX_ADDON_EXPORT_FUNCTION(Punctuation, pushPunctuation); FCITX_ADDON_EXPORT_FUNCTION(Punctuation, cancelLast); bool enabled() const { return *config_.enabled; } void setEnabled(bool enabled, fcitx::InputContext *ic) { if (enabled != *config_.enabled) { config_.enabled.setValue(enabled); toggleAction_.update(ic); } } bool inWhiteList(fcitx::InputContext *inputContext) const; private: FCITX_ADDON_DEPENDENCY_LOADER(notifications, instance_->addonManager()); fcitx::Instance *instance_; fcitx::FactoryFor factory_; fcitx::ScopedConnection commitConn_, keyEventConn_; std::vector>> eventWatchers_; std::unordered_map profiles_; PunctuationConfig config_; ToggleAction toggleAction_{this}; }; class PunctuationFactory : public fcitx::AddonFactory { public: fcitx::AddonInstance *create(fcitx::AddonManager *manager) override { return new Punctuation(manager->instance()); } }; #endif // _PUNCTUATION_PUNCTUATION_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/modules/punctuation/punctuation_public.h000066400000000000000000000031611361043647100301700ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #ifndef _PUNCTUATION_PUNCTUATION_PUBLIC_H_ #define _PUNCTUATION_PUNCTUATION_PUBLIC_H_ #include namespace fcitx { class InputContext; } FCITX_ADDON_DECLARE_FUNCTION( Punctuation, getPunctuation, const std::pair &(const std::string &language, uint32_t unicode)); FCITX_ADDON_DECLARE_FUNCTION(Punctuation, cancelLast, const std::string &(const std::string &language, InputContext *ic)); FCITX_ADDON_DECLARE_FUNCTION(Punctuation, pushPunctuation, const std::string &(const std::string &language, InputContext *ic, uint32_t unicode)); #endif // _PUNCTUATION_PUNCTUATION_PUBLIC_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/po/000077500000000000000000000000001361043647100205045ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/po/CMakeLists.txt000066400000000000000000000000621361043647100232420ustar00rootroot00000000000000fcitx5_install_translation(fcitx5-chinese-addons) fcitx5-chinese-addons-0.0~git20200117.4261e23/po/LINGUAS000066400000000000000000000000311361043647100215230ustar00rootroot00000000000000 ca da de ja ko ru zh_CN fcitx5-chinese-addons-0.0~git20200117.4261e23/po/ca.po000066400000000000000000000326421361043647100214360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # Robert Antoni Buj Gelonch , 2017 # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:01-0800\n" "PO-Revision-Date: 2017-11-23 04:30+0000\n" "Last-Translator: Robert Antoni Buj Gelonch , 2017\n" "Language-Team: Catalan (https://www.transifex.com/fcitx/teams/12005/ca/)\n" "Language: ca\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" #: im/table/state.cpp:622 msgid " Return for " msgstr "" #: im/table/state.cpp:619 msgid " for " msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "Selecciona automàticament la candidata" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "Pinyin al núvol" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "Estat de pinyin al núvol" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "El pinyin al núvol està inhabilitat." #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "El pinyin al núvol està habilitat." #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "" #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "" #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "No s'ha pogut trobar el pinyin." #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "Mostra els suggeriments per a la paraula" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "Mostra el suggeriment personalitzat" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "" #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "" #: im/table/ime.h:70 msgid "End key" msgstr "Tecla Fi" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "" #: im/table/ime.h:76 msgid "Exact Match" msgstr "Coincidència exacta" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "" #: im/table/ime.h:35 msgid "File" msgstr "Fitxer" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "" #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "" #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "" #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "" #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "" #: im/table/ime.h:56 msgid "Icon" msgstr "Icona" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "" #: im/table/ime.h:77 msgid "Learning" msgstr "" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "Modifica el diccionari" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "" #: im/table/ime.h:39 msgid "Next page" msgstr "Av Pàg" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" #: im/table/engine.cpp:113 msgid "Not available" msgstr "No disponible" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "" #: im/table/ime.h:69 msgid "Order policy" msgstr "Política d'ordenació" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "Pinyin" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "" #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "Predicció" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "Premeu %1% per %2%" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "Premeu %1% per %2% i %3% per %4%" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "" #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "" #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "" #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "" #: im/table/ime.h:37 msgid "Prev page" msgstr "Re Pàg" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "Puntuació" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "Retorn" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "Desa la frase automàtica" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "" #: im/table/ime.h:47 msgid "Selection" msgstr "Selecció" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "Mostra la predicció de paraules" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "Shuangpin" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "Xinès simplificat" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "El xinès simplificat està habilitat." #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "Traducció de xinès simplificat i tradicional" #: im/table/table.conf.in:3 msgid "Table" msgstr "Taula" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "" #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "Xinès tradicional" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "El xinès tradicional està habilitat." #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "Utilitza dret i esquerre per seleccionar el caràcter:" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "Utilitza dret i esquerre per seleccionar el text:" #: im/table/ime.h:53 msgid "Use full width" msgstr "" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "Wubi" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "Wubi Pinyin" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "{0} ({1})" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "{0} no està a la taula." #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "{0}: sense codi corresponent." #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "{0}: {1}" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/da.po000066400000000000000000000371671361043647100214460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # scootergrisen, 2019 # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-20 00:01-0800\n" "PO-Revision-Date: 2017-11-23 04:30+0000\n" "Last-Translator: scootergrisen, 2019\n" "Language-Team: Danish (https://www.transifex.com/fcitx/teams/12005/da/)\n" "Language: da\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" #: im/table/state.cpp:622 msgid " Return for " msgstr " Retur for " #: im/table/state.cpp:619 msgid " for " msgstr " for " #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "%1 findes allerede, vil du overskrive ordbogen?" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "%1% downloadet." #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "&Gennemse Sogou Cell-ordbog online" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "&Ryd ordbog" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "&Ryd brugerdata" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "&Importér" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "&Fjern" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "Er du sikker på, at du vil slette %1?" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "Er du sikker på, at du vil slette alle ordbøger?" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "Automatisk fraselængde" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "Automatisk sæt af regel" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "Automatisk valg af kandidat" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "Automatisk valg af kandidatlængde" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "Automatisk valg af sidste kandidat når der ikke er noget nyt match" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "Backend" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "Bingchan" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "Gennemse Sogou Cell-ordbogsarkiv" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "Cangjie" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "Ryd &al data" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "Sky-Pinyin" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "Sky-Pinyin-indeks" #: im/pinyin/pinyin.cpp:621 msgid "Cloud Pinyin Status" msgstr "Status for sky-Pinyin" #: im/pinyin/pinyin.cpp:623 msgid "Cloud Pinyin is disabled." msgstr "Sky-Pinyin er deaktiveret." #: im/pinyin/pinyin.cpp:622 msgid "Cloud Pinyin is enabled." msgstr "Sky-Pinyin er aktiveret." #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "Udfør rå input når der ikke er nogen kandidat" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "Bekræft sletning" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "Konvertering mislykkedes." #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "Konverter holdt op med at virke." #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "Kunne ikke finde pinyin." #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "" "Oprettelse af mappe mislykkedes. Tjek venligst at du har rettighed eller at " "disken ikke er fuld." #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "Oprettelse af midlertidig fil mislykkedes." #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "" "Oprettelse af midlertidig fil mislykkedes. Tjek venligst at du har rettighed " "eller at disken ikke er fuld." #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "Dialog" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "Dianbaoma" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "Ordbøger" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "Ordbog findes allerede" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "Vis tip for ord" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "Vis tilpasset tip" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "Sortér ikke ord kortere" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "Download færdig" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "Download startet." #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "Aktivér sky-Pinyin" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "Aktivér forudsigelse" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "Aktiverede inputmetoder" #: im/table/ime.h:70 msgid "End key" msgstr "Slut-tast" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "Erbi" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "Fejl ved sletning af %1." #: im/table/ime.h:76 msgid "Exact Match" msgstr "Præcist match" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "Ekstra Pinyin-funktionalitet" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "Kunne ikke oprette mappe" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "Kunne ikke oprette anmodning." #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "Kunne ikke oprette midlertidig fil" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "Kunne ikke hente runtime-mappe" #: im/table/ime.h:35 msgid "File" msgstr "Fil" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "Filhandling mislykkedes" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "Fra &fil" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "Fra &Sogou Cell-ordbogsfil" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "Fuld tegnbredde" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "Fuld tegnbredde er deaktiveret." #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "Fuld tegnbredde er aktiveret." #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "Fuld tegnbredde" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "Tegnsætning i fuld bredde" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "Tegnsætning i fuld bredde er deaktiveret." #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "Tegnsætning i fuld bredde er aktiveret." #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "Uafklarede Pinyin-indstillinger" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "Halv tegnbredde" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "Tegnsætning i halv bredde" #: im/table/ime.h:56 msgid "Icon" msgstr "Ikon" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "Indre segment (xian -> xi'an)" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "Input ordbogsnavn" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "Tast til at udløse hurtigfrase" #: im/table/ime.h:77 msgid "Learning" msgstr "Læring" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "Pinyin-opslag" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "Maksimum længde for Pinyin" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "Rediger ordbog" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "Nyt ordbogsnavn:" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "Næste kandidat" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "Næste side" #: im/table/ime.h:39 msgid "Next page" msgstr "Næste side" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" "Ingen gennemsøgning udenfor pinyin.sogou.com, viderestiller nu til " "startsiden." #: im/table/engine.cpp:113 msgid "Not available" msgstr "Ikke tilgængelig" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "Antal sætninger" #: im/table/ime.h:69 msgid "Order policy" msgstr "Regel for rækkefølge" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "Sidestørrelse" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "Pinyin" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "Pinyin-ordbogshåndtering" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "Brug venligst denne funktionalitet efter du har skrevet noget tekst." #: im/pinyin/pinyin.cpp:457 msgid "Prediction" msgstr "Forudsigelse" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "Størrelse på forudsigelse" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "Præfikstast til at udløse Pinyin" #: im/pinyin/pinyin.cpp:851 msgid "Press %1% for %2%" msgstr "Tryk på %1% for %2%" #: im/pinyin/pinyin.cpp:847 msgid "Press %1% for %2% and %3% for %4%" msgstr "Tryk på %1% for %2% og %3% for %4%" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "Tryk på Backspace for at glemme." #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "Tryk på Delete for at flytte." #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "Tryk på mellemrum for at indsætte." #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "Forrige kandidat" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "Forrige side" #: im/table/ime.h:37 msgid "Prev page" msgstr "Forrige side" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "Tegnsætning" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "Fjern &alle" #: im/pinyin/pinyin.cpp:848 msgid "Return" msgstr "Retur" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "Gem automatisk frase" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "Scel-fil (*.scel)" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "Vælg ordbogsfil" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "Vælg scel-fil" #: im/table/ime.h:47 msgid "Selection" msgstr "Valg" #: im/pinyin/pinyin.cpp:458 msgid "Show prediction words" msgstr "Vis forudsigelsesord" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "Shuangpin" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "Shuangpin-profil" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "Forenklet kinesisk" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "Forenklet kinesisk er aktiveret." #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "Oversættelse af forenklet og traditionel kinesisk" #: im/table/table.conf.in:3 msgid "Table" msgstr "Tabel" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "Midlertidig fil oprettet." #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "Tast til at skifte" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "Tast til at skifte" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "Traditionel kinesisk" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "Traditionel kinesisk er aktiveret." #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "Oversættelsesmotor" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "Brug venstre og højre til at vælge tegn: " #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "Brug venstre og højre til at vælge tekst. " #: im/table/ime.h:53 msgid "Use full width" msgstr "Brug fuld bredde" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "Brug preedit i program når det er muligt" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "Wanfeng" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "Jokertegn matcher tast" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "Forkert link" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "Wubi" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "Wubi Pinyin" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "Ziranma" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "about:blank" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "an <-> ang" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "c <-> ch" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "en <-> eng" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "f <-> h" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "gn -> ng" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "ian <-> iang" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "in <-> ing" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "l <-> n" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "s <-> sh" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "u <-> ou" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "u <-> v" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "uan <-> uang" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "ue -> ve" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "z <-> zh" #: im/pinyin/pinyin.cpp:113 msgid "{0} ({1})" msgstr "{0} ({1})" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "{0} er ikke i tabellen." #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "{0}: Ingen tilhørende kode." #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "{0}: {1}" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/de.po000066400000000000000000000371431361043647100214440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # mar well , 2018 # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:01-0800\n" "PO-Revision-Date: 2017-11-23 04:30+0000\n" "Last-Translator: mar well , 2018\n" "Language-Team: German (https://www.transifex.com/fcitx/teams/12005/de/)\n" "Language: de\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" #: im/table/state.cpp:622 msgid " Return for " msgstr "" #: im/table/state.cpp:619 msgid " for " msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "%1 existiert bereits, soll das Wörterbuch überschrieben werden?" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "%1% Heruntergeladen." #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "&Sogou Wörterbuchverzeichnis für Mobiles Online durchsuchen" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "&Nutzerdaten löschen" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "Sind Sie sicher, dass %1 gelöscht werden soll?" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "Sind Sie sicher, dass alle Wörterbücher gelöscht werden sollen?" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "Länge der Auto-Phrase" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "Satz automatischer Regeln" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "Kandidaten automatisch auswählen" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "Kandidatenlänge automatisch auswählen" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "" "Automatisch den letzten Kandidaten auswählen, wenn es keine neuen Treffer " "gibt" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "Bingchan" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "Sogou Wörterbuchverzeichnis für Mobiles durchsuchen" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "Cangjie" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "&Alle Daten löschen" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "Cloud Pinyin" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "Cloud Pinyin Status" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "Cloud Pinyin ist ausgeschaltet." #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "Cloud Pinyin ist eingeschaltet." #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "Roher Eingabe zustimmen, wenn kein Kandidat vorhanden ist" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "Löschen bestätigen" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "Konvertierung fehlgeschlagen." #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "Konverter abgestürzt." #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "Pinyin kann nicht gefunden werden" #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "" "Kopieren des Verzeichnisses fehlgeschlagen. Bitte überprüfen Sie die " "Dateiberechtigungen oder ob die Festplatte voll ist." #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "Erstellen der temporären Datei fehlgeschlagen." #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "" "Kopieren der temporären Datei fehlgeschlagen. Bitte überprüfen Sie die " "Dateiberechtigungen oder ob die Festplatte voll ist." #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "Dianbaoma" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "Wörterbücher" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "Wörterbuch existiert schon" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "Hinweis für Wort anzeigen" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "Standardhinweis zeigen" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "Download beendet" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "Download begonnen." #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "" #: im/table/ime.h:70 msgid "End key" msgstr "" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "Erbi" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "Fehler beim Löschen von %1." #: im/table/ime.h:76 msgid "Exact Match" msgstr "Genaue Übereinstimmung" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "Extra Pinyin-Funktionalitat" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "Verzeichnis konnte nicht erstellt werden" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "Anforderung fehlgeschlagen." #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "Erstellen der temporären Datei fehlgeschlagen" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "Laufzeitverzeichnis konnte nicht gefunden werden" #: im/table/ime.h:35 msgid "File" msgstr "Datei" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "Dateioperation gescheitert" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "Von &Datei" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "Von der &Sogou Wörterbuchdatei für Mobiles" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "Vollbreite Zeichen" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "Vollbreite Zeichen sind ausgeschaltet." #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "Vollbreite Zeichen sind eingeschlaltet." #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "Vollbreite Zeichen" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "Vollbreite Interpunktion" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "Vollbreite Interpunktion ist ausgeschaltet." #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "Vollbreite Satzzeichen ist aktiviert." #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "Halbbreite Zeichen" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "Halbweite Satzzeichen werden verwendet" #: im/table/ime.h:56 msgid "Icon" msgstr "Icon" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "Name des Eingabewörterbuchs" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "Trigger Key für QuickPhrase" #: im/table/ime.h:77 msgid "Learning" msgstr "Lernen" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "Pinyin nachschlagen" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "Wörterbuch ändern" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "Neuer Wörterbuchname:" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "" #: im/table/ime.h:39 msgid "Next page" msgstr "Nächste Seite" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" "Browsen außerhalb von pinyin.sogou.com nicht möglich. Sie werden zur " "Homepage umgeleitet." #: im/table/engine.cpp:113 msgid "Not available" msgstr "Nicht verfügbar" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "" #: im/table/ime.h:69 msgid "Order policy" msgstr "Regel der Reihenfolge" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "Pinyin" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "Pinyin-Wörterbuch-Manager" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "" "Bitte benutzen Sie diese Funktionalität nach der Eingabe von etwas Text." #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "Autovervollständigen" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "Festgelegte Taste um Pinyin anzuschalten" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "%1% für %2% drücken" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "%1% für %2% und %3% für %4% drücken" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "Zum vergessen Rücktaste drücken" #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "Zum Entfernen Löschen drücken" #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "Zum Einfügen Leertaste drücken." #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "" #: im/table/ime.h:37 msgid "Prev page" msgstr "Vorherige Seite" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "Interpunktion" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "Zurück" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "Automatische Phrase speichern" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "Scel Datei (*.scel)" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "Wörterbuchdatei auswählen" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "Scel Datei auswählen" #: im/table/ime.h:47 msgid "Selection" msgstr "Auswahl" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "Wörter der Autovervollständigung anzeigen" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "Shuangpin" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "Chinesische Kurzzeichen" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "Chinesische Kurzzeichen aktiviert." #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "Übersetzung simplizifiertes und traditionelles Chinesisch " #: im/table/table.conf.in:3 msgid "Table" msgstr "Tabelle" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "Temporäre Datei erstellt." #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "Chinesische Langzeichen" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "Chinesische Langzeichen aktiviert." #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "Pfeiltasten Links und Rechts benutzen, um Zeichen auszuwählen" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "Pfeiltasten Links und Rechts benutzen, um Text auszuwählen" #: im/table/ime.h:53 msgid "Use full width" msgstr "Verwende Vollbreite Form der Zeichen" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "Wanfeng" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "Taste für passende Wildcards" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "Falscher Link" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "Wubi" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "Wubi Pinyin" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "Ziranma" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "{0} ({1})" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "{0} ist nicht in der Tabelle." #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "{0}: Kein passender Code" #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "{0}: {1}" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/fcitx5-chinese-addons.pot000066400000000000000000000305671361043647100253270ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:01-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: LANG\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: im/table/state.cpp:622 msgid " Return for " msgstr "" #: im/table/state.cpp:619 msgid " for " msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "" #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "" #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "" #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "" #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "" #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "" #: im/table/ime.h:70 msgid "End key" msgstr "" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "" #: im/table/ime.h:76 msgid "Exact Match" msgstr "" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "" #: im/table/ime.h:35 msgid "File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "" #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "" #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "" #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "" #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "" #: im/table/ime.h:56 msgid "Icon" msgstr "" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "" #: im/table/ime.h:77 msgid "Learning" msgstr "" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "" #: im/table/ime.h:39 msgid "Next page" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" #: im/table/engine.cpp:113 msgid "Not available" msgstr "" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "" #: im/table/ime.h:69 msgid "Order policy" msgstr "" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "" #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "" #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "" #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "" #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "" #: im/table/ime.h:37 msgid "Prev page" msgstr "" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "" #: im/table/ime.h:47 msgid "Selection" msgstr "" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "" #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "" #: im/table/table.conf.in:3 msgid "Table" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "" #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "" #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "" #: im/table/ime.h:53 msgid "Use full width" msgstr "" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "" #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "" #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/ja.po000066400000000000000000000310121361043647100214330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # csslayer , 2017 msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:00-0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: csslayer , 2017\n" "Language-Team: Japanese (https://www.transifex.com/fcitx/teams/12005/ja/)\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: im/table/state.cpp:622 msgid " Return for " msgstr "" #: im/table/state.cpp:619 msgid " for " msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "" #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "" #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "" #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "" #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "" #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "" #: im/table/ime.h:70 msgid "End key" msgstr "" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "" #: im/table/ime.h:76 msgid "Exact Match" msgstr "" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "" #: im/table/ime.h:35 msgid "File" msgstr "ファイル" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "" #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "" #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "" #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "" #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "" #: im/table/ime.h:56 msgid "Icon" msgstr "" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "" #: im/table/ime.h:77 msgid "Learning" msgstr "" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "" #: im/table/ime.h:39 msgid "Next page" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" #: im/table/engine.cpp:113 msgid "Not available" msgstr "" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "" #: im/table/ime.h:69 msgid "Order policy" msgstr "" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "" #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "" #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "" #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "" #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "" #: im/table/ime.h:37 msgid "Prev page" msgstr "" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "" #: im/table/ime.h:47 msgid "Selection" msgstr "" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "" #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "" #: im/table/table.conf.in:3 msgid "Table" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "" #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "" #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "" #: im/table/ime.h:53 msgid "Use full width" msgstr "" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "" #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "" #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/ko.po000066400000000000000000000361441361043647100214650ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # Bon Keun Seo , 2017 # 이정희 , 2019 # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:01-0800\n" "PO-Revision-Date: 2017-11-23 04:30+0000\n" "Last-Translator: 이정희 , 2019\n" "Language-Team: Korean (https://www.transifex.com/fcitx/teams/12005/ko/)\n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: im/table/state.cpp:622 msgid " Return for " msgstr "" #: im/table/state.cpp:619 msgid " for " msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "%1이(가) 이미 존재합니다. 이 사전을 덮어 쓰시겠습니까?" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "%1% 다운로드됨." #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "사용자 데이터 비우기(&C)" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "%1을(를) 지우시겠습니까?" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "모든 사전을 삭제 하시겠습니까?" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "자동 문구 길이" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "자동 규칙 모음" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "자동 후보 선택" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "자동 후보 선택 길이" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "일치하는 것이 없으면 마지막 후보를 자동 선택" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "Sogou 셀 사전 저장소 찾아보기" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "창힐" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "모든 데이터 비우기(&A)" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "클라우드 Pinyin" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "클라우드 Pinyin 상태" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "클라우드 Pinyin이 비활성화됨." #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "클라우드 Pinyin이 활성화됨." #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "후보가 없을 때엔 키입력을 그대로 사용" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "삭제 확인" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "변환하지 못했습니다." #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "변환도구가 충돌했습니다." #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "Pinyin를 찾을 수 없음" #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "디렉토리 생성에 실패했습니다. 권한 또는 디스크 공간을 확인하십시오." #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "임시 파일 생성에 실패했습니다." #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "임시 파일을 만들지 못했습니다. 권한 또는 디스크 공간을 확인하십시오." #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "사전" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "단어 후보 보이기" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "사용자 힌트 보이기" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "짧은 순으로 단어를 정렬하지 않기" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "다운로드 완료됨" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "다운로드 시작됨." #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "" #: im/table/ime.h:70 msgid "End key" msgstr "중지 키" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "%1을 삭제하는 중 오류 발생" #: im/table/ime.h:76 msgid "Exact Match" msgstr "정확한 일치" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "추가 병음 기능" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "디렉토리를 만들지 못했습니다" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "요청을 생성하지 못했습니다." #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "임시 파일을 만들지 못했습니다" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "런타임 디렉토리를 가져 오지 못했습니다" #: im/table/ime.h:35 msgid "File" msgstr "파일" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "파일 작업 실패" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "전각 문자" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "전각 문자 비활성화됨." #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "전각 문자 활성화됨." #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "전각 문자" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "전각 부호" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "전각 부호 비활성화됨." #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "전각 부호 활성화됨." #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "반각 문자" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "반각 부호" #: im/table/ime.h:56 msgid "Icon" msgstr "아이콘" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "입력 사전 이름" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "QuickPhrase 발동 키" #: im/table/ime.h:77 msgid "Learning" msgstr "학습" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "병음 검색" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "사전 수정" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "새로운 사전 이름:" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "" #: im/table/ime.h:39 msgid "Next page" msgstr "다음 페이지" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" #: im/table/engine.cpp:113 msgid "Not available" msgstr "사용할 수 없음" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "" #: im/table/ime.h:69 msgid "Order policy" msgstr "정렬 정책" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "병음(Pinyin)" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "Pinyin 사전 관리도구" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "글자를 입력한 후에 이 기능을 사용하세요." #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "예측" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "병음 발동을 위한 사전입력 키" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "%2%를 위해 %1%을 누르세요" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "%2%를 위해 %1%을, %4%를 위해 %3%을 누르세요" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "무시하기 위해 백스페이스를 누르세요." #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "제거하기 위해 Delete키를 누르세요." #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "입력하기 위해 스페이스를 누르세요" #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "" #: im/table/ime.h:37 msgid "Prev page" msgstr "앞 페이지" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "문장부호" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "돌아가기" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "자동 문구 저장" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "Scel 파일 (*.scel)" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "사전 파일 선택" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "scel 파일 선택" #: im/table/ime.h:47 msgid "Selection" msgstr "선택" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "예상 단어 보이기" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "Shuangpin" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "간체 중국어" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "간체 중국어가 활성화됨." #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "간체 / 번체 중국어 번역" #: im/table/table.conf.in:3 msgid "Table" msgstr "표" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "임시 파일 생성됨." #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "번체 중국어" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "번체 중국어가 활성화됨." #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "문자 선택을 위해 좌/우키 사용:" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "문장 선택을 위해 좌/우키 사용:" #: im/table/ime.h:53 msgid "Use full width" msgstr "전각 문자 사용" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "와일드 카드 매칭 키" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "Wubi" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "Wubi 병음" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "{0} ({1})" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "{0}은 표에 없습니다." #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "{0}: 해당 코드가 없음" #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "{0}: {1}" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/ru.po000066400000000000000000000371451361043647100215040ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # TotalCaesar659 , 2017 # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:01-0800\n" "PO-Revision-Date: 2017-11-23 04:30+0000\n" "Last-Translator: TotalCaesar659 , 2017\n" "Language-Team: Russian (https://www.transifex.com/fcitx/teams/12005/ru/)\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" #: im/table/state.cpp:622 msgid " Return for " msgstr " Return for " #: im/table/state.cpp:619 msgid " for " msgstr " for " #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "Автоматически устанавливать длину фразы" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "Автоматически устанавливать правила" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "Автоматически выбирать кандидат" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "Автоматически выбирать длину кандидата" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "" "Автоматически выбирать последний кандидат при отсутствии новых совпадений" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "Cloud Pinyin" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "Статус Cloud Pinyin" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "Cloud Pinyin отключен." #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "Cloud Pinyin включен." #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "Передать прямой ввод при отсутствии кандидатов" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "" #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "" #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "Не удается найти пиньинь." #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "Показывать подсказку для слова" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "Показывать собственную подсказку" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "Не сортировать слова короче" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "" #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "" #: im/table/ime.h:70 msgid "End key" msgstr "Клавиша End" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "" #: im/table/ime.h:76 msgid "Exact Match" msgstr "Точное совпадение" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "Дополнительная функциональность пиньинь" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "" #: im/table/ime.h:35 msgid "File" msgstr "Файл" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "Полноширинный символ" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "Полноширинный символ отключен." #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "Полноширинный символ включен." #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "Полноширинный символ" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "Полноширинная пунктуация" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "Полноширинная пунктуация отключена." #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "Полноширинная пунктуация включена." #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "Полуширинный символ" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "Полуширинная пунктуация" #: im/table/ime.h:56 msgid "Icon" msgstr "Иконка" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "Клавиша для активации быстрой фразы" #: im/table/ime.h:77 msgid "Learning" msgstr "Обучение" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "Изучение пиньинь" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "Изменить словарь" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "" #: im/table/ime.h:39 msgid "Next page" msgstr "Следующая страница" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "" #: im/table/engine.cpp:113 msgid "Not available" msgstr "Недоступно" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "" #: im/table/ime.h:69 msgid "Order policy" msgstr "Политика порядка" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "Пиньинь" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "Пожалуйста, используйте эту функцию после набора текста." #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "Предсказание" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "Клавиша-префикс для активации пиньинь" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "Нажмите %1% для %2%" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "Нажмите %1% для %2% и %3% для %4%" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "Нажмите Backspace, чтобы забыть." #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "Нажмите Delete, чтобы удалить." #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "Нажмите пробел, чтобы вставить." #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "" #: im/table/ime.h:37 msgid "Prev page" msgstr "Предыдущая страница" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "Пунктуация" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "Return" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "Сохранить автоматическую фразу" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "" #: im/table/ime.h:47 msgid "Selection" msgstr "Выбор" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "Показать слова-предсказания" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "Шуанпинь" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "Упрощенный китайский" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "Упрощенный китайский включен." #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "Перевод упрощенного и традиционного китайского" #: im/table/table.conf.in:3 msgid "Table" msgstr "Таблица" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "" #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "Традиционный китайский" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "Традиционный китайский включен." #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "Используйте влево и вправо для выбора символа:" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "Используйте влево и вправо для выбора текста." #: im/table/ime.h:53 msgid "Use full width" msgstr "Использовать полную ширину" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "Клавиша, соответствующая карточке" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "Wubi" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "Wubi Pinyin" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "{0} нет в таблице." #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "{0}: Нет соответствующего кода." #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "{0}: {1}" fcitx5-chinese-addons-0.0~git20200117.4261e23/po/zh_CN.po000066400000000000000000000360711361043647100220540ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the fcitx5-chinese-addons package. # # Translators: # Mingcong Bai , 2018 # wwj402 , 2018 # csslayer , 2019 # msgid "" msgstr "" "Project-Id-Version: fcitx5-chinese-addons\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2019-11-11 00:01-0800\n" "PO-Revision-Date: 2017-11-23 04:30+0000\n" "Last-Translator: csslayer , 2019\n" "Language-Team: Chinese (China) (https://www.transifex.com/fcitx/teams/12005/" "zh_CN/)\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: im/table/state.cpp:622 msgid " Return for " msgstr "回车以" #: im/table/state.cpp:619 msgid " for " msgstr "以" #: gui/pinyindictmanager/pinyindictmanager.cpp:135 msgid "%1 already exists, do you want to overwrite this dictionary?" msgstr "%1 已存在,是否要覆盖这个词典?" #: gui/pinyindictmanager/filedownloader.cpp:83 msgid "%1% Downloaded." msgstr "%1%已下载" #: gui/pinyindictmanager/pinyindictmanager.cpp:44 msgid "&Browse Sogou Cell Dictionary Online" msgstr "在线浏览搜狗细胞词典(&B)" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:55 #. i18n: ectx: property (text), widget (QPushButton, clearDictButton_) #: rc.cpp:18 #, kde-format msgid "&Clear Dict" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:51 msgid "&Clear User Data" msgstr "清理用户数据(&C)" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:22 #. i18n: ectx: property (text), widget (QPushButton, importButton_) #: rc.cpp:9 #, kde-format msgid "&Import" msgstr "" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:33 #. i18n: ectx: property (text), widget (QPushButton, removeButton_) #: rc.cpp:12 #, kde-format msgid "&Remove" msgstr "" #: gui/pinyindictmanager/pinyindictmanager.cpp:356 msgid "Are you sure to delete %1?" msgstr "您确定要删除 %1?" #: gui/pinyindictmanager/pinyindictmanager.cpp:324 msgid "Are you sure to delete all dictionaries?" msgstr "您确定要删除所有字典吗?" #: im/table/ime.h:73 msgid "Auto phrase length" msgstr "自动词组长度" #: im/table/ime.h:82 msgid "Auto rule set" msgstr "自动组词使用规则" #: im/table/ime.h:60 msgid "Auto select candidate" msgstr "自动选择候选词" #: im/table/ime.h:62 msgid "Auto select candidate Length" msgstr "自动选择候选词长度" #: im/table/ime.h:65 msgid "Auto select last candidate when there is no new match" msgstr "没有新匹配时自动选择最后的候选词" #: modules/cloudpinyin/cloudpinyin.h:45 msgid "Backend" msgstr "后端" #: im/table/qxm.conf.in.in:3 msgid "Bingchan" msgstr "冰蟾全息" #: gui/pinyindictmanager/browserdialog.cpp:65 msgid "Browse Sogou Cell Dict repository" msgstr "浏览搜狗细胞词库" #: im/table/cangjie.conf.in.in:3 msgid "Cangjie" msgstr "仓颉" #: gui/pinyindictmanager/pinyindictmanager.cpp:52 msgid "Clear &All Data" msgstr "清理所有数据(&A)" #: modules/cloudpinyin/cloudpinyin.conf.in:3 msgid "Cloud Pinyin" msgstr "云拼音" #: im/pinyin/pinyin.h:68 msgid "Cloud Pinyin Index" msgstr "云拼音位置" #: im/pinyin/pinyin.cpp:616 msgid "Cloud Pinyin Status" msgstr "云拼音状态" #: im/pinyin/pinyin.cpp:618 msgid "Cloud Pinyin is disabled." msgstr "云拼音已禁用。" #: im/pinyin/pinyin.cpp:617 msgid "Cloud Pinyin is enabled." msgstr "云拼音已启用。" #: im/table/ime.h:68 msgid "Commit raw input when there is no candidate" msgstr "没有候选词时提交原始输入" #: gui/pinyindictmanager/pinyindictmanager.cpp:323 #: gui/pinyindictmanager/pinyindictmanager.cpp:355 msgid "Confirm deletion" msgstr "确认删除" #: gui/pinyindictmanager/processrunner.cpp:62 msgid "Convert failed." msgstr "转换失败。" #: gui/pinyindictmanager/processrunner.cpp:56 #: gui/pinyindictmanager/renamefile.cpp:46 msgid "Converter crashed." msgstr "转换器崩溃。" #: im/table/state.cpp:450 msgid "Could not find pinyin." msgstr "无法找到拼音。" #: gui/pinyindictmanager/pinyindictmanager.cpp:108 #: gui/pinyindictmanager/pinyindictmanager.cpp:219 #: gui/pinyindictmanager/pinyindictmanager.cpp:277 msgid "Create directory failed. Please check the permission or disk space." msgstr "创建目录失败。请检查权限或磁盘空间。" #: gui/pinyindictmanager/filedownloader.cpp:34 msgid "Create temporary file failed." msgstr "创建临时文件失败。" #: gui/pinyindictmanager/pinyindictmanager.cpp:119 msgid "Creating temp file failed. Please check the permission or disk space." msgstr "创建临时文件失败。请检查权限或磁盘空间。" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:14 #. i18n: ectx: property (windowTitle), widget (QDialog, BrowserDialog) #: rc.cpp:3 #, kde-format msgid "Dialog" msgstr "" #: im/table/db.conf.in.in:3 msgid "Dianbaoma" msgstr "电报码" #: im/pinyin/pinyin.h:104 msgid "Dictionaries" msgstr "词典" #: gui/pinyindictmanager/pinyindictmanager.cpp:134 msgid "Dictionary already exists" msgstr "词典已经存在" #: im/table/ime.h:78 msgid "Display Hint for word" msgstr "显示词的提示" #: im/table/ime.h:80 msgid "Display custom hint" msgstr "显示自定义提示" #: im/table/ime.h:58 msgid "Don't sort word shorter" msgstr "不对短于长度的词排序" #: gui/pinyindictmanager/filedownloader.cpp:90 msgid "Download Finished" msgstr "下载已完成" #: gui/pinyindictmanager/filedownloader.cpp:52 msgid "Download started." msgstr "下载已开始。" #: im/pinyin/pinyin.h:66 msgid "Enable Cloud Pinyin" msgstr "启用云拼音" #: im/pinyin/pinyin.h:63 msgid "Enable Prediction" msgstr "启用预测" #: modules/chttrans/chttrans.h:42 msgid "Enabled Input Methods" msgstr "启用的输入法" #: im/table/ime.h:70 msgid "End key" msgstr "中止键" #: im/table/erbi.conf.in.in:3 msgid "Erbi" msgstr "二笔" #: gui/pinyindictmanager/pinyindictmanager.cpp:365 msgid "Error while deleting %1." msgstr "删除 %1 时出错。" #: im/table/ime.h:76 msgid "Exact Match" msgstr "精确匹配" #: modules/pinyinhelper/pinyinhelper.conf.in:3 msgid "Extra Pinyin functionality" msgstr "额外拼音功能" #: gui/pinyindictmanager/pinyindictmanager.cpp:107 msgid "Failed to create directory" msgstr "创建目录失败" #: gui/pinyindictmanager/filedownloader.cpp:48 msgid "Failed to create request." msgstr "创建请求失败。" #: gui/pinyindictmanager/pinyindictmanager.cpp:118 msgid "Failed to create temp file" msgstr "创建临时文件失败" #: gui/pinyindictmanager/pinyindictmanager.cpp:218 #: gui/pinyindictmanager/pinyindictmanager.cpp:276 msgid "Failed to get runtime directory" msgstr "获取 runtime 目录失败" #: im/table/ime.h:35 msgid "File" msgstr "文件" #: gui/pinyindictmanager/pinyindictmanager.cpp:364 msgid "File Operation Failed" msgstr "文件操作失败" #: gui/pinyindictmanager/pinyindictmanager.cpp:41 msgid "From &File" msgstr "从文件(&F)" #: gui/pinyindictmanager/pinyindictmanager.cpp:42 msgid "From &Sogou Cell Dictionary File" msgstr "来自搜狗细胞词典文件(&S)" #: modules/fullwidth/fullwidth.cpp:85 modules/fullwidth/fullwidth.h:40 msgid "Full width Character" msgstr "全角字符" #: modules/fullwidth/fullwidth.cpp:87 msgid "Full width Character is disabled." msgstr "全角字符已禁用。" #: modules/fullwidth/fullwidth.cpp:86 msgid "Full width Character is enabled." msgstr "全角字符已启用。" #: modules/fullwidth/fullwidth.conf.in:3 msgid "Full width character" msgstr "全角字符" #: modules/punctuation/punctuation.h:65 msgid "Full width punctuation" msgstr "全角标点" #: modules/punctuation/punctuation.cpp:155 msgid "Full width punctuation is disabled." msgstr "全角标点已禁用。" #: modules/punctuation/punctuation.cpp:154 msgid "Full width punctuation is enabled." msgstr "全角标点已启用。" #: im/pinyin/pinyin.h:103 msgid "Fuzzy Pinyin Settings" msgstr "模糊音设置" #: modules/fullwidth/fullwidth.h:41 msgid "Half width Character" msgstr "半角字符" #: modules/punctuation/punctuation.h:66 msgid "Half width punctuation" msgstr "半角标点" #: im/table/ime.h:56 msgid "Icon" msgstr "图标" #: im/pinyin/pinyin.h:43 msgid "Inner Segment (xian -> xi'an)" msgstr "内模糊音节 (xian -> xi'an)" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "Input Dictionary Name" msgstr "输入词典名称" #: im/table/ime.h:55 msgid "Key to trigger quickphrase" msgstr "快速输入的触发键" #: im/table/ime.h:77 msgid "Learning" msgstr "学习" #: im/table/engine.h:45 msgid "Lookup pinyin" msgstr "查找拼音" #: modules/cloudpinyin/cloudpinyin.h:44 msgid "Minimum Pinyin Length" msgstr "" #: im/table/engine.h:40 msgid "Modify dictionary" msgstr "修改词典" #: gui/pinyindictmanager/pinyindictmanager.cpp:94 msgid "New Dictionary Name:" msgstr "新词典名称:" #: im/pinyin/pinyin.h:94 msgid "Next Candidate" msgstr "下一个候选词" #: im/pinyin/pinyin.h:82 msgid "Next Page" msgstr "下一页" #: im/table/ime.h:39 msgid "Next page" msgstr "下一页" #: gui/pinyindictmanager/browserdialog.cpp:115 msgid "No browsing outside pinyin.sogou.com, now redirect to home page." msgstr "不允许访问 pinyin.sogou.com 之外的网页,将重定向到主页。" #: im/table/engine.cpp:113 msgid "Not available" msgstr "不可用" #: im/pinyin/pinyin.h:98 msgid "Number of Sentence" msgstr "句子数量" #: im/table/ime.h:69 msgid "Order policy" msgstr "排序规则" #: im/pinyin/pinyin.h:59 msgid "Page size" msgstr "页大小" #: im/pinyin/pinyin-addon.conf.in:3 im/pinyin/pinyin.conf.in:3 msgid "Pinyin" msgstr "拼音" #: gui/pinyindictmanager/pinyindictmanager.cpp:87 msgid "Pinyin dictionary manager" msgstr "拼音词典管理器" #: im/table/state.cpp:436 msgid "Please use this functionality after typing some text." msgstr "请在输入一些文字之后再使用这个功能。" #: im/pinyin/pinyin.cpp:454 msgid "Prediction" msgstr "预测" #: im/pinyin/pinyin.h:62 msgid "Prediction Size" msgstr "预测个数" #: im/table/ime.h:59 msgid "Prefix key to trigger Pinyin" msgstr "触发拼音的前缀键" #: im/pinyin/pinyin.cpp:846 msgid "Press %1% for %2%" msgstr "按下%1%输入%2%" #: im/pinyin/pinyin.cpp:842 msgid "Press %1% for %2% and %3% for %4%" msgstr "按下%1%输入%2%,按下%3%输入%4%" #: im/table/state.cpp:467 msgid "Press Backspace to forget." msgstr "按下退格键以忘记。" #: im/table/state.cpp:470 msgid "Press Delete to remove." msgstr "按下删除键来移除。" #: im/table/state.cpp:464 msgid "Press space to insert." msgstr "按下空格键来插入。" #: im/pinyin/pinyin.h:88 msgid "Prev Candidate" msgstr "上一个候选词" #: im/pinyin/pinyin.h:76 msgid "Prev Page" msgstr "上一页" #: im/table/ime.h:37 msgid "Prev page" msgstr "上一页" #: modules/punctuation/punctuation.cpp:153 #: modules/punctuation/punctuation.conf.in:3 msgid "Punctuation" msgstr "标点" #. i18n: file: gui/pinyindictmanager/pinyindictmanager.ui:44 #. i18n: ectx: property (text), widget (QPushButton, removeAllButton_) #: rc.cpp:15 #, kde-format msgid "Remove &All" msgstr "" #: im/pinyin/pinyin.cpp:843 msgid "Return" msgstr "返回" #: im/table/ime.h:75 msgid "Save auto phrase" msgstr "保存自动组词" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Scel file (*.scel)" msgstr "Scel 文件 (*.scel)" #: gui/pinyindictmanager/pinyindictmanager.cpp:154 msgid "Select Dictionary File" msgstr "选择词典文件" #: gui/pinyindictmanager/pinyindictmanager.cpp:195 msgid "Select scel file" msgstr "选择 scel 文件" #: im/table/ime.h:47 msgid "Selection" msgstr "选择" #: im/pinyin/pinyin.cpp:455 msgid "Show prediction words" msgstr "显示联想词组" #: im/pinyin/shuangpin.conf.in:3 msgid "Shuangpin" msgstr "双拼" #: im/pinyin/pinyin.h:101 msgid "Shuangpin Profile" msgstr "双拼方案" #: modules/chttrans/chttrans.cpp:87 modules/chttrans/chttrans.h:75 msgid "Simplified Chinese" msgstr "简体中文" #: modules/chttrans/chttrans.cpp:89 msgid "Simplified Chinese is enabled." msgstr "简体中文已启用。" #: modules/chttrans/chttrans.conf.in:3 msgid "Simplified and Traditional Chinese Translation" msgstr "简繁转换" #: im/table/table.conf.in:3 msgid "Table" msgstr "码表" #: gui/pinyindictmanager/filedownloader.cpp:38 msgid "Temporary file created." msgstr "已创建临时文件。" #: modules/cloudpinyin/cloudpinyin.h:41 msgid "Toggle Key" msgstr "切换键" #: modules/fullwidth/fullwidth.h:30 modules/punctuation/punctuation.h:36 #: modules/chttrans/chttrans.h:40 msgid "Toggle key" msgstr "切换键" #: modules/chttrans/chttrans.cpp:86 modules/chttrans/chttrans.h:74 msgid "Traditional Chinese" msgstr "繁体中文" #: modules/chttrans/chttrans.cpp:88 msgid "Traditional Chinese is enabled." msgstr "繁体中文已启用。" #: modules/chttrans/chttrans.h:37 msgid "Translate engine" msgstr "转换引擎" #: im/table/state.cpp:442 msgid "Use Left and Right to select character: " msgstr "使用左右键来选择字符:" #: im/table/state.cpp:453 msgid "Use Left and Right to select text. " msgstr "使用左右键来选择字符。" #: im/table/ime.h:53 msgid "Use full width" msgstr "使用全角字符" #: im/pinyin/pinyin.h:72 msgid "Use preedit in application when possible" msgstr "可用时在应用程序中显示预编辑文本" #: im/table/wanfeng.conf.in.in:3 msgid "Wanfeng" msgstr "晚风" #: im/table/ime.h:71 msgid "Wildcard matching Key" msgstr "模糊键" #: gui/pinyindictmanager/browserdialog.cpp:114 msgid "Wrong Link" msgstr "链接错误" #: im/table/wbx.conf.in.in:3 msgid "Wubi" msgstr "五笔字型" #: im/table/wbpy.conf.in.in:3 msgid "Wubi Pinyin" msgstr "五笔拼音" #: im/table/zrm.conf.in.in:3 msgid "Ziranma" msgstr "自然码" #. i18n: file: gui/pinyindictmanager/browserdialog.ui:21 #. i18n: ectx: property (url), widget (QWebEngineView, webView_) #: rc.cpp:6 #, kde-format msgid "about:blank" msgstr "" #: im/pinyin/pinyin.h:45 msgid "an <-> ang" msgstr "an <-> ang" #: im/pinyin/pinyin.h:51 msgid "c <-> ch" msgstr "c <-> ch" #: im/pinyin/pinyin.h:46 msgid "en <-> eng" msgstr "en <-> eng" #: im/pinyin/pinyin.h:52 msgid "f <-> h" msgstr "f <-> h" #: im/pinyin/pinyin.h:42 msgid "gn -> ng" msgstr "gn -> ng" #: im/pinyin/pinyin.h:47 msgid "ian <-> iang" msgstr "ian <-> iang" #: im/pinyin/pinyin.h:48 msgid "in <-> ing" msgstr "in <-> ing" #: im/pinyin/pinyin.h:53 msgid "l <-> n" msgstr "l <-> n" #: im/pinyin/pinyin.h:54 msgid "s <-> sh" msgstr "s <-> sh" #: im/pinyin/pinyin.h:49 msgid "u <-> ou" msgstr "u <-> ou" #: im/pinyin/pinyin.h:44 msgid "u <-> v" msgstr "u <-> v" #: im/pinyin/pinyin.h:50 msgid "uan <-> uang" msgstr "uan <-> uang" #: im/pinyin/pinyin.h:41 msgid "ue -> ve" msgstr "ue -> ve" #: im/pinyin/pinyin.h:55 msgid "z <-> zh" msgstr "z <-> zh" #: im/pinyin/pinyin.cpp:112 msgid "{0} ({1})" msgstr "{0} ({1})" #: im/table/state.cpp:485 msgid "{0} is not in table." msgstr "{0} 不在码表中。" #: im/table/state.cpp:474 msgid "{0}: No corresponding code." msgstr "{0}:没有对应的码。" #: im/table/state.cpp:459 im/table/state.cpp:482 msgid "{0}: {1}" msgstr "{0}:{1}" fcitx5-chinese-addons-0.0~git20200117.4261e23/test/000077500000000000000000000000001361043647100210455ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/test/CMakeLists.txt000066400000000000000000000015451361043647100236120ustar00rootroot00000000000000configure_file(testdir.h.in ${CMAKE_CURRENT_BINARY_DIR}/testdir.h @ONLY) include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_executable(testpunctuation testpunctuation.cpp) target_link_libraries(testpunctuation Fcitx5::Core Fcitx5::Module::Punctuation) add_dependencies(testpunctuation punctuation punctuation.conf.in-fmt) add_test(NAME testpunctuation COMMAND testpunctuation) add_executable(testcloudpinyin testcloudpinyin.cpp) target_link_libraries(testcloudpinyin Fcitx5::Core Fcitx5::Module::CloudPinyin) add_dependencies(testcloudpinyin cloudpinyin) add_executable(testpinyinhelper testpinyinhelper.cpp) target_link_libraries(testpinyinhelper Fcitx5::Core Fcitx5::Module::PinyinHelper) add_dependencies(testpinyinhelper pinyinhelper pinyinhelper.conf.in-fmt) add_test(NAME testpinyinhelper COMMAND testpinyinhelper ${PROJECT_BINARY_DIR}/modules/pinyinhelper) fcitx5-chinese-addons-0.0~git20200117.4261e23/test/testcloudpinyin.cpp000066400000000000000000000035201361043647100250060ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "cloudpinyin_public.h" #include "testdir.h" #include #include #include #include int main(int argc, char *argv[]) { if (argc < 3) { return 1; } setenv("FCITX_ADDON_DIRS", argv[2], 1); setenv("FCITX_DATA_DIRS", (std::string(argv[1]) + "/..").c_str(), 1); fcitx::EventLoop loop; fcitx::AddonManager manager(argv[1]); manager.setEventLoop(&loop); manager.registerDefaultLoader(nullptr); manager.load(); auto cloudpinyin = manager.addon("cloudpinyin", true); int returned = 0; auto callback = [&loop, &returned](const std::string &pinyin, const std::string &hanzi) { std::cout << "Pinyin: " << pinyin << std::endl; std::cout << "Hanzi: " << hanzi << std::endl; returned++; if (returned == 1) { loop.quit(); } }; cloudpinyin->call("nihao", callback); cloudpinyin->call("ceshi", callback); loop.exec(); return 0; } fcitx5-chinese-addons-0.0~git20200117.4261e23/test/testdir.h.in000066400000000000000000000016251361043647100233050ustar00rootroot00000000000000/* * Copyright (C) 2017~2017 by CSSlayer * wengxt@gmail.com * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) 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; see the file COPYING. If not, * see . */ #ifndef _TEST_TESTDIR_H_ #define _TEST_TESTDIR_H_ #define TESTING_SOURCE_DIR "@CMAKE_SOURCE_DIR@" #define TESTING_BINARY_DIR "@CMAKE_BINARY_DIR@" #endif // _TEST_TESTDIR_H_ fcitx5-chinese-addons-0.0~git20200117.4261e23/test/testpinyinhelper.cpp000066400000000000000000000037311361043647100251630ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "pinyinhelper_public.h" #include "testdir.h" #include #include #include #include int main() { setenv("FCITX_ADDON_DIRS", TESTING_BINARY_DIR "/modules/pinyinhelper", 1); setenv("FCITX_DATA_DIRS", TESTING_BINARY_DIR "/modules", 1); fcitx::AddonManager manager(TESTING_BINARY_DIR "/modules/pinyinhelper"); manager.registerDefaultLoader(nullptr); manager.load(); auto pinyinhelper = manager.addon("pinyinhelper", true); FCITX_ASSERT(pinyinhelper); std::vector expect{"nǐ"}; auto result = pinyinhelper->call( fcitx::utf8::getChar("你")); for (auto &s : result) { FCITX_INFO() << s << " "; } FCITX_ASSERT(result == expect); auto result2 = pinyinhelper->call("2511", 3); for (auto &s : result2) { FCITX_INFO() << s.first << " " << pinyinhelper->call( s.second); } auto result3 = pinyinhelper->call("szhh", 3); FCITX_ASSERT(result2 == result3); return 0; } fcitx5-chinese-addons-0.0~git20200117.4261e23/test/testpunctuation.cpp000066400000000000000000000032641361043647100250270ustar00rootroot00000000000000// // Copyright (C) 2017~2017 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include "punctuation_public.h" #include "testdir.h" #include #include #include int main() { setenv("FCITX_ADDON_DIRS", TESTING_BINARY_DIR "/modules/punctuation", 1); setenv("FCITX_DATA_DIRS", TESTING_BINARY_DIR "/modules:" TESTING_SOURCE_DIR "/modules", 1); fcitx::AddonManager manager(TESTING_BINARY_DIR "/modules/punctuation"); manager.registerDefaultLoader(nullptr); manager.load(); auto punctuation = manager.addon("punctuation", true); FCITX_ASSERT(punctuation); FCITX_ASSERT( punctuation->call("zh_CN", ',') .first == ","); FCITX_ASSERT( punctuation->call("zh_CN", '"') .first == "“"); FCITX_ASSERT( punctuation->call("zh_CN", '"') .second == "”"); return 0; } fcitx5-chinese-addons-0.0~git20200117.4261e23/test/valgrind_suppress000066400000000000000000000001401361043647100245350ustar00rootroot00000000000000{ ignore_libcrypto_conditional_jump_errors Memcheck:Leak ... obj:*/libcrypto.so.* } fcitx5-chinese-addons-0.0~git20200117.4261e23/tools/000077500000000000000000000000001361043647100212265ustar00rootroot00000000000000fcitx5-chinese-addons-0.0~git20200117.4261e23/tools/CMakeLists.txt000066400000000000000000000002271361043647100237670ustar00rootroot00000000000000add_executable(scel2org5 scel2org5.cpp) target_link_libraries(scel2org5 Fcitx5::Utils) install(TARGETS scel2org5 DESTINATION ${CMAKE_INSTALL_BINDIR}) fcitx5-chinese-addons-0.0~git20200117.4261e23/tools/scel2org5.cpp000066400000000000000000000153111361043647100235400ustar00rootroot00000000000000// // Copyright (C) 2010~2018 by CSSlayer // wengxt@gmail.com // // 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; see the file COPYING. If not, // see . // #include #include #include #include #include #include #include #include #include #include #include #include using namespace fcitx; #define HEADER_SIZE 12 #define BUFLEN 0x1000 #define DESC_START 0x130 #define DESC_LENGTH (0x338 - 0x130) #define LDESC_LENGTH (0x540 - 0x338) #define NEXT_LENGTH (0x1540 - 0x540) #define PINYIN_SIZE 4 template void readOrAbort(const UnixFD &fd, T *value, int n, const char *error) { if (fs::safeRead(fd.fd(), value, n * sizeof(T)) != static_cast(n * sizeof(T))) { FCITX_FATAL() << error; } } template void readOrAbort(const UnixFD &fd, T *value, const char *error) { return readOrAbort(fd, value, 1, error); } std::string unicodeToUTF8(const char16_t *value, size_t size) { return std::wstring_convert, char16_t>{} .to_bytes(value, value + size); } std::string unicodeToUTF8(const char *value, size_t size) { FCITX_ASSERT(size % 2 == 0) << "Invalid size of string"; auto ustr = reinterpret_cast(value); std::u16string str; str.reserve(size / 2); for (size_t i = 0; i < size / 2; i++) { // either le or be will be 0 if (ustr[i] == 0) { break; } str.push_back(le16toh(ustr[i])); } return unicodeToUTF8(str.data(), str.size()); } static const char header_str[HEADER_SIZE] = {'\x40', '\x15', '\0', '\0', '\x44', '\x43', '\x53', '\x01', '\x01', '\0', '\0', '\0'}; static const char pinyin_str[PINYIN_SIZE] = {'\x9d', '\x01', '\0', '\0'}; static void usage() { puts("scel2org - Convert .scel file to libime compatible file (SEE NOTES " "BELOW)\n" "\n" " usage: scel2org [OPTION] [scel file]\n" "\n" " -o specify the output file, if not specified, the output " "will\n" " be stdout.\n" " -h display this help.\n" "\n" "NOTES:\n" " Always check the produced output for errors.\n"); exit(1); } int main(int argc, char **argv) { int c; const char *outputFile = nullptr; while ((c = getopt(argc, argv, "o:h")) != -1) { switch (c) { case 'o': outputFile = optarg; break; case 'h': default: usage(); break; } } std::ofstream fout; std::ostream *out; if (!outputFile || strcmp(outputFile, "-") == 0) { out = &std::cout; } else { fout.open(outputFile, std::ios::out | std::ios::binary); out = &fout; } if (optind >= argc) { usage(); return 1; } UnixFD fd = UnixFD::own(open(argv[optind], O_RDONLY)); if (!fd.isValid()) { FCITX_ERROR() << "Cannot open file: " << argv[optind]; return 1; } char headerBuf[HEADER_SIZE]; readOrAbort(fd, headerBuf, HEADER_SIZE, "Failed to read header"); FCITX_ASSERT(memcmp(headerBuf, header_str, HEADER_SIZE) == 0) << " format error."; FCITX_ASSERT(lseek(fd.fd(), DESC_START, SEEK_SET) != static_cast(-1)); char descBuf[DESC_LENGTH]; readOrAbort(fd, descBuf, DESC_LENGTH, "Failed to read description"); std::cerr << "DESC:" << unicodeToUTF8(descBuf, DESC_LENGTH) << std::endl; char ldescBuf[LDESC_LENGTH]; readOrAbort(fd, ldescBuf, LDESC_LENGTH, "Failed to read long description"); std::cerr << "LDESC:" << unicodeToUTF8(ldescBuf, LDESC_LENGTH) << std::endl; char nextBuf[NEXT_LENGTH]; readOrAbort(fd, nextBuf, NEXT_LENGTH, "Failed to read next description"); std::cerr << "NEXT:" << unicodeToUTF8(nextBuf, NEXT_LENGTH) << std::endl; char pyBuf[PINYIN_SIZE]; readOrAbort(fd, pyBuf, PINYIN_SIZE, "Failed to read py"); FCITX_ASSERT(memcmp(pyBuf, pinyin_str, PINYIN_SIZE) == 0); std::vector pys; while (true) { int16_t index; int16_t count; readOrAbort(fd, &index, "failed to read index"); readOrAbort(fd, &count, "failed to read pinyin count"); std::vector buf; buf.resize(count); readOrAbort(fd, buf.data(), count, "Failed to read py"); std::string py = unicodeToUTF8(buf.data(), buf.size()); // Replace ue with ve if (py == "lue" || py == "nue") { py[py.size() - 2] = 'v'; } pys.push_back(py); if (py == "zuo") { break; } } while (true) { int16_t symcount; int16_t count; int16_t wordcount; auto readResult = fs::safeRead(fd.fd(), &symcount, sizeof(int16_t)); if (readResult == 0) { break; } if (readResult < 0) { FCITX_FATAL() << "Failed to read result"; } readOrAbort(fd, &count, "Failed to read count"); wordcount = count / 2; std::vector pyindex; pyindex.resize(wordcount); readOrAbort(fd, pyindex.data(), wordcount, "Failed to read pyindex"); int s; for (s = 0; s < symcount; s++) { std::vector buf; readOrAbort(fd, &count, "Failed to read count"); buf.resize(count); readOrAbort(fd, buf.data(), count, "Failed to read text"); std::string bufout = unicodeToUTF8(buf.data(), buf.size()); *out << bufout << "\t"; *out << pys[pyindex[0]]; for (auto i = 1; i < wordcount; i++) { *out << '\'' << pys[pyindex[i]]; } *out << "\t0" << std::endl; readOrAbort(fd, &count, "failed to read count"); buf.resize(count); readOrAbort(fd, buf.data(), buf.size(), "failed to read buf"); } } return 0; }