pax_global_header00006660000000000000000000000064150410601340014504gustar00rootroot0000000000000052 comment=7b5b276a97f283b20a985ddf417884b83afd880e chewing-editor-0.1.2/000077500000000000000000000000001504106013400144145ustar00rootroot00000000000000chewing-editor-0.1.2/.editorconfig000066400000000000000000000003651504106013400170750ustar00rootroot00000000000000; EditorConfig is awesome: http://EditorConfig.org root = true [*] charset = "utf-8" end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = space indent_size = 4 [*.ui] indent_style = space indent_size = 1 chewing-editor-0.1.2/.gitattributes000066400000000000000000000000471504106013400173100ustar00rootroot00000000000000test/data/import/uhash.dat/**/* binary chewing-editor-0.1.2/.github/000077500000000000000000000000001504106013400157545ustar00rootroot00000000000000chewing-editor-0.1.2/.github/CONTRIBUTING.md000066400000000000000000000011531504106013400202050ustar00rootroot00000000000000# Before Submitting a Bug or Feature Request * Please check if this issue is already reported by using the search feature in Github. * Please read [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/). # Known Issue * chewing-editor does not check the correction of input (See [#108](https://github.com/chewing/chewing-editor/issues/108)). * User shall be able not to input bopomofo when add new phrase (See [#2](https://github.com/chewing/chewing-editor/issues/2)). * bopomofo cannot be displayed (See ). chewing-editor-0.1.2/.github/ISSUE_TEMPLATE.md000066400000000000000000000000541504106013400204600ustar00rootroot00000000000000# What is your environment? * OS version chewing-editor-0.1.2/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000000001504106013400215430ustar00rootroot00000000000000chewing-editor-0.1.2/.github/workflows/000077500000000000000000000000001504106013400200115ustar00rootroot00000000000000chewing-editor-0.1.2/.github/workflows/ci.yml000066400000000000000000000036061504106013400211340ustar00rootroot00000000000000name: Continuous Integration on: push: branches: [ "master" ] pull_request: branches: [ "master" ] env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release CFLAGS: -fsanitize=address CXXFLAGS: -fsanitize=address jobs: build: strategy: matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 with: submodules: 'true' - name: Install dependencies for Ubuntu run: | sudo apt-get update sudo apt-get install --yes help2man qtbase5-dev qttools5-dev qttools5-dev-tools libchewing3-dev lcov libgtest-dev gcc --version g++ --version gcov --version if: ${{ matrix.os == 'ubuntu-latest' }} - name: Install dependencies for macOS run: | # dependencies brew update brew install libchewing qt@5 googletest # Allow CMake to find qt@5 by passing down the environment variable echo "CMAKE_PREFIX_PATH=$(brew --prefix qt@5)" >> $GITHUB_ENV if: ${{ matrix.os == 'macos-latest' }} - name: Configure CMake run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_GCOV=yes - name: Show config run: cmake -B ${{github.workspace}}/build -LA - name: Build run: cmake --build ${{github.workspace}}/build -v --config ${{env.BUILD_TYPE}} - name: Test working-directory: ${{github.workspace}}/build run: ctest -C ${{env.BUILD_TYPE}} --output-on-failure - name: Collect coverage stats run: scripts/lcov.sh if: ${{ matrix.os == 'ubuntu-latest' }} - name: Coveralls uses: coverallsapp/github-action@1.1.3 with: github-token: ${{ secrets.GITHUB_TOKEN }} path-to-lcov: coverage.info if: ${{ matrix.os == 'ubuntu-latest' }} chewing-editor-0.1.2/.gitignore000066400000000000000000000004411504106013400164030ustar00rootroot00000000000000CMake* !CMakeLists.txt !/cmake *.cmake !/cmake/*.cmake Makefile gmock/ *moc* qrc* *.qrc.depends chewing-editor chewing-editor.exe chewing-editor.desktop chewing-editor.1* config.h ui_*.h *.json *.a run-test* *.qm coverage* chewing-editor.dSYM/ chewing-editor.app/ Testing/ /build/ chewing-editor-0.1.2/CMakeLists.txt000066400000000000000000000211671504106013400171630ustar00rootroot00000000000000# chewing-editor: Chewing userphrase editor # Copyright (C) 2014 Chewing Development Team # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # override default c/c++ flags, add /MT to link VC++ runtime statically. set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/c_flag_overrides.cmake) set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake) cmake_minimum_required(VERSION 3.10.0...3.31.6) project(chewing-editor VERSION 0.1.2 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) include(GNUInstallDirs) if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") set(CMAKE_CXX_FLAGS "-g -O2 ${CMAKE_CXX_FLAGS}") option(ENABLE_GCOV "Coverage support" false) if(ENABLE_GCOV) set(CMAKE_CXX_FLAGS "--coverage ${CMAKE_CXX_FLAGS}") endif() find_program(VALGRIND valgrind) if (VALGRIND) option(USE_VALGRIND "Use valgrind when testing" true) endif() elseif(MSVC) # MBCS is the default in msvc, overwrite to unicode add_definitions(-DUNICODE -D_UNICODE) endif() add_definitions(-DTESTDATA="${PROJECT_SOURCE_DIR}/test/data" -DQT_DISABLE_DEPRECATED_BEFORE=0x050e00) find_package(PkgConfig) find_package(Qt5Widgets REQUIRED) find_package(Qt5LinguistTools) # libchewing # MODIFY IF NEEDED, e.g. ${CMAKE_CURRENT_SOURCE_DIR}/libchewing/lib/ set(CHEWING_LIBRARY_DIRS ) # MODIFY IF NEEDED, e.g. ${CMAKE_CURRENT_SOURCE_DIR}/libchewing/lib/*.lib set(CHEWING_LIBRARIES ) # MODIFY IF NEEDED, e.g. ${CMAKE_CURRENT_SOURCE_DIR}/libchewing/include/chewing set(CHEWING_INCLUDE_DIRS ) if (CHEWING_INCLUDE_DIRS AND CHEWING_LIBRARIES AND CHEWING_LIBRARY_DIRS) # if all listed variables are TRUE find_package_handle_standard_args(chewing DEFAULT_MSG CHEWING_LIBRARIES CHEWING_INCLUDE_DIRS) mark_as_advanced(CHEWING_LIBRARIES CHEWING_INCLUDE_DIRS) else() pkg_check_modules(CHEWING REQUIRED chewing>=0.4.0) endif() pkg_check_modules(GTEST REQUIRED gtest>=1.7.0 IMPORTED_TARGET) # Qt library set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(QT_VERSION 5) # Git describe find_package(Git) if (GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git/HEAD") execute_process( COMMAND ${GIT_EXECUTABLE} describe --tags WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} RESULT_VARIABLE git_describe_result OUTPUT_VARIABLE PROJECT_GIT_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() configure_file( ${PROJECT_SOURCE_DIR}/config.h.in ${PROJECT_BINARY_DIR}/include/config.h ) install( FILES ${PROJECT_SOURCE_DIR}/chewing-editor.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications ) include_directories( ${PROJECT_BINARY_DIR}/include ${PROJECT_SOURCE_DIR}/src/exporter ${PROJECT_SOURCE_DIR}/src/importer ${PROJECT_SOURCE_DIR}/src/model ${PROJECT_SOURCE_DIR}/src/ui ${PROJECT_SOURCE_DIR}/src/util ${PROJECT_SOURCE_DIR}/src/view ${CHEWING_INCLUDE_DIRS} ${Qt5Widgets_INCLUDES} ) link_directories(${CHEWING_LIBRARY_DIRS}) include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/platform_apple.cmake) # resources QT5_ADD_RESOURCES(qt_resources ${PROJECT_SOURCE_DIR}/rc/resources.qrc) # i18n set(TRANSLATION_LIST en_US zh_TW) set(TS_DIR "${PROJECT_SOURCE_DIR}/ts") set(QM_DIR "${PROJECT_SOURCE_DIR}/ts") add_custom_target(prepare_lupdate COMMAND ${CMAKE_COMMAND} -E make_directory ${TS_DIR} ) add_custom_target(lupdate) add_custom_target(prepare_lrelease COMMAND ${CMAKE_COMMAND} -E make_directory ${QM_DIR} ) foreach(TRANSLATION ${TRANSLATION_LIST}) set(TS_FILE "${TS_DIR}/${CMAKE_PROJECT_NAME}_${TRANSLATION}.ts") set(QM_FILE "${QM_DIR}/${CMAKE_PROJECT_NAME}_${TRANSLATION}.qm") add_custom_target("${TRANSLATION}-ts" COMMAND ${Qt5_LUPDATE_EXECUTABLE} ${PROJECT_SOURCE_DIR}/src -ts ${TS_FILE} DEPENDS prepare_lupdate ) add_dependencies(lupdate "${TRANSLATION}-ts") add_custom_command( OUTPUT ${QM_FILE} COMMAND ${Qt5_LRELEASE_EXECUTABLE} ${TS_FILE} -qm ${QM_FILE} DEPENDS prepare_lrelease ${TS_FILE} ) list(APPEND QM_FILES ${QM_FILE}) endforeach() add_custom_target(lrelease ALL DEPENDS ${QM_FILES}) QT5_ADD_RESOURCES(qt_resources ${PROJECT_SOURCE_DIR}/ts/ts.qrc) # exporter file(GLOB_RECURSE exporter_src ${PROJECT_SOURCE_DIR}/src/exporter/*) add_library(exporter STATIC ${exporter_src}) target_link_libraries(exporter Qt5::Widgets) # importer file(GLOB_RECURSE importer_src ${PROJECT_SOURCE_DIR}/src/importer/*) add_library(importer STATIC ${importer_src}) target_link_libraries(importer Qt5::Widgets) # ui file(GLOB ui_src ${PROJECT_SOURCE_DIR}/src/ui/*) qt5_wrap_ui(ui ${ui_src}) # util file(GLOB util_src ${PROJECT_SOURCE_DIR}/src/util/*) add_library(util STATIC ${util_src}) target_link_libraries(util Qt5::Widgets) # chewing-editor file(GLOB chewing-editor_src ${PROJECT_SOURCE_DIR}/src/* ${PROJECT_SOURCE_DIR}/src/model/* ${PROJECT_SOURCE_DIR}/src/ui/* ${PROJECT_SOURCE_DIR}/src/view/* ${ui} ) add_executable(chewing-editor WIN32 ${MACOSX_APP} ${chewing-editor_src} ${qt_resources} ${PROJECT_SOURCE_DIR}/rc/chewing-editor.rc) # on Windows, remove "WIN32" for a console window target_link_libraries(chewing-editor ${CHEWING_LIBRARIES} exporter importer util ) if(MSVC) target_link_libraries(chewing-editor # append libraries Qt5::Widgets "${_qt5Widgets_install_prefix}/lib/qtpcre.lib" "${_qt5Widgets_install_prefix}/lib/qtfreetype.lib" "${_qt5Widgets_install_prefix}/lib/qtharfbuzzng.lib" "${_qt5Widgets_install_prefix}/lib/Qt5PlatformSupport.lib" "${_qt5Widgets_install_prefix}/plugins/platforms/qwindows.lib" imm32.lib winmm.lib Ws2_32.lib ) endif() target_link_libraries(chewing-editor Qt5::Widgets) install(PROGRAMS ${CMAKE_BINARY_DIR}/chewing-editor DESTINATION ${CMAKE_INSTALL_BINDIR}) # icon install(FILES ${CMAKE_SOURCE_DIR}/share/icons/chewing-editor.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps) install(FILES ${CMAKE_SOURCE_DIR}/rc/chewing-editor.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps) # manpage find_program(HELP2MAN help2man) find_program(GZIP gzip) if (HELP2MAN) set(manpage ${PROJECT_BINARY_DIR}/chewing-editor.1) set(h2m ${PROJECT_SOURCE_DIR}/chewing-editor.h2m) add_custom_command( OUTPUT ${manpage} COMMAND ${HELP2MAN} --include=${h2m} --section=1 --no-info --no-discard-stderr --output=${manpage} ${PROJECT_BINARY_DIR}/chewing-editor DEPENDS chewing-editor ${h2m} ) if (GZIP) add_custom_command( OUTPUT ${manpage}.gz COMMAND ${GZIP} -n -f ${manpage} DEPENDS ${manpage} ) set(manpage ${manpage}.gz) endif() add_custom_target(manpage ALL DEPENDS ${manpage}) install(FILES ${manpage} DESTINATION "${CMAKE_INSTALL_MANDIR}/man1/") endif() # testing enable_testing() file(GLOB run-test_src test/*.cpp ) add_executable(run-test ${run-test_src} ) target_link_libraries(run-test PkgConfig::GTEST exporter importer util pthread ) target_link_libraries(run-test Qt5::Widgets) add_test(test run-test) if (USE_VALGRIND) add_test("valgrind-run-test" ${VALGRIND} --error-exitcode=255 --leak-check=full ${PROJECT_BINARY_DIR}/run-test) endif() add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) add_dependencies(check chewing-editor run-test) # package set(CPACK_SOURCE_GENERATOR TGZ) set(CPACK_SOURCE_IGNORE_FILES "^${PROJECT_SOURCE_DIR}/.git" "^${PROJECT_SOURCE_DIR}/.jj" "^${PROJECT_SOURCE_DIR}/build" ) set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) include(CPack) chewing-editor-0.1.2/COPYING000066400000000000000000000432541504106013400154570ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. chewing-editor-0.1.2/README.md000066400000000000000000000061151504106013400156760ustar00rootroot00000000000000# Chewing Editor [![GitHub Actions Status](https://github.com/chewing/chewing-editor/actions/workflows/ci.yml/badge.svg)](https://github.com/chewing/chewing-editor/actions) [![Coveralls Status](https://img.shields.io/coveralls/chewing/chewing-editor.svg)](https://coveralls.io/github/chewing/chewing-editor) chewing-editor is a cross platform chewing user phrase editor. It provides a easy way to manage user phrase. With it, user can customize their user phrase to increase input performance. # Install * Arch Linux: install from AUR: [Stable release](https://aur.archlinux.org/packages/chewing-editor/), [Development](https://aur.archlinux.org/packages/chewing-editor-git/) * Mageia: install via `urpmi chewing-editor` - available in cauldron, Mageia 6 and later. * Debian/Ubuntu Linux: install via `apt-get install chewing-editor` # Development ## Tools Requirement * [CMake](https://www.cmake.org/) >= 3.0.0 * gcc >= 4.8 or Visual Studio Express 2012 * [libchewing](https://github.com/chewing/libchewing) >= 0.4.0 * Qt = 5 * Editor with [EditorConfig](http://editorconfig.org/) support * [lcov](http://ltp.sourceforge.net/coverage/lcov.php) for coverage testing ## Build chewing-editor can be built by the following commands: cmake . make If cmake cannot find Qt5, check the environment variable `CMAKE_PREFIX_PATH` which shall point to Qt5 installation path. For example: `C:\Qt\Qt5.1.1\5.1.1\msvc2012_64`. ## Test A custom target `make check` is used to build and run unit test. ## Coverage Report chewing-editor integrates with gcov to provide code coverage report. The following commands will generate coverage report for unit test. cmake . -DENABLE_GCOV=yes make check scripts/lcov.sh The coverage report will be in `coveragereport` directory. ## Translation ### Update Translations Please use the following steps to update translations: * `cmake .` * `make lupdate` * ts files will be updated by `lupdate` * Use `linguist` to edit ts files ### Add A New Translation Please use the following steps to add a new translation: * Add locale in `CMakeFiles.txt` * `cmake .` * `make lupdate` * ts files will be updated by `lupdate` * Use `linguist` to edit ts files # Known Issues ## Bopomofo cannot Display Correctly Qt5 before v5.3.0 has problem displaying bopomofo with HarfBuzz-NG. If you encounter this issue, please upgrade your Qt5 to v5.3.0, or run chewing-editor with `QT_HARFBUZZ=old`. See also: * * # Bugs & Feature Request Please report any bug & feature request to # Author & Contributors * ChangZhuo Chen (陳昌倬) * 鄭鴻旗 * Mike Tzou * Yao-Po Wang * Peter Dave Hello * David Kuo * Bruce Liu # Licenses * This project is licensed under [GPL-2.0](https://opensource.org/licenses/GPL-2.0) or any later version. * [Google C++ Mocking Framework](https://code.google.com/p/googlemock/) is licensed under [New BSD License](https://opensource.org/licenses/BSD-3-Clause) chewing-editor-0.1.2/chewing-editor.desktop000066400000000000000000000003761504106013400207250ustar00rootroot00000000000000[Desktop Entry] Version=1.0 Type=Application Name=Chewing Editor Comment=Chewing Userphrase Editor Exec=chewing-editor Icon=chewing-editor Categories=Utility;TextTools;Qt; # Translation Name[zh_TW]=Chewing Editor Comment[zh_TW]=新酷音詞庫編輯器 chewing-editor-0.1.2/chewing-editor.h2m000066400000000000000000000004241504106013400177340ustar00rootroot00000000000000[NAME] chewing-editor - chewing userphrase editor [SYNOPSIS] chewing-editor [-v|--version] [-h|--help] [-d|--debug] [AUTHOR] Written by chewing development team [REPORTING BUGS] Report bug to chewing-editor-0.1.2/cmake/000077500000000000000000000000001504106013400154745ustar00rootroot00000000000000chewing-editor-0.1.2/cmake/c_flag_overrides.cmake000066400000000000000000000005741504106013400220010ustar00rootroot00000000000000if(MSVC) set(CMAKE_C_FLAGS_DEBUG_INIT "/MTd /Zi /Ob0 /Od /RTC1 /D_DEBUG") set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /GL /Gw /D NDEBUG") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /OPT:REF /OPT:ICF") set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") endif() chewing-editor-0.1.2/cmake/cxx_flag_overrides.cmake000066400000000000000000000006061504106013400223550ustar00rootroot00000000000000if(MSVC) set(CMAKE_CXX_FLAGS_DEBUG_INIT "/MTd /Zi /Ob0 /Od /RTC1 /D_DEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /GL /Gw /D NDEBUG") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/LTCG /OPT:REF /OPT:ICF") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") endif() chewing-editor-0.1.2/cmake/platform_apple.cmake000066400000000000000000000021251504106013400215030ustar00rootroot00000000000000if (APPLE) set(MACOSX_TRANSLATION_LIST English zh_TW) set(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME}) set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) set(MACOSX_BUNDLE_LONG_VERSION_STRING ${PROJECT_VERSION}) set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") set(MACOSX_BUNDLE_COPYRIGHT ${COPYRIGHT}) set(MACOSX_BUNDLE_GUI_IDENTIFIER ${IDENTIFIER}) set(MACOSX_BUNDLE_ICON_FILE "chewing-editor") foreach(MACOSX_TRANSLATION ${MACOSX_TRANSLATION_LIST}) file(GLOB translation_files ${PROJECT_SOURCE_DIR}/rc/macosx/${MACOSX_TRANSLATION}.lproj/* ) set_source_files_properties(${translation_files} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/${MACOSX_TRANSLATION}.lproj) list(APPEND MACOSX_TRANSLATION_FILES ${translation_files}) endforeach() set_source_files_properties(${PROJECT_SOURCE_DIR}/rc/chewing-editor.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) set(MACOSX_APP MACOSX_BUNDLE "${PROJECT_SOURCE_DIR}/rc/chewing-editor.icns" ${MACOSX_TRANSLATION_FILES}) endif() chewing-editor-0.1.2/config.h.in000066400000000000000000000003641504106013400164420ustar00rootroot00000000000000#define PROJECT_NAME "@CMAKE_PROJECT_NAME@" #define PROJECT_VERSION "@PROJECT_VERSION@" #define PROJECT_VERSION_RC @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@ #cmakedefine PROJECT_GIT_VERSION "@PROJECT_GIT_VERSION@" chewing-editor-0.1.2/rc/000077500000000000000000000000001504106013400150205ustar00rootroot00000000000000chewing-editor-0.1.2/rc/chewing-editor.icns000066400000000000000000001574171504106013400206250ustar00rootroot00000000000000icnsis32 z05453Fӿu~&I"cNVx">S "BY %ǎ&,^KB|>?)1cFAA?f fkS "BY %ǎ&,^KB|>?)1cFAA?f fkS "BY %ǎ&,^KB|>?)1cFAA?f fkA?^RQP_JNʅ 9;<8<;Bbv9Qpdi2Gc%a8AacЂ  5謇 #!!"" F3a"0Y };Tw;Sw!I/001 100;Sw#;Sw#2$%%$! d?:Sx!36 S.O"܀pQ#Z)Ӂ\q*.##Iс9"L ,-Ձ!WV WWYB#N:P؁$O8Lہ123$$Q1Bށ:$S"ɾ, !9=?BDFJ5$U  #!!T"^?A@\>A?^RQP_JNʅ 9;<8<;Bbv9Qpdi2Gc%a8AacЂ  5謇 #!!"" F3a"0Y };Tw;Sw!I/001 100;Sw#;Sw#2$%%$! d?:Sx!36 S.O"܀pQ#Z)Ӂ\q*.##Iс9"L ,-Ձ!WV WWYB#N:P؁$O8Lہ123$$Q1Bށ:$S"ɾ, !9=?BDFJ5$U  #!!T"^?A@\>A?^l8mkih32 opozsed ,RKJh. %-컀 S+(+ u< )+ t< {n |х}nooqLPr2joon~!i!!ă gv%ejB"{ ! #(#u<" #,s;"դ }/ܲs;"|ك3ֲs;"j̃8ϲs;#W< ɴs; #g$'("'+@ qs< #D> s6 #꯭Is %$ڃفـNms$#fRYq$ YWG26&$_\8܂%daqۅ %6Pif %Rznk%Ikrq&A_wv< =&&:S|{W&2F:}'INK  ''#UVUpkUVUopozsed ,RKJh. %-컀 S+(+ u< )+ t< {n |х}nooqLPr2joon~!i!!ă gv%ejB"{ ! #(#u<" #,s;"դ }/ܲs;"|ك3ֲs;"j̃8ϲs;#W< ɴs; #g$'("'+@ qs< #D> s6 #꯭Is %$ڃفـNms$#fRYq$ YWG26&$_\8܂%daqۅ %6Pif %Rznk%Ikrq&A_wv< =&&:S|{W&2F:}'INK  ''#UVUpkUVUopozsed ,RKJh. %-컀 S+(+ u< )+ t< {n |х}nooqLPr2joon~!i!!ă gv%ejB"{ ! #(#u<" #,s;"դ }/ܲs;"|ك3ֲs;"j̃8ϲs;#W< ɴs; #g$'("'+@ qs< #D> s6 #꯭Is %$ڃفـNms$#fRYq$ YWG26&$_\8܂%daqۅ %6Pif %Rznk%Ikrq&A_wv< =&&:S|{W&2F:}'INK  ''#UVUpkUVUh8mk it32'rC787=Ė"$#=}ڡ|ڡ{١wyءog#&$wנ\Vku֠KFbtՠ;9YrԠ/1PqӠt+HoѰ@ @mа? 7lΰ? /jͰ? 'i˰? !h˰? 8po-Wpon@ ߕ/ ѕ      /Õ% %%%~&k&X&,*) *'i&C'H kt ^"ik'D  ?  'A ?  (>?  (;? (8? (5? )tuvoQwuvϑ? )!? )|? )xs? * g#j? *V'b? *H+Z? *:/R? +{,2K? +j6C? +VԐ:;? +r3670 76DՐ>3? , B,7? ,"F':? , J$A? |,𕄅͡N* ? z-S ?[|zz{9-Y?-^t?.˪c`?. hN?.~m=݆?.r-χ?/x ?/}?/ </ dfge$0!sW0"`R0#XN0$nJ1%Qfe)aC1'ȕ`JKG1( •U 1)I 2*= 2+3 ē 2-,ȓ 2.$͓ 3/ѓ 30ԓ31~֓42u ٓ i~}s44mۓ՛'45d!ޓ̛$46\$ ě"57S' 59 gik8*$!o5;-'  !5<1+6>4.6@726B:56D>96G@<6L@@6Q@D6V?S  Ad  JŭŨC787=Ė"$#=}ڡ|ڡ{١wyءog#&$wנ\Vku֠KFbtՠ;9YrԠ/1PqӠt+HoѰ@ @mа? 7lΰ? /jͰ? 'i˰? !h˰? 8po-Wpon@ ߕ/ ѕ      /Õ% %%%~&k&X&,*) *'i&C'H kt ^"ik'D  ?  'A ?  (>?  (;? (8? (5? )tuvoQwuvϑ? )!? )|? )xs? * g#j? *V'b? *H+Z? *:/R? +{,2K? +j6C? +VԐ:;? +r3670 76DՐ>3? , B,7? ,"F':? , J$A? |,𕄅͡N* ? z-S ?[|zz{9-Y?-^t?.˪c`?. hN?.~m=݆?.r-χ?/x ?/}?/ </ dfge$0!sW0"`R0#XN0$nJ1%Qfe)aC1'ȕ`JKG1( •U 1)I 2*= 2+3 ē 2-,ȓ 2.$͓ 3/ѓ 30ԓ31~֓42u ٓ i~}s44mۓ՛'45d!ޓ̛$46\$ ě"57S' 59 gik8*$!o5;-'  !5<1+6>4.6@726B:56D>96G@<6L@@6Q@D6V?S  Ad  JŭŨC787=Ė"$#=}ڡ|ڡ{١wyءog#&$wנ\Vku֠KFbtՠ;9YrԠ/1PqӠt+HoѰ@ @mа? 7lΰ? /jͰ? 'i˰? !h˰? 8po-Wpon@ ߕ/ ѕ      /Õ% %%%~&k&X&,*) *'i&C'H kt ^"ik'D  ?  'A ?  (>?  (;? (8? (5? )tuvoQwuvϑ? )!? )|? )xs? * g#j? *V'b? *H+Z? *:/R? +{,2K? +j6C? +VԐ:;? +r3670 76DՐ>3? , B,7? ,"F':? , J$A? |,𕄅͡N* ? z-S ?[|zz{9-Y?-^t?.˪c`?. hN?.~m=݆?.r-χ?/x ?/}?/ </ dfge$0!sW0"`R0#XN0$nJ1%Qfe)aC1'ȕ`JKG1( •U 1)I 2*= 2+3 ē 2-,ȓ 2.$͓ 3/ѓ 30ԓ31~֓42u ٓ i~}s44mۓ՛'45d!ޓ̛$46\$ ě"57S' 59 gik8*$!o5;-'  !5<1+6>4.6@726B:56D>96G@<6L@@6Q@D6V?S  Ad  JŭŨt8mk@ic08R& jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2d#Creator: JasPer Version 1.900.1R \@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP P߂H oi\M&^d+6r)3BP1h(3 >|D%֧9w?G-NEщ|D%֧9w?G-NEщ|D%֧9w?G-NEщJ.ړG!+j65MY  H m*%&ie6YY'3ͫW㴺'jU1B9Z_UT x!{$-2dYY6 q,=@N,xyM MA V-Ϗ\mRrTM ǔJ.ړG!+j65MY  H m*%&ie6YY'3ͫW㴺'jU1B9Z_UT x!{$-2dYY6 q,=@N,xyM MA V-Ϗ\mRrTM ǔJ.ړG!+j65MY  H m*%&ie6YY'3ͫW㴺'jU1B9Z_UT x!{$-2dYY6 q,=@N,xyM MA V-Ϗ\mRrTM ǔ\LpGfMsj<8^n 'UXd bGu߁SU^SDxG|g \LpGfMsj<8^n 'UXd bGu߁SU^SDxG|g \LpGfMsj<8^n 'UXd bGu߁SU^SDxG|g Sc>]S׵IŁD,9."O;, d"0 ܃ 2` ^3 w5fȪk4/_jf9EJEQvqHu6j0 >.kxB y.W `ֹpda2z) $Kbıa}qפNۦzx@ymCo1ڼ>vjRnrӨmf DԺlPxT4mąWip IN|Yh[+~Tt$k_McD[Z(("BԚU6̧[y/Hyy^BYY bSt e9{+t~UD'F5"leV!&׮Z}R9 ef,)@/֔ܞ$Ѱ_OtR B<2eq=l<]feCvpnt-eU pcRTK.=4ܙ'j|w^EG=&gvfdžH?%O,]ہɒt}Ox?!b͒vXO\Houx̻uO@eAvt̝ڷ^9qNt2C#sut\>hC6u6xou'T{x.fx}zrqu3oS\Ӯ'>g3===$UtŒrk . ޻b]O&)'WAZP$si4vsA)Wse\갻 6AO=I}ݙfz5#"G>NySn㲛4|fplOk[M 'CmAš=X=npmDBN0 8ș\ Ilվ}elEž,9,Aԧ9#t׻qqj(E @H>Sc>]S׵IŁD,9."O;, d"0 ܃ 2` ^3 w5fȪk4/_jf9EJEQvqHu6j0 >.kxB y.W `ֹpda2z) $Kbıa}qפNۦzx@ymCo1ڼ>vjRnrӨmf DԺlPxT4mąWip IN|Yh[+~Tt$k_McD[Z(("BԚU6̧[y/Hyy^BYY bSt e9{+t~UD'F5"leV!&׮Z}R9 ef,)@/֔ܞ$Ѱ_OtR B<2eq=l<]feCvpnt-eU pcRTK.=4ܙ'j|w^EG=&gvfdžH?%O,]ہɒt}Ox?!b͒vXO\Houx̻uO@eAvt̝ڷ^9qNt2C#sut\>hC6u6xou'T{x.fx}zrqu3oS\Ӯ'>g3===$UtŒrk . ޻b]O&)'WAZP$si4vsA)Wse\갻 6AO=I}ݙfz5#"G>NySn㲛4|fplOk[M 'CmAš=X=npmDBN0 8ș\ Ilվ}elEž,9,Aԧ9#t׻qqj(E @H>Sc>]S׵IŁD,9."O;, d"0 ܃ 2` ^3 w5fȪk4/_jf9EJEQvqHu6j0 >.kxB y.W `ֹpda2z) $Kbıa}qפNۦzx@ymCo1ڼ>vjRnrӨmf DԺlPxT4mąWip IN|Yh[+~Tt$k_McD[Z(("BԚU6̧[y/Hyy^BYY bSt e9{+t~UD'F5"leV!&׮Z}R9 ef,)@/֔ܞ$Ѱ_OtR B<2eq=l<]feCvpnt-eU pcRTK.=4ܙ'j|w^EG=&gvfdžH?%O,]ہɒt}Ox?!b͒vXO\Houx̻uO@eAvt̝ڷ^9qNt2C#sut\>hC6u6xou'T{x.fx}zrqu3oS\Ӯ'>g3===$UtŒrk . ޻b]O&)'WAZP$si4vsA)Wse\갻 6AO=I}ݙfz5#"G>NySn㲛4|fplOk[M 'CmAš=X=npmDBN0 8ș\ Ilվ}elEž,9,Aԧ9#t׻ñuހ0߅pJӫ # uN &5kjqtIg0Pei@E#E`>fnTSωJU;E8C>nˏh#ǽσEd0:Q3'q9P?nf"PJGrM@siFˎ\IxR,˷ΟAoIOCYŸ%gEU2J7!4# D30:h 2sܝΞ\[Aq)^YYU| u;~f8< wDsD`;g0U!D_Xv߼ ˴+WЍN׺N5SjQ$Oחe_ƶuyښ؊3 ePLrĠ޲yPFl`#X_4rC]XrA7%ᗢd-{Y*Ex3u)dg$7`p},*GMMNDjԦwcFaܡ0m'rɷ D\p|U,/9i5-Dęa*nJ7Z 8F[DE.DMѕ8\=7w"I v9"ʞ,X@ _#&_ڒ[)K&3cB? Չ@©\c|o4|׽qlj=ågJVԁpS5=f{Sad1 ߦꏖTGkKz5I:&oQ7 )l27R"qx 6IBJL Q V^ hr}`M%0>02N(&i??{DZ%Z=s:S_clWM[_)yط B&.f]H.@Gԁl)Tʜ+K3<+{+TG(,6. 5NJG͉(p<z<7IJՆlr[Ixg ,)_Z\3둑CN/DpX`;I.GZUAwڑկ7(<)g]d|UzJRXR"&.^8G0`{D tksç] &#~閗35x1@)r:Ar ɏndE LI[TY N̊!QYfVB X v ӣ*<Hѣ3s])0oW E854dslD9z(*A\>-0Aɳ^~NqodiB?~k4W[+e%C_ N (WnUqVU-mHFOүOQ };.e//?i-C ,Nǡ;g3#3qfBfnTSωJU;E8C>nˏh#ǽσEd0:Q3'q9P?nf"PJGrM@siFˎ\IxR,˷ΟAoIOCYŸ%gEU2J7!4# D30:h 2sܝΞ\[Aq)^YYU| u;~f8< wDsD`;g0U!D_Xv߼ ˴+WЍN׺N5SjQ$Oחe_ƶuyښ؊3 ePLrĠ޲yPFl`#X_4rC]XrA7%ᗢd-{Y*Ex3u)dg$7`p},*GMMNDjԦwcFaܡ0m'rɷ D\p|U,/9i5-Dęa*nJ7Z 8F[DE.DMѕ8\=7w"I v9"ʞ,X@ _#&_ڒ[)K&3cB? Չ@©\c|o4|׽qlj=ågJVԁpS5=f{Sad1 ߦꏖTGkKz5I:&oQ7 )l27R"qx 6IBJL Q V^ hr}`M%0>02N(&i??{DZ%Z=s:S_clWM[_)yط B&.f]H.@Gԁl)Tʜ+K3<+{+TG(,6. 5NJG͉(p<z<7IJՆlr[Ixg ,)_Z\3둑CN/DpX`;I.GZUAwڑկ7(<)g]d|UzJRXR"&.^8G0`{D tksç] &#~閗35x1@)r:Ar ɏndE LI[TY N̊!QYfVB X v ӣ*<Hѣ3s])0oW E854dslD9z(*A\>-0Aɳ^~NqodiB?~k4W[+e%C_ N (WnUqVU-mHFOүOQ };.e//?i-C ,Nǡ;g3#3qfBfnTSωJU;E8C>nˏh#ǽσEd0:Q3'q9P?nf"PJGrM@siFˎ\IxR,˷ΟAoIOCYŸ%gEU2J7!4# D30:h 2sܝΞ\[Aq)^YYU| u;~f8< wDsD`;g0U!D_Xv߼ ˴+WЍN׺N5SjQ$Oחe_ƶuyښ؊3 ePLrĠ޲yPFl`#X_4rC]XrA7%ᗢd-{Y*Ex3u)dg$7`p},*GMMNDjԦwcFaܡ0m'rɷ D\p|U,/9i5-Dęa*nJ7Z 8F[DE.DMѕ8\=7w"I v9"ʞ,X@ _#&_ڒ[)K&3cB? Չ@©\c|o4|׽qlj=ågJVԁpS5=f{Sad1 ߦꏖTGkKz5I:&oQ7 )l27R"qx 6IBJL Q V^ hr}`M%0>02N(&i??{DZ%Z=s:S_clWM[_)yط B&.f]H.@Gԁl)Tʜ+K3<+{+TG(,6. 5NJG͉(p<z<7IJՆlr[Ixg ,)_Z\3둑CN/DpX`;I.GZUAwڑկ7(<)g]d|UzJRXR"&.^8G0`{D tksç] &#~閗35x1@)r:Ar ɏndE LI[TY N̊!QYfVB X v ӣ*<Hѣ3s])0oW E854dslD9z(*A\>-0Aɳ^~NqodiB?~k4W[+e%C_ N (WnUqVU-mHFOүOQ };.e//?i-C ,Nǡ;g3#3qfBUԀq ȓPPTVx hXġǦ-کN'}2e[ Y;ȑH{S?ZMFKZƒ|h@N]@F枹gQelh94cJq-3p:J73Ѳm5Rİs%o+ع݇[z҂.{%Q-\LJ5l S_`%=M|%ՙx;\\\4nY?jHA)>AՓԠN=Dp -3@ssY,f-%xYN :S+ I9_Qt?뎠iq[+B?ժSge4= p(.l79B~?7Yi.KE#(+;4u_,A;#IE3XnD荽_W5gU:LSQDeΔN=ABGDՆ"lV=B%FF"RVv_1Uu՟\o'-pI< '%jS*Rv[i/? V&ubk|.ގ2EQH PR<KV0;"~LRUpsu +QYLo;=8Z!hyk]U2$Fs&?UF+d#܁shm. 1dVM-\T xt_Ba "(1Y@@ʙ$ɾUn7eYN#z$ҼVm-^1qgzw{ExE5? rLd +iQq|5/Ph M*B6w^qB蠜Ϙ9ʣy$NM)Cǡk>OqzTT&j-vh€~2eKqPn-pz'C6.#%,1^\ӸPaLniRZKqCw1DmD% پ0AqAGulB<ħv2@?v )bB[3?daFP FyufE:6FJ0`3hUy"9ƮK 8O3u֌G |`jpȿTjI ^|@0)D:,F^[#.ԝ<禰`={yڍ@>=Kb„I/VpChrW "r妉H@`0a j1_n00(Z"5j(o6`t$luP3y҂dH1[pgIcNŸ9 K"ZϣĒRe7vj] DOE0Dʂ˚FP5 e;Gpe4=Qvʈ]RT.-ތ^Zs}(ɉ !m!,5NojO+.pl2TI @*;YFk`CRw@ג_ pq}0vr " n+fCHFsD͈6BCrwFJ0~9`d*qx_j2J 7o[ k.K= Ie !V9!5:V걫c*ɰz6l߶Bgık~ J&Bd:Ꮂ*9bRIQQ |֕|iY[|֧p 1㜄/7Ǔ0E:}N&݋ITd_ͮ+* zd78^ڴSҸ)hm euE85gpUUM\r-mHM3"ue%MT$F4= ~:5tڜJdb4cq;g?ъnM0w]zŝeE%nc&C.7(`q#F-&&)V VEE/Br+ gl[&9O۩߶n~Ov >UԀq ȓPPTVx hXġǦ-کN'}2e[ Y;ȑH{S?ZMFKZƒ|h@N]@F枹gQelh94cJq-3p:J73Ѳm5Rİs%o+ع݇[z҂.{%Q-\LJ5l S_`%=M|%ՙx;\\\4nY?jHA)>AՓԠN=Dp -3@ssY,f-%xYN :S+ I9_Qt?뎠iq[+B?ժSge4= p(.l79B~?7Yi.KE#(+;4u_,A;#IE3XnD荽_W5gU:LSQDeΔN=ABGDՆ"lV=B%FF"RVv_1Uu՟\o'-pI< '%jS*Rv[i/? V&ubk|.ގ2EQH PR<KV0;"~LRUpsu +QYLo;=8Z!hyk]U2$Fs&?UF+d#܁shm. 1dVM-\T xt_Ba "(1Y@@ʙ$ɾUn7eYN#z$ҼVm-^1qgzw{ExE5? rLd +iQq|5/Ph M*B6w^qB蠜Ϙ9ʣy$NM)Cǡk>OqzTT&j-vh€~2eKqPn-pz'C6.#%,1^\ӸPaLniRZKqCw1DmD% پ0AqAGulB<ħv2@?v )bB[3?daFP FyufE:6FJ0`3hUy"9ƮK 8O3u֌G |`jpȿTjI ^|@0)D:,F^[#.ԝ<禰`={yڍ@>=Kb„I/VpChrW "r妉H@`0a j1_n00(Z"5j(o6`t$luP3y҂dH1[pgIcNŸ9 K"ZϣĒRe7vj] DOE0Dʂ˚FP5 e;Gpe4=Qvʈ]RT.-ތ^Zs}(ɉ !m!,5NojO+.pl2TI @*;YFk`CRw@ג_ pq}0vr " n+fCHFsD͈6BCrwFJ0~9`d*qx_j2J 7o[ k.K= Ie !V9!5:V걫c*ɰz6l߶Bgık~ J&Bd:Ꮂ*9bRIQQ |֕|iY[|֧p 1㜄/7Ǔ0E:}N&݋ITd_ͮ+* zd78^ڴSҸ)hm euE85gpUUM\r-mHM3"ue%MT$F4= ~:5tڜJdb4cq;g?ъnM0w]zŝeE%nc&C.7(`q#F-&&)V VEE/Br+ gl[&9O۩߶n~Ov >UԀq ȓPPTVx hXġǦ-کN'}2e[ Y;ȑH{S?ZMFKZƒ|h@N]@F枹gQelh94cJq-3p:J73Ѳm5Rİs%o+ع݇[z҂.{%Q-\LJ5l S_`%=M|%ՙx;\\\4nY?jHA)>AՓԠN=Dp -3@ssY,f-%xYN :S+ I9_Qt?뎠iq[+B?ժSge4= p(.l79B~?7Yi.KE#(+;4u_,A;#IE3XnD荽_W5gU:LSQDeΔN=ABGDՆ"lV=B%FF"RVv_1Uu՟\o'-pI< '%jS*Rv[i/? V&ubk|.ގ2EQH PR<KV0;"~LRUpsu +QYLo;=8Z!hyk]U2$Fs&?UF+d#܁shm. 1dVM-\T xt_Ba "(1Y@@ʙ$ɾUn7eYN#z$ҼVm-^1qgzw{ExE5? rLd +iQq|5/Ph M*B6w^qB蠜Ϙ9ʣy$NM)Cǡk>OqzTT&j-vh€~2eKqPn-pz'C6.#%,1^\ӸPaLniRZKqCw1DmD% پ0AqAGulB<ħv2@?v )bB[3?daFP FyufE:6FJ0`3hUy"9ƮK 8O3u֌G |`jpȿTjI ^|@0)D:,F^[#.ԝ<禰`={yڍ@>=Kb„I/VpChrW "r妉H@`0a j1_n00(Z"5j(o6`t$luP3y҂dH1[pgIcNŸ9 K"ZϣĒRe7vj] DOE0Dʂ˚FP5 e;Gpe4=Qvʈ]RT.-ތ^Zs}(ɉ !m!,5NojO+.pl2TI @*;YFk`CRw@ג_ pq}0vr " n+fCHFsD͈6BCrwFJ0~9`d*qx_j2J 7o[ k.K= Ie !V9!5:V걫c*ɰz6l߶Bgık~ J&Bd:Ꮂ*9bRIQQ |֕|iY[|֧p 1㜄/7Ǔ0E:}N&݋ITd_ͮ+* zd78^ڴSҸ)hm euE85gpUUM\r-mHM3"ue%MT$F4= ~:5tڜJdb4cq;g?ъnM0w]zŝeE%nc&C.7(`q#F-&&)V VEE/Br+ gl[&9chewing-editor-0.1.2/rc/chewing-editor.ico000066400000000000000000011326601504106013400204350ustar00rootroot00000000000000  B% (R% (x`` 8@@ (B00 %W(( h|    hHPNG  IHDR뼮% IDATxyձsT &%&1 *(  >wF'&nAq=.DILT$FP (w3sg1ANS3]]s:u,<E$v (%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨PcaH Omy, 0 D] 3a+b̅[ÀwY }k!B֙Ǒz4Z'6Qioȁq@ϰ19pѰ3> . 6NֱZmROÏ`P* nU=\7χm "Nئ)~ ܑakaif8hؖ ܟm⇺ {TZ$^ p^؆ o~ئ)~{^eX2Dm=:l- r x3̊ x0 ԿY_VBv@Z;o-h?,/-Abuլ e4myOπ6KKk#4L/Rd%;y)sM1?C6MCf//f᳅5̓zO7:'›=f^f)~Iy{GW{3` a1a'JȻ*M2mPϫw=ݬ>,vJ xp4; |jrx bhΆmw~}'{2Z?;_ɻ m-;:hҴj$7^)lT~iV;Qa&qXa!AEl oZ/[] ޿ ˬm F{;|5C[Ck98;̊wL؆`d6IMo ܽ;5qS|owLfuI6IM~8E&ϴ|۸~ZT#fG?mR,M!uCq$ [q2 2:u6ut Td\[v [^6,tE:@53y0r{(!V<> (,^ѷ2FCs0 F<{/.}sA"rCtX=3-pBŸ_A`^ 6wuu'$״.Y1pKUP%7>)ޭ2D۰Els0.?iTcU!.Od|88v{,q5 I.R=]E~~a[&@$xwb9D1E߮=n{́#BԳ#Fİe2WoNH9 ;V-Z+%ĽZak6 2B׀wmؖɠ@)h)<_a~` eq2-C&`߰-AR4\h)Ӥ'`A@V7L@EHU^m@fa[&I|Aӭ: kXOeE0In^5ԝn[핰\< .7ATT}]@ `~Zv4C!9?lP&5dn}l@$&kuphYV} V'Jkw^UŝOpmv  z}Z GBVf-=nD3 8VIEbȼjw6l;[[Sܹ)D3mC#@ )p= wi-#d5#)d2ƀ ,5ᏃE }شDoGtf86bJL/^WSsR^'8$Bt՝j-cجb>ĕV2d:zN̛a+_=v]w=3# [rkڏ?4iw&o|2.(͏΁XvQ̐mT!!W˛L@]GÇal~0b!')$?$+u/1SY:q.iӂhа$B@l~[Ui 媣 a5$v.uS tOak4d 1 )g,uEīr1c)Ĺ"fhiP::o|C/-3ؿ(c}ؚzLOH5 Cj f r=_"\QrUK( m:Ǔa`TvXwKU>b+R'`Th0ʌ< [EnY6A&%pVئ)FQ|2 B[Pe8!aI; jUM'fbljhʴog [Afp000Q5 85 vaxۅG ka<`uc{ :'v }P~X{|p5xN^ %CW:bA@IsՍj3{!;c{`p W^5 RwiSFt|lyx+\r1tzU5:k֠ Z4'ϝGACρu1b9{ǁ#!z|lGA@s9|ʁb`ǰdb=1= |SPZn03 n6C2 FS!\B%sЯ[0cv$\,zJ1|.0`oR߇ffCne2/X2+<+m&5 ? ˧ =[`oCc o/r.5+Wf;`k: +€ TJ-F[C(ֹ9 !]Xd: m+η $%ƽ¶Rh4=g^_F2Sh"ЗxAGT[؆*#rE ăٌ֡#me⍆츀B Lj/-UZF@Kʌ2S!Brŝn˅RkeA>l8Rn(U!VB=GRnЕ-EreOc6{+d`9\pw7 Av¶THy"y7ܝ%BmӡHp_(<ς¶RrԷ 3xfez axZQɸ!{B00ZnPk=T:I~[w`)L݆^%L ? 6l#/Q7Ɍ_Cbg m+w,d (dC=6H M"Jg=+m. : - xp~DwPa9$wֆm'!l@<Y޹f⎄lW!chwLc#$:2vd/M'q3|Ҡг!%0QBـ{#Q[ #l+M; :_m@&0ħMmD`-qil?ې<,l+Mkʔqc5\ɫ%4p:^pj( cq Ȝ=v GRX ixhf%d4r |^? ڼ5H[KeU {4dXCi{p78&E-x[>BoZAyry0 tDHDtwg{9X px-cc[f>pM8^gCf LkZؖ(a"3m} 2;n~}\ %}X"0 0%Ld6&5Hmh])%p/'?ܠyʂ+Տ̆GoT~|\ u{ o@*gc!k PF9z%v;i b ;ߘ Z=IpѓE\*b ypy!lDL%Rd&®?xr@ħ^.? ܝ J5Z6ܼZO6(h:bs!2[ ~s"] ]MY#=<m*:lUT d^:n%Y??4|;8~=tW5XEQ a#7Nn@M|R hYpK8e*0S\X7>?,; ^@{ps\S7|m.\:<3٘b\*܅pѐ X nE %93ȯ NU/u % 4|76,ySC{Y B}|\LÅ2)@ {`u g,,O&`sJ*@nr#`sM4XMpb~%ζWGvj}z?[ %9a+&G|W|z][~:??nNw>>/!փ]n@%a+"K \ѣu!Ē2t{KI$ٞ¬W[cI||lq'J8Ǟł;] a+=bWcVF0'`ׇMQ* f;akMݰ "jp\{? ~/wϲVM7XɗskZ ܗ>?QKa&rm+1W!vō87:@.p +߈ %0/LxJYm p!vN 7ү[3֮?J`%/c8ir}L ©kJJ3N>Fk,g³Í{+dWv)mI)R-% ~0!L1dx`oy/|68R|C kإ|nDZ+t`v@!>[Y;w8vF2ޗ/bC qKEkƍO`2,@Jj G:(b݆z@8_YC$$eHz{:cö8ėɗ[$ =̋q\|#e9HnSU| J)9UˀO&a^n(8g_x6N86> Vϰ&rfB _fzC~ z?m^  hM2`\=@& 闁ߙ*FgC\$6G_Ϳ `Z]Zo{`THv i4mCnJ :/HLJY֠w$R ^` _T^B\!"Ri~ZSmH"e/wy`@@M4<k }``Y_1, ZCUu%njaq.[n p& +,`\%!#MCۙ',i;pM rzˍ΁T`a/%Sx^ \3ﴓyas4w_B$\ \!ƀcNfiz<1`M+w'O0]j$j% mDvpJ@ \Sq2a2aL@Az|AW`O1{yVIQ/-1Ag({Ͽ `m `=.ŐXN:Ua+Yc- ,=o5y%W`T>Yg%W`x·*APN J'[IJ &d?5T9!kˀ+(\p@rH( x?# :o"5vgճ 5$WY0@OU7`; w<0H t5DAߪ]2J i.;+D6p:(c| e2Z@xH]\8}#1>@sg!S&.B$Cry` ouc@93*,U/b x7 CN@ v# j@Y Ʈ?`.R ѲˎLVɰ݂;X$_3%7+Tn[x <v JCe}Լ ,zm76,u|-؆Aa`ܭ* ӠiGm`VV}Q`\/|cwlV҂2dGHI͠`P0k,XU2$NO%>bG/N r[Ϯ0`K89׀@}ì2)箂JD_Sh إ=JĮrS@j6T#5=`@G4l$,\ F7/۹l `:@4f@J`٥Rȴ㓻 ~[ 0*இ2c+|оZhp2ԼInƠe`g5HTAiwWvnYG1;=$5/o2 ,w& ۬ ُ )ӭC2K (;8kdd,Լɼ])&Xs \CRxl&8A[XCsM&nҀ>Y6],pJu54 뤖G ˀWRFvKBR&}ANwmܕw/X 9xO ޔ^g8s t> c%߽VE"LX :!v`mr } VZ[M,fBm6ZHߕbMZ=mrD`= v'X@"r#u` 5x` `b_/ \O)",{ )p$0JoI/9q7Mliiu;:lLv늯^L;~"uNeא]< J1S+~|JUbALЦ&3Y|ߡm h_) sQĮG˗j wUsĎ|*:OA W pv`4IElL7T ]}l !|n+5])EU`<#k"NJNW~.\ZRQb=5leGLU%tak1JTGvp8+P䩹xiK:|*o"O|XakFfV 5tP;36Q1A|:jDī5RPuP|V0V+`V&*&7U L@ȵo6+q=]~ `֌~`+<8o/)p?;~/a .}ڰ`uIru%Cq`҆ċE)_ă/%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨P@Q":E0%¨PONKIENDB`( @**KKKMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMJJJ|||gggKKKMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMIII___AAA QQQ]]]DDD SSSWWWDDDSSSSSSDDDSSSOOODDDSSSKKKDDDSSSHHHDDDSSSDDDDDDQQQ@@@DDD NNN===CCC JJJ999CCC GGG555CCC CCC111CCC@@@...CCC===***###$$$$$$'''''')))++++++...//////222222444666666;;;===???CCCDDDHHHKKKKKKPPPQQQTTTXXXXXX]]]___```eeefffiiimmmmmmrrrtttvvv{{{{{{???BBB999'''+++yyyBBB666###999}}}BBB222111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111222%%%333 @@@AAAaaa ///GGGAAAuuu,,,PPPAAA}}})))\\\AAA###%%%hhh@@@***""" MMMjjj@@@222 @@@::: @@@CCC???LLL???XXX??? ddd???qqq >>>~~~ >>>>>> ===%%%===***===000===555===:::<<<@@@||| <<<GGG###vvv---<<<PPP***rrr111;;;000lll777;;;ggg(((;;;bbb;;;^^^:::~~~ZZZ''':::yyyVVV444|||:::tttQQQDDD :::}}}oooNNNWWW 999{{{kkkJJJjjj 999yyyfffFFF}}} 999vvvaaaAAA 888rrr]]]=== 888lllYYY999 888fffTTT666''' 888aaaPPP222666 777[[[LLL---EEE 777UUUGGG***XXX 777YYY MMM&&&kkk 777"""~~~ 666 666 +++AAA@@@@@@@@@@@@@@@===666 ???666SSS((( DDD555%%%rrr''' GGG555(((kkk''' KKK555111   ---ggg''' NNN555$$$ 111aaa''' RRR444%%% 888[[[''' UUU444%%% AAA''' XXX444%%% III''' \\\444PPPCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEE;;; 999EEEDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCMMMRRR''' ___333 [[[''' ccc333!!!ccc''' fff333///lll''' iii222===(((uuu''' mmm222KKK888}}}''' ppp222YYYGGG''' ttt222gggWWW''' www111wwwfff''' {{{111vvv''' ~~~111|||''' 111www''' 000 rrr ''' 000 nnn''' 000iii''' 000###eee''' ///444!!!```''' ///(((\\\''' ///AAA111XXX ''' ///DDD111SSS$$$''' ...GGG111OOO(((''' ...JJJ111KKK000''' ...NNN111FFF888''' ...QQQ111BBB@@@((( ---TTT111>>>GGG'''  ---XXX111999[[[^^^^^^^^^^^^___KKKTTT___^^^^^^^^^^^^^^^___DDD???___^^^^^^^^^^^^^^^```AAA---[[[111555,,,^^^111111,,,bbb111,,,,,,[[[,,,(((,,,SSS///111111111111111111111111111111111111111111111111111111111111111111111111111111111 ,,,111111111111111111111111111111111111111111111111...###+++(((ppp+++***+++***+++********* *********+++***222!!!***<<<---***EEE>>>111OOOOOO zzzpppXXX```((( bbbrrr''' kkk''' uuu444777666666666666666666666666777555777666666666666666666666666666666666666666666666''' ~~~HHHMMM''' NNNTTT''' NNNUUU''' NNNVVV''' NNNXXX''' NNNYYY'''  NNNZZZ((( NNN[[[$$$ NNN]]]MMM)))+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"""&&&++++++++++++++++++,,,,,,+++++++++++++++++++++++++++++++++++++++++++++++++++++++++,,,NNN^^^555NNN___IIINNNaaaZZZ NNNbbblll'''NNNddd}}}000NNNeee'''888LLLggg222aaa(((***************************************'''kkkiii ===kkkIIIlllVVVnnn fffppp000wwwrrr@@@sssTTTuuu( **SSS AAAddd JJJDDD666VVV???@@@666QQQ@@@<<<666LLL@@@999666GGG@@@555666DDD>>>222666BBB:::...666@@@777+++666>>>444'''  !!!555<<<111$$$ooo555;;;--- 555999 gggiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiikkk888*** """555777SSS'''$$$444666\\\$$$'''444555ddd!!! iii~~~}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}sss444444mmm444222uuu 333111~~~ 333000 333/// 222...$$$ 222---,,,222+++333 222***=== 111)))III JJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKGGG111((( UUU aaaCCC111'''```nnnJJJ111%%%QQQfffeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee)))XXXNNN000$$$```RRR000###sssWWW000"""dddffffffffffffffffffffffffffffffgggeee$$$000!!! <<</// }}}???///xxx ???///rrr---???///mmm===???...hhhNNN???...~~~ccc```???... ^^^ttt???...YYY???---SSS ???[[[|||zzzzzz{{{999---NNN*** ??? zzz---JJJ$$$AAA??? |||,,,FFF''':::??? ,,, BBB,,,777??? ,,,""">>>333??? ,,, :::;;;??? +++rrr333666666666666666666666666666666666666666666666666666666666777000 777666666666666666666666666666666666666666666DDD666CCC??? +++VVV222KKK??? +++jjj///RRR??? +++{{{,,,+++ZZZ??? ***:::'''bbb??? ***HHH###jjj??? ***VVVsss??? *** ggg|||??? )))xxx??? )))??? )))!!!??? )))tttuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvvoooQQQwwwuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuvvv??? (((555??? (((888??? (((;;; ??? (((>>> ??? '''AAA kkkttt ^^^"""iiikkk'''DDD'''HHH&&&CCC&&&,,,***************************************************))) ******************************'''iii&&&XXX&&&kkk%%%~~~%%%%%%%%%    ////// @@@ ??? 888pppoooooooooooooooooo---WWWpppoooooooooooooooooooooooonnn??? !!!hhh??? '''iii??? ///jjj??? 777lll@@@ @@@mmmttt+++HHHooo///111PPPqqq;;;999YYYrrrKKKFFFbbbttt\\\VVVkkkuuuoooggg###&&&&&&&&&&&&&&&&&&&&&&&&$$$wwwwwwyyy{{{|||}}}CCC777888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888777==="""$$$$$$$$$$$$$$$$$$$$$###===(` **<<<000666777000666333000666000000666---000333)))000000&&&///---###DDD333///***JJJ///###:::&&&MMM///HHHvvv###QQQ...OOO BBBcccaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ...WWW... ___... hhh--- qqq --- zzz  ---  ---  ,,,  [[[,,, !!! (((rrr,,,333RRRPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQHHH vvv+++yyy+++^^^QQQRRRRRRRRRRRRRRRRRRRRRSSS(((+++###+++000***@@@***RRR***eee***zzz)))|||......///)))vvvYYY)))qqqyyyzzz___)))fffhhhhhhhhhhhhhhhgggvvvlllqqq___(((gggPPP___(((yyybbbrrr___(((---000000000000000000000000000000000000000000111)))111000000000000000000000000000---]]]qqq___'''xxxYYYqqq___'''TTTqqq___'''OOOqqq___'''JJJ qqq___&&& EEEqqq___&&&@@@qqq___&&&<<<qqq___ &&&uuu[[[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\^^^777SSS]]]\\\\\\\\\\\\\\\\\\\\\\\\[[[ppp999qqq___ %%%&&&555###qqq___ %%%&&&111)))qqq___%%%&&&------kkk~~~ZZZ%%%&&&))) 777;;;;;;;;;;;;;;;///:::;;;;;;///$$$'''&&&$$$""""""$$$FFF$$$&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'''###'''&&&&&&&&&&&&&&&&&&***$$$######%%%###%%%"""***###"""  000222000YYYhhhJJJ:::>>>sss```BBB''')))))))))*** '''))))))))))))))))))&&&jjjqqq___JJJ///111qqq___SSS444 777qqq___]]]444 888sss```ggg444 999<<<FFFmmm 222qqq444 :::[[[{{{444 <<<mmm444 ===~~~222 ???@@@BBB"""CCC=== KKK(@ @**kkkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmlllnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmlll,,,&&&***+++***...(((***,,,%%%***)))""""""[[[]]]```bbbeeegggjjjmmmooorrruuuwwwzzz}}}???)))&&&hhh)))$$$666###qqq)))<<<[[[ """IIIHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIII&&&)))CCCfff(((JJJrrr(((SSS((([[[(((ddd hhh]]]'''hhh '''>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>???))))))''' 444===>>>>>>>>>>>>???(((''' EEE&&&|||WWW&&&vvvkkk&&&~~~%%%~~~%%%!!!\\\%%%cccKKKLLLLLLIII''' ^^^%%%JJJ---^^^$$$+++***************************%%%******************)))???444^^^ $$$ ;;;^^^ $$$ ...BBB^^^ $$$;;;{{{JJJ^^^ ###HHHvvvRRR^^^###]]]CCCEEEEEEEEEEEEEEEEEEEEEEEE??? EEEEEEEEEEEEEEEEEEBBBqqqZZZ^^^###)))^^^lllddd___###---aaagggNNNEEEmmm"""///bbbbbb""",,,WWW\\\"""www $$$$$$$$$$$$$$$$$$$$$!!!$$$$$$$$$$$$!!!SSSWWW"""```CCCRRR bbbVVV\\\ 222kkkgggMMMyyyuuu|||___|||+++LLL^^^AAAsss^^^AAAsssvvv^^^____________```QQQ ###___aaa777NNN```____________^^^BBBttt+++DDDvvv>>>%%%!!!"""!!!'''EEExxxOOOGGGyyyaaa FFFzzz(0` $**UUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUUpppkkkUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUUU###'''  ''':::}}}'''IIINNNNNNNNNNNNNNNNNNNNNKKK{{{WWW&&&222FFFvvv<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<===&&&&&&:::SSS|||qqq&&&AAA___wwwkkk%%%IIIkkkrrrfff%%%RRRzzznnnaaaqqq%%%666PPPiii\\\888%%%dddWWWGGG222666666666&&&$$$___RRRYYYqqq$$$ YYYNNNmmmsss$$$###fffIIIsss %%%$$$DDD>>> sss666 ###@@@ qqqsss<<< ###<<< sss;;; ###ggg$$$'''''''''''''''((("""''''''''''''+++888sss;;;###WWW333sss;;;"""jjj///sss;;;"""|||,,,sss;;;"""}}}(((###uuu<<<""" ###%%%eeejjjBBB"""{{{ !!! ###!!!!!!gggvvv!!!iii~~~}}}nnnooooooqqqLLLPPPrrr222jjjoooooonnnttt<<<{{{nnn |||uuu<<<)))+++SSS+++(((+++ %%%---RRRKKKJJJhhh... ,,,oooppppppppppppppppppppppppppppppppppppppppppppppppooozzzssseeeddd((P **TTTKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLJJJfffLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKKKSSS"""&&& SSS{{{{{{~~~"""%%%%%%((((((((((((((()))===%%%+++)))888777777777777777777777555%%%555$$$<<< $$$EEE///$$$<<<KKK$$$ >>>111111111### ###)))###tttuuuuuuuuuuuuuuuxxxxxxxxxwwwuuuuuuuuuttt<<<;;;>>>###777XXX```###>>>[[[{{{???...VVVbbb###HHH$$$&&&&&&&&&&&&### %%%&&&&&&###OOOvvvGGG...VVVeee###111:::pppOOO...VVViii""">>>IIIkkkWWW...VVVlll"""eeeggggggggggggbbb&&&gggggggggeeefffaaa...WWWrrr!!!<<<___aaa111sss mmmeee***}}}888!!!===]]]\\\!!!mmmKKKMMMMMMMMMJJJMMMMMMKKKUUU+++|||:::===>>>999 666222======<<>>AAAAAAAAAAAAAAAAAAAAAAAA???^^^!!!!!!TTT"""!!!999===???BBBDDDFFFJJJ555$$$UUU  ###:::$$$SSS""",,, 111222222222222222333$$$$$$QQQ111BBB$$$OOO888LLL!!!WWWVVVVVVVVVWWWWWWYYYBBB###NNN:::PPP999"""LLL ,,,---------------\\\qqq***...######IIIpppQQQ###ZZZ))) SSS...OOO""" ddd???:::SSSxxx!!!333666;;;SSSwww###222$$$$$$$$$%%%%%%$$$!!!;;;SSSwww###;;;SSSwww!!!III///000000111 111000000;;;TTTwwwFFF333aaa"""000YYY }}}###!!!!!!""""""   555iii222GGGccc%%%aaa888AAAaaacccvvv999QQQpppddd999;;;<<<888<<<;;;BBBbbbRRRQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQPPP___JJJNNN(0 **www444777777666666666666555UUUPPP666888888888888888444wwwKKK"""MMMHHHvvv@@@!!!```KKKDDD...------------ $$$,,,GGG???$$$222BBB;;;JJJ!!!SSSXXXXXXYYY???>>>777 ///***###777333*** """zzz{{{{{{yyyyyy{{{yyy... MMMpppaaahhhppp*** hhhqqq $$$"""###!!!111&&& hhhttt   """""" gggvvv 888!!!999000%%% !!!###SSSHHH{{{fffSSS)))BBB DDDSSSVVVyyy[[["""###  ---!!!YYY@@@BBBBBBBBBBBBBBBBBB@@@QQQPPPZZZ(  **,,,...//////---NNN000+++***++++++~~~ppp|||eee,,,aaammmccc {{{***---...###(((,,,...{{{uuummm000}}}~~~vvvqqqwwwYYY(((kkk<<>>???)))111YYY %%%&&&,,,xxx""">>>SSS """BBB&&&III"""cccNNNVVVzzz000555444555333FFFuuu~~~chewing-editor-0.1.2/rc/chewing-editor.png000066400000000000000000000050711504106013400204410ustar00rootroot00000000000000PNG  IHDRy IDATx^ A '@@q '@@q '@@هqa9sdnItc1iZLDhE@I-ZߤS!jcX& [*Կ[mkkh̝;sur99%;x=;0r" S ,o? e@z;Ȝ >ǯv'!@\Q*ݗ gS\&&8B1@F3 8tɊS:jZh`L*ўѼ(ffdAaN@1Eg TIƓ!`% |}sW3>0iTfÔ +A^>]  cX*G@@: IAH7et2g'`KN;g)z4 - a'T ۰@̋?-ڰbQ #Q}w7 zT~ pxEW1PAG{=g-DNJ@xK!s,KpZ% s/L)PE]`D0qnrT)>ꆧ̙Wl`ww4H)p˙l?}F {:/ /LY;tV՟[Fy(o9FB)_]j  _Q pϴnNRx6'e$5'80P( 20;k%IEO",jQuJ 0~#̬Ɔq rAV ":  ^|Ӹ}_?O5) HJٵ7Πm4aoWwt!ugzXVWҚ6f_iʋRef(H-K@@:;} (А0AF"8>0$z&N=W@o @X0=Ox?er7 0{,tP˫ٝ7i /@P؂3 ҟvI `%L#AWėf&TT%`PL;ٌehEx3k-;@ Hu !`Ld$)B@Etd`L,; #=Ŕt៞m&tUd-`䪏q k>Pț ;;1t95huB HA krxOOÌ&t5ɕN~$̬|װE'׃Bg_xq q ypW#bV_wJG? Br {wJ -`e_ 'zѣ[ [^?_]#z[#Qw-\!%|¥&w"-;OD<c{o=,9t][N{F-BD5ߕp .G`ˁ|Mo\`ܯN@`34͏ o{fAeu~`_>X(9J@ _逆o…EHKPVL4L0 [6=34⎛`+ 5HIZ$dTdF*@#_ZC]o `&޲ dz[ a;δ`~6gknx:3[ O #include "include/config.h" #define VER_FILEVERSION PROJECT_VERSION_RC #define VER_FILEVERSION_STR PROJECT_VERSION #define VER_PRODUCTVERSION PROJECT_VERSION_RC #define VER_PRODUCTVERSION_STR PROJECT_VERSION #ifndef DEBUG #define VER_DEBUG 0 #else #define VER_DEBUG VS_FF_DEBUG #endif 1 VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_PRODUCTVERSION FILEFLAGSMASK VER_DEBUG FILEFLAGS VER_DEBUG FILEOS VOS__WINDOWS32 FILETYPE VFT_APP FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904E4" BEGIN VALUE "CompanyName", "Chewing Development Team" VALUE "FileDescription", "Cross platform chewing user phrase editor" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "chewing-editor" VALUE "LegalCopyright", "Copyright 2016 Chewing Development Team" VALUE "OriginalFilename", "chewing-editor.exe" VALUE "ProductName", "chewing-editor" VALUE "ProductVersion", VER_PRODUCTVERSION_STR END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END chewing-editor-0.1.2/rc/macosx/000077500000000000000000000000001504106013400163125ustar00rootroot00000000000000chewing-editor-0.1.2/rc/macosx/English.lproj/000077500000000000000000000000001504106013400210305ustar00rootroot00000000000000chewing-editor-0.1.2/rc/macosx/English.lproj/InfoPlist.strings000066400000000000000000000000411504106013400243450ustar00rootroot00000000000000CFBundleName = "Chewing Editor"; chewing-editor-0.1.2/rc/macosx/English.lproj/locversion.plist000066400000000000000000000006171504106013400242740ustar00rootroot00000000000000 LprojCompatibleVersion 220.2 LprojLocale en LprojRevisionLevel 1 LprojVersion 235 chewing-editor-0.1.2/rc/macosx/zh_TW.lproj/000077500000000000000000000000001504106013400204725ustar00rootroot00000000000000chewing-editor-0.1.2/rc/macosx/zh_TW.lproj/InfoPlist.strings000066400000000000000000000000531504106013400240120ustar00rootroot00000000000000CFBundleName = "新酷音詞庫編輯器"; chewing-editor-0.1.2/rc/macosx/zh_TW.lproj/locversion.plist000066400000000000000000000006221504106013400237320ustar00rootroot00000000000000 LprojCompatibleVersion 220.2 LprojLocale zh_TW LprojRevisionLevel 1 LprojVersion 235 chewing-editor-0.1.2/rc/resources.qrc000066400000000000000000000001411504106013400175350ustar00rootroot00000000000000 chewing-editor.png chewing-editor-0.1.2/scripts/000077500000000000000000000000001504106013400161035ustar00rootroot00000000000000chewing-editor-0.1.2/scripts/generate_ico.sh000077500000000000000000000003071504106013400210660ustar00rootroot00000000000000#!/bin/sh # require ImageMagick # in order to get sufficient resolution from svg, oversample to 72*16 = 1152 dpi convert -density 1152 chewing-editor.svg -define icon:auto-resize chewing-editor.ico chewing-editor-0.1.2/scripts/lcov.sh000077500000000000000000000035361504106013400174140ustar00rootroot00000000000000#!/bin/sh # Copyright (c) 2012 libchewing Core Team. See ChangeLog for details. # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. DEPENDENCIES="lcov genhtml" for dep in $DEPENDENCIES do echo -n "Find $dep.........." if ! which $dep; then echo "not found"; exit 1; fi done #echo -n "Check directory...." #if [ ! -e "src" ]; then # echo "not found"; # exit 1; #fi #echo "ok" ABSPATH=$(cd "$(dirname "$0")/.."; pwd) lcov --ignore-errors empty,mismatch --directory $PWD --capture --output-file coverage.info --no-checksum --compat-libtool lcov --ignore-errors empty,mismatch --remove coverage.info "/usr/include/*" "$ABSPATH/gmock/*" "$ABSPATH/test/*" --output-file coverage.info LANG=C genhtml --prefix $ABSPATH --output-directory coveragereport \ --title "Code Coverage" --legend --ignore-errors empty,mismatch --show-details coverage.info chewing-editor-0.1.2/share/000077500000000000000000000000001504106013400155165ustar00rootroot00000000000000chewing-editor-0.1.2/share/icons/000077500000000000000000000000001504106013400166315ustar00rootroot00000000000000chewing-editor-0.1.2/share/icons/chewing-editor.svg000066400000000000000000000106371504106013400222710ustar00rootroot00000000000000 image/svg+xml chewing-editor-0.1.2/src/000077500000000000000000000000001504106013400152035ustar00rootroot00000000000000chewing-editor-0.1.2/src/exporter/000077500000000000000000000000001504106013400170535ustar00rootroot00000000000000chewing-editor-0.1.2/src/exporter/ChewingExporter.cpp000066400000000000000000000030671504106013400227020ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "ChewingExporter.h" #include #include #include #include ChewingExporter::ChewingExporter(const QString& path) :UserphraseExporter{path} { } void ChewingExporter::addUserphraseImpl( const QString& phrase, const QString& bopomofo) { QJsonObject obj; obj["phrase"] = phrase; obj["bopomofo"] = bopomofo; array_.append(obj); return; } bool ChewingExporter::saveImpl() { QJsonObject root; root["userphrase"] = array_; QJsonDocument doc{root}; QFile file{path_}; if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { qDebug() << "Cannot open" << path_; return false; } file.write(doc.toJson()); return true; } chewing-editor-0.1.2/src/exporter/ChewingExporter.h000066400000000000000000000025311504106013400223420ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include "UserphraseExporter.h" #include #include class ChewingExporter final: public UserphraseExporter { public: explicit ChewingExporter(const QString& path); ChewingExporter(const ChewingExporter&) = delete; ChewingExporter& operator=(const ChewingExporter&) = delete; virtual ~ChewingExporter() = default; protected: virtual void addUserphraseImpl ( const QString& phrase, const QString& bopomofo) override; virtual bool saveImpl() override; QJsonArray array_; }; chewing-editor-0.1.2/src/exporter/UserphraseExporter.cpp000066400000000000000000000023321504106013400234310ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseExporter.h" #include UserphraseExporter::UserphraseExporter(const QString& path) :path_{path} { } void UserphraseExporter::addUserphrase( const QString& phrase, const QString& bopomofo) { addUserphraseImpl(phrase, bopomofo); } bool UserphraseExporter::save() { return saveImpl(); } const QString UserphraseExporter::getPath() { return QFileInfo{path_}.fileName(); } chewing-editor-0.1.2/src/exporter/UserphraseExporter.h000066400000000000000000000026201504106013400230760ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include class UserphraseExporter { public: explicit UserphraseExporter(const QString& path); UserphraseExporter(const UserphraseExporter&) = delete; UserphraseExporter& operator=(const UserphraseExporter&) = delete; virtual ~UserphraseExporter() = default; void addUserphrase( const QString& phrase, const QString& bopomofo); bool save(); const QString getPath(); protected: virtual void addUserphraseImpl( const QString& phrase, const QString& bopomofo) = 0; virtual bool saveImpl() = 0; QString path_; }; chewing-editor-0.1.2/src/importer/000077500000000000000000000000001504106013400170445ustar00rootroot00000000000000chewing-editor-0.1.2/src/importer/ChewingImporter.cpp000066400000000000000000000045261504106013400226650ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "ChewingImporter.h" #include #include #include #include #include #include #include ChewingImporter::ChewingImporter(const QString& path) :UserphraseImporter{path} { UserphraseSet result; QFile file{path_}; if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Cannot open file" << path_; return; } QJsonParseError err; auto doc = QJsonDocument::fromJson(file.readAll(), &err); if (doc.isNull()) { qWarning() << "parse json error in " << path_ << err.errorString(); return; } if (!doc.isObject()) { qWarning() << "root is not an object in" << path_; return; } auto root = doc.object(); if (!root["userphrase"].isArray()) { qWarning() << "userphrase is not an array in " << path_; return; } auto array = root["userphrase"].toArray(); for (auto i = array.begin(); i != array.end(); ++i) { if (!(*i).isObject()) { qWarning() << "skip non object in " << path_; continue; } auto obj = (*i).toObject(); if (!obj["phrase"].isString() || !obj["bopomofo"].isString()) { qWarning() << "phrase or bopomofo is not a string in" << path_; continue; } result.insert(Userphrase{ obj["phrase"].toString(), obj["bopomofo"].toString() }); } std::swap(userphrase_, result); supportedFormat_ = true; } chewing-editor-0.1.2/src/importer/ChewingImporter.h000066400000000000000000000021661504106013400223300ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include "UserphraseImporter.h" class ChewingImporter final : public UserphraseImporter { public: explicit ChewingImporter(const QString& path); ChewingImporter(const ChewingImporter&) = delete; ChewingImporter& operator=(const ChewingImporter&) = delete; virtual ~ChewingImporter() = default; }; chewing-editor-0.1.2/src/importer/HashImporter.cpp000066400000000000000000000105021504106013400221530ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "HashImporter.h" #include #include #include #include #include #include #include const size_t SIGNATURE_SIZE = 4; const size_t CHEWING_LIFETIME_SIZE = 4; const size_t USERPHRASE_SIZE = 125; const size_t USERPHRASE_LEN_OFFSET = 16; const size_t BOPOMOFO_SIZE = 4; const int BOPOMOFO_SHIFT[] = { 9, 7, 3, 0 }; const int BOPOMOFO_MASK[] = { 0x1F, 0x3, 0xF, 0x7 }; const int BOPOMOFO_LEN[] = { 3, 3, 3, 2 }; const char *const BOPOMOFO_TABLE[] = { // ㄅㄆㄇㄈㄉㄊㄋㄌㄍㄎㄏㄐㄑㄒㄓㄔㄕㄖㄗㄘㄙ "\xE3\x84\x85\xE3\x84\x86\xE3\x84\x87\xE3\x84\x88\xE3\x84\x89" "\xE3\x84\x8A\xE3\x84\x8B\xE3\x84\x8C\xE3\x84\x8D\xE3\x84\x8E" "\xE3\x84\x8F\xE3\x84\x90\xE3\x84\x91\xE3\x84\x92\xE3\x84\x93" "\xE3\x84\x94\xE3\x84\x95\xE3\x84\x96\xE3\x84\x97\xE3\x84\x98" "\xE3\x84\x99", // ㄧㄨㄩ "\xE3\x84\xA7\xE3\x84\xA8\xE3\x84\xA9", // ㄚㄛㄜㄝㄞㄟㄠㄡㄢㄣㄤㄥㄦ "\xE3\x84\x9A\xE3\x84\x9B\xE3\x84\x9C\xE3\x84\x9D\xE3\x84\x9E" "\xE3\x84\x9F\xE3\x84\xA0\xE3\x84\xA1\xE3\x84\xA2\xE3\x84\xA3" "\xE3\x84\xA4\xE3\x84\xA5\xE3\x84\xA6", // ˙ˊˇˋ "\xCB\x99\xCB\x8A\xCB\x87\xCB\x8B" }; static uint16_t getUint16(const char *ptr) { auto uptr = reinterpret_cast(ptr); return (uptr[0] << 0) | (uptr[1] << 8); } static QString getBopomofoFromPhoneArray(const std::vector &phone_array) { QByteArray buf; for (auto it = phone_array.begin(); it != phone_array.end(); ++it) { qDebug() << "*it = " << *it; for (size_t i = 0; i < BOPOMOFO_SIZE; ++i) { size_t idx = ((*it >> BOPOMOFO_SHIFT[i]) & BOPOMOFO_MASK[i]); if (idx == 0) { continue; } buf.append(&BOPOMOFO_TABLE[i][(idx - 1)* BOPOMOFO_LEN[i]], BOPOMOFO_LEN[i]); } buf.append(' '); } buf[buf.length()-1] = 0; qDebug() << "buf = " << buf; return QString(buf); } HashImporter::HashImporter(const QString& path) :UserphraseImporter{path} { QFile file{path}; int ret; if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Cannot open file" << path_; return; } QDataStream data{&file}; std::vector buffer(USERPHRASE_SIZE); ret = data.readRawData(&buffer[0], SIGNATURE_SIZE); if (ret != SIGNATURE_SIZE) { qWarning() << "Cannot read signature" << path_; return; } if (memcmp(&buffer[0], "CBiH", CHEWING_LIFETIME_SIZE) != 0) { qWarning() << "Cannot find signature `CBiH`" << path_; return; } ret = data.readRawData(&buffer[0], CHEWING_LIFETIME_SIZE); if (ret != CHEWING_LIFETIME_SIZE) { qWarning() << "Cannot read chewing_lifetime" << path_; return; } UserphraseSet result; while (data.readRawData(&buffer[0], USERPHRASE_SIZE) == USERPHRASE_SIZE) { size_t pos = USERPHRASE_LEN_OFFSET; int phone_len = static_cast(buffer[pos]); ++pos; std::vector phone_array; for (int i = 0; i < phone_len; ++i) { phone_array.push_back(getUint16(&buffer[pos])); pos += 2; } int phrase_len = static_cast(buffer[pos]); ++pos; buffer[pos + phrase_len] = 0; result.insert(Userphrase{ QString{&buffer[pos]}, getBopomofoFromPhoneArray(phone_array) }); } std::swap(userphrase_, result); supportedFormat_ = true; } chewing-editor-0.1.2/src/importer/HashImporter.h000066400000000000000000000021411504106013400216200ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include "UserphraseImporter.h" class HashImporter final : public UserphraseImporter { public: explicit HashImporter(const QString& path); HashImporter(const HashImporter&) = delete; HashImporter& operator=(const HashImporter&) = delete; virtual ~HashImporter() = default; }; chewing-editor-0.1.2/src/importer/UserphraseImporter.cpp000066400000000000000000000033611504106013400234160ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseImporter.h" #include "ChewingImporter.h" #include "HashImporter.h" UserphraseImporter::UserphraseImporter(const QString& path) :path_{path} ,supportedFormat_{false} ,userphrase_{} { } bool UserphraseImporter::isSupportedFormat() { return supportedFormat_; } const UserphraseSet& UserphraseImporter::getUserphraseSet() { return userphrase_; } const QString UserphraseImporter::getPath() { QFileInfo info{path_}; return info.fileName(); } std::shared_ptr createUserphraseImporter(const QString& path) { std::shared_ptr ptr; /* * FIXME: We shall check file type before creating UserphraseImporter * object. */ ptr.reset(new ChewingImporter(path)); if (ptr.get()->isSupportedFormat()) { return ptr; } ptr.reset(new HashImporter(path)); if (ptr.get()->isSupportedFormat()) { return ptr; } return ptr; } chewing-editor-0.1.2/src/importer/UserphraseImporter.h000066400000000000000000000027331504106013400230650ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include #include #include #include "UserphraseSet.h" class UserphraseImporter { public: explicit UserphraseImporter(const QString& path); UserphraseImporter(const UserphraseImporter&) = delete; UserphraseImporter& operator=(const UserphraseImporter&) = delete; virtual ~UserphraseImporter() = default; bool isSupportedFormat(); const UserphraseSet& getUserphraseSet(); const QString getPath(); protected: QString path_; bool supportedFormat_; UserphraseSet userphrase_; }; std::shared_ptr createUserphraseImporter(const QString& path); chewing-editor-0.1.2/src/main.cpp000066400000000000000000000123221504106013400166330ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #ifdef _MSC_VER #include Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) #endif #include "ChewingEditor.h" void messageHandlerHelper(QtMsgType type, const QMessageLogContext& context, const QString& message, QtMsgType level) { if (type < level) { return; } auto msg = message.toUtf8(); auto file = QFileInfo{context.file}.fileName().toUtf8(); switch(type) { case QtDebugMsg: fprintf(stdout, "Debug: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); abort(); break; default: break; } } void emptyMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { messageHandlerHelper(type, context, message, QtWarningMsg); } void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { messageHandlerHelper(type, context, message, QtDebugMsg); } void loadTranslation(QApplication &app, QTranslator &qtTranslator, QTranslator &chewingTranslator) { QString qtFileName{"qt_" + QLocale::system().name()}; QString qtDirectory{QLibraryInfo::location(QLibraryInfo::TranslationsPath)}; bool qtLoaded = qtTranslator.load(qtFileName, qtDirectory); qDebug() << "Load" << qtFileName << qtDirectory << qtLoaded; app.installTranslator(&qtTranslator); QString chewingFileName{":/" PROJECT_NAME "_" + QLocale::system().name()}; bool chewingLoaded = chewingTranslator.load(chewingFileName); qDebug() << "Load" << chewingFileName << chewingLoaded; app.installTranslator(&chewingTranslator); } void printVersion() { QString msg{QCoreApplication::translate("main", "%1\n") .arg(PROJECT_VERSION)}; printf("%s", msg.toUtf8().constData()); } void printArg(const QString &arg, const QString &description) { printf("%s\n\t%s\n\n", arg.toUtf8().constData(), description.toUtf8().constData()); } void printHelp(const QString &name) { QString description{QCoreApplication::translate("main", "chewing-editor is a cross platform chewing user phrase editor written " "in Qt5. It provides a user friendly GUI to manage user phrase. With it," " user can customize user phrase to enhance chewing input performance.")}; printf("%s\n\n", description.toUtf8().constData()); printArg( QCoreApplication::translate("main", "-d, --debug"), QCoreApplication::translate("main", "Enable debug message.")); printArg( QCoreApplication::translate("main", "-v, --version"), QCoreApplication::translate("main", "Print program version.")); printArg( QCoreApplication::translate("main", "-h, --help"), QCoreApplication::translate("main", "Print help message.")); } void printUnknownArgs(const QString &unknown) { printf("Unknown options: %s\n", unknown.toUtf8().constData()); } void readArgument(QApplication &app) { auto args = QCoreApplication::arguments(); auto name = QFileInfo{args.at(0)}.fileName(); for (int i = 1; i < args.size(); ++i) { auto arg = args.at(i); if (arg.compare("-d") == 0 || arg.compare("--debug") == 0) { qInstallMessageHandler(debugMessageHandler); } else if (arg.compare("-v") == 0 || arg.compare("--version") == 0) { printVersion(); exit(0); } else if (arg.compare("-h") == 0 || arg.compare("--help") == 0) { printHelp(name); exit(0); } else { printUnknownArgs(arg); printHelp(name); exit(1); } } } int main(int argc, char *argv[]) { qInstallMessageHandler(emptyMessageHandler); QApplication app{argc, argv}; QTranslator qtTranslator; QTranslator chewingTranslator; loadTranslation(app, qtTranslator, chewingTranslator); readArgument(app); ChewingEditor w; w.show(); return app.exec(); } chewing-editor-0.1.2/src/model/000077500000000000000000000000001504106013400163035ustar00rootroot00000000000000chewing-editor-0.1.2/src/model/UserphraseModel.cpp000066400000000000000000000155321504106013400221170ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseModel.h" #include #include #include static void logger(void *data, int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); size_t len = vsnprintf(NULL, 0, fmt, ap); va_end(ap); std::vector buffer(len + 1); va_start(ap, fmt); vsnprintf(&buffer[0], buffer.size(), fmt, ap); va_end(ap); if (buffer[len - 1] == '\n') { buffer[len - 1] = 0; } if (level <= CHEWING_LOG_INFO) { qDebug() << &buffer[0]; } else if (level <= CHEWING_LOG_WARN) { qWarning() << &buffer[0]; } else if (level <= CHEWING_LOG_ERROR) { qCritical() << &buffer[0]; } } UserphraseModel::UserphraseModel(QObject *parent, const char *path) :QAbstractListModel{parent} ,ctx_{chewing_new2(nullptr, path, logger, nullptr), chewing_delete} ,userphrase_{} ,addresult_(1) { if (!ctx_) { // FIXME: Report error here qCritical() << "chewing_new2() fails"; } } int UserphraseModel::rowCount(const QModelIndex &parent) const { return userphrase_.size(); } QVariant UserphraseModel::data(const QModelIndex &index, int role) const { switch (role) { case Qt::DisplayRole: return userphrase_[index.row()].display_; case Qt::WhatsThisRole: // FIXME: Provide "What's This?" break; default: break; } return QVariant(); } void UserphraseModel::remove(QModelIndexList indexList) { if (indexList.empty()) { qDebug() << "indexList is empty"; return; } std::sort(indexList.begin(), indexList.end(), [] (const QModelIndex& a, const QModelIndex& b) { // QModelIndex provides operator< but no operator> return !(a < b); }); // XXX: indexList is in revsrsed order, so first is actual last, and vice // verse. auto first = indexList.last().row(); auto last = indexList.first().row(); emit beginRemoveRows(indexList.first().parent(), first, last); foreach(auto item, indexList) { auto index = item.row(); qDebug() << userphrase_[index].phrase_ << userphrase_[index].bopomofo_; auto ret = chewing_userphrase_remove( ctx_.get(), userphrase_[index].phrase_.toUtf8().constData(), userphrase_[index].bopomofo_.toUtf8().constData()); if (ret > 0) { removerecord_.push_back(Userphrase{userphrase_[index]}); // FIXME: std::vector::erase is an inefficient operation. userphrase_.erase(userphrase_.begin() + index); } else { qWarning() << "chewing_userphrase_remove() returns" << ret; } // FIXME: Handle chewing_userphrase_remove fails. } emit endRemoveRows(); emit removePhraseCompleted(indexList.size()); } void UserphraseModel::refresh() { UserphraseSet userphrase; std::vector phrase; unsigned int phrase_len; std::vector bopomofo; unsigned int bopomofo_len; chewing_userphrase_enumerate(ctx_.get()); while (chewing_userphrase_has_next(ctx_.get(), &phrase_len, &bopomofo_len)) { phrase.resize(phrase_len); bopomofo.resize(bopomofo_len); int ret = chewing_userphrase_get(ctx_.get(), &phrase[0], phrase.size(), &bopomofo[0], bopomofo.size()); if (ret == -1) { qWarning() << "chewing_userphrase_get() returns" << ret; continue; } qDebug() << "Get userphrase:" << &phrase[0] << &bopomofo[0]; userphrase.insert(Userphrase{ QString::fromUtf8(&phrase[0]), QString::fromUtf8(&bopomofo[0]) }); } emit beginResetModel(); userphrase_.swap(userphrase); emit endResetModel(); qDebug() << "Total userphrase" << userphrase_.size(); emit refreshCompleted(userphrase_.size()); } void UserphraseModel::importUserphrase(std::shared_ptr importer) { size_t old_count = userphrase_.size(); if (!importer.get()->isSupportedFormat()) { emit importCompleted(false, importer.get()->getPath(), 0, old_count); return; } auto result = importer.get()->getUserphraseSet(); for (auto& i: result) { add(i.phrase_, i.bopomofo_); } size_t new_count = userphrase_.size(); emit importCompleted(true, importer.get()->getPath(), new_count - old_count, new_count); } void UserphraseModel::exportUserphrase(std::shared_ptr exporter) { size_t exported = userphrase_.size(); for (auto& i: userphrase_) { exporter.get()->addUserphrase(i.phrase_, i.bopomofo_); } bool result = exporter.get()->save(); emit exportCompleted(result, exporter.get()->getPath(), exported); } QString UserphraseModel::checkBopomofo(const QString &bopomofo) const { QString replaceBopomofo = bopomofo; replaceBopomofo.replace(QString::fromUtf8("一"),QString::fromUtf8("ㄧ")); replaceBopomofo.replace(QString::fromUtf8("丫"),QString::fromUtf8("ㄚ")); return replaceBopomofo; } void UserphraseModel::add(const QString &phrase, const QString &bopomofo) { QString replaceBopomofo = checkBopomofo(bopomofo); auto ret = chewing_userphrase_add( ctx_.get(), phrase.toUtf8().constData(), replaceBopomofo.toUtf8().constData()); addresult_ = ret; if (ret > 0) { emit beginResetModel(); userphrase_.insert(Userphrase{ phrase, bopomofo }); emit endResetModel(); emit addNewPhraseCompleted(userphrase_[userphrase_.size()-1]); } else { qWarning() << "chewing_userphrase_add() returns" << ret; refresh(); emit addNewPhraseFailed(); } } const Userphrase *UserphraseModel::getUserphrase(const QModelIndex& idx) { return &userphrase_[idx.row()]; } void UserphraseModel::undo() { if (!removerecord_.empty()) { auto last = removerecord_.end() - 1; const QString phrase = last->display_; add(last->phrase_, last->bopomofo_); removerecord_.erase(last); emit undoCompleted(phrase); } } chewing-editor-0.1.2/src/model/UserphraseModel.h000066400000000000000000000051311504106013400215560ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include #include #include "Userphrase.h" #include "UserphraseExporter.h" #include "UserphraseImporter.h" #include "UserphraseSet.h" class UserphraseModel final: public QAbstractListModel { Q_OBJECT public: UserphraseModel(QObject * parent = 0, const char *path = nullptr); UserphraseModel(const UserphraseModel& x) = delete; UserphraseModel& operator=(const UserphraseModel& x) = delete; virtual ~UserphraseModel() = default; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; const Userphrase *getUserphrase(const QModelIndex& idx); int getAddResult() const {return addresult_;} signals: void importCompleted( bool result, const QString& file, size_t imported, size_t total); void exportCompleted( bool result, const QString& file, size_t exported); void addNewPhraseCompleted(const Userphrase& userphrase); void removePhraseCompleted(size_t count); void refreshCompleted(size_t count); void addNewPhraseFailed(); void undoCompleted(const QString &phrase); public slots: void refresh(); void add(const QString &phrase, const QString &bopomofo); void importUserphrase(std::shared_ptr importer); void exportUserphrase(std::shared_ptr exporter); void remove(QModelIndexList indexList); void undo(); private: QString checkBopomofo(const QString &bopomofo) const; std::unique_ptr ctx_; UserphraseSet userphrase_; std::vector removerecord_; int addresult_; }; chewing-editor-0.1.2/src/model/UserphraseSortFilterProxyModel.cpp000066400000000000000000000032471504106013400251770ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseSortFilterProxyModel.h" #include #include UserphraseSortFilterProxyModel::UserphraseSortFilterProxyModel(QObject *parent) :QSortFilterProxyModel{parent} { } void UserphraseSortFilterProxyModel::add(const QString &phrase, const QString &bopomofo) { sourceModel()->add(phrase, bopomofo); } void UserphraseSortFilterProxyModel::remove(QModelIndexList indexList) { if (indexList.empty()) { qDebug() << "indexList is empty"; return; } QModelIndexList sourceIndexList; for (auto i = indexList.constBegin(); i != indexList.constEnd(); ++i) { sourceIndexList.push_back(mapToSource(*i)); } sourceModel()->remove(std::move(sourceIndexList)); } const Userphrase *UserphraseSortFilterProxyModel::getUserphrase(const QModelIndex& idx) { return sourceModel()->getUserphrase(mapToSource(idx)); } chewing-editor-0.1.2/src/model/UserphraseSortFilterProxyModel.h000066400000000000000000000033121504106013400246350ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include "UserphraseModel.h" class UserphraseSortFilterProxyModel final : public QSortFilterProxyModel { Q_OBJECT public: explicit UserphraseSortFilterProxyModel(QObject * parent = 0); UserphraseSortFilterProxyModel(const UserphraseSortFilterProxyModel& x) = delete; UserphraseSortFilterProxyModel& operator=(const UserphraseSortFilterProxyModel& x) = delete; virtual ~UserphraseSortFilterProxyModel() = default; virtual void setSourceModel(UserphraseModel* model) { QSortFilterProxyModel::setSourceModel(model); } UserphraseModel* sourceModel () const { return dynamic_cast(QSortFilterProxyModel::sourceModel()); } const Userphrase *getUserphrase(const QModelIndex& idx); public slots: void add(const QString &phrase, const QString &bopomofo); void remove(QModelIndexList indexList); }; chewing-editor-0.1.2/src/ui/000077500000000000000000000000001504106013400156205ustar00rootroot00000000000000chewing-editor-0.1.2/src/ui/ChewingEditor.ui000066400000000000000000000074301504106013400207160ustar00rootroot00000000000000 ChewingEditor 0 0 800 600 320 240 Chewing user phrase editor Add Remove Undo Refresh Search QAbstractItemView::ExtendedSelection 0 0 800 20 File Help &Import &Export About Chewing editor QAction::AboutRole About Qt QAction::AboutQtRole E&xit QAction::QuitRole Notification QLabel
Notification.h
UserphraseView QListView
UserphraseView.h
chewing-editor-0.1.2/src/ui/UserphraseDialog.ui000066400000000000000000000027151504106013400214250ustar00rootroot00000000000000 UserphraseDialog 0 0 250 111 Add new phrase QLayout::SetDefaultConstraint Phrase: Bopomofo: QDialogButtonBox::Cancel|QDialogButtonBox::Ok chewing-editor-0.1.2/src/ui/UserphraseViewMenu.ui000066400000000000000000000011431504106013400217570ustar00rootroot00000000000000 UserphraseViewMenu Add Modify Remove chewing-editor-0.1.2/src/util/000077500000000000000000000000001504106013400161605ustar00rootroot00000000000000chewing-editor-0.1.2/src/util/Userphrase.cpp000066400000000000000000000020151504106013400210030ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "Userphrase.h" Userphrase::Userphrase(const QString& phrase, const QString& bopomofo) :phrase_{phrase} ,bopomofo_{bopomofo} ,display_{} { display_ = QString("%1 (%2)").arg(phrase).arg(bopomofo); } chewing-editor-0.1.2/src/util/Userphrase.h000066400000000000000000000021711504106013400204530ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include class Userphrase final { public: Userphrase(const QString& phrase, const QString& bopomofo); Userphrase(const Userphrase&) = default; Userphrase& operator=(const Userphrase&) = default; ~Userphrase() = default; QString phrase_; QString bopomofo_; QString display_; }; chewing-editor-0.1.2/src/util/UserphraseSet.cpp000066400000000000000000000037261504106013400214710ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseSet.h" #include bool UserphraseSet::insert(Userphrase&& userphrase) { auto ret = dedup_.insert(userphrase.display_); if (!ret.second) { // Duplicate item shall not be stored. qDebug() << "Duplicate phrase:" << userphrase.phrase_ << "bopomofo:" << userphrase.bopomofo_; return false; } userphrase_.push_back(std::move(userphrase)); return true; } void UserphraseSet::erase(iterator it) { dedup_.erase(it->display_); userphrase_.erase(it); } UserphraseSet::iterator UserphraseSet::begin() { return userphrase_.begin(); } UserphraseSet::iterator UserphraseSet::end() { return userphrase_.end(); } UserphraseSet::const_iterator UserphraseSet::begin() const { return userphrase_.begin(); } UserphraseSet::const_iterator UserphraseSet::end() const { return userphrase_.end(); } size_t UserphraseSet::size() const { return userphrase_.size(); } const Userphrase& UserphraseSet::operator[](size_t index) const { return userphrase_[index]; } void UserphraseSet::swap(UserphraseSet& set) noexcept { userphrase_.swap(set.userphrase_); dedup_.swap(set.dedup_); } chewing-editor-0.1.2/src/util/UserphraseSet.h000066400000000000000000000032341504106013400211300ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include #include "Userphrase.h" class UserphraseSet { public: UserphraseSet() = default; UserphraseSet(const UserphraseSet&) = default; UserphraseSet& operator=(const UserphraseSet&) = default; virtual ~UserphraseSet() = default; typedef std::vector::const_iterator const_iterator; typedef std::vector::iterator iterator; bool insert(Userphrase&& userphrase); void erase(iterator it); iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; size_t size() const; bool empty() const { return userphrase_.empty(); } const Userphrase& operator[](size_t index) const; void swap(UserphraseSet& set) noexcept; private: std::vector userphrase_; std::set dedup_; }; chewing-editor-0.1.2/src/view/000077500000000000000000000000001504106013400161555ustar00rootroot00000000000000chewing-editor-0.1.2/src/view/ChewingEditor.cpp000066400000000000000000000240661504106013400214240ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "ChewingEditor.h" #include "ui_ChewingEditor.h" #include "config.h" #include #include #include #include "ChewingImporter.h" #include "ChewingExporter.h" static int import_count; ChewingEditor::ChewingEditor(QWidget *parent) :QMainWindow{parent} ,ui_{new Ui::ChewingEditor} ,model_{new UserphraseModel{this}} ,proxyModel_{new UserphraseSortFilterProxyModel{this}} ,fileDialog_{new QFileDialog{this}} { ui_.get()->setupUi(this); proxyModel_->setSourceModel(model_); ui_.get()->userphraseView->setModel(proxyModel_); setupFileSelection(); setupImport(); setupExport(); setupAdd(); setupRemove(); setupRefresh(); setupUndo(); setupFilter(); setupAboutWidget(); // exit action shortcut_exit_ = new QShortcut(QKeySequence::Quit, this); connect( shortcut_exit_, SIGNAL(activated()), SLOT(close()) ); connect( ui_.get()->actionExit, SIGNAL(triggered()), SLOT(close()) ); // modify action shortcut_modify_ = new QShortcut(Qt::Key_Return, this); connect( shortcut_modify_, SIGNAL(activated()), ui_.get()->userphraseView, SLOT(showModifyUserphraseDialog()) ); } ChewingEditor::~ChewingEditor() { } void ChewingEditor::execFileDialog(DialogType type) { dialogType_ = type; qDebug() << "dialogType_ = " << dialogType_; switch (dialogType_) { case DIALOG_IMPORT: fileDialog_->setWindowTitle(tr("Import")); fileDialog_->setAcceptMode(QFileDialog::AcceptOpen); fileDialog_->setFileMode(QFileDialog::ExistingFile); fileDialog_->setOption(QFileDialog::DontConfirmOverwrite, true); fileDialog_->selectFile(""); break; case DIALOG_EXPORT: fileDialog_->setWindowTitle(tr("Export")); fileDialog_->setAcceptMode(QFileDialog::AcceptSave); fileDialog_->setFileMode(QFileDialog::AnyFile); fileDialog_->setOption(QFileDialog::DontConfirmOverwrite, false); fileDialog_->selectFile("chewing.json"); break; default: Q_ASSERT(!"Unknown DialogType"); } emit fileDialog_->exec(); } void ChewingEditor::selectImportFile() { // reset import_count import_count = 0; qDebug() << "import_count = " << import_count; execFileDialog(DIALOG_IMPORT); } void ChewingEditor::selectExportFile() { execFileDialog(DIALOG_EXPORT); } void ChewingEditor::finishFileSelection(const QString& file) { qDebug() << "dialogType_ = " << dialogType_; switch (dialogType_) { case DIALOG_IMPORT: // Do nothing after the first trigger if (import_count == 0) { importUserphrase(file); import_count++; } qDebug() << "import_count = " << import_count; break; case DIALOG_EXPORT: exportUserphrase(file); break; default: Q_ASSERT(!"Unknown DialogType"); } } void ChewingEditor::importUserphrase(const QString& file) { emit model_->importUserphrase(createUserphraseImporter(file)); } void ChewingEditor::exportUserphrase(const QString& file) { // TODO: Find a suitable exporter std::shared_ptr exporter(new ChewingExporter{file}); emit model_->exportUserphrase(exporter); } void ChewingEditor::showAbout() { QString caption = QString("

%1

%2

") .arg(tr("About Chewing Editor")) #ifdef PROJECT_GIT_VERSION .arg(tr("Version %1 (%2).").arg(PROJECT_VERSION).arg(PROJECT_GIT_VERSION)); #else .arg(tr("Version %1.").arg(PROJECT_VERSION)); #endif QString text = QString("

%1\n\n%2\n\n%3\n\n%4\n\n%5\n\n%6

") .arg("Chewing editor is a cross platform Chewing user phrase editor. " "It provides a easy way to manage user phrase. With it, user can " "customize their user phrase to increase input performance.") .arg("Chewing editor is licensed under the GNU GPL version 2.0 or later version.") .arg("Please see COPYING " "for detail of Chewing editor licensing.") .arg("Copyright© 2004-2016 by Chewing Core Team and contributors on " "GitHub.") .arg("Chewing editor is developed as an open source project on " "https://github.com/chewing/chewing-editor.") .arg("Any suggestions are welcomed on " "https://github.com/chewing/chewing-editor/issues"); QMessageBox aboutBox(this); aboutBox.setWindowTitle(tr("About Chewing Editor")); aboutBox.setText(caption); aboutBox.setInformativeText(text); aboutBox.setStandardButtons(QMessageBox::Ok); aboutBox.setDefaultButton(QMessageBox::Ok); QPixmap pm(QLatin1String(":/chewing-editor.png")); if (!pm.isNull()) aboutBox.setIconPixmap(pm); aboutBox.exec(); } void ChewingEditor::showDeleteConfirmWindow() { if(ui_.get()->userphraseView->selectionModel()->selectedIndexes().size() == 0) return; QString text = tr("Do you want to delete this phrase?"); QMessageBox deleteBox(this); deleteBox.setWindowTitle(tr("Delete phrase")); deleteBox.setText(text); deleteBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); deleteBox.setDefaultButton(QMessageBox::No); connect( deleteBox.button(QMessageBox::Yes), SIGNAL(clicked()), ui_.get()->userphraseView, SLOT(remove()) ); deleteBox.exec(); } void ChewingEditor::setupFileSelection() { fileDialog_->setNameFilter("*.json"); connect( fileDialog_, SIGNAL(fileSelected(const QString&)), this, SLOT(finishFileSelection(const QString &)) ); } void ChewingEditor::setupImport() { shortcut_import_ = new QShortcut(Qt::CTRL + Qt::Key_I, this); connect( shortcut_import_, SIGNAL(activated()), this, SLOT(selectImportFile()) ); connect( ui_.get()->actionImport, SIGNAL(triggered()), this, SLOT(selectImportFile()) ); connect( model_, SIGNAL(importCompleted(bool, const QString&, size_t, size_t)), ui_.get()->notification, SLOT(notifyImportCompleted(bool, const QString&, size_t, size_t)) ); // initialize import_count import_count = 0; qDebug() << "import_count = " << import_count; } void ChewingEditor::setupExport() { shortcut_export_ = new QShortcut(Qt::CTRL + Qt::Key_E, this); connect( shortcut_export_, SIGNAL(activated()), this, SLOT(selectExportFile()) ); connect( ui_.get()->actionExport, SIGNAL(triggered()), this, SLOT(selectExportFile()) ); connect( model_, SIGNAL(exportCompleted(bool, const QString&, size_t)), ui_.get()->notification, SLOT(notifyExportCompleted(bool, const QString&, size_t)) ); } void ChewingEditor::setupAdd() { shortcut_add_ = new QShortcut(QKeySequence::New, this); connect( shortcut_add_, SIGNAL(activated()), ui_.get()->userphraseView, SLOT(showAddUserphraseDialog()) ); connect( ui_.get()->addButton, SIGNAL(pressed()), ui_.get()->userphraseView, SLOT(showAddUserphraseDialog()) ); connect( model_, SIGNAL(addNewPhraseCompleted(const Userphrase&)), ui_.get()->notification, SLOT(notifyAddNewPhraseCompleted(const Userphrase&)) ); connect( model_, SIGNAL(addNewPhraseFailed()), ui_.get()->notification, SLOT(notifyAddNewPhraseFailed()) ); } void ChewingEditor::setupRemove() { shortcut_remove_ = new QShortcut(QKeySequence::Delete, this); connect( shortcut_remove_, SIGNAL(activated()), this, SLOT(showDeleteConfirmWindow()) ); connect( ui_.get()->removeButton, SIGNAL(pressed()), this, SLOT(showDeleteConfirmWindow()) ); connect( model_, SIGNAL(removePhraseCompleted(size_t)), ui_.get()->notification, SLOT(notifyRemovePhraseCompleted(size_t)) ); } void ChewingEditor::setupRefresh() { shortcut_refresh_ = new QShortcut(Qt::CTRL + Qt::Key_R, this); connect( shortcut_refresh_, SIGNAL(activated()), model_, SLOT(refresh()) ); connect( ui_.get()->refreshButton, SIGNAL(pressed()), model_, SLOT(refresh()) ); connect( model_, SIGNAL(refreshCompleted(size_t)), ui_.get()->notification, SLOT(notifyRefreshCompleted(size_t)) ); emit model_->refresh(); } void ChewingEditor::setupUndo() { connect( ui_.get()->undoButton, SIGNAL(pressed()), model_, SLOT(undo()) ); connect( model_, SIGNAL(undoCompleted(const QString&)), ui_.get()->notification, SLOT(notifyUndoCompleted(const QString&)) ); } void ChewingEditor::setupFilter() { connect( ui_.get()->userphraseFilter, SIGNAL(textEdited(const QString&)), ui_.get()->userphraseView, SLOT(setFilterString(const QString&)) ); } void ChewingEditor::setupAboutWidget() { connect( ui_.get()->actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()) ); connect( ui_.get()->actionAbout, SIGNAL(triggered()), this, SLOT(showAbout()) ); } chewing-editor-0.1.2/src/view/ChewingEditor.h000066400000000000000000000043761504106013400210730ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include #include #include "UserphraseDialog.h" #include "Notification.h" #include "UserphraseSortFilterProxyModel.h" namespace Ui { class ChewingEditor; } class ChewingEditor final: public QMainWindow { Q_OBJECT public: explicit ChewingEditor(QWidget *parent = 0); ChewingEditor(const ChewingEditor&) = delete; ChewingEditor& operator=(const ChewingEditor&) = delete; ~ChewingEditor(); // = default; public slots: void selectImportFile(); void selectExportFile(); void finishFileSelection(const QString& file); void showAbout(); void showDeleteConfirmWindow(); private: enum DialogType { DIALOG_IMPORT, DIALOG_EXPORT, }; void setupFileSelection(); void setupImport(); void setupExport(); void setupAdd(); void setupRemove(); void setupRefresh(); void setupUndo(); void setupFilter(); void setupAboutWidget(); void importUserphrase(const QString& file); void exportUserphrase(const QString& file); void execFileDialog(DialogType type); std::unique_ptr ui_; UserphraseModel *model_; UserphraseSortFilterProxyModel *proxyModel_; QFileDialog *fileDialog_; DialogType dialogType_; QShortcut *shortcut_add_, *shortcut_modify_, *shortcut_remove_, *shortcut_refresh_, *shortcut_import_, *shortcut_export_, *shortcut_exit_; }; chewing-editor-0.1.2/src/view/Notification.cpp000066400000000000000000000051311504106013400213070ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "Notification.h" #include Notification::Notification(QWidget* parent) :QLabel(parent) { } void Notification::notifyImportCompleted( bool result, const QString& path, size_t imported, size_t total) { qDebug() << result << path << imported << total; if (result) { setText( tr("%1 %2 %3") .arg(tr("Import \"%1\" successful.").arg(path)) .arg(tr("%n phrase(s) are imported.", 0, imported)) .arg(tr("Total %n user phrase(s).", 0, total))); } else { setText(tr("Import \"%1\" failed.").arg(path)); } } void Notification::notifyExportCompleted( bool result, const QString& path, size_t exported) { qDebug() << result << path << exported; if (result) { setText( tr("%1 %2") .arg(tr("Export \"%1\" successful.").arg(path)) .arg(tr("%n phrase(s) are exported.", 0, exported))); } else { setText(tr("Export \"%1\" failed.").arg(path)); } } void Notification::notifyAddNewPhraseCompleted(const Userphrase& userphrase) { qDebug() << userphrase.display_; setText(tr("Add new phrase %1 successful.").arg(userphrase.display_)); } void Notification::notifyRemovePhraseCompleted(size_t count) { qDebug() << count; setText(tr("Remove %n phrase(s) successful.", 0, count)); } void Notification::notifyRefreshCompleted(size_t count) { qDebug() << count; setText(tr("Refresh completed. Total %n user phrase(s).", 0, count)); } void Notification::notifyAddNewPhraseFailed() { setText(tr("Add new phrase failed. Please enter the bopomofo for each word and try again.")); } void Notification::notifyUndoCompleted(const QString &phrase) { setText(tr("Undo completed. Revert %1.").arg(phrase)); } chewing-editor-0.1.2/src/view/Notification.h000066400000000000000000000031041504106013400207520ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include "Userphrase.h" class Notification final: public QLabel { Q_OBJECT public: explicit Notification(QWidget* parent = 0); Notification(const Notification&) = delete; Notification& operator=(const Notification&) = delete; virtual ~Notification() = default; public slots: void notifyImportCompleted(bool result, const QString& path, size_t imported, size_t total); void notifyExportCompleted(bool result, const QString& path, size_t exported); void notifyAddNewPhraseCompleted(const Userphrase& userphrase); void notifyRemovePhraseCompleted(size_t count); void notifyRefreshCompleted(size_t count); void notifyAddNewPhraseFailed(); void notifyUndoCompleted(const QString &phrase); }; chewing-editor-0.1.2/src/view/UserphraseDialog.cpp000066400000000000000000000033151504106013400221240ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseDialog.h" #include "ui_UserphraseDialog.h" UserphraseDialog::UserphraseDialog(QWidget *parent) :QDialog{parent} ,ui_{new Ui::UserphraseDialog} { ui_.get()->setupUi(this); setupConnect(); } UserphraseDialog::~UserphraseDialog() { } void UserphraseDialog::setupConnect() { connect( ui_.get()->buttonBox, SIGNAL(accepted()), this, SLOT(accept()) ); connect( ui_.get()->buttonBox, SIGNAL(rejected()), this, SLOT(reject()) ); } QString UserphraseDialog::getPhrase() const { return ui_.get()->phrase->text().trimmed(); } QString UserphraseDialog::getBopomofo() const { return ui_.get()->bopomofo->text().trimmed(); } void UserphraseDialog::setText(const QString& phrase, const QString& bopomofo) { ui_.get()->phrase->setText(phrase); ui_.get()->bopomofo->setText(bopomofo); ui_->phrase->setFocus(Qt::PopupFocusReason); } chewing-editor-0.1.2/src/view/UserphraseDialog.h000066400000000000000000000026051504106013400215720ustar00rootroot00000000000000 /* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include namespace Ui { class UserphraseDialog; } class UserphraseDialog final: public QDialog { Q_OBJECT public: explicit UserphraseDialog(QWidget *parent = 0); UserphraseDialog(const UserphraseDialog&) = delete; UserphraseDialog& operator=(const UserphraseDialog&) = delete; ~UserphraseDialog(); // = default; QString getPhrase() const; QString getBopomofo() const; void setText(const QString& phrase, const QString& bopomofo); private: void setupConnect(); std::unique_ptr ui_; }; chewing-editor-0.1.2/src/view/UserphraseView.cpp000066400000000000000000000072551504106013400216460ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseModel.h" #include "UserphraseView.h" #include UserphraseView::UserphraseView(QWidget *parent) :QListView{parent} ,UserphraseDialog_{new UserphraseDialog{this}} ,menu_(new UserphraseViewMenu{this}) { setupContextMenu(); setupAddUserphraseDialog(); // setup double click connect( this, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(showModifyUserphraseDialog()) ); } void UserphraseView::showAddUserphraseDialog() { dialogType_ = DIALOG_ADD; UserphraseDialog_->setText("", ""); UserphraseDialog_->setWindowTitle(tr("Add new phrase")); emit UserphraseDialog_->exec(); } void UserphraseView::showModifyUserphraseDialog() { if (selectionModel()->selectedIndexes().size() != 1) { return; } dialogType_ = DIALOG_MODIFY; auto userphrase = model()->getUserphrase(selectionModel()->selectedIndexes().first()); UserphraseDialog_->setText(userphrase->phrase_, userphrase->bopomofo_); UserphraseDialog_->setWindowTitle(tr("Modify phrase")); originalphrase_ = userphrase->phrase_; originalbopomofo_ = userphrase->bopomofo_; emit UserphraseDialog_->exec(); } void UserphraseView::addPhrase(int result) { if (result != QDialog::Accepted) { return; } QString phrase = UserphraseDialog_->getPhrase(); QString bopomofo = UserphraseDialog_->getBopomofo(); qDebug() << "Add" << phrase << "(" << bopomofo << ")"; if (dialogType_ == DIALOG_MODIFY) { remove(); } emit model()->add(phrase, bopomofo); if (dialogType_ == DIALOG_MODIFY) { if (model()->sourceModel()->getAddResult() <= 0) { emit model()->add(originalphrase_, originalbopomofo_); } } } void UserphraseView::remove() { auto selection = selectionModel(); emit model()->remove(selection->selectedIndexes()); selection->reset(); } void UserphraseView::setFilterString(const QString& text) { model()->setFilterWildcard(text); } void UserphraseView::setupContextMenu() { setContextMenuPolicy(Qt::CustomContextMenu); connect( this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&)) ); connect( menu_->getActionRemovePhrase(), SIGNAL(triggered()), this, SLOT(remove()) ); } void UserphraseView::showContextMenu(const QPoint& point) { emit menu_->execWithSelectInfo(mapToGlobal(point), selectionModel()->selectedIndexes().size()); } void UserphraseView::setupAddUserphraseDialog() { connect( menu_->getActionAddPhrase(), SIGNAL(triggered()), this, SLOT(showAddUserphraseDialog()) ); connect( menu_->getActionModifyPhrase(), SIGNAL(triggered()), this, SLOT(showModifyUserphraseDialog()) ); connect( UserphraseDialog_, SIGNAL(finished(int)), this, SLOT(addPhrase(int)) ); } chewing-editor-0.1.2/src/view/UserphraseView.h000066400000000000000000000037671504106013400213170ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include "UserphraseDialog.h" #include "UserphraseSortFilterProxyModel.h" #include "UserphraseViewMenu.h" class UserphraseView final : public QListView { Q_OBJECT public: explicit UserphraseView(QWidget *parent = 0); UserphraseView(const UserphraseView&) = delete; UserphraseView& operator=(const UserphraseView&) = delete; virtual ~UserphraseView() = default; virtual void setModel(UserphraseSortFilterProxyModel *model) { QListView::setModel(model); } public slots: void showAddUserphraseDialog(); void showModifyUserphraseDialog(); void addPhrase(int result); void remove(); void setFilterString(const QString& text); void showContextMenu(const QPoint& point); protected: UserphraseSortFilterProxyModel* model() const { return dynamic_cast(QListView::model()); } private: enum DialogType { DIALOG_ADD, DIALOG_MODIFY, }; void setupContextMenu(); void setupAddUserphraseDialog(); UserphraseDialog *UserphraseDialog_; UserphraseViewMenu *menu_; bool dialogType_; QString originalphrase_; QString originalbopomofo_; }; chewing-editor-0.1.2/src/view/UserphraseViewMenu.cpp000066400000000000000000000036121504106013400224640ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "UserphraseViewMenu.h" #include "ui_UserphraseViewMenu.h" UserphraseViewMenu::UserphraseViewMenu(QWidget *parent) :QMenu{parent} ,ui_{new Ui::UserphraseViewMenu} { ui_.get()->setupUi(this); } UserphraseViewMenu::~UserphraseViewMenu() { } void UserphraseViewMenu::execWithSelectInfo(const QPoint &point, int selected) { switch (selected) { case 0: ui_.get()->actionModifyPhrase->setEnabled(false); ui_.get()->actionRemovePhrase->setEnabled(false); break; case 1: ui_.get()->actionModifyPhrase->setEnabled(true); ui_.get()->actionRemovePhrase->setEnabled(true); break; default: ui_.get()->actionModifyPhrase->setEnabled(false); ui_.get()->actionRemovePhrase->setEnabled(true); break; } exec(point); } QAction *UserphraseViewMenu::getActionAddPhrase() { return ui_.get()->actionAddPhrase; } QAction *UserphraseViewMenu::getActionModifyPhrase() { return ui_.get()->actionModifyPhrase; } QAction *UserphraseViewMenu::getActionRemovePhrase() { return ui_.get()->actionRemovePhrase; } chewing-editor-0.1.2/src/view/UserphraseViewMenu.h000066400000000000000000000026601504106013400221330ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include namespace Ui { class UserphraseViewMenu; } class UserphraseViewMenu final : public QMenu { Q_OBJECT public: explicit UserphraseViewMenu(QWidget *parent = 0); UserphraseViewMenu(const UserphraseViewMenu&) = delete; UserphraseViewMenu& operator=(const UserphraseViewMenu&) = delete; virtual ~UserphraseViewMenu(); QAction *getActionAddPhrase(); QAction *getActionModifyPhrase(); QAction *getActionRemovePhrase(); public slots: void execWithSelectInfo(const QPoint &point, int selected); private: std::unique_ptr ui_; }; chewing-editor-0.1.2/test/000077500000000000000000000000001504106013400153735ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/000077500000000000000000000000001504106013400163045ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/import/000077500000000000000000000000001504106013400176165ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/import/json/000077500000000000000000000000001504106013400205675ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/import/json/broken/000077500000000000000000000000001504106013400220475ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/import/json/broken/not_json.json000066400000000000000000000000301504106013400245640ustar00rootroot00000000000000This is not a json file chewing-editor-0.1.2/test/data/import/json/broken/root_not_object.json000066400000000000000000000000041504106013400261250ustar00rootroot00000000000000[ ] chewing-editor-0.1.2/test/data/import/json/broken/userphrase_not_array.json000066400000000000000000000000601504106013400271750ustar00rootroot00000000000000{ "userphrase": "userphrase is not array" } chewing-editor-0.1.2/test/data/import/json/chewing_one_valid_phrase.json000066400000000000000000000004671504106013400264770ustar00rootroot00000000000000{ "userphrase": [ { "bopomofo": "ㄘㄜˋ ㄕˋ", "phrase": "測試" }, { "bopomofo": "ㄘㄜˋ ㄕˋ" }, { "phrase": "測試" }, { "bopomofo": [], "phrase": [] } ] } chewing-editor-0.1.2/test/data/import/uhash.dat/000077500000000000000000000000001504106013400214755ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/import/uhash.dat/broken/000077500000000000000000000000001504106013400227555ustar00rootroot00000000000000chewing-editor-0.1.2/test/data/import/uhash.dat/broken/corrupted_chewing_lifetime000066400000000000000000000000071504106013400302660ustar00rootroot00000000000000CBiHchewing-editor-0.1.2/test/data/import/uhash.dat/broken/corrupted_signature000066400000000000000000000000031504106013400267610ustar00rootroot00000000000000CBichewing-editor-0.1.2/test/data/import/uhash.dat/broken/wrong_signature000066400000000000000000000004021504106013400261110ustar00rootroot00000000000000CBihf$f$f$("測試P)P)P)一下chewing-editor-0.1.2/test/data/import/uhash.dat/uhash.dat000066400000000000000000000004021504106013400232730ustar00rootroot00000000000000CBiHf$f$f$("測試P)P)P)一下chewing-editor-0.1.2/test/testChewingExporter.cpp000066400000000000000000000060251504106013400221170ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gtest/gtest.h" #include #include #include #include #include #include #include "ChewingExporter.h" class TestChewingExporter : public ::testing::Test { protected: TestChewingExporter(); virtual ~TestChewingExporter() = default; virtual void SetUp() {} virtual void TearDown() {} QTemporaryDir dir_; QString path_; }; TestChewingExporter::TestChewingExporter() :dir_() ,path_() { path_ = QString("%1/chewing.json").arg(dir_.path()); //dir_.setAutoRemove(false); } TEST_F(TestChewingExporter, WriteNoUserphrase) { ASSERT_TRUE(dir_.isValid()); ChewingExporter exporter(path_); ASSERT_TRUE(exporter.save()); QFile file{QString{path_}}; ASSERT_TRUE(file.open(QIODevice::ReadOnly | QIODevice::Text)); auto root = QJsonDocument::fromJson(file.readAll()).object(); auto userphrase = root.value("userphrase"); ASSERT_TRUE(userphrase.isArray()); auto array = userphrase.toArray(); ASSERT_EQ(0, array.size()); } TEST_F(TestChewingExporter, WriteOneUserphrase) { ASSERT_TRUE(dir_.isValid()); ChewingExporter exporter(path_.toStdString().c_str()); exporter.addUserphrase( QString("\xE6\xB8\xAC\xE8\xA9\xA6" /* 測試 */), QString("\xE3\x84\x98\xE3\x84\x9C\xCB\x8B \xE3\x84\x95\xCB\x8B" /* ㄘㄜˋ ㄕˋ */) ); ASSERT_TRUE(exporter.save()); QFile file{path_}; ASSERT_TRUE(file.open(QIODevice::ReadOnly | QIODevice::Text)); auto root = QJsonDocument::fromJson(file.readAll()).object(); auto userphrase = root.value("userphrase"); ASSERT_TRUE(userphrase.isArray()); auto array = userphrase.toArray(); ASSERT_EQ(1, array.size()); ASSERT_TRUE(array.at(0).isObject()); auto obj = array.at(0).toObject(); EXPECT_EQ( QString("\xE6\xB8\xAC\xE8\xA9\xA6" /* 測試 */), obj["phrase"].toString()); EXPECT_EQ( QString("\xE3\x84\x98\xE3\x84\x9C\xCB\x8B \xE3\x84\x95\xCB\x8B" /* ㄘㄜˋ ㄕˋ */), obj["bopomofo"].toString()); } TEST_F(TestChewingExporter, PathError) { ASSERT_TRUE(dir_.isValid()); ChewingExporter exporter{TESTDATA "/NoSuchPath/chewing.json"}; ASSERT_FALSE(exporter.save()); } chewing-editor-0.1.2/test/testChewingImporter.cpp000066400000000000000000000045361504106013400221150ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gtest/gtest.h" #include #include #include "ChewingImporter.h" class TestChewingImporter : public ::testing::Test { protected: TestChewingImporter() = default; virtual ~TestChewingImporter() = default; virtual void SetUp() {} virtual void TearDown() {} }; TEST_F(TestChewingImporter, ReadNoUserphrase) { auto list = QDir{TESTDATA "/import/json/broken"}.entryList(QDir::Files); ASSERT_GT(list.size(), 0); foreach(auto file, list) { auto path = QString("%1/%2").arg(TESTDATA "/import/json/broken").arg(file); ChewingImporter importer{path}; EXPECT_FALSE(importer.isSupportedFormat()); EXPECT_TRUE(importer.getUserphraseSet().empty()); } } TEST_F(TestChewingImporter, ReadOneUserphrase) { QString path{TESTDATA "/import/json/chewing_one_valid_phrase.json"}; ChewingImporter importer{path}; EXPECT_TRUE(importer.isSupportedFormat()); EXPECT_EQ(QFileInfo{path}.fileName(), importer.getPath()); auto result = importer.getUserphraseSet(); ASSERT_EQ(1, result.size()); EXPECT_EQ(0, QString::compare( QString("\xE6\xB8\xAC\xE8\xA9\xA6" /* 測試 */), result[0].phrase_)); EXPECT_EQ(0, QString::compare( QString("\xE3\x84\x98\xE3\x84\x9C\xCB\x8B \xE3\x84\x95\xCB\x8B" /* ㄘㄜˋ ㄕˋ */), result[0].bopomofo_)); } TEST_F(TestChewingImporter, PathError) { ChewingImporter importer{TESTDATA "/NoSuchPath/chewing.json"}; EXPECT_FALSE(importer.isSupportedFormat()); EXPECT_TRUE(importer.getUserphraseSet().empty()); } chewing-editor-0.1.2/test/testHashImporter.cpp000066400000000000000000000051401504106013400214040ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gtest/gtest.h" #include #include #include "HashImporter.h" class TestHashImporter : public ::testing::Test { protected: TestHashImporter() = default; virtual ~TestHashImporter() = default; virtual void SetUp() {} virtual void TearDown() {} }; TEST_F(TestHashImporter, ReadUserphrase) { QString path{TESTDATA "/import/uhash.dat/uhash.dat"}; HashImporter importer{path}; EXPECT_TRUE(importer.isSupportedFormat()); EXPECT_EQ(QFileInfo{path}.fileName(), importer.getPath()); auto result = importer.getUserphraseSet(); EXPECT_EQ(2, result.size()); EXPECT_EQ(0, QString::compare( QString("\xE6\xB8\xAC\xE8\xA9\xA6" /* 測試 */), result[0].phrase_)); EXPECT_EQ(0, QString::compare( QString("\xE3\x84\x98\xE3\x84\x9C\xCB\x8B \xE3\x84\x95\xCB\x8B" /* ㄘㄜˋ ㄕˋ */), result[0].bopomofo_)); EXPECT_EQ(0, QString::compare( QString("\xE4\xB8\x80\xE4\xB8\x8B" /* 一下 */), result[1].phrase_)); EXPECT_EQ(0, QString::compare( QString("\xE3\x84\xA7\xCB\x8A \xE3\x84\x92\xE3\x84\xA7\xE3\x84\x9A\xCB\x8B" /* ㄧˊ ㄒㄧㄚˋ */), result[1].bopomofo_)); } TEST_F(TestHashImporter, ReadBrokenHash) { auto list = QDir{TESTDATA "/import/uhash.dat/broken"}.entryList(QDir::Files); ASSERT_GT(list.size(), 0); foreach(auto file, list) { auto path = QString("%1/%2").arg(TESTDATA "/import/uhash.dat/broken").arg(file); HashImporter importer{path}; EXPECT_FALSE(importer.isSupportedFormat()); EXPECT_TRUE(importer.getUserphraseSet().empty()); } } TEST_F(TestHashImporter, PathError) { HashImporter importer{TESTDATA "/NoSuchPath/uhash.dat"}; EXPECT_FALSE(importer.isSupportedFormat()); EXPECT_TRUE(importer.getUserphraseSet().empty()); } chewing-editor-0.1.2/test/testUserphraseImporter.cpp000066400000000000000000000031111504106013400226360ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gtest/gtest.h" #include #include "UserphraseImporter.h" class TestUserphraseImporter : public ::testing::Test { protected: TestUserphraseImporter() = default; virtual ~TestUserphraseImporter() = default; }; TEST_F(TestUserphraseImporter, createUserphraseImporter) { std::shared_ptr importer; importer = createUserphraseImporter(QString{TESTDATA "/import/json/chewing_one_valid_phrase.json"}); EXPECT_TRUE(importer.get()->isSupportedFormat()); importer = createUserphraseImporter(QString{TESTDATA "/import/uhash.dat/uhash.dat"}); EXPECT_TRUE(importer.get()->isSupportedFormat()); importer = createUserphraseImporter(QString{TESTDATA "/NoSuchPath/NoSuchFile"}); EXPECT_FALSE(importer.get()->isSupportedFormat()); } chewing-editor-0.1.2/test/testUserphraseSet.cpp000066400000000000000000000103211504106013400215710ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "gtest/gtest.h" #include "UserphraseSet.h" #if (defined _MSC_VER) && (_MSC_VER >= 1600) # pragma execution_character_set("utf-8") #endif class TestUserphraseSet : public ::testing::Test { protected: TestUserphraseSet() = default; virtual ~TestUserphraseSet() = default; UserphraseSet set_; }; /* * Use macro here because we want to know line number when it fails. Function * will hide line number. */ #define COMPARE_USERPHRASE(it, phrase, bopomofo) do { \ EXPECT_EQ(0, QString::compare((phrase), (it)->phrase_)); \ EXPECT_EQ(0, QString::compare((bopomofo), (it)->bopomofo_)); \ } while (0) TEST_F(TestUserphraseSet, InsertDuplicated) { ASSERT_TRUE(set_.insert(Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_FALSE(set_.insert(Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_EQ(1, set_.size()); COMPARE_USERPHRASE(set_.begin(), "測試", "ㄘㄜˋ ㄕˋ"); } TEST_F(TestUserphraseSet, IndexOperator) { ASSERT_TRUE(set_.insert(Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_EQ(1, set_.size()); EXPECT_EQ(0, QString::compare("測試", set_[0].phrase_)); EXPECT_EQ(0, QString::compare("ㄘㄜˋ ㄕˋ", set_[0].bopomofo_)); } TEST_F(TestUserphraseSet, Enumerate) { Userphrase data[] = { Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")}, Userphrase{QString("一下"), QString("ㄧˊ ㄒㄧㄚˋ")}, }; ASSERT_TRUE(set_.insert(Userphrase{data[0]})); ASSERT_TRUE(set_.insert(Userphrase{data[1]})); ASSERT_EQ(2, set_.size()); int i = 0; for (auto it = set_.begin(); it != set_.end(); ++it, ++i) { COMPARE_USERPHRASE(it, data[i].phrase_, data[i].bopomofo_); } } TEST_F(TestUserphraseSet, Erase) { ASSERT_TRUE(set_.insert(Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_TRUE(set_.insert(Userphrase{QString("一下"), QString("ㄧˊ ㄒㄧㄚˋ")})); ASSERT_EQ(2, set_.size()); set_.erase(set_.begin()); ASSERT_EQ(1, set_.size()); COMPARE_USERPHRASE(set_.begin(), "一下", "ㄧˊ ㄒㄧㄚˋ"); } TEST_F(TestUserphraseSet, SamePhraseDifferentBopomofo) { ASSERT_TRUE(set_.insert(Userphrase{QString("什麼"), QString("ㄕㄣˊ ㄇㄜ˙")})); ASSERT_TRUE(set_.insert(Userphrase{QString("什麼"), QString("ㄕㄜˊ ㄇㄜ˙")})); ASSERT_EQ(2, set_.size()); COMPARE_USERPHRASE(set_.begin(), "什麼", "ㄕㄣˊ ㄇㄜ˙"); COMPARE_USERPHRASE(set_.begin() + 1, "什麼", "ㄕㄜˊ ㄇㄜ˙"); set_.erase(set_.begin()); ASSERT_EQ(1, set_.size()); COMPARE_USERPHRASE(set_.begin(), "什麼", "ㄕㄜˊ ㄇㄜ˙"); } TEST_F(TestUserphraseSet, DifferentPhraseSameBopomofo) { ASSERT_TRUE(set_.insert(Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_TRUE(set_.insert(Userphrase{QString("策試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_EQ(2, set_.size()); COMPARE_USERPHRASE(set_.begin(), "測試", "ㄘㄜˋ ㄕˋ"); COMPARE_USERPHRASE(set_.begin() + 1, "策試", "ㄘㄜˋ ㄕˋ"); set_.erase(set_.begin() + 1); ASSERT_EQ(1, set_.size()); COMPARE_USERPHRASE(set_.begin(), "測試", "ㄘㄜˋ ㄕˋ"); } TEST_F(TestUserphraseSet, Swap) { ASSERT_TRUE(set_.insert(Userphrase{QString("測試"), QString("ㄘㄜˋ ㄕˋ")})); ASSERT_EQ(1, set_.size()); UserphraseSet set; set.swap(set_); EXPECT_EQ(0, set_.size()); EXPECT_EQ(1, set.size()); } chewing-editor-0.1.2/test/testmain.cpp000066400000000000000000000042441504106013400177270ustar00rootroot00000000000000/* * chewing-editor: Chewing userphrase editor * Copyright (C) 2014 Chewing Development Team * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "gtest/gtest.h" bool verbose = false; void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { auto msg = message.toUtf8(); auto file = QFileInfo{context.file}.fileName().toUtf8(); if (!verbose) { return; } switch(type) { case QtDebugMsg: fprintf(stdout, "Debug: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s %s:%d)\n", msg.constData(), context.function, file.constData(), context.line); abort(); break; default: break; } } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); qInstallMessageHandler(debugMessageHandler); for (int i = 0; i < argc; ++i) { if (strcmp(argv[i], "-v") == 0) { verbose = true; } if (strcmp(argv[i], "-s") == 0) { verbose = false; } } return RUN_ALL_TESTS(); } chewing-editor-0.1.2/ts/000077500000000000000000000000001504106013400150425ustar00rootroot00000000000000chewing-editor-0.1.2/ts/chewing-editor_en_US.ts000066400000000000000000000220651504106013400214200ustar00rootroot00000000000000 ChewingEditor Chewing user phrase editor File Add Remove Search Help &Import &Export E&xit Refresh Undo About Chewing editor About Qt Import Export Notification %1 %2 %3 %1 %2 %n phrase(s) are imported. %n phrase is imported. %n phrases are imported. Total %n user phrase(s). Total %n user phrase. Total %n user phrases. %n phrase(s) are exported. %n phrase is exported. %n phrases are exported. Import "%1" successful. Import "%1" failed. Export "%1" successful. Export "%1" failed. Add new phrase %1 successful. Remove %n phrase(s) successful. Remove %n phrase successful. Remove %n phrases successful. Refresh completed. Total %n user phrase(s). Refresh completed. Total %n user phrase. Refresh completed. Total %n user phrases. Add new phrase failed. Please enter the bopomofo for each word and try again. Undo completed. Revert %1. UserphraseDialog Add new phrase Phrase: Bopomofo: UserphraseView Add new phrase Modify phrase UserphraseViewMenu Add Modify Remove main %1 chewing-editor is a cross platform chewing user phrase editor written in Qt5. It provides a user friendly GUI to manage user phrase. With it, user can customize user phrase to enhance chewing input performance. -d, --debug Enable debug message. -v, --version Print program version. -h, --help Print help message. chewing-editor-0.1.2/ts/chewing-editor_zh_TW.ts000066400000000000000000000256331504106013400214460ustar00rootroot00000000000000 ChewingEditor Chewing user phrase editor 新酷音詞庫編輯器 Filter 過濾 File 檔案 Edit 編輯 Add 新增 Remove 刪除 Search 搜尋 Help 求助 &Import 匯入(&I) &Export 匯出(&E) E&xit 離開(&X) Add phrase 新增詞彙 Remove phrase 刪除詞彙 Refresh 更新 Undo 復原 About Chewing editor 關於新酷音詞庫編輯器 About Qt 關於 Qt Import 匯入 Export 匯出 Do you want to delete this phrase? 你想要刪除這個詞彙嗎? Delete phrase 刪除詞彙 Notification %1 %2 %3 Import %1 successful. 成功匯入 "%1" 。 %n phrase(s) are imported. 匯入 %n 個詞彙。 Total %n user phrase(s). 目前共有 %n 個詞彙。 %1 %2 %n phrase(s) are exported. 有 %n 個詞彙被匯出。 Import "%1" successful. 成功匯入 "%1" 。 Import "%1" failed. 無法匯入 "%1"。 Export "%1" successful. 成功匯出 "%1" 。 Export "%1" failed. 匯出 "%1" 失敗。 Add new phrase %1 successful. 成功新增 「%1」。 Remove %n phrase(s) successful. 成功移除 %n 個詞彙。 Refresh completed. Total %n user phrase(s). 更新完成。共有 %n 個詞彙。 Add new phrase failed. Please enter the bopomofo for each word and try again. 新增詞彙失敗。請輸入每個字的注音後再試一次。 Undo completed. Revert %1. 復原完成。復原 「%1」。 UserphraseDialog Add new user phrase 新增詞彙 phrase 詞彙 bopomofo 注音 Add new phrase 新增詞彙 Phrase: 詞彙: Bopomofo: 注音: UserphraseView Add new phrase 新增詞彙 Modify phrase 修改詞彙 UserphraseViewMenu Add 新增 Modify 修改 Remove 刪除 main %1 chewing-editor is a cross platform chewing user phrase editor written in Qt5. It provides a user friendly GUI to manage user phrase. With it, user can customize user phrase to enhance chewing input performance. 新酷音詞庫編輯器是一個使用 Qt5 撰寫的跨平台新酷音詞彙編輯器。他提供了友善的圖形化使用者界面讓使用者管理詞彙,讓使用者可以自行客製化詞庫以提昇新酷音輸入法的表現。 -d, --debug Enable debug message. 啟用偵錯資訊 -v, --version Print program version. 顯示程式版本資訊 -h, --help Print help message. 顯示說明訊息 chewing-editor-0.1.2/ts/ts.qrc000066400000000000000000000002241504106013400161750ustar00rootroot00000000000000 chewing-editor_en_US.qm chewing-editor_zh_TW.qm