pax_global_header00006660000000000000000000000064143363453620014523gustar00rootroot0000000000000052 comment=6c8e82ef597412613a741fbda6555eeedc315b86 kcm-fcitx-master/000077500000000000000000000000001433634536200142455ustar00rootroot00000000000000kcm-fcitx-master/.gitignore000066400000000000000000000001041433634536200162300ustar00rootroot00000000000000build/* *.kdev4 .kdev_include_paths .directory *.kate-swp *.orig *~ kcm-fcitx-master/CMakeLists.txt000066400000000000000000000062161433634536200170120ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.3 FATAL_ERROR) project(kcm-fcitx) set(QT_MIN_VERSION "5.11.0") find_package(ECM 1.0.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) include(FeatureSummary) option(ENABLE_TEST "Enable test" Off) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Core Gui Widgets X11Extras) find_package(KF5 5.64 REQUIRED COMPONENTS CoreAddons WidgetsAddons ConfigWidgets ItemViews I18n KIO ) find_package(FcitxQt5DBusAddons 1.1.0 REQUIRED) find_package(FcitxQt5WidgetsAddons 1.1.0 REQUIRED) set(MAJOR_VERSION "0") set(MINOR_VERSION "5") set(PATCH_VERSION "4") set(SUFFIX_VERSION "") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(VERSION_STRING "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}") if(NOT SUFFIX_VERSION) set(VERSION_STRING_FULL "${VERSION_STRING}") else(NOT SUFFIX_VERSION) set(VERSION_STRING_FULL "${VERSION_STRING}-${SUFFIX_VERSION}") endif(NOT SUFFIX_VERSION) find_package(PkgConfig REQUIRED) find_package(Gettext REQUIRED) find_package(Fcitx 4.2.8 REQUIRED) find_package(XkbFile REQUIRED) find_package(X11 REQUIRED) set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -fvisibility=hidden ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-sign-compare -Wno-unused-parameter -fvisibility=hidden ${CMAKE_CXX_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined,--as-needed ${CMAKE_SHARED_LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "-Wl,--no-undefined,--as-needed ${CMAKE_MODULE_LINKER_FLAGS}") string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" FCITX4_MAJOR_VERSION "${FCITX4_VERSION}") string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" FCITX4_MINOR_VERSION "${FCITX4_VERSION}") string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" FCITX4_PATCH_VERSION "${FCITX4_VERSION}") EXECUTE_PROCESS(COMMAND "${FCITX4_FCITXCONFIG_EXECUTABLE}" --exec-prefix OUTPUT_VARIABLE FCITX4_EXEC_PREFIX ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) set(package ${FCITX4_PACKAGE_NAME}) set(datadir ${CMAKE_INSTALL_PREFIX}/share) set(localedir ${CMAKE_INSTALL_PREFIX}/share/locale) set(exec_prefix "${CMAKE_INSTALL_PREFIX}/bin") find_program(some_x_program NAMES iceauth xrdb xterm) if (NOT some_x_program) set(some_x_program /usr/bin/xrdb) message("Warning: Could not determine X binary directory. Assuming /usr/bin.") endif (NOT some_x_program) get_filename_component(proto_xbindir "${some_x_program}" PATH) get_filename_component(XBINDIR "${proto_xbindir}" ABSOLUTE) get_filename_component(xrootdir "${XBINDIR}" PATH) set(XLIBDIR "${xrootdir}/lib/X11") configure_file(config.h.in config.h) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories( ${FCITX4_FCITX_INCLUDE_DIRS} ${FCITX4_FCITX_UTILS_INCLUDE_DIRS} ${FCITX4_FCITX_CONFIG_INCLUDE_DIRS} ) link_directories( ${FCITX4_FCITX_LIBRARY_DIRS} ${FCITX4_FCITX_UTILS_LIBRARY_DIRS} ${FCITX4_FCITX_CONFIG_LIBRARY_DIRS} ) add_subdirectory(po) add_subdirectory(src) add_subdirectory(layout) kcm-fcitx-master/COPYING000066400000000000000000000431051433634536200153030ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 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 Library 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 St, 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 Library General Public License instead of this License. kcm-fcitx-master/README000066400000000000000000000000001433634536200151130ustar00rootroot00000000000000kcm-fcitx-master/cmake/000077500000000000000000000000001433634536200153255ustar00rootroot00000000000000kcm-fcitx-master/cmake/FindXkbFile.cmake000066400000000000000000000021531433634536200204550ustar00rootroot00000000000000# - Try to find the XKBFILE libraries # Once done this will define # # XKBFILE_FOUND - system has XKBFILE # XKBFILE_INCLUDE_DIR - the XKBFILE include directory # XKBFILE_LIBRARIES - XKBFILE library # # Copyright (c) 2012 CSSlayer # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. if(XKBFILE_INCLUDE_DIR AND XKBFILE_LIBRARIES) # Already in cache, be silent set(XKBFILE_FIND_QUIETLY TRUE) endif(XKBFILE_INCLUDE_DIR AND XKBFILE_LIBRARIES) find_package(PkgConfig) pkg_check_modules(PC_LIBXKBFILE xkbfile) find_path(XKBFILE_MAIN_INCLUDE_DIR NAMES XKBfile.h HINTS ${PC_LIBXKBFILE_INCLUDEDIR} PATH_SUFFIXES "X11/extensions") find_library(XKBFILE_LIBRARIES NAMES xkbfile HINTS ${PC_LIBXKBFILE_LIBDIR}) set(XKBFILE_INCLUDE_DIR "${XKBFILE_MAIN_INCLUDE_DIR}") include(FindPackageHandleStandardArgs) find_package_handle_standard_args(XkbFile DEFAULT_MSG XKBFILE_LIBRARIES XKBFILE_MAIN_INCLUDE_DIR) mark_as_advanced(XKBFILE_INCLUDE_DIR XKBFILE_LIBRARIES) kcm-fcitx-master/config.h.in000066400000000000000000000013001433634536200162620ustar00rootroot00000000000000#define VERSION_STRING_FULL "@VERSION_STRING_FULL@" #define DATADIR "@datadir@" #define LOCALEDIR "@localedir@" #define EXEC_PREFIX "@exec_prefix@" #define PACKAGE "@package@" #cmakedefine XLIBDIR "@XLIBDIR@" #define FCITX4_EXEC_PREFIX "@FCITX4_EXEC_PREFIX@" #define FCITX4_MAJOR_VERSION @FCITX4_MAJOR_VERSION@ #define FCITX4_MINOR_VERSION @FCITX4_MINOR_VERSION@ #define FCITX4_PATCH_VERSION @FCITX4_PATCH_VERSION@ #define FCITX_CHECK_VERSION(major,minor,micro) \ (FCITX4_MAJOR_VERSION > (major) || \ (FCITX4_MAJOR_VERSION == (major) && FCITX4_MINOR_VERSION > (minor)) || \ (FCITX4_MAJOR_VERSION == (major) && FCITX4_MINOR_VERSION == (minor) && \ FCITX4_PATCH_VERSION >= (micro)))kcm-fcitx-master/layout/000077500000000000000000000000001433634536200155625ustar00rootroot00000000000000kcm-fcitx-master/layout/CMakeLists.txt000066400000000000000000000014051433634536200203220ustar00rootroot00000000000000include_directories( ${X11_Xkb_INCLUDE_PATH} ${X11_Xkblib_INCLUDE_PATH} ) set(kbd_layout_viewer_SOURCES main.cpp keyboardlayoutwidget.cpp ) fcitx_translate_add_sources(${kbd_layout_viewer_SOURCES} kbd-layout-viewer.desktop.in) add_executable(kbd-layout-viewer ${kbd_layout_viewer_SOURCES}) target_link_libraries(kbd-layout-viewer ${FCITX4_FCITX_CONFIG_LIBRARIES} Qt5::Widgets KF5::I18n Qt5::X11Extras ${X11_X11_LIB} ${XKBFILE_LIBRARIES} ${X11_Xkblib_LIB}) install(TARGETS kbd-layout-viewer DESTINATION ${BIN_INSTALL_DIR}) fcitx_translate_add_apply_source( kbd-layout-viewer.desktop.in "${CMAKE_CURRENT_BINARY_DIR}/kbd-layout-viewer.desktop") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kbd-layout-viewer.desktop" DESTINATION ${CMAKE_INSTALL_APPDIR}) kcm-fcitx-master/layout/deadmapdata.h000066400000000000000000000024501433634536200201610ustar00rootroot00000000000000struct DeadMap { uint dead; uint nondead; } deadMapData[] = { {XK_dead_grave, 0x0060}, {XK_dead_acute, 0x00b4}, {XK_dead_circumflex, 0x02c6}, {XK_dead_tilde, 0x02dc}, {XK_dead_macron, 0x00af}, {XK_dead_breve, 0x02D8}, {XK_dead_abovedot, 0x02D9}, {XK_dead_diaeresis, 0x00A8}, {XK_dead_abovering, 0x02DA}, {XK_dead_doubleacute, 0x02DD}, {XK_dead_caron, 0x02C7}, {XK_dead_cedilla, 0x00B8}, {XK_dead_ogonek, 0x02DB}, {XK_dead_iota, 0x0269}, {XK_dead_voiced_sound, 0x309B}, {XK_dead_semivoiced_sound, 0x309A}, {XK_dead_belowdot, 0x0323}, {XK_dead_hook, 0x0309}, {XK_dead_horn, 0x031b}, {XK_dead_stroke, 0x0335}, {XK_dead_abovecomma, 0x0312}, {XK_dead_abovereversedcomma, 0x0314}, {XK_dead_doublegrave, 0x030f}, {XK_dead_belowring, 0x0325}, {XK_dead_belowmacron, 0x0331}, {XK_dead_belowcircumflex, 0x032D}, {XK_dead_belowtilde, 0x0330}, {XK_dead_belowbreve, 0x032e}, {XK_dead_belowdiaeresis, 0x0324}, {XK_dead_invertedbreve, 0x0311}, {XK_dead_belowcomma, 0x0326}, {XK_dead_currency, 0x00A4}, /* dead vowels for universal syllable entry */ {XK_dead_a, 0x0061}, {XK_dead_A, 0x0041}, {XK_dead_e, 0x0065}, {XK_dead_E, 0x0045}, {XK_dead_i, 0x0069}, {XK_dead_I, 0x0049}, {XK_dead_o, 0x006f}, {XK_dead_O, 0x004f}, {XK_dead_u, 0x0075}, {XK_dead_U, 0x0055}, {XK_dead_small_schwa, 0x0259}, {XK_dead_capital_schwa, 0x018F}, }; kcm-fcitx-master/layout/kbd-layout-viewer.desktop.in000066400000000000000000000003071433634536200231340ustar00rootroot00000000000000[Desktop Entry] Exec=kbd-layout-viewer Icon=input-keyboard Type=Application _Name=Keyboard layout viewer _Comment=View keyboard layout _X-KDE-Keywords=keyboard;input;im Categories=Qt;KDE;Utility; kcm-fcitx-master/layout/keyboardlayoutwidget.cpp000066400000000000000000001272571433634536200225460ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include static const int XKeyPress = KeyPress; static const int XKeyRelease = KeyRelease; #undef KeyPress #undef KeyRelease #include #include #include "config.h" #include "keyboardlayoutwidget.h" #include "deadmapdata.h" #define INVALID_KEYCODE ((uint)(-1)) #define TEXT_SIZE (0.8) #ifndef XKB_RULES_XML_FILE #define XKB_RULES_XML_FILE "/usr/share/X11/xkb/rules/evdev.xml" #endif struct DrawingItemCompare { bool operator() (const DrawingItem* a, const DrawingItem* b) { return a->priority < b->priority; } }; static KeyboardDrawingGroupLevel defaultGroupsLevels[] = { {0, 1}, {0, 3}, {0, 0}, {0, 2} }; static KeyboardDrawingGroupLevel *pGroupsLevels[] = { defaultGroupsLevels, defaultGroupsLevels + 1, defaultGroupsLevels + 2, defaultGroupsLevels + 3 }; static bool FcitxXkbInitDefaultLayout (QStringList& layout, QStringList& variant); static bool FcitxXkbInitDefaultOption (QString& model, QString& option); static QString FcitxXkbGetRulesName() { XkbRF_VarDefsRec vd; char *tmp = NULL; if (XkbRF_GetNamesProp(QX11Info::display(), &tmp, &vd) && tmp != NULL ) { return tmp; } return QString(); } static QString FcitxXkbFindXkbRulesFile() { QString rulesFile; QString rulesName = FcitxXkbGetRulesName(); if ( rulesName.isNull() ) { QString xkbParentDir; const QString base = XLIBDIR; int count = base.count('/'); if( count >= 3 ) { // .../usr/lib/X11 -> /usr/share/X11/xkb vs .../usr/X11/lib -> /usr/X11/share/X11/xkb const char* delta = base.endsWith("X11") ? "/../../share/X11" : "/../share/X11"; QString dirPath = base + delta; QDir dir(dirPath); if( dir.exists() ) { xkbParentDir = dir.canonicalPath(); } else { dirPath = dirPath + "/X11"; dir = QDir(dirPath); if( dir.exists() ) { xkbParentDir = dir.canonicalPath(); } } } if( xkbParentDir.isEmpty() ) { xkbParentDir = "/usr/share/X11"; } rulesFile = QString("%1/xkb/rules/%2.xml").arg(xkbParentDir).arg(rulesName); } if (rulesFile.isNull()) rulesFile = XKB_RULES_XML_FILE; return rulesFile; } static KeySym normalizedKeySym(KeySym sym) { if (sym == XK_ISO_Left_Tab) { return XK_Tab; } return sym; } KeyboardLayoutWidget::KeyboardLayoutWidget(QWidget* parent): QWidget(parent), ratio(1.0), trackModifiers(false ) { uint i = 0; for (i = 0; i < sizeof(deadMapData) / sizeof(deadMapData[0]); i ++) deadMap[deadMapData[i].dead] = deadMapData[i].nondead; xkb = XkbGetKeyboard (QX11Info::display(), XkbGBN_GeometryMask | XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask | XkbGBN_SymbolsMask | XkbGBN_IndicatorMapMask, XkbUseCoreKbd); if (!xkb) return; groupLevels = pGroupsLevels; XkbGetNames (QX11Info::display(), XkbAllNamesMask, xkb); l3mod = XkbKeysymToModifiers (QX11Info::display(), XK_ISO_Level3_Shift); xkbOnDisplay = true; alloc (); init(); initColors(); setFocusPolicy(Qt::StrongFocus); } void KeyboardLayoutWidget::setGroup(int group) { XkbRF_VarDefsRec rdefs; XkbComponentNamesRec rnames; QString rulesPath = "./rules/evdev"; char c[] = "C"; XkbRF_RulesPtr rules = XkbRF_Load (rulesPath.toLocal8Bit().data(), c, True, True); if (rules == NULL) { rulesPath = FcitxXkbFindXkbRulesFile(); if (rulesPath.endsWith(".xml")) { rulesPath.chop(4); } rules = XkbRF_Load (rulesPath.toLocal8Bit().data(), c, True, True); } if (rules == NULL) { return; } memset (&rdefs, 0, sizeof (XkbRF_VarDefsRec)); memset (&rnames, 0, sizeof (XkbComponentNamesRec)); QString model, option; QStringList layouts, variants; if (!FcitxXkbInitDefaultOption(model, option)) return; if (!FcitxXkbInitDefaultLayout(layouts, variants)) return; rdefs.model = !model.isNull() ? strdup(model.toUtf8().constData()) : NULL; rdefs.layout = layouts.count() > group ? strdup(layouts[group].toUtf8().constData()) : NULL; rdefs.variant = variants.count() > group ? strdup(variants[group].toUtf8().constData()) : NULL; rdefs.options = !option.isNull() ? strdup(option.toUtf8().constData()) : NULL; XkbRF_GetComponents (rules, &rdefs, &rnames); free (rdefs.model); free (rdefs.layout); free (rdefs.variant); free (rdefs.options); setKeyboard(&rnames); } static bool FcitxXkbInitDefaultOption (QString& model, QString& option) { Display* dpy = QX11Info::display(); XkbRF_VarDefsRec vd; char *tmp = NULL; if (!XkbRF_GetNamesProp(dpy, &tmp, &vd) || !tmp) return false; if (!vd.model || !vd.layout) return false; if (vd.model) model = vd.model; else model = QString(); if (vd.options) option = vd.options; else option = QString(); return true; } static bool FcitxXkbInitDefaultLayout (QStringList& layout, QStringList& variant) { Display* dpy = QX11Info::display(); XkbRF_VarDefsRec vd; char *tmp = NULL; if (!XkbRF_GetNamesProp(dpy, &tmp, &vd) || !tmp) return false; if (!vd.model || !vd.layout) return false; QString variantString, layoutString; if (vd.layout) layoutString = vd.layout; else layoutString = QString(); if (vd.variant) variantString = vd.variant; else variantString = QString(); layout = layoutString.split(','); variant = variantString.split(','); return true; } void KeyboardLayoutWidget::setKeyboardLayout(const QString& layout, const QString& variant) { XkbRF_VarDefsRec rdefs; XkbComponentNamesRec rnames; QString rulesPath = "./rules/evdev"; char c[] = "C"; XkbRF_RulesPtr rules = XkbRF_Load (rulesPath.toLocal8Bit().data(), c, True, True); if (rules == NULL) { rulesPath = FcitxXkbFindXkbRulesFile(); if (rulesPath.endsWith(".xml")) { rulesPath.chop(4); } rules = XkbRF_Load (rulesPath.toLocal8Bit().data(), c, True, True); } if (rules == NULL) { return; } memset (&rdefs, 0, sizeof (XkbRF_VarDefsRec)); memset (&rnames, 0, sizeof (XkbComponentNamesRec)); QString model, option; if (!FcitxXkbInitDefaultOption(model, option)) return; rdefs.model = !model.isNull() ? strdup(model.toUtf8().constData()) : NULL; rdefs.layout = !layout.isNull() ? strdup(layout.toUtf8().constData()) : NULL; rdefs.variant = !variant.isNull() ? strdup(variant.toUtf8().constData()) : NULL; rdefs.options = !option.isNull() ? strdup(option.toUtf8().constData()) : NULL; XkbRF_GetComponents (rules, &rdefs, &rnames); free (rdefs.model); free (rdefs.layout); free (rdefs.variant); free (rdefs.options); setKeyboard(&rnames); } void KeyboardLayoutWidget::setKeyboard(XkbComponentNamesPtr names) { release(); if (xkb) XkbFreeKeyboard(xkb, 0, true); if (names) { xkb = XkbGetKeyboardByName (QX11Info::display(), XkbUseCoreKbd, names, 0, XkbGBN_GeometryMask | XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask | XkbGBN_ClientSymbolsMask | XkbGBN_IndicatorMapMask, false); xkbOnDisplay = false; } else { xkb = XkbGetKeyboard (QX11Info::display(), XkbGBN_GeometryMask | XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask | XkbGBN_SymbolsMask | XkbGBN_IndicatorMapMask, XkbUseCoreKbd); XkbGetNames (QX11Info::display(), XkbAllNamesMask, xkb); xkbOnDisplay = true; } if (xkb == NULL) return; alloc (); init(); initColors(); generatePixmap(true); repaint(); } void KeyboardLayoutWidget::alloc() { physicalIndicators.clear(); physicalIndicatorsSize = xkb->indicators->phys_indicators + 1; physicalIndicators.reserve(physicalIndicatorsSize); for (int i = 0; i < physicalIndicatorsSize; i++) physicalIndicators << NULL; keys = new DrawingKey[xkb->max_key_code + 1]; } void KeyboardLayoutWidget::release() { physicalIndicators.clear(); physicalIndicatorsSize = 0; if (keys) { delete[] keys; keys = NULL; } if (colors) { delete[] colors; colors = NULL; } foreach(DrawingItem* item, keyboardItems) { switch (item->type) { case KEYBOARD_DRAWING_ITEM_TYPE_INVALID: case KEYBOARD_DRAWING_ITEM_TYPE_KEY: break; case KEYBOARD_DRAWING_ITEM_TYPE_KEY_EXTRA: case KEYBOARD_DRAWING_ITEM_TYPE_DOODAD: delete item; break; } } keyboardItems.clear(); } void KeyboardLayoutWidget::init() { int i, j, k; int x, y; if (!xkb) return; for (i = 0; i < xkb->geom->num_doodads; i++) { XkbDoodadRec *xkbdoodad = xkb->geom->doodads + i; Doodad* doodad = new Doodad; doodad->type = KEYBOARD_DRAWING_ITEM_TYPE_DOODAD; doodad->originX = 0; doodad->originY = 0; doodad->angle = 0; doodad->priority = xkbdoodad->any.priority * 256 * 256; doodad->doodad = xkbdoodad; initInicatorDoodad (xkbdoodad, *doodad); keyboardItems << doodad; } for (i = 0; i < xkb->geom->num_sections; i++) { XkbSectionRec *section = xkb->geom->sections + i; uint priority; // qDebug() << "initing section " << i << " containing " << section->num_rows << " rows\n"; x = section->left; y = section->top; priority = section->priority * 256 * 256; for (j = 0; j < section->num_rows; j++) { XkbRowRec *row = section->rows + j; // qDebug() << " initing row " << j; x = section->left + row->left; y = section->top + row->top; for (k = 0; k < row->num_keys; k++) { XkbKeyRec *xkbkey = row->keys + k; DrawingKey* key; XkbShapeRec *shape = xkb->geom->shapes + xkbkey->shape_ndx; uint keycode = findKeycode (xkbkey->name.name); if (keycode == INVALID_KEYCODE) continue; // qDebug() << " initing key " << k << ", shape: " // << shape << "(" << xkb->geom->shapes <<" + " << xkbkey->shape_ndx << "), code: " << keycode; if (row->vertical) y += xkbkey->gap; else x += xkbkey->gap; if (keycode >= xkb->min_key_code && keycode <= xkb->max_key_code) { key = &keys[keycode]; if (key->type == KEYBOARD_DRAWING_ITEM_TYPE_INVALID) { key->type = KEYBOARD_DRAWING_ITEM_TYPE_KEY; } else { /* duplicate key for the same keycode, already defined as KEYBOARD_DRAWING_ITEM_TYPE_KEY */ key = new DrawingKey; key->type = KEYBOARD_DRAWING_ITEM_TYPE_KEY_EXTRA; } } else { key = new DrawingKey; key->type = KEYBOARD_DRAWING_ITEM_TYPE_KEY_EXTRA; } key->xkbkey = xkbkey; key->angle = section->angle; rotateRectangle (section->left, section->top, x, y, section->angle, key->originX, key->originY); key->priority = priority; key->keycode = keycode; keyboardItems << key; if (row->vertical) y += shape->bounds.y2; else x += shape->bounds.x2; priority++; } } for (j = 0; j < section->num_doodads; j++) { XkbDoodadRec *xkbdoodad = section->doodads + j; Doodad *doodad = new Doodad; doodad->type = KEYBOARD_DRAWING_ITEM_TYPE_DOODAD; doodad->originX = x; doodad->originY = y; doodad->angle = section->angle; doodad->priority = priority + xkbdoodad->any.priority; doodad->doodad = xkbdoodad; initInicatorDoodad (xkbdoodad, *doodad); keyboardItems << doodad; } } std::sort(keyboardItems.begin(), keyboardItems.end(), DrawingItemCompare()); } void KeyboardLayoutWidget::initColors() { bool result; int i; if (!xkb) return; colors = new QColor[xkb->geom->num_colors]; for (i = 0; i < xkb->geom->num_colors; i++) { result = parseXkbColorSpec (xkb->geom->colors[i]. spec, colors[i]); if (!result) qWarning() << "init_colors: unable to parse color " << xkb->geom->colors[i].spec; } } void KeyboardLayoutWidget::focusOutEvent(QFocusEvent* event) { if (!xkb) { QWidget::focusOutEvent(event); return; } bool update = false; for (int i = xkb->min_key_code; i <= xkb->max_key_code; i ++) { if (keys[i].pressed) { update = true; keys[i].pressed = false; } } if (update) { generatePixmap(true); repaint(); } QWidget::focusOutEvent(event); } /* see PSColorDef in xkbprint */ bool KeyboardLayoutWidget::parseXkbColorSpec (char* colorspec, QColor& color) { long level; color.setAlphaF(1); if (strcasecmp (colorspec, "black") == 0) { color = Qt::black; } else if (strcasecmp (colorspec, "white") == 0) { color = Qt::white; } else if (strncasecmp (colorspec, "grey", 4) == 0 || strncasecmp (colorspec, "gray", 4) == 0) { level = strtol (colorspec + 4, NULL, 10); color.setRedF(1.0 - level / 100.0); color.setGreenF(1.0 - level / 100.0); color.setBlueF(1.0 - level / 100.0); } else if (strcasecmp (colorspec, "red") == 0) { color = Qt::red; } else if (strcasecmp (colorspec, "green") == 0) { color = Qt::green; } else if (strcasecmp (colorspec, "blue") == 0) { color = Qt::blue; } else if (strncasecmp (colorspec, "red", 3) == 0) { level = strtol (colorspec + 3, NULL, 10); color.setRedF(level / 100.0); color.setGreenF(0); color.setBlueF(0); } else if (strncasecmp (colorspec, "green", 5) == 0) { level = strtol (colorspec + 5, NULL, 10); color.setRedF(0); color.setGreenF(level / 100.0); color.setBlueF(0); } else if (strncasecmp (colorspec, "blue", 4) == 0) { level = strtol (colorspec + 4, NULL, 10); color.setRedF(0); color.setGreenF(0); color.setBlueF(level / 100.0); } else return false; return true; } uint KeyboardLayoutWidget::findKeycode(const char* keyName) { #define KEYSYM_NAME_MAX_LENGTH 4 uint keycode; int i, j; XkbKeyNamePtr pkey; XkbKeyAliasPtr palias; uint is_name_matched; const char *src, *dst; if (!xkb) return INVALID_KEYCODE; pkey = xkb->names->keys + xkb->min_key_code; for (keycode = xkb->min_key_code; keycode <= xkb->max_key_code; keycode++) { is_name_matched = 1; src = keyName; dst = pkey->name; for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) { if ('\0' == *src) break; if (*src++ != *dst++) { is_name_matched = 0; break; } } if (is_name_matched) { return keycode; } pkey++; } palias = xkb->names->key_aliases; for (j = xkb->names->num_key_aliases; --j >= 0;) { is_name_matched = 1; src = keyName; dst = palias->alias; for (i = KEYSYM_NAME_MAX_LENGTH; --i >= 0;) { if ('\0' == *src) break; if (*src++ != *dst++) { is_name_matched = 0; break; } } if (is_name_matched) { keycode = findKeycode (palias->real); return keycode; } palias++; } return INVALID_KEYCODE; } void KeyboardLayoutWidget::rotateRectangle(int origin_x, int origin_y, int x, int y, int angle, int& rotated_x, int& rotated_y) { rotated_x = origin_x + (x - origin_x) * cos (M_PI * angle / 1800.0) - (y - origin_y) * sin (M_PI * angle / 1800.0); rotated_y = origin_y + (x - origin_x) * sin (M_PI * angle / 1800.0) + (y - origin_y) * cos (M_PI * angle / 1800.0); } void KeyboardLayoutWidget::initInicatorDoodad(XkbDoodadRec * xkbdoodad, Doodad& doodad) { if (!xkb) return; if (xkbdoodad->any.type == XkbIndicatorDoodad) { int index; Atom iname = 0; Atom sname = xkbdoodad->indicator.name; unsigned long phys_indicators = xkb->indicators->phys_indicators; Atom *pind = xkb->names->indicators; for (index = 0; index < XkbNumIndicators; index++) { iname = *pind++; /* name matches and it is real */ if (iname == sname && (phys_indicators & (1 << index))) break; if (iname == 0) break; } if (iname == 0) return; else { physicalIndicators[index] = &doodad; /* Trying to obtain the real state, but if fail - just assume OFF */ if (!XkbGetNamedIndicator (QX11Info::display(), sname, NULL, &doodad.on, NULL, NULL)) doodad.on = 0; } } } void KeyboardLayoutWidget::generatePixmap(bool force) { if (!xkb) return; double ratioX = (double) width() / xkb->geom->width_mm; double ratioY = (double) height() / xkb->geom->height_mm; ratio = qMin(ratioX, ratioY); int w = xkb->geom->width_mm * ratio; int h = xkb->geom->height_mm * ratio; if (w == image.width() && h == image.height() && !force) return; image = QPixmap(QSize(w, h) * devicePixelRatio()); image.setDevicePixelRatio(devicePixelRatio()); image.fill(Qt::transparent); QPainter painter(&image); painter.setRenderHint(QPainter::Antialiasing, true); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.fillRect(image.rect(), Qt::transparent); foreach(DrawingItem* item , keyboardItems) { if (!xkb) return; switch (item->type) { case KEYBOARD_DRAWING_ITEM_TYPE_INVALID: break; case KEYBOARD_DRAWING_ITEM_TYPE_KEY: case KEYBOARD_DRAWING_ITEM_TYPE_KEY_EXTRA: drawKey (&painter, (DrawingKey *) item); break; case KEYBOARD_DRAWING_ITEM_TYPE_DOODAD: drawDoodad (&painter, (Doodad *) item); break; } } /* QVector vec; vec << QPointF(20, 20); vec << QPointF(200, 20); vec << QPointF(200, 200); vec << QPointF(20, 200); QBrush brush(Qt::gray); painter.setBrush(brush); roundedPolygon(&painter, false, 20, vec);*/ /*image.save("/tmp/test.png", "png");*/ } void KeyboardLayoutWidget::drawKey(QPainter* painter, DrawingKey* key) { XkbShapeRec *shape; QColor color; XkbOutlineRec *outline; int origin_offset_x; /* gint i; */ if (!xkb) return; shape = xkb->geom->shapes + key->xkbkey->shape_ndx; if (key->pressed) color = qApp->palette().color(QPalette::Active, QPalette::Highlight); else color = colors[key->xkbkey->color_ndx]; /* draw the primary outline */ outline = shape->primary ? shape->primary : shape->outlines; drawOutline (painter, outline, color, key->angle, key->originX, key->originY); #if 0 /* don't draw other outlines for now, since * the text placement does not take them into account */ for (i = 0; i < shape->num_outlines; i++) { if (shape->outlines + i == shape->approx || shape->outlines + i == shape->primary) continue; draw_outline (context, shape->outlines + i, NULL, key->angle, key->origin_x, key->origin_y); } #endif origin_offset_x = calcShapeOriginOffsetX (outline); drawKeyLabel (painter, key->keycode, key->angle, key->originX + origin_offset_x, key->originY, shape->bounds.x2, shape->bounds.y2, key->pressed); } int KeyboardLayoutWidget::calcShapeOriginOffsetX(XkbOutlineRec* outline) { int rv = 0; int i; XkbPointPtr point = outline->points; if (outline->num_points < 3) return 0; for (i = outline->num_points; --i > 0;) { int x1 = point->x; int y1 = point++->y; int x2 = point->x; int y2 = point->y; /*vertical, bottom to top (clock-wise), on the left */ if ((x1 == x2) && (y1 > y2) && (x1 > rv)) { rv = x1; } } return rv; } void KeyboardLayoutWidget::drawOutline(QPainter* painter, XkbOutlinePtr outline, QColor color, int angle, int originX, int originY) { if (outline->num_points == 1) { if (color.isValid()) drawRectangle (painter, color, angle, originX, originY, outline->points[0].x, outline->points[0].y, outline->corner_radius); drawRectangle (painter, QColor(), angle, originX, originY, outline->points[0].x, outline->points[0].y, outline->corner_radius); } else if (outline->num_points == 2) { int rotated_x0, rotated_y0; //qDebug() << "angle" << angle ; rotateCoordinate (originX, originY, originX + outline->points[0].x, originY + outline->points[0].y, angle, &rotated_x0, &rotated_y0); if (color.isValid()) drawRectangle (painter, color, angle, rotated_x0, rotated_y0, outline->points[1].x, outline->points[1].y, outline->corner_radius); drawRectangle (painter, QColor(), angle, rotated_x0, rotated_y0, outline->points[1].x, outline->points[1].y, outline->corner_radius); } else { if (color.isValid()) drawPolygon (painter, color, originX, originY, outline->points, outline->num_points, outline->corner_radius); drawPolygon (painter, QColor(), originX, originY, outline->points, outline->num_points, outline->corner_radius); } } void KeyboardLayoutWidget::rotateCoordinate(int originX, int originY, int x, int y, int angle, int* rotated_x, int* rotated_y) { QTransform translate; QTransform rotate; QTransform translate2; QTransform trans; translate.translate(-originX, -originY); translate2.translate(originX, originY); rotate.rotate(angle / 10); trans = translate * rotate * translate2; trans.map(x, y, rotated_x, rotated_y); } int KeyboardLayoutWidget::xkbToPixmapCoord (int n) { return n * ratio; } double KeyboardLayoutWidget::xkbToPixmapDouble (double d) { return d * ratio; } void KeyboardLayoutWidget::drawPolygon(QPainter* painter, QColor fill_color, int xkb_x, int xkb_y, XkbPointPtr xkb_points, unsigned int num_points, unsigned int radius) { QVector points; bool filled; unsigned int i; if (fill_color.isValid()) { filled = true; } else { fill_color = Qt::gray; filled = false; } QBrush brush(fill_color); painter->save(); painter->setBrush(brush); for (i = 0; i < num_points; i++) { QPointF point; point.setX(xkbToPixmapCoord (xkb_x + xkb_points[i].x)); point.setY(xkbToPixmapCoord (xkb_y + xkb_points[i].y)); points << point; } roundedPolygon (painter, filled, xkbToPixmapDouble (radius), points); painter->restore(); } double distance(double x, double y) { return qSqrt ((x * x) + (y * y)); } double distance(const QPointF& a, const QPointF& b) { QPointF d = a - b; return distance(d.x(), d.y()); } double angle(const QVector2D& norm) { qreal result = qAcos(norm.x()); if (norm.y() > 0) result = 2 * M_PI - result; return result / M_PI * 180.0; } /* draw an angle from the current point to b and then to c, * with a rounded corner of the given radius. */ void KeyboardLayoutWidget::roundedCorner (QPainterPath& path, QPointF b, QPointF c, double radius) { /* we may have 5 point here * a is the current point * c is the end point * and b is the corner * we will have a rounded corner with radious (maybe adjust by a,b,c position) * * a1 is on a-b, and c1 is on b-c */ QPointF a = path.currentPosition(); //qDebug() << "current" << a << b << c; /* make sure radius is not too large */ double dist1 = distance (a, b); double dist2 = distance (b, c); //qDebug() << "dist" << dist1 << dist2 << radius; radius = qMin (radius, qMin (dist1, dist2)); QPointF ba = a - b; QPointF bc = c - b; QVector2D na(ba); QVector2D nc(bc); na.normalize(); nc.normalize(); qreal cosine = QVector2D::dotProduct(na, nc); qreal halfcosine = qSqrt((1 + cosine) / 2); qreal halfsine = qSqrt( 1- halfcosine * halfcosine); qreal halftan = halfsine / halfcosine; QPointF a1 = b + na.toPointF() * (radius / halftan); QPointF c1 = b + nc.toPointF() * (radius / halftan); QVector2D n = na + nc; n.normalize(); QPointF ctr = b + n.toPointF() * radius / halfsine; QRectF arcRect(ctr.x() - radius, ctr.y() - radius, 2 * radius, 2 * radius); qreal phiA, phiC; //qDebug() << c1 << ctr << a1; QVector2D ctra = QVector2D(a1 - ctr); QVector2D ctrc = QVector2D(c1 - ctr); ctra.normalize(); ctrc.normalize(); phiA = angle(ctra); phiC = angle(ctrc); qreal delta = phiC - phiA; while (delta > 0) delta -= 360; while (delta < -360) delta += 360; if (delta <- 180) delta += 360; //qDebug() << arcRect << ctra << ctrc << ctr << "degree" << phiA << phiC; path.lineTo(a1); path.arcTo(arcRect, phiA, delta); path.lineTo(c1); path.lineTo(c); } void KeyboardLayoutWidget::roundedPolygon(QPainter* painter, bool filled, double radius, const QVector< QPointF >& points) { int i, j; QPainterPath path; path.moveTo((points[points.size() - 1] + points[0]) / 2); for (i = 0; i < points.size(); i++) { j = (i + 1) % points.size(); roundedCorner (path, points[i], (points[i] + points[j]) / 2, radius); // qDebug() << "corner " << points[i] << points[j]; }; path.closeSubpath(); if (filled) { painter->fillPath(path, painter->brush()); } else { painter->drawPath(path); } } void KeyboardLayoutWidget::drawRectangle(QPainter* painter, QColor color, int angle, int xkb_x, int xkb_y, int xkb_width, int xkb_height, unsigned int radius) { if (angle == 0) { int x, y, width, height; bool filled; if (color.isValid()) { filled = true; } else { color = Qt::gray; filled = false; } x = xkbToPixmapCoord (xkb_x); y = xkbToPixmapCoord (xkb_y); width = xkbToPixmapCoord (xkb_x + xkb_width) - x; height = xkbToPixmapCoord (xkb_y + xkb_height) - y; drawCurveRectangle (painter, filled, color, x, y, width, height, xkbToPixmapDouble (radius)); } else { XkbPointRec points[4]; int x, y; points[0].x = xkb_x; points[0].y = xkb_y; rotateCoordinate (xkb_x, xkb_y, xkb_x + xkb_width, xkb_y, angle, &x, &y); points[1].x = x; points[1].y = y; rotateCoordinate (xkb_x, xkb_y, xkb_x + xkb_width, xkb_y + xkb_height, angle, &x, &y); points[2].x = x; points[2].y = y; rotateCoordinate (xkb_x, xkb_y, xkb_x, xkb_y + xkb_height, angle, &x, &y); points[3].x = x; points[3].y = y; /* the points we've calculated are relative to 0,0 */ drawPolygon (painter, color, 0, 0, points, 4, radius); } } void KeyboardLayoutWidget::drawCurveRectangle(QPainter* painter, bool filled, QColor color, int x, int y, int width, int height, double radius) { double x1, y1; if (!width || !height) return; x1 = x + width; y1 = y + height; radius = qMin (radius, (double) qMin (width / 2, height / 2)); QPainterPath path; path.moveTo(x, y + radius); path.arcTo(x, y, 2 * radius, 2 * radius, 180, -90); path.lineTo (x1 - radius, y); path.arcTo (x1 - 2 * radius, y, 2 * radius, 2 * radius, 90, - 90); path.lineTo (x1, y1 - radius); path.arcTo (x1 - 2 * radius, y1 - 2 * radius, 2 * radius, 2 * radius, 0, -90); path.lineTo (x + radius, y1); path.arcTo (x , y1 - 2 * radius, 2 * radius, 2 * radius, -90, -90); path.closeSubpath(); painter->save(); if (filled) { QBrush brush(color); painter->fillPath (path, brush); } else { painter->setPen(color); painter->drawPath(path); } painter->restore(); } KeyboardLayoutWidget::~KeyboardLayoutWidget() { release(); } void KeyboardLayoutWidget::drawKeyLabel(QPainter* painter, uint keycode, int angle, int xkb_origin_x, int xkb_origin_y, int xkb_width, int xkb_height, bool is_pressed) { if (!xkb) return; int padding = 23 * ratio; /* 2.3mm */ int x = xkbToPixmapCoord (xkb_origin_x); int y = xkbToPixmapCoord (xkb_origin_y); int width = xkbToPixmapCoord (xkb_origin_x + xkb_width) - x; int height = xkbToPixmapCoord (xkb_origin_y + xkb_height) - y; QString syms[KEYBOARD_DRAWING_POS_TOTAL] = {0,0,0,0}; for (int glp = KEYBOARD_DRAWING_POS_TOPLEFT; glp < KEYBOARD_DRAWING_POS_TOTAL; glp++) { if (groupLevels[glp] == NULL) continue; int g = groupLevels[glp]->group; int l = groupLevels[glp]->level; if (g < 0 || g >= XkbKeyNumGroups (xkb, keycode)) continue; if (l < 0 || l >= XkbKeyGroupWidth (xkb, keycode, g)) continue; /* Skip "exotic" levels like the "Ctrl" level in PC_SYSREQ */ if (l > 0) { uint mods = XkbKeyKeyType (xkb, keycode, g)->mods.mask; if ((mods & (ShiftMask | l3mod)) == 0) continue; } KeySym keysym = 0; if (trackModifiers) { uint mods_rtrn; if (XkbTranslateKeyCode (xkb, keycode, XkbBuildCoreState(mods, g), &mods_rtrn, &keysym)) { syms[glp] = keySymToString(keysym); } } else { keysym = XkbKeySymEntry (xkb, keycode, l, g); syms[glp] = keySymToString(keysym); } } // TOPLEFT TOPRIGHT // BOTTOMLEFT BOTTOMRIGHT int end[KEYBOARD_DRAWING_POS_TOTAL]; const int TOPLEFT = KEYBOARD_DRAWING_POS_TOPLEFT, TOPRIGHT = KEYBOARD_DRAWING_POS_TOPRIGHT, BOTTOMLEFT = KEYBOARD_DRAWING_POS_BOTTOMLEFT, BOTTOMRIGHT = KEYBOARD_DRAWING_POS_BOTTOMRIGHT; end[TOPLEFT] = TOPLEFT; end[TOPRIGHT] = TOPRIGHT; end[BOTTOMLEFT] = BOTTOMLEFT; end[BOTTOMRIGHT] = BOTTOMRIGHT; if (syms[BOTTOMLEFT] == syms[BOTTOMRIGHT] || syms[BOTTOMRIGHT].isNull()) { syms[BOTTOMRIGHT] = QString(); end[BOTTOMLEFT] = BOTTOMRIGHT; end[BOTTOMRIGHT] = -1; } if (syms[TOPLEFT] == syms[TOPRIGHT] || syms[TOPRIGHT].isNull()) { syms[TOPRIGHT] = QString(); end[TOPLEFT] = TOPRIGHT; end[TOPRIGHT] = -1; } if ((syms[BOTTOMLEFT] == syms[TOPLEFT] || syms[TOPLEFT].isNull()) && ((end[BOTTOMLEFT] == BOTTOMLEFT && end[TOPLEFT] == TOPLEFT) || (end[BOTTOMLEFT] == BOTTOMRIGHT && end[TOPLEFT] == TOPRIGHT))) { syms[TOPLEFT] = QString(); end[BOTTOMLEFT] = end[TOPLEFT]; end[TOPLEFT] = -1; } if (!syms[BOTTOMRIGHT].isNull() && (syms[BOTTOMRIGHT] == syms[TOPRIGHT] || (syms[TOPRIGHT].isNull() && end[TOPRIGHT] != -1))) { syms[TOPRIGHT] = QString(); end[BOTTOMRIGHT] = TOPRIGHT; } for (int glp = KEYBOARD_DRAWING_POS_TOPLEFT; glp < KEYBOARD_DRAWING_POS_TOTAL; glp++) { if (!syms[glp].isEmpty()) { drawKeyLabelHelper (painter, syms[glp], angle, glp, end[glp], x, y, width, height, padding, is_pressed); /* reverse y order */ } } } void KeyboardLayoutWidget::drawKeyLabelHelper(QPainter* painter, const QString &text_, int angle, int glp, int end_glp, int x, int y, int width, int height, int padding, bool is_pressed) { QString text = text_; if (padding >= height / 2) padding = 0; if (padding >= width / 2) padding = 0; Qt::Alignment align; QRectF rect(padding, padding, (width - 2 * padding), (height - 2 * padding)); QRectF textRect; QMarginsF margin(0, 0, 0, 0); // TOPLEFT TOPRIGHT // BOTTOMLEFT BOTTOMRIGHT switch (glp) { case KEYBOARD_DRAWING_POS_TOPLEFT: align = Qt::AlignTop | Qt::AlignLeft; margin.setBottom(rect.height() / 2); break; case KEYBOARD_DRAWING_POS_BOTTOMLEFT: align = Qt::AlignBottom | Qt::AlignLeft; break; case KEYBOARD_DRAWING_POS_TOPRIGHT: align = Qt::AlignTop | Qt::AlignRight; margin.setBottom(rect.height() / 2); break; case KEYBOARD_DRAWING_POS_BOTTOMRIGHT: align = Qt::AlignBottom | Qt::AlignRight; margin.setLeft(rect.width() / 2); break; default: return; } switch (end_glp) { case KEYBOARD_DRAWING_POS_TOPLEFT: margin.setRight(rect.width() / 2); break; case KEYBOARD_DRAWING_POS_BOTTOMLEFT: margin.setRight(rect.width() / 2); margin.setTop(rect.height() / 2); break; case KEYBOARD_DRAWING_POS_TOPRIGHT: break; case KEYBOARD_DRAWING_POS_BOTTOMRIGHT: margin.setTop(rect.height() / 2); break; default: return; } textRect = rect.marginsRemoved(margin); // which means we have longer width if (textRect.width() == rect.width() && textRect.height() != rect.height()) { text.replace('\n', ' '); } painter->save(); QTransform trans; trans.translate(x + padding / 2, y + padding / 2); trans.rotate(angle / 10); painter->setTransform(trans); //painter->fillRect(QRectF(0, 0, width - padding, height - padding), QBrush(Qt::blue)); // painter->setClipRect(QRect(x + padding / 2, y + padding / 2, width - padding, height - padding)); trans.reset(); trans.translate(x, y); trans.rotate(angle / 10); QFont font = painter->font(); // Normalize maximum text size { QFontMetricsF fm(font); qreal h = fm.size(align | Qt::TextSingleLine, text).height(); if (h > rect.height() / 2) { qreal scale = rect.height() / 2 / h; font.setPointSizeF(font.pointSizeF() * scale); } } // fit it in rect { QFontMetricsF fm(font); qreal h = fm.size(align, text).height(); if (h > textRect.height()) { qreal scale = textRect.height() / h; font.setPointSizeF(font.pointSizeF() * scale); } } int maxTry = 3; while (maxTry--) { QFontMetricsF fm(font); qreal w = fm.size(align, text).width(); if (w > textRect.width()) { qreal scale = textRect.width() / w; font.setPointSizeF(font.pointSizeF() * scale); } else { break; } } painter->setFont(font); painter->setTransform(trans); #if 0 painter->save(); painter->setPen(QPen(Qt::red)); painter->drawRect(textRect); painter->restore(); #endif painter->drawText(textRect, align | Qt::TextDontClip, text); painter->restore(); #if 0 QString name[KEYBOARD_DRAWING_POS_TOTAL]; name[KEYBOARD_DRAWING_POS_TOPLEFT] = "TOPLEFT"; name[KEYBOARD_DRAWING_POS_TOPRIGHT] = "TOPRIGHT"; name[KEYBOARD_DRAWING_POS_BOTTOMLEFT] = "BOTTOMLEFT"; name[KEYBOARD_DRAWING_POS_BOTTOMRIGHT] = "BOTTOMRIGHT"; qDebug() << "KEY" << text << name[glp] << name[end_glp] << rect << textRect; #endif } void KeyboardLayoutWidget::drawDoodad(QPainter* painter, Doodad* doodad) { switch (doodad->doodad->any.type) { case XkbOutlineDoodad: case XkbSolidDoodad: drawShapeDoodad (painter, doodad, &doodad->doodad->shape); break; case XkbTextDoodad: drawTextDoodad (painter, doodad, &doodad->doodad->text); break; case XkbIndicatorDoodad: drawIndicatorDoodad (painter, doodad, &doodad->doodad->indicator); break; case XkbLogoDoodad: /* g_print ("draw_doodad: logo: %s\n", doodad->doodad->logo.logo_name); */ /* XkbLogoDoodadRec is essentially a subclass of XkbShapeDoodadRec */ drawShapeDoodad (painter, doodad, &doodad->doodad->shape); break; } } void KeyboardLayoutWidget::drawShapeDoodad(QPainter* painter, Doodad* doodad, XkbShapeDoodadPtr shapeDoodad) { XkbShapeRec *shape; QColor color; int i; if (!xkb) return; shape = xkb->geom->shapes + shapeDoodad->shape_ndx; color = colors[shapeDoodad->color_ndx]; /* draw the primary outline filled */ drawOutline (painter, shape->primary ? shape->primary : shape->outlines, color, doodad->angle, doodad->originX + shapeDoodad->left, doodad->originY + shapeDoodad->top); /* stroke the other outlines */ for (i = 0; i < shape->num_outlines; i++) { if (shape->outlines + i == shape->approx || shape->outlines + i == shape->primary) continue; drawOutline (painter, shape->outlines + i, QColor(), doodad->angle, doodad->originX + shapeDoodad->left, doodad->originY + shapeDoodad->top); } } void KeyboardLayoutWidget::drawTextDoodad(QPainter* painter, Doodad* doodad, XkbTextDoodadPtr textDoodad) { int x, y; if (!xkb) return; x = xkbToPixmapCoord (doodad->originX + textDoodad->left); y = xkbToPixmapCoord (doodad->originY + textDoodad->top); QRect rect(0, 0, xkbToPixmapDouble(textDoodad->width), xkbToPixmapDouble(textDoodad->height)); QTransform trans; trans.translate(x, y); trans.rotate(textDoodad->angle / 10); QString text(textDoodad->text); int line = text.count('\n') + 1; QFont font = painter->font(); font.setPixelSize((rect.height() / 2)); QFontMetricsF fm(font); qreal h = fm.height() * line; if (h > rect.height()) { double sz = font.pixelSize() / h * rect.height(); if (sz < 1) sz = 1; font.setPixelSize(sz); } qreal w = fm.width(textDoodad->text); if (w > rect.width()) { double sz = font.pixelSize() / w * rect.width(); if (sz < 1) sz = 1; font.setPixelSize(sz); } painter->save(); painter->setFont(font); painter->setTransform(trans); painter->drawText(rect, Qt::AlignLeft, textDoodad->text); painter->restore(); } void KeyboardLayoutWidget::drawIndicatorDoodad(QPainter* painter, Doodad* doodad, XkbIndicatorDoodadPtr indicatorDoodad) { QColor color; XkbShapeRec *shape; int i; if (!xkb) return; initInicatorDoodad(doodad->doodad, *doodad); shape = xkb->geom->shapes + indicatorDoodad->shape_ndx; color = colors[(doodad->on ? indicatorDoodad->on_color_ndx : indicatorDoodad->off_color_ndx)]; for (i = 0; i < 1; i++) drawOutline (painter, shape->outlines + i, color, doodad->angle, doodad->originX + indicatorDoodad->left, doodad->originY + indicatorDoodad->top); } void KeyboardLayoutWidget::paintEvent(QPaintEvent* event) { QWidget::paintEvent(event); QPainter p(this); p.setClipRect(event->rect()); p.setCompositionMode(QPainter::CompositionMode_SourceOver); int dx = (rect().width() - image.width() / image.devicePixelRatio()) / 2; int dy = (rect().height() - image.height() / image.devicePixelRatio()) / 2; QRect r(QPoint(dx, dy), image.size() / image.devicePixelRatio()); r.moveTo(dx, dy); p.drawPixmap(r, image, image.rect()); } void KeyboardLayoutWidget::resizeEvent(QResizeEvent* event) { generatePixmap(); update(); QWidget::resizeEvent(event); } void KeyboardLayoutWidget::keyPressEvent(QKeyEvent* event) { return keyEvent(event); } void KeyboardLayoutWidget::keyReleaseEvent(QKeyEvent* event) { return keyEvent(event); } void KeyboardLayoutWidget::keyEvent(QKeyEvent* event) { do { if (!xkb) break; if (event->type() != QEvent::KeyPress && event->type() != QEvent::KeyRelease) break; DrawingKey* key = &keys[event->nativeScanCode()]; if (event->nativeScanCode() > xkb->max_key_code || event->nativeScanCode() < xkb->min_key_code || key->xkbkey == NULL) { break; } if (event->type() == QEvent::KeyPress && key->pressed) break; if (event->type() == QEvent::KeyRelease && !key->pressed) break; key->pressed = (event->type() == QEvent::KeyPress); generatePixmap(true); repaint(); } while(0); } QString KeyboardLayoutWidget::keySymToString(unsigned long keysym) { if (keysym == 0 || keysym == XK_VoidSymbol) return {}; keysym = normalizedKeySym(keysym); keysym = (KeySym) FcitxHotkeyPadToMain((FcitxKeySym) keysym); uint32_t unicode = FcitxKeySymToUnicode((FcitxKeySym) keysym); if (deadMap.contains(keysym)) { unicode = deadMap[keysym]; } QString text; if (unicode && QChar::category(unicode) != QChar::Other_Control && !QChar::isSpace(unicode)) { text = QString::fromUcs4(&unicode, 1); } else { if (keysym == XK_Prior) { text = "PgUp"; } else if (keysym == XK_Next) { text = "PgDn"; } else { text = QString(XKeysymToString(keysym)); } } if (text != "_") { if (text.endsWith("_L") || text.endsWith("_R")) text = text.replace('_', ' '); else text = text.replace('_', '\n'); } return text; } kcm-fcitx-master/layout/keyboardlayoutwidget.h000066400000000000000000000114231433634536200221760ustar00rootroot00000000000000/* this file is based on from libgnomekbd/libgnomekbd/gkbd-keyboard-drawing.c */ #ifndef KEYBOARDLAYOUTWIDGET_H #define KEYBOARDLAYOUTWIDGET_H #include #include #include #include class QPainter; struct Doodad; struct _XkbDesc; struct _XkbShapeDoodad; union _XkbDoodad; typedef enum { KEYBOARD_DRAWING_ITEM_TYPE_INVALID = 0, KEYBOARD_DRAWING_ITEM_TYPE_KEY, KEYBOARD_DRAWING_ITEM_TYPE_KEY_EXTRA, KEYBOARD_DRAWING_ITEM_TYPE_DOODAD } KeyboardDrawingItemType; typedef enum { KEYBOARD_DRAWING_POS_TOPLEFT, KEYBOARD_DRAWING_POS_TOPRIGHT, KEYBOARD_DRAWING_POS_BOTTOMLEFT, KEYBOARD_DRAWING_POS_BOTTOMRIGHT, KEYBOARD_DRAWING_POS_TOTAL, KEYBOARD_DRAWING_POS_FIRST = KEYBOARD_DRAWING_POS_TOPLEFT, KEYBOARD_DRAWING_POS_LAST = KEYBOARD_DRAWING_POS_BOTTOMRIGHT } KeyboardDrawingGroupLevelPosition; struct DrawingItem { DrawingItem() : type(KEYBOARD_DRAWING_ITEM_TYPE_INVALID), originX(0), originY(0), angle(0), priority(0) { } virtual ~DrawingItem() {} KeyboardDrawingItemType type; int originX; int originY; int angle; uint priority; }; struct Doodad : public DrawingItem{ Doodad() : doodad(0), on(0) { } union _XkbDoodad* doodad; int on; }; struct DrawingKey : public DrawingItem{ DrawingKey() : xkbkey(0), pressed(false), keycode(0) { } struct _XkbKey *xkbkey; bool pressed; uint keycode; }; struct KeyboardDrawingGroupLevel { int group; int level; }; class KeyboardLayoutWidget : public QWidget { Q_OBJECT public: explicit KeyboardLayoutWidget(QWidget* parent = 0); virtual ~KeyboardLayoutWidget(); void setGroup(int group); void setKeyboardLayout(const QString& layout, const QString& variant); void generatePixmap(bool force = false); protected: void keyPressEvent(QKeyEvent * event) override; void keyReleaseEvent(QKeyEvent * event) override; void paintEvent(QPaintEvent* event) override; void init(); void alloc(); void release(); void initInicatorDoodad(union _XkbDoodad* xkbdoodad, Doodad& doodad); uint findKeycode(const char* keyName); void rotateRectangle(int origin_x, int origin_y, int x, int y, int angle, int& rotated_x, int& rotated_y); bool parseXkbColorSpec(char* colorspec, QColor& color); void initColors(); void focusOutEvent(QFocusEvent* event) override; void drawKey(QPainter* painter, DrawingKey* item); void drawDoodad(QPainter* painter, Doodad* doodad); void drawKeyLabel(QPainter* painter, uint keycode, int angle, int arg4, int originY, int x2, int y2, bool pressed); void drawKeyLabelHelper(QPainter* painter, const QString &text, int angle, int glp, int end_glp, int x, int y, int width, int height, int padding, bool is_pressed); void drawShapeDoodad(QPainter* painter, Doodad* doodad, struct _XkbShapeDoodad* shapeDoodad); void drawTextDoodad(QPainter* painter, Doodad* doodad, struct _XkbTextDoodad* textDoodad); void drawIndicatorDoodad(QPainter* painter, Doodad* doodad, struct _XkbIndicatorDoodad* indicatorDoodad); int calcShapeOriginOffsetX(struct _XkbOutline* outline); void drawOutline(QPainter* painter, struct _XkbOutline* outline, QColor color, int angle, int originX, int originY); void drawRectangle(QPainter* painter, QColor color, int angle, int xkb_x, int xkb_y, int xkb_width, int xkb_height, unsigned int radius); void drawPolygon(QPainter* painter, QColor color, int originX, int originY, struct _XkbPoint* points, unsigned int num_points, unsigned int radius); void rotateCoordinate(int originX, int originY, int x, int y, int angle, int* rotated_x, int* rotated_y); int xkbToPixmapCoord (int n); double xkbToPixmapDouble (double d); void roundedPolygon(QPainter* painter, bool filled, double radius, const QVector< QPointF >& points); void drawCurveRectangle(QPainter* painter, bool filled, QColor color, int x, int y, int width, int height, double radius); void roundedCorner (QPainterPath& path, QPointF b, QPointF c, double radius); void resizeEvent(QResizeEvent* event) override; void setKeyboard(struct _XkbComponentNames* xkbDesc); private: void keyEvent(QKeyEvent *keyEvent); QString keySymToString(unsigned long keysym); QList keyboardItems; DrawingKey* keys; QList physicalIndicators; struct _XkbDesc* xkb; unsigned int l3mod; int physicalIndicatorsSize; bool xkbOnDisplay; QColor* colors; QPixmap image; double ratio; KeyboardDrawingGroupLevel** groupLevels; bool trackModifiers; int mods; QMap deadMap; }; #endif kcm-fcitx-master/layout/main.cpp000066400000000000000000000063031433634536200172140ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include "config.h" #include "keyboardlayoutwidget.h" int main(int argc, char* argv[]) { QApplication app(argc, argv); app.setApplicationName(QLatin1String("kbd-layout-viewer")); app.setApplicationVersion(QLatin1String(VERSION_STRING_FULL)); QCommandLineParser parser; parser.setApplicationDescription(i18n("A general keyboard layout viewer")); parser.addHelpOption(); parser.addOptions({ {{"g", "group"}, i18n("Keyboard layout (0-3)"), i18n("group")}, {{"l", "layout"}, i18n("Keyboard "), i18n("layout")}, {{"v", "variant"}, i18n("Keyboard layout "), i18n("variant")} }); parser.process(app); int group = -1; QString variant, layout; if (parser.isSet("group")) { group = parser.value("group").toInt(); } if (parser.isSet("layout")) { layout = parser.value("layout"); } if (parser.isSet("variant")) { variant = parser.value("variant"); } if (!QX11Info::isPlatformX11()) { qFatal("Only X11 is supported"); return 1; } app.setAttribute(Qt::AA_UseHighDpiPixmaps); QMainWindow mainWindow; mainWindow.setWindowIcon(QIcon::fromTheme("input-keyboard")); mainWindow.setWindowTitle(i18n("Keyboard Layout viewer")); mainWindow.setMinimumSize(QSize(900,400)); KeyboardLayoutWidget widget; if (group > 0 || layout.isNull()) { if (group < 0) group = 0; widget.setGroup(group); } else if (!layout.isNull()) { widget.setKeyboardLayout(layout, variant); } mainWindow.setCentralWidget(&widget); mainWindow.show(); return app.exec(); } kcm-fcitx-master/po/000077500000000000000000000000001433634536200146635ustar00rootroot00000000000000kcm-fcitx-master/po/CMakeLists.txt000066400000000000000000000004201433634536200174170ustar00rootroot00000000000000file(GLOB PO_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.po) foreach(po_file ${PO_FILES}) string(REPLACE ".po" "" po_lang "${po_file}") fcitx_translate_add_po_file("${po_lang}" "${po_file}") endforeach() fcitx_translate_set_pot_target(pot kcm_fcitx kcm_fcitx.pot) kcm-fcitx-master/po/ca.po000066400000000000000000000245441433634536200156170ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Robert Antoni Buj Gelonch , 2017 # Walter Garcia-Fontes , 2017 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: Walter Garcia-Fontes , 2017\n" "Language-Team: Catalan (http://www.transifex.com/fcitx/fcitx/language/ca/)\n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "&Configura l'aparença" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "%Elimina l'aparença" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

Avís:

\n" "

Heu d'utilitzar la " "interfície d'usuari clàssica per utilitzar la funció de l'aparença.

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "Disposició de teclat predeterminada:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "Configuració del mètode d'entrada:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "Disposició de teclat:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "Altres" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "Seleccioneu el mètode d'entrada:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "Un visualitzador general de disposició de teclat" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "Configuració del complement" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "Aparença" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "Autor" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "Mètode d'entrada disponible:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "No es pot connectar a fcitx amb DBus, està fcitx en execució?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "" "No es pot carregar la informació de la interfície d'usuari utilitzada " "actualment" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Configura fcitx" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "Configura el mètode d'entrada" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "Copia" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "Ha fallat la còpia" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Drets d'autor (c) 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "Mètode d'entrada actual:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "Predeterminat" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Mòdul de configuració de fcitx" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "Primera candidata" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Forrma" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "Configuració global" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "Mètode d'entrada" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "Mètode d'entrada predeterminat" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "Teclat " #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "Visualitzador de disposició de teclat" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "Disposició del teclat (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "Disposició del teclat " #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "" "Disposició de teclat que s'ha d'utilitzar quan no hi ha cap mètode d'entrada " "actiu" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "Visualitzador de disposició de teclat" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "Gestiona l'aparença" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "Plurilingüe" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "Cap opció de configuració per a %1." #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "Mo%stra sols la llengua actual" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "Les opcions que es llisten aquí poden ser anul·lades per mètodes d'entrada " "específics, generalment incloent-hi el nombre de candidates, la drecera de " "teclat Re Pàg i Av Pàg. Potser heu d'anar a la configuració del mètode " "d'entrada corresponent per canviar-les." #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "Altres" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "Altres candidats" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "Cerca complements" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "Cerca el mètode d'entrada" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "Selecciona la &lletra..." #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "Seleccioneu la disposició de teclat predeterminada" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "Mostra l'opció &avançada" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "No es pot carregar l'aparença %1" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "El primer mètode d'entrada serà l'estat inactiu. Generalment heu de posar " "Keyboard o Keyboard - nom de disposició en el primer " "lloc." #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "Desconegut" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "No existeix la configuració d'usuari, voleu obrir el fitxer del sistema o " "copiar el fitxer del sistema al fitxer d'usuari?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "Visualitza la disposició de teclat" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "Visualitza el sistema" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "Què fer" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "Els vostres correus electrònics" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Els vostres noms" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "grup" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "teclat;entrada;mètode d'entrada;fcitx" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "teclat;entrada;mètode d'entrada" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "disposició" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "variant" kcm-fcitx-master/po/da.po000066400000000000000000000235501433634536200156140ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # scootergrisen, 2017,2019 # scootergrisen, 2017,2019-2020 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: scootergrisen, 2017,2019\n" "Language-Team: Danish (http://www.transifex.com/fcitx/fcitx/language/da/)\n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "&Konfigurer skin" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "&Slet skin" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

Bemærk:

\n" "

Du skal bruge klassisk " "brugerflade for at bruge skin-funktion.

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "Standardtastaturlayout:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "Inputmetodeindstilling:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "Tastaturlayout:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "Andre" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "Vælg inputmetode:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "En generel tastaturlayout-fremviser" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "Tilføjelseskonfiguration" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "Udseende" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "Forfatter" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "Tilgængelig inputmetode:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "Kan ikke oprette forbindelse til Fcitx med DBus - kører Fcitx?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "" "Kan ikke indlæse information om brugergrænseflade som bruges i øjeblikket" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Konfigurer Fcitx" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "Konfigurer inputmetode" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "Kopiér" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "Kopiering mislykkedes" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Ophavsret 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "Nuværende inputmetode:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "Standard" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx-konfigurationsmodul" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "Første kandidat" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Formular" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "Global konfiguration" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "Inputmetode" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "Standardinputmetode" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "Tastatur " #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "Tastaturlayout-fremviser" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "Tastaturlayout (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "Tastaturlayout " #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "Tastaturlayout som skal bruges når der ikke er nogen aktiv inputmetode" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "Tastaturlayout-fremviser" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "Håndter skin" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "Flersproget" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "Ingen konfigurationsvalgmuligheder for %1." #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "&Vis kun nuværende sprog" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "Valgmuligheder som vises her kan tilsidesættes af specifik inputmetode, " "oftest med kandidatnummer, hottast af forrige side og næste side. Det kan " "være at du skal gå til konfiguration af tilhørende inputmetode for at ændre " "dem." #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "Andre" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "Anden kandidat" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "Søg efter tilføjelser" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "Søg efter inputmetode" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "Vælg &skrifttype ..." #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "Vælg standardtastaturlayout" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "Vis &avanceret valgmulighed" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "Skin %1 kan ikke indlæses" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "Den første inputmetode vil være i inaktiv tilstand. Typisk skal der først " "stå Tastatur eller Tastatur - layoutnavn." #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "Ukendt" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "Brugerkonfigurationen findes ikke - vil du åbne systemfilen eller kopiere " "systemfilen til brugerfilen?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "Vis tastaturlayout" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "Vis system" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "Skal gøres" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "Dine e-mails" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Dine navne" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "gruppe" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "tastatur;input;im;fcitx" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "tastatur;input;im" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "layout" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "variant" kcm-fcitx-master/po/de.po000066400000000000000000000243561433634536200156250ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # csslayer , 2014 # mar well , 2012-2013 # mar well , 2014,2017-2018 # csslayer , 2014 # csslayer , 2014 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: csslayer , 2014\n" "Language-Team: German (http://www.transifex.com/fcitx/fcitx/language/de/)\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "&Skin konfigurieren" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "&Skin löschen" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" " \n" "

Hinweis:

\n" "

Um die Skins zu nutzen " "muss das Classic-UI verwendet werden.

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "Standard Tastaturlayout:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "Einstellungen Eingabemethode:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "Tastatur Layout:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "Weitere" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "Auswahl Eingabemethode:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "Ein allgemeiner Betrachter für Tastaturlayouts" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "Konfiguration Addons" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "Aussehen" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "Autor" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "Verfügbare Eingabemethoden" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "DBus kann sich nicht mit FCITX verbinden. Läuft FCITX?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "" "Die zur momentan verwendeten Oberfläche gehörende Info-Datei kann nicht " "geladen werden" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Fcitx konfigurieren" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "FCITX konfigurieren" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "Kopieren" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "Kopieren gescheitert" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Copyright 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "Aktive Eingabemethode:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "Standard" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx Konfigurationsmodul" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "Erster Kandidat" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Form" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "Globale Einstellungen" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "Eingabemethode" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "Standard Eingabemethode" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "Tastatur " #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "Ansicht Tastaturlayout" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "Tastaturlayout (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "Tastaturlayout " #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "Verwendetes Tastaturlayout wenn keine Eingabemethode Aktiv ist" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "Tastaturlayout-Betrachter" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "Skins managen" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "Mehrsprachig" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "Keine Optionen zur Konfiguration für %1" #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "Nur &gegenwärtige Sprache anzeigen" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "Die aufgelisteten Optionen - z.B. Anzahl der Kandidaten, Tasten für " "vorherige oder nächste Kandidaten - werden möglicherweise wegen " "Einstellungen der gewählten Eingabemethode außer Kraft gesetzt. Diese " "Einstellungen müssen dann in den Einstellungen der Eingabemethode festgelegt " "werden." #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "Andere" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "Anderer Kandidat" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "Addons suchen" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "Eingabemethoden filtern" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "Auswahl &Font" #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "Standard Tastaturlayout auswählen" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "Erweiterte &Einstellungen anzeigen" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "Skin %1 kann nicht geladen werden" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "Die erste Eingabemethode wird die inaktive sein. Normalerweise sollte " "Tastatur oder Tastatur - Tastaturlayoutals Erstes " "stehen." #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "Unbekannt" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "Es existiert keine Nutzerkonfiguration. Soll die Systemkonfiguration " "geöffnet oder die Systemkonfiguration kopiert und als Nutzerkonfiguration " "verwendet werden?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "Tastaturlayout ansehen" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "System ansehen" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "Was zu tun ist" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "marwell.1980@freenet.de" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Marcus Wellendorf" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "Gruppe" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "Tastatur,Eingabe,Eingabemethode,fcitx" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "Tastatur;Eingabe;Eingabemethode" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "Layout" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "Variante" kcm-fcitx-master/po/ja.po000066400000000000000000000252141433634536200156210ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # しろう <>, 2013 # あわしろいくや , 2017 # csslayer , 2014 # あわしろいくや , 2017 # Takuro Onoue , 2020 # csslayer , 2014 # csslayer , 2014 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: Takuro Onoue , 2020\n" "Language-Team: Japanese (http://www.transifex.com/fcitx/fcitx/language/ja/)\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "スキン設定 (&C)" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "スキン削除 (&D)" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

注意:

\n" "

スキン機能を使うにはクラ" "シックUIを使う必要があります

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "既定のキーボードレイアウト:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "入力メソッドの設定:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "キーボードレイアウト:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "その他" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "入力メソッド選択:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "一般的なキーボドレイアウトビューアー" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "アドオン設定" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "見た目" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "作者" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "有効な入力メソッド:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "DBusがFcitxと接続できませんでした。Fcitxは動いていますか?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "現在のユーザーインターフェース設定が読み込めません" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Fcitxの設定" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "入力メソッドの設定" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "コピー" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "コピーに失敗しました" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Copyright 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "現在の入力メソッド:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "既定" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx設定モジュール" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "最初の候補" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "フォーム" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "全般の設定" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "入力メソッド" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "既定の入力メソッド" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "キーボード " #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "キーボードレイアウトビューアー" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "キーボードレイアウト (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "キーボードレイアウト " #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "どの入力メソッドが有効でない場合のキーボードレイアウト" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "キーボードレイアウトビューアー" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "スキンの管理" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "多言語" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "%1 に設定オプションはありません。" #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "現在の言語のみ表示 (&S)" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "これらのオプションは特定の入力メソッドで上書きされることがあります。候補数、" "前ページや次ページのホットキーなどはその可能性が高いです。これらの動作を変え" "るには、対応する入力メソッドの設定が必要です。" #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "その他" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "他の候補" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "アドオンの検索" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "入力メソッドの検索" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "フォント選択 (&F)" #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "既定のキーボードレイアウトを選択" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "拡張オプションの表示 (&A)" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "スキン %1 を読み込めません" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "最初の入力メソッドは無効の状態で使用されます。たいてい最初のキーボード" "またはキーボード -レイアウト名で追加できます。" #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "不明" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "ユーザー設定がありません。システム全体のファイルを開くか、システム全体のファ" "イルをユーザーのファイルとしてコピーしますか?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "キーボードレイアウトを見る" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "システムの表示" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "したいこと" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "shirou.faw@gmail.com,ikunya@gmail.com" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "r_rudi, ikunya" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "グループ" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "keyboard,input,im,fcitx" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "keyboard;input;im" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "レイアウト" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "バリアント" kcm-fcitx-master/po/kcm_fcitx.pot000066400000000000000000000165721433634536200173710ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: LANG\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "" #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "" #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "" #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "" #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "" #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "" #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "" kcm-fcitx-master/po/ko.po000066400000000000000000000243131433634536200156370ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Bon Keun Seo , 2017 # Junghee Lee , 2021 # Junghee Lee , 2020 # Junghee Lee , 2022 # Junghee Lee , 2021 # Junghee Lee , 2020,2022 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: Junghee Lee , 2022\n" "Language-Team: Korean (http://www.transifex.com/fcitx/fcitx/language/ko/)\n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "스킨 구성하기(&C)" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "스킨 삭제(&D)" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

주의:

\n" "

클래식 UI를 사용해야 스킨" "을 사용할 수 있습니다.

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "기본 키보드 자판:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "입력기 설정:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "키보드 자판:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "기타" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "입력기 선택:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "일반 키보드 자판 보기도구" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "애드온 구성" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "모양새" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "작성자" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "사용가능한 입력기:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "DBus로 Fcitx에 연결할 수 없습니다. Fcitx가 실행되고 있습니까?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "현재 사용자 인터페이스 정보를 불러올 수 없음" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Fcitx 구성하기" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "입력기 구성하기" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "복사" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "복사 실패" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "저작권자 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "현재 입력기:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "기본값" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx 구성 모듈" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "첫 후보" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "폼" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "전역 구성" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "입력기" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "입력기 기본값" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "키보드 <자판>" #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "키보드 자판 보기도구" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "키보드 자판 <그룹> (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "키보드 자판 <변형>" #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "활성 입력기가 없을 때 사용할 키보드 자판" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "키보드 자판 보기도구" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "스킨 관리" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "다국어" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "%1에 대한 구성 옵션들이 없습니다." #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "현재 언어만 표시(&S)" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "표시된 옵션은 입력기에 의해 덮어씌워질 수 있습니다. 대체로 후보 개수, 이전 혹" "은 다음 페이지의 단축기 등이 해당됩니다. 그냥 당연한 거 같아요.해당 입력기의 " "구성 페이지에서 변경 가능합니다." #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "기타" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "다른 후보" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "애드온 검색" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "입력기 검색" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "글꼴 선택...(&F)" #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "기본 키보드 자판 선택" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "고급 옵션 표시(&A)" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "스킨 %1 을 불러올 수 없음" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "첫번째 입력기가 비활성화 상태입니다. 대체로 키보드 또는 키보드 - " " 자판명 을 첫 항목으로 하여야 합니다." #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "알 수 없음 " #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "사용자 구성이 존재하지 않습니다. 시스템 파일을 열거나 시스템 파일을 사용자 파" "일로 복사하시겠습니까?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "키보드 자판 보기" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "시스템 보기" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "어떡할까요?" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "당신의 이메일" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "당신의 이름" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "그룹" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "keyboard,input,im,fcitx키보드;입력;입력기" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "keyboard;input;im;키보드;입력;입력기" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "자판" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "변형" kcm-fcitx-master/po/ru.po000066400000000000000000000271751433634536200156650ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # TotalCaesar659 , 2016 # TotalCaesar659 , 2016-2017 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: TotalCaesar659 , 2016\n" "Language-Team: Russian (http://www.transifex.com/fcitx/fcitx/language/ru/)\n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || " "(n%100>=11 && n%100<=14)? 2 : 3);\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "&Настроить скин" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "&Удалить скин" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

Примечание:

\\n

Для использования функций скина необходим классический " "интерфейс.

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "Раскладка клавиатуры по умолчанию:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "Настройка метода ввода:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "Раскладка клавиатуры:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "Другое" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "Выбрать метод ввода:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "Основной просмотрщик раскладки клавиатуры" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "Настройки дополнения" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "Внешний вид" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "Автор" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "Доступный метод ввода:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "Не удалось соединиться с Fcitx через DBus, запущен ли Fcitx?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "Невозможно загрузить информацию о текущем интерфейсе пользователя" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Настроить Fcitx" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "Настроить метод ввода" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "Копировать" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "Не удалось копировать файл" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Copyright 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "Текущий метод ввода:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "По умолчанию" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Модуль настройки Fcitx" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "Первый кандидат" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Форма" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "Глобальные настройки" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "Метод ввода" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "Метод ввода по умолчанию" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "Клавиатура " #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "Просмотрщик раскладки клавиатуры" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "Раскладка клавиатуры (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "Раскладка клавиатуры " #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "Раскладка клавиатуры при неактивных методах ввода" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "Просмотрщик раскладки клавиатуры" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "Выбрать скин" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "Многоязычный" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "Нет настроек для %1." #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "&Показывать только текущий язык" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "Приведенные здесь настройки могут быть отменены определенным методом ввода, " "обычно включающим номер кандидата, горячую клавишу предыдущей и следующей " "страницы. Для их изменения вам может потребоваться перейти в настройки " "соответствующего метода ввода." #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "Другое" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "Другой кандидат" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "Найти дополнения" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "Поиск метода ввода" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "Выбрать &шрифт..." #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "Выбрать раскладку клавиатуры по умолчанию" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "Показать &дополнительные настройки" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "Невозможно выбрать скин %1" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "Первый метод ввода будет неактивным. Обычно вам потребуется установить " "Клавиатура или Клавиатура - название раскладки на " "первое место." #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "Неизвестно" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "Файл настроек пользователя не существует, вы хотите открыть системный файл " "или копировать его на место файла пользователя?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "Просмотреть раскладку клавиатуры" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "Открыть системный файл" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "Что сделать" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "Ваши адреса электронной почты" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Ваши имена" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "группа" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "keyboard,input,im,fcitx" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "keyboard;input;im" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "раскладка" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "вариант" kcm-fcitx-master/po/tr.po000066400000000000000000000241621433634536200156550ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # しろう <>, 2013 # abc Def , 2020-2021 # csslayer , 2014,2017 # Gökhan Kalayci , 2017 # csslayer , 2017 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: abc Def , 2020-2021\n" "Language-Team: Turkish (http://www.transifex.com/fcitx/fcitx/language/tr/)\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "&Temayı Yapılandır" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "&Temayı Sil" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

Uyarı:

\n" "

Tema fonksiyonunu " "kullanmak için Klasik UI kullanmanız gerekir.

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "Varsayılan Klavye Düzeni :" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "Giriş Yöntemi Ayarları:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "Klavye Düzeni:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "Diğer" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "Giriş Yöntemini Seç:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "Genel bir klavye düzeni görüntüleyici" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "Eklenti Yapılandırma" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "Görünüm" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "Yazar" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "Kullanılabilir Giriş Yöntemi:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "DBus tarafından Fcitx'e bağlanılamıyor, Fcitx çalışıyor mu?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "Şu anda kullanılan kullanıcı arabirimi bilgileri yüklenemiyor" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Fcitx'i Yapılandır" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "Giriş Yöntemini Yapılandır" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "Kopyala" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "Kopyalama başarısız" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Copyright 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "Geçerli Giriş Yöntemi:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "Varsayılan" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx Yapılandırma Modülü" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "Birinci aday" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Form" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "Küresel Yapılandırma" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "Giriş Yöntemi" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "Giriş Yöntemi Varsayılanı" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "Klavye" #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "Klavye Serilimi görüntüleyici" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "Klavye düzen (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "Klavye Düzeni" #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "Giriş yöntemi etkin değilken kullanılacak klavye düzeni" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "Klavye Düzeni görüntüleyici" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "Tema Yönet" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "Çok dilli" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "%1 için yapılandırma seçeneği yok." #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "Göster :&Sadece Geçerli Dili" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "Burada listelenen seçenekler, genellikle aday numarası, önceki sayfanın ve " "sonraki sayfanın kısayol tuşu dahil olmak üzere belirli bir giriş yöntemiyle " "geçersiz kılınabilir. Bunları değiştirmek için ilgili giriş yönteminin " "yapılandırmasına gitmeniz gerekebilir." #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "Diğer" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "Diğer aday" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "Eklentileri Ara" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "Giriş Yöntemi Ara" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "Seç &Yazı tipi..." #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "Varsayılan klavye düzenini seçin" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "Gelişmiş &Seçeneği Göster" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "%1 teması yüklenemedi" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "İlk giriş yöntemi aktif değildirr. Genellikle Klavye veya " "Klavye - düzen adı koymanız gerekir." #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "Bilinmeyen" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "Kullanıcı yapılandırması yok, sistem dosyasını açmak veya sistem dosyasını " "kullanıcı dosyasına kopyalamak istiyor musunuz?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "Klavye serilimini görüntüle" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "Sistemi gör" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "Ne yapalım" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "E-posta adresleriniz" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Adlarınız" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "grup" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "keyboard,input,im,fcitx" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "keyboard;input;im" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "düzeni" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "türü" kcm-fcitx-master/po/vi.po000066400000000000000000000202321433634536200156400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # csslayer , 2014 # dinhdangkhoi , 2014 # dinhdangkhoi , 2014 # Lê Trường An , 2013 # csslayer , 2014 # csslayer , 2014 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: csslayer , 2014\n" "Language-Team: Vietnamese (http://www.transifex.com/fcitx/fcitx/language/" "vi/)\n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "&Cấu hình vỏ ngoài" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "&Xóa vỏ ngoài" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "Cấu hình Addon" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "Dáng vẻ bên ngoài" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "Cấu hình Fcitx" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "Sao chép" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "Sao chép thất bại" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Copyright 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "Mặc định" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "Ứng cử viên đầu tiên" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Mẫu" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "Cấu hình chung" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "Kiểu gõ" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "" #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "" #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "Quản lý vỏ ngoài" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "Đa ngôn ngữ" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "" #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "Khác" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "Ứng cử viên khác" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "Tìm kiếm Addons" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "Chọn &Font..." #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "Hiện tùy c&họn nâng cao" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "Vỏ ngoài %1 không thể nạp" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "Không rõ" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "Xem thông tin hệ thống" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "Phải làm gì" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "dinhdangkhoi.fs@gmail.com" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Đinh Đăng Khôi" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "" kcm-fcitx-master/po/zh_CN.po000066400000000000000000000240211433634536200162230ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Christopher Meng , 2012 # csslayer , 2011,2014,2017 # marguerite su , 2014 # Ukyoi , 2011 # csslayer , 2014,2017 # csslayer , 2011 # csslayer , 2010-2013 # wwj402 , 2014 # wwj402 , 2014 # csslayer , 2011,2014 # Xuetian Weng , 2012 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-06-02 20:30+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: Xuetian Weng , 2012\n" "Language-Team: Chinese (China) (http://www.transifex.com/fcitx/fcitx/" "language/zh_CN/)\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "配置皮肤(&C)" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "删除皮肤(&D)" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

注意:

\n" "

您需要使用经典界面才能使用" "皮肤功能。

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "默认键盘布局:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "输入法设置:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "键盘布局:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "其它" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "选择输入法:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "通用键盘布局查看器" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "附加组件配置" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "外观" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "作者" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "可用输入法:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "无法通过 DBus 连接到 Fcitx,Fcitx 是否正在运行?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "无法加载当前所用用户界面信息" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "配置 Fcitx" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "配置输入法" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "复制" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "复制失败" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "Copyright 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "当前输入法:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "默认" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx 配置模块" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "第一候选词" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "表格" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "全局配置" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "输入法" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "输入法默认" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "键盘 <布局>" #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "键盘布局查看器" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "键盘布局<分组号> (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "键盘布局<变体>" #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "无活动输入法时使用的键盘布局" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "键盘布局查看器" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "管理皮肤" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "多语言" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "%1 无配置选项。" #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "仅显示当前语言(&S)" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "这里列出的选项可能是由特定的输入法占用了,通常包括候选编号,上一页和下一页的" "热键。你可能需要去相应的输入法配置中更改。" #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "其它" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "其它候选词" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "搜索附加组件" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "搜索输入法" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "选择字体(&F)..." #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "选择默认键盘布局" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "显示高级选项(&A)" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "无法加载皮肤 %1" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "第一个输入法将为非激活状态。通常您需要将键盘键盘 - 布局名称放在第一位。" #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "未知" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "用户配置不存在,您想要打开系统配置还是将系统配置复制为用户配置?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "查看键盘布局" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "查看系統配置" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "操作" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "翁学天" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "wengxt@gmail.com" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "翁学天" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "分组" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "keyboard,input,im,fcitx,输入法,小企鹅,键盘,输入" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "keyboard;input;im;输入法;键盘;输入" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "布局" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "变体" kcm-fcitx-master/po/zh_TW.po000066400000000000000000000241031433634536200162560ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Alisha , 2012 # Alisha , 2011-2012 # csslayer , 2014 # PHLin , 2017 # Gerald Du , 2015 # 黃柏諺 , 2015,2017 # PHLin , 2017 # csslayer , 2014 # csslayer , 2012-2013 # 如月飛羽 , 2022 # 黃柏諺 , 2015,2017 msgid "" msgstr "" "Project-Id-Version: fcitx\n" "Report-Msgid-Bugs-To: fcitx-dev@googlegroups.com\n" "POT-Creation-Date: 2022-11-20 06:36+0000\n" "PO-Revision-Date: 2011-11-16 06:53+0000\n" "Last-Translator: 如月飛羽 , 2022\n" "Language-Team: Chinese (Taiwan) (http://www.transifex.com/fcitx/fcitx/" "language/zh_TW/)\n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/impage.cpp:84 #, kde-format msgctxt "%1 is language name, %2 is country name" msgid "%1 (%2)" msgstr "%1 (%2)" #. i18n: file: src/skinpage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, configureSkinButton) msgid "&Configure Skin" msgstr "設定佈景(&C)" #. i18n: file: src/skinpage.ui:51 #. i18n: ectx: property (text), widget (QPushButton, deleteSkinButton) msgid "&Delete Skin" msgstr "刪除佈景(&D)" #. i18n: file: src/skinpage.ui:65 #. i18n: ectx: property (text), widget (QLabel, label) msgid "" "\n" "\n" "

Notice:

\n" "

You need to use Classic UI " "to use skin function.

" msgstr "" "\n" "\n" "

注意:

\n" "

需要經典介面來使用佈景功" "能。

" #. i18n: file: src/impage.ui:292 #. i18n: ectx: property (text), widget (QLabel, label_3) msgid "Default keyboard layout:" msgstr "預設鍵盤佈局:" #: src/imconfigdialog.cpp:98 #, kde-format msgid "Input Method Setting:" msgstr "輸入法設定:" #: src/imconfigdialog.cpp:42 #, kde-format msgid "Keyboard Layout:" msgstr "鍵盤佈局:" #: src/configwidget.cpp:450 #, kde-format msgid "Other" msgstr "其他" #. i18n: file: src/impage.ui:302 #. i18n: ectx: property (text), widget (QLabel, label_4) msgid "Select Input Method:" msgstr "選擇輸入法:" #: layout/main.cpp:37 #, kde-format msgid "A general keyboard layout viewer" msgstr "一般鍵盤佈局檢視器" #: src/module.cpp:129 #, kde-format msgid "Addon Config" msgstr "附加元件設定" #: src/module.cpp:121 #, kde-format msgid "Appearance" msgstr "外觀" #: src/module.cpp:91 #, kde-format msgid "Author" msgstr "作者" #. i18n: file: src/impage.ui:83 #. i18n: ectx: property (text), widget (QLabel, label) msgid "Available Input Method:" msgstr "可用輸入法:" #: src/erroroverlay.cpp:43 #, kde-format msgid "Cannot connect to Fcitx by DBus, is Fcitx running?" msgstr "無法透過 DBus 連接到 Fcitx,Fcitx 是否正在運行?" #: src/uipage.cpp:16 #, kde-format msgid "Cannot load currently used user interface info" msgstr "無法載入目前使用的使用者介面資訊" #: src/module.cpp:85 #, kde-format msgid "Configure Fcitx" msgstr "設定 Fcitx" #: src/kcm_fcitx.desktop.in:12 msgid "Configure Input Method" msgstr "設定輸入法" #: src/subconfigwidget.cpp:232 #, kde-format msgid "Copy" msgstr "複製" #: src/subconfigwidget.cpp:245 #, kde-format msgid "Copy failed" msgstr "複製失敗" #: src/module.cpp:87 #, kde-format msgid "Copyright 2012 Xuetian Weng" msgstr "版權所有 2012 Xuetian Weng" #. i18n: file: src/impage.ui:176 #. i18n: ectx: property (text), widget (QLabel, label_2) msgid "Current Input Method:" msgstr "目前輸入法:" #: src/imconfigdialog.cpp:47 #, kde-format msgid "Default" msgstr "預設" #: src/module.cpp:83 #, kde-format msgid "Fcitx Configuration Module" msgstr "Fcitx 設定模組" #: src/skinpage.cpp:217 #, kde-format msgid "First candidate" msgstr "第一候選詞" #. i18n: file: src/configpage.ui:14 #. i18n: ectx: property (windowTitle), widget (QWidget, ConfigPage) #. i18n: file: src/fontbutton.ui:20 #. i18n: ectx: property (windowTitle), widget (QWidget, FontButton) msgid "Form" msgstr "Form" #: src/module.cpp:113 #, kde-format msgid "Global Config" msgstr "全域設定" #: src/module.cpp:104 src/kcm_fcitx.desktop.in:11 #, kde-format msgid "Input Method" msgstr "輸入法" #: src/imconfigdialog.cpp:49 #, kde-format msgid "Input Method Default" msgstr "輸入法預設" #: layout/main.cpp:44 #, kde-format msgid "Keyboard " msgstr "鍵盤 " #: layout/main.cpp:74 #, kde-format msgid "Keyboard Layout viewer" msgstr "鍵盤佈局檢視器" #: layout/main.cpp:41 #, kde-format msgid "Keyboard layout (0-3)" msgstr "鍵盤配置 (0-3)" #: layout/main.cpp:47 #, kde-format msgid "Keyboard layout " msgstr "鍵盤配置 " #. i18n: file: src/impage.ui:38 #. i18n: ectx: property (toolTip), widget (QPushButton, defaultLayoutButton) msgid "Keyboard layout to use when no input method active" msgstr "無作用中輸入法時使用的鍵盤佈局" #: layout/kbd-layout-viewer.desktop.in:6 msgid "Keyboard layout viewer" msgstr "鍵盤佈局檢視器" #: src/module.cpp:178 #, kde-format msgid "Manage Skin" msgstr "管理佈景" #: src/impage.cpp:53 #, kde-format msgid "Multilingual" msgstr "多語言" #: src/uipage.cpp:45 #, kde-format msgid "No configuration options for %1." msgstr "%1 無配置選項" #. i18n: file: src/impage.ui:115 #. i18n: ectx: property (text), widget (QCheckBox, onlyCurrentLanguageCheckBox) msgid "Only &Show Current Language" msgstr "只顯示目前語言(&S)" #. i18n: file: src/configpage.ui:54 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "Options listed here might be overridden by specific input method, usually " "including candidate number, hotkey of previous page and next page. You may " "need go to configuration of corresponding input method to change them." msgstr "" "在此列出的選項可能被特定的輸入法覆寫,通常包括候選字數,上一頁和下一頁翻頁" "鍵。您可能需要到對應輸入法的設定來修改這些選項。" #: src/configwidget.cpp:560 src/impage.cpp:69 #, kde-format msgid "Other" msgstr "其他" #: src/skinpage.cpp:218 #, kde-format msgid "Other candidate" msgstr "其他候選詞" #: src/addonselector.cpp:375 #, kde-format msgid "Search Addons" msgstr "搜尋附加元件" #: src/impage.cpp:481 #, kde-format msgid "Search Input Method" msgstr "搜尋輸入法" #. i18n: file: src/fontbutton.ui:51 #. i18n: ectx: property (text), widget (QPushButton, fontSelectButton) msgid "Select &Font..." msgstr "選擇字體(&F)" #. i18n: file: src/impage.ui:41 #. i18n: ectx: property (text), widget (QPushButton, defaultLayoutButton) msgid "Select default keyboard layout" msgstr "選擇預設鍵盤佈局" #: src/addonselector.cpp:382 src/configwidget.cpp:606 #, kde-format msgid "Show &Advance option" msgstr "顯示進階選項(&A)" #: src/skinpage.cpp:387 #, kde-format msgid "Skin %1 Cannot be loaded" msgstr "無法載入佈景 %1" #. i18n: file: src/impage.ui:277 #. i18n: ectx: property (text), widget (QLabel, infoLabel) msgid "" "The first input method will be inactive state. Usually you need to put " "Keyboard or Keyboard - layout name in the first place." msgstr "" "第一個輸入法將作爲非作用中狀態。通常您需要將鍵盤或者鍵盤 - 佈局名" "稱放到第一個。" #: src/impage.cpp:50 #, kde-format msgid "Unknown" msgstr "未知" #: src/subconfigwidget.cpp:230 #, kde-format msgid "" "User config doesn't exisits, do you want to open system file or copy system " "file to user file?" msgstr "" "使用者設定不存在,您想要開啟系統設定文件,還是要將系統設定文件複製到使用者設" "定文件?" #: layout/kbd-layout-viewer.desktop.in:7 msgid "View keyboard layout" msgstr "檢視鍵盤佈局" #: src/subconfigwidget.cpp:233 #, kde-format msgid "View system" msgstr "查看系統" #: src/subconfigwidget.cpp:231 #, kde-format msgid "What to do" msgstr "要做什麼" #: src/module.cpp:91 #, kde-format msgid "Xuetian Weng" msgstr "Xuetian Weng" msgctxt "EMAIL OF TRANSLATORS" msgid "Your emails" msgstr "alisha.4m@gmail.com" msgctxt "NAME OF TRANSLATORS" msgid "Your names" msgstr "Alisha" #: layout/main.cpp:42 #, kde-format msgid "group" msgstr "群組" #: src/kcm_fcitx.desktop.in:14 msgid "keyboard,input,im,fcitx" msgstr "keyboard,input,im,fcitx,輸入法,鍵盤,輸入" #: layout/kbd-layout-viewer.desktop.in:9 msgid "keyboard;input;im" msgstr "keyboard;input;im;輸入法;鍵盤;輸入" #: layout/main.cpp:45 #, kde-format msgid "layout" msgstr "配置" #: layout/main.cpp:48 #, kde-format msgid "variant" msgstr "變體" kcm-fcitx-master/src/000077500000000000000000000000001433634536200150345ustar00rootroot00000000000000kcm-fcitx-master/src/CMakeLists.txt000066400000000000000000000026621433634536200176020ustar00rootroot00000000000000include_directories(${PROJECT_SOURCE_DIR}/layout) add_definitions(-DTRANSLATION_DOMAIN=\"kcm_fcitx\") set(kcm_SRCS main.cpp module.cpp addonselector.cpp configwidget.cpp global.cpp subconfigparser.cpp subconfigpattern.cpp subconfig.cpp subconfigwidget.cpp skinpage.cpp impage.cpp uipage.cpp imconfigdialog.cpp dummyconfig.cpp verticalscrollarea.cpp fontbutton.cpp configpage.cpp erroroverlay.cpp ../layout/keyboardlayoutwidget.cpp ) set(kcm_UIS module.ui skinpage.ui impage.ui fontbutton.ui configpage.ui) fcitx_translate_add_sources(${kcm_SRCS} ${kcm_UIS} kcm_fcitx.desktop.in) ki18n_wrap_ui(kcm_SRCS ${kcm_UIS}) add_library(kcm_fcitx MODULE ${kcm_SRCS}) target_link_libraries(kcm_fcitx Qt5::Widgets Qt5::X11Extras KF5::CoreAddons KF5::WidgetsAddons KF5::ConfigWidgets KF5::ItemViews KF5::I18n KF5::KIOCore KF5::KIOWidgets FcitxQt5::WidgetsAddons FcitxQt5::DBusAddons ${FCITX4_FCITX_UTILS_LIBRARIES} ${FCITX4_FCITX_CONFIG_LIBRARIES} ${FCITX4_FCITX_LIBRARIES} ${LIBINTL_LIBRARY} ${X11_X11_LIB} ${XKBFILE_LIBRARIES} ${X11_Xkblib_LIB} ) install(TARGETS kcm_fcitx DESTINATION ${CMAKE_INSTALL_PLUGINDIR}) fcitx_translate_add_apply_source( kcm_fcitx.desktop.in "${CMAKE_CURRENT_BINARY_DIR}/kcm_fcitx.desktop") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/kcm_fcitx.desktop" DESTINATION ${CMAKE_INSTALL_KSERVICES5DIR}) if(ENABLE_TEST) add_subdirectory(test) endif(ENABLE_TEST) kcm-fcitx-master/src/addonselector.cpp000066400000000000000000000356241433634536200204000ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include #include #include // KDE #include #include #include // system #include // Fcitx #include #include // self #include "config.h" #include "addonselector.h" #include "addonselector_p.h" #include "configwidget.h" #include "module.h" #include "global.h" #include "subconfigparser.h" #define MARGIN 5 namespace Fcitx { AddonSelector::Private::Private(AddonSelector* parent) : QObject(parent), listView(0), categoryDrawer(0), parent(parent) { } AddonSelector::Private::~Private() { } int AddonSelector::Private::dependantLayoutValue(int value, int width, int totalWidth) const { if (listView->layoutDirection() == Qt::LeftToRight) { return value; } return totalWidth - width - value; } AddonSelector::Private::AddonModel::AddonModel(AddonSelector::Private *addonSelector_d, QObject* parent) : QAbstractListModel(parent), addonSelector_d(addonSelector_d) { } AddonSelector::Private::AddonModel::~AddonModel() { } QModelIndex AddonSelector::Private::AddonModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent); return createIndex(row, column, (row < addonEntryList.count()) ? (void*) addonEntryList.at(row) : 0); } QVariant AddonSelector::Private::AddonModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || !index.internalPointer()) { return QVariant(); } FcitxAddon *addonEntry = static_cast(index.internalPointer()); switch (role) { case Qt::DisplayRole: return QString::fromUtf8(addonEntry->generalname); case CommentRole: return QString::fromUtf8(addonEntry->comment); case ConfigurableRole: { FcitxConfigFileDesc* cfdesc = Global::instance()->GetConfigDesc(QString::fromUtf8(addonEntry->name).append(".desc")); return (bool)(cfdesc != NULL || strlen(addonEntry->subconfig) != 0); } case Qt::DecorationRole: return QVariant(); case Qt::CheckStateRole: return addonEntry->bEnabled; case KCategorizedSortFilterProxyModel::CategoryDisplayRole: { const FcitxConfigOptionDesc *codesc = FcitxConfigDescGetOptionDesc(addonEntry->config.configFile->fileDesc, "Addon", "Category"); const FcitxConfigEnum *e = &codesc->configEnum; return QString::fromUtf8(dgettext("fcitx", e->enumDesc[addonEntry->category])); } case KCategorizedSortFilterProxyModel::CategorySortRole: return (int) addonEntry->category; default: return QVariant(); } } bool AddonSelector::Private::AddonModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid()) { return false; } bool ret = false; if (role == Qt::CheckStateRole) { FcitxAddon* addon = static_cast(index.internalPointer()); addon->bEnabled = value.toBool(); QString buf = QString("%1.conf").arg(addon->name); FILE* fp = FcitxXDGGetFileUserWithPrefix("addon", buf.toLocal8Bit().constData(), "w", NULL); if (fp) { fprintf(fp, "[Addon]\nEnabled=%s\n", addon->bEnabled ? "True" : "False"); fclose(fp); } ret = true; } if (ret) { emit dataChanged(index, index); } return ret; } void AddonSelector::Private::AddonModel::addAddon(FcitxAddon* addon) { beginInsertRows(QModelIndex(), addonEntryList.count(), addonEntryList.count()); addonEntryList << addon; endInsertRows(); } int AddonSelector::Private::AddonModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } return addonEntryList.count(); } AddonSelector::Private::ProxyModel::ProxyModel(AddonSelector::Private *addonSelector_d, QObject *parent) : KCategorizedSortFilterProxyModel(parent) , addonSelector_d(addonSelector_d) { sort(0); } AddonSelector::Private::ProxyModel::~ProxyModel() { } bool AddonSelector::Private::ProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { Q_UNUSED(sourceParent) const QModelIndex index = sourceModel()->index(sourceRow, 0); const FcitxAddon* addonInfo = static_cast(index.internalPointer()); if ((!addonInfo->bEnabled || addonInfo->advance) && !addonSelector_d->advanceCheckbox->isChecked()) { return false; } if (addonInfo->category == AC_FRONTEND && !addonSelector_d->advanceCheckbox->isChecked()) { return false; } if (!addonSelector_d->lineEdit->text().isEmpty()) { return QString(addonInfo->name).contains(addonSelector_d->lineEdit->text(), Qt::CaseInsensitive) || QString::fromUtf8(addonInfo->generalname).contains(addonSelector_d->lineEdit->text(), Qt::CaseInsensitive) || QString::fromUtf8(addonInfo->comment).contains(addonSelector_d->lineEdit->text(), Qt::CaseInsensitive); } return true; } bool AddonSelector::Private::ProxyModel::subSortLessThan(const QModelIndex &left, const QModelIndex &right) const { FcitxAddon* l = static_cast(left.internalPointer()); FcitxAddon* r = static_cast(right.internalPointer()); return QString::fromUtf8(l->name).compare(QString::fromUtf8(r->name), Qt::CaseInsensitive) < 0; } AddonSelector::Private::AddonDelegate::AddonDelegate(AddonSelector::Private *addonSelector_d, QObject *parent) : KWidgetItemDelegate(addonSelector_d->listView, parent) , checkBox(new QCheckBox) , pushButton(new QPushButton) , addonSelector_d(addonSelector_d) { pushButton->setIcon(QIcon::fromTheme("configure")); // only for getting size matters } AddonSelector::Private::AddonDelegate::~AddonDelegate() { delete checkBox; delete pushButton; } void AddonSelector::Private::AddonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (!index.isValid()) { return; } int xOffset = 0; if (addonSelector_d->advanceCheckbox->isChecked()) xOffset = checkBox->sizeHint().width(); painter->save(); QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0); QRect contentsRect(addonSelector_d->dependantLayoutValue(MARGIN * 2 + option.rect.left() + xOffset, option.rect.width() - MARGIN * 2 - xOffset, option.rect.width()), MARGIN + option.rect.top(), option.rect.width() - MARGIN * 2 - xOffset, option.rect.height() - MARGIN * 2); int lessHorizontalSpace = MARGIN * 2 + pushButton->sizeHint().width(); contentsRect.setWidth(contentsRect.width() - lessHorizontalSpace); if (option.state & QStyle::State_Selected) painter->setPen(option.palette.highlightedText().color()); if (addonSelector_d->listView->layoutDirection() == Qt::RightToLeft) contentsRect.translate(lessHorizontalSpace, 0); painter->save(); QFont font = titleFont(option.font); QFontMetrics fmTitle(font); painter->setFont(font); painter->drawText(contentsRect, Qt::AlignLeft | Qt::AlignTop, fmTitle.elidedText(index.model()->data(index, Qt::DisplayRole).toString(), Qt::ElideRight, contentsRect.width())); painter->restore(); painter->drawText(contentsRect, Qt::AlignLeft | Qt::AlignBottom, option.fontMetrics.elidedText(index.model()->data(index, CommentRole).toString(), Qt::ElideRight, contentsRect.width())); painter->restore(); } QSize AddonSelector::Private::AddonDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { int i = 4; int j = 1; QFont font = titleFont(option.font); QFontMetrics fmTitle(font); return QSize(fmTitle.horizontalAdvance(index.model()->data(index, Qt::DisplayRole).toString()) + 0 + MARGIN * i + pushButton->sizeHint().width() * j, fmTitle.height() + option.fontMetrics.height() + MARGIN * 2); } QList AddonSelector::Private::AddonDelegate::createItemWidgets(const QModelIndex& index) const { QList widgetList; QCheckBox *enabledCheckBox = new QCheckBox; connect(enabledCheckBox, SIGNAL(clicked(bool)), this, SLOT(slotStateChanged(bool))); connect(enabledCheckBox, SIGNAL(clicked(bool)), this, SLOT(emitChanged())); QPushButton *configurePushButton = new QPushButton; configurePushButton->setIcon(QIcon::fromTheme("configure")); connect(configurePushButton, SIGNAL(clicked(bool)), this, SLOT(slotConfigureClicked())); setBlockedEventTypes(enabledCheckBox, QList() << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick << QEvent::KeyPress << QEvent::KeyRelease); setBlockedEventTypes(configurePushButton, QList() << QEvent::MouseButtonPress << QEvent::MouseButtonRelease << QEvent::MouseButtonDblClick << QEvent::KeyPress << QEvent::KeyRelease); widgetList << enabledCheckBox << configurePushButton; return widgetList; } void AddonSelector::Private::AddonDelegate::updateItemWidgets(const QList widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index) const { QCheckBox *checkBox = static_cast(widgets[0]); checkBox->resize(checkBox->sizeHint()); checkBox->move(addonSelector_d->dependantLayoutValue(MARGIN, checkBox->sizeHint().width(), option.rect.width()), option.rect.height() / 2 - checkBox->sizeHint().height() / 2); checkBox->setVisible(addonSelector_d->advanceCheckbox->isChecked()); QPushButton *configurePushButton = static_cast(widgets[1]); QSize configurePushButtonSizeHint = configurePushButton->sizeHint(); configurePushButton->resize(configurePushButtonSizeHint); configurePushButton->move(addonSelector_d->dependantLayoutValue(option.rect.width() - MARGIN - configurePushButtonSizeHint.width(), configurePushButtonSizeHint.width(), option.rect.width()), option.rect.height() / 2 - configurePushButtonSizeHint.height() / 2); if (!index.isValid() || !index.internalPointer()) { checkBox->setVisible(false); configurePushButton->setVisible(false); } else { checkBox->setChecked(index.model()->data(index, Qt::CheckStateRole).toBool()); configurePushButton->setEnabled(index.model()->data(index, Qt::CheckStateRole).toBool()); configurePushButton->setVisible(index.model()->data(index, ConfigurableRole).toBool()); } } void AddonSelector::Private::AddonDelegate::slotStateChanged(bool state) { if (!focusedIndex().isValid()) return; const QModelIndex index = focusedIndex(); const_cast(index.model())->setData(index, state, Qt::CheckStateRole); } void AddonSelector::Private::AddonDelegate::emitChanged() { emit changed(true); } void AddonSelector::Private::AddonDelegate::slotConfigureClicked() { const QModelIndex index = focusedIndex(); FcitxAddon* addonEntry = static_cast(index.internalPointer()); QPointer configDialog(ConfigWidget::configDialog(addonSelector_d->parent->parent, addonEntry)); if (configDialog.isNull()) return; configDialog->exec(); delete configDialog; } void AddonSelector::load() { } void AddonSelector::save() { } AddonSelector::AddonSelector(Module* parent) : QWidget(parent), d(new Private(this)), parent(parent) { QVBoxLayout* layout = new QVBoxLayout; layout->setMargin(0); d->lineEdit = new QLineEdit(this); d->lineEdit->setClearButtonEnabled(true); d->lineEdit->setPlaceholderText(i18n("Search Addons")); d->listView = new KCategorizedView(this); d->listView->setVerticalScrollMode(QListView::ScrollPerPixel); d->listView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); d->categoryDrawer = new KCategoryDrawer(d->listView); d->listView->setCategoryDrawer(d->categoryDrawer); d->advanceCheckbox = new QCheckBox(this); d->advanceCheckbox->setText(i18n("Show &Advance option")); d->advanceCheckbox->setChecked(false); d->proxyModel = new Private::ProxyModel(d, this); d->addonModel = new Private::AddonModel(d, this); d->proxyModel->setCategorizedModel(true); d->proxyModel->setSourceModel(d->addonModel); d->listView->setModel(d->proxyModel); d->listView->setAlternatingBlockColors(true); Private::AddonDelegate *addonDelegate = new Private::AddonDelegate(d, this); d->listView->setItemDelegate(addonDelegate); d->listView->setMouseTracking(true); d->listView->viewport()->setAttribute(Qt::WA_Hover); connect(d->lineEdit, SIGNAL(textChanged(QString)), d->proxyModel, SLOT(invalidate())); connect(d->advanceCheckbox, SIGNAL(clicked(bool)), d->proxyModel, SLOT(invalidate())); connect(addonDelegate, SIGNAL(changed(bool)), this, SIGNAL(changed(bool))); connect(addonDelegate, SIGNAL(configCommitted(QByteArray)), this, SIGNAL(configCommitted(QByteArray))); layout->addWidget(d->lineEdit); layout->addWidget(d->listView); layout->addWidget(d->advanceCheckbox); this->setLayout(layout); } void AddonSelector::addAddon(FcitxAddon* fcitxAddon) { d->addonModel->addAddon(fcitxAddon); d->proxyModel->sort(0); } QFont AddonSelector::Private::AddonDelegate::titleFont(const QFont &baseFont) const { QFont retFont(baseFont); retFont.setBold(true); return retFont; } AddonSelector::~AddonSelector() { delete d->listView->itemDelegate(); delete d->listView; // depends on some other things in d, make sure this dies first. delete d; } } kcm-fcitx-master/src/addonselector.h000066400000000000000000000036221433634536200200360ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef __FCITX_ADDON_SELECTOR_H__ #define __FCITX_ADDON_SELECTOR_H__ // Qt #include struct _FcitxAddon; namespace Fcitx { class Module; class AddonSelector : public QWidget { Q_OBJECT public: AddonSelector(Module* parent); virtual ~AddonSelector(); void load(); void save(); void addAddon(struct _FcitxAddon* fcitxAddon); Q_SIGNALS: void changed(bool hasChanged); void configCommitted(const QByteArray& componentName); private: class Private; Private* d; Module* parent; }; } #endif kcm-fcitx-master/src/addonselector_p.h000066400000000000000000000111651433634536200203560ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef __FCITX_ADDON_SELECTOR_P_H__ #define __FCITX_ADDON_SELECTOR_P_H__ // Qt #include #include #include // KDE #include #include // Fcitx #include // self #include "addonselector.h" class KCategoryDrawer; class KCategorizedView; class QPushButton; class QCheckBox; namespace Fcitx { class AddonSelector::Private : public QObject { Q_OBJECT public: enum ExtraRoles { CommentRole = 0x19880209, ConfigurableRole = 0x20080331 }; Private(AddonSelector* parent); virtual ~Private(); int dependantLayoutValue(int value, int width, int totalWidth) const; public: class AddonModel; class ProxyModel; class AddonDelegate; QLineEdit* lineEdit; KCategorizedView* listView; KCategoryDrawer *categoryDrawer; AddonModel *addonModel; ProxyModel *proxyModel; AddonDelegate *addonDelegate; QCheckBox* advanceCheckbox; private: AddonSelector* parent; }; class AddonSelector::Private::AddonModel : public QAbstractListModel { Q_OBJECT public: AddonModel(AddonSelector::Private *addonSelector_d, QObject* parent = 0); virtual ~AddonModel(); QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; void addAddon(FcitxAddon* addon); private: QList addonEntryList; AddonSelector::Private *addonSelector_d; }; class AddonSelector::Private::ProxyModel : public KCategorizedSortFilterProxyModel { Q_OBJECT public: ProxyModel(AddonSelector::Private *addonSelector_d, QObject* parent = 0); virtual ~ProxyModel(); protected: bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; bool subSortLessThan(const QModelIndex& left, const QModelIndex& right) const override; private: AddonSelector::Private* addonSelector_d; }; class AddonSelector::Private::AddonDelegate : public KWidgetItemDelegate { Q_OBJECT public: AddonDelegate(AddonSelector::Private *addonSelector_d, QObject* parent = 0); virtual ~AddonDelegate(); void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; Q_SIGNALS: void changed(bool hasChanged); void configCommitted(const QByteArray& addonName); protected: QList< QWidget* > createItemWidgets(const QModelIndex &index) const override; void updateItemWidgets(const QList< QWidget* > widgets, const QStyleOptionViewItem& option, const QPersistentModelIndex& index) const override; private Q_SLOTS: void slotStateChanged(bool state); void emitChanged(); void slotConfigureClicked(); private: QFont titleFont(const QFont &baseFont) const; QCheckBox *checkBox; QPushButton *pushButton; QList moduleProxyList; AddonSelector::Private* addonSelector_d; }; } #endif kcm-fcitx-master/src/configpage.cpp000066400000000000000000000044241433634536200176460ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2013~2013 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "configpage.h" #include "global.h" #include "configwidget.h" #include "ui_configpage.h" namespace Fcitx { ConfigPage::ConfigPage(QWidget* parent): QWidget(parent) ,m_ui(new Ui::ConfigPage) { m_ui->setupUi(this); FcitxConfigFileDesc* configDesc = Global::instance()->GetConfigDesc("config.desc"); m_configWidget = new ConfigWidget(configDesc, "", "config", QString(), "global"); m_ui->layout->insertWidget(0, m_configWidget); // m_ui->infoIconLabel->setPixmap(KIcon("dialog-information").pixmap(KIconLoader::SizeSmallMedium)); connect(m_configWidget, SIGNAL(changed()), this, SIGNAL(changed())); } ConfigPage::~ConfigPage() { delete m_ui; } void ConfigPage::load() { m_configWidget->load(); } void ConfigPage::save() { m_configWidget->buttonClicked(QDialogButtonBox::Ok); } void ConfigPage::defaults() { m_configWidget->buttonClicked(QDialogButtonBox::RestoreDefaults); } } kcm-fcitx-master/src/configpage.h000066400000000000000000000034631433634536200173150ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2013~2013 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef CONFIGPAGE_H #define CONFIGPAGE_H #include namespace Ui { class ConfigPage; } namespace Fcitx { class ConfigWidget; class ConfigPage : public QWidget { Q_OBJECT public: explicit ConfigPage(QWidget* parent = 0); virtual ~ConfigPage(); void load(); void save(); void defaults(); signals: void changed(); private: Ui::ConfigPage* m_ui; ConfigWidget* m_configWidget; }; } #endif // CONFIGPAGE_H kcm-fcitx-master/src/configpage.ui000066400000000000000000000034211433634536200174750ustar00rootroot00000000000000 ConfigPage 0 0 659 405 Form Qt::Horizontal 0 0 22 22 22 22 Options listed here might be overridden by specific input method, usually including candidate number, hotkey of previous page and next page. You may need go to configuration of corresponding input method to change them. true kcm-fcitx-master/src/configwidget.cpp000066400000000000000000000766641433634536200202340ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include #include #include #include #include #include #include #include #include #include // KDE #include #include #include #include // system #include // Fcitx #include #include #include #include // self #include "config.h" #include "configwidget.h" #include "subconfigparser.h" #include "subconfigwidget.h" #include "global.h" #include "dummyconfig.h" #include "verticalscrollarea.h" #include "fontbutton.h" #define RoundColor(c) ((c)>=0?((c)<=255?c:255):0) namespace Fcitx { static bool KeySequenceToHotkey(const QKeySequence& keyseq, FcitxQtModifierSide side, FcitxHotkey* hotkey); static QKeySequence HotkeyToKeySequence(FcitxHotkey* hotkey); static void SyncFilterFunc(FcitxGenericConfig* gconfig, FcitxConfigGroup *group, FcitxConfigOption *option, void *value, FcitxConfigSync sync, void *arg); ConfigWidget::ConfigWidget(FcitxConfigFileDesc* cfdesc, const QString& prefix, const QString& name, const QString& subconfig, const QString& addonName, QWidget* parent) : QWidget(parent) , m_cfdesc(cfdesc) , m_prefix(prefix) , m_name(name) , m_addonName(addonName) , m_switchLayout(new QVBoxLayout) , m_simpleWidget(0) , m_fullWidget(0) , m_advanceCheckBox(0) , m_config(0) , m_parser(new SubConfigParser(subconfig, this)) , m_simpleUiType(CW_NoShow) , m_fullUiType(CW_NoShow) { if (cfdesc) m_config = new DummyConfig(cfdesc); setupConfigUi(); } ConfigWidget::ConfigWidget(FcitxAddon* addonEntry, QWidget* parent): QWidget(parent) , m_cfdesc(Global::instance()->GetConfigDesc(QString::fromUtf8(addonEntry->name).append(".desc"))) , m_prefix("conf") , m_name(QString::fromUtf8(addonEntry->name).append(".config")) , m_addonName(addonEntry->name) , m_switchLayout(new QVBoxLayout) , m_simpleWidget(0) , m_fullWidget(0) , m_advanceCheckBox(0) , m_config(0) , m_parser(new SubConfigParser(QString::fromUtf8(addonEntry->subconfig), this)) , m_simpleUiType(CW_NoShow) , m_fullUiType(CW_NoShow) { if (m_cfdesc) m_config = new DummyConfig(m_cfdesc); setupConfigUi(); } ConfigWidget::~ConfigWidget() { if (m_config) delete m_config; } void ConfigWidget::buttonClicked(QDialogButtonBox::StandardButton code) { if (!m_cfdesc) return; if (code == QDialogButtonBox::RestoreDefaults) { FcitxConfigResetConfigToDefaultValue(m_config->genericConfig()); FcitxConfigBindSync(m_config->genericConfig()); } else if (code == QDialogButtonBox::Ok) { FILE* fp = FcitxXDGGetFileUserWithPrefix(m_prefix.toLocal8Bit().constData(), m_name.toLocal8Bit().constData(), "w", NULL); if (fp) { FcitxConfigSaveConfigFileFp(fp, m_config->genericConfig(), m_cfdesc); fclose(fp); } if (Global::instance()->inputMethodProxy()) { if (m_addonName.isEmpty()) { Global::instance()->inputMethodProxy()->ReloadConfig(); } else { Global::instance()->inputMethodProxy()->ReloadAddonConfig(m_addonName); } } } } void ConfigWidget::load() { if (!m_cfdesc) return; FILE *fp; fp = FcitxXDGGetFileWithPrefix(m_prefix.toLocal8Bit().constData(), m_name.toLocal8Bit().constData(), "r", NULL); if (!fp) return; m_config->load(fp); m_config->sync(); fclose(fp); } void ConfigWidget::createConfigOptionWidget(FcitxConfigGroupDesc* cgdesc, FcitxConfigOptionDesc* codesc, QString& label, QString& tooltip, QWidget*& inputWidget, void*& newarg) { FcitxConfigOptionDesc2* codesc2 = (FcitxConfigOptionDesc2*) codesc; void* oldarg = NULL; void* argument = NULL; QString name(QString("%1/%2").arg(cgdesc->groupName).arg(codesc->optionName)); if (m_argMap.contains(name)) { oldarg = m_argMap[name]; } if (codesc->desc && codesc->desc[0]) label = QString::fromUtf8(dgettext(m_cfdesc->domain, codesc->desc)); else label = QString::fromUtf8(dgettext(m_cfdesc->domain, codesc->optionName)); if (codesc2->longDesc && codesc2->longDesc[0]) { tooltip = QString::fromUtf8(dgettext(m_cfdesc->domain, codesc2->longDesc)); } switch (codesc->type) { case T_Integer: { QSpinBox* spinbox = new QSpinBox(this); spinbox->setMaximum(codesc2->constrain.integerConstrain.max); spinbox->setMinimum(codesc2->constrain.integerConstrain.min); inputWidget = spinbox; if (!oldarg) { connect(spinbox, SIGNAL(valueChanged(int)), this, SIGNAL(changed())); argument = inputWidget; } else { QSpinBox* oldspinbox = (QSpinBox*) oldarg; connect(oldspinbox, SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int))); connect(spinbox, SIGNAL(valueChanged(int)), oldspinbox, SLOT(setValue(int))); } break; } case T_Color: { ColorButton* colorButton = new ColorButton(this); inputWidget = colorButton; if (!oldarg) { connect(colorButton, SIGNAL(changed(QColor)), this, SIGNAL(changed())); argument = inputWidget; } else { ColorButton* oldColorButton = (ColorButton*) oldarg; connect(colorButton, SIGNAL(changed(QColor)), oldColorButton, SLOT(setColor(QColor))); connect(oldColorButton, SIGNAL(changed(QColor)), colorButton, SLOT(setColor(QColor))); } } break; case T_Boolean: { QCheckBox* checkBox = new QCheckBox(this); inputWidget = checkBox; if (!oldarg) { connect(checkBox, SIGNAL(toggled(bool)), this, SIGNAL(changed())); argument = inputWidget; } else { QCheckBox* oldCheckBox = (QCheckBox*) oldarg; connect(checkBox, SIGNAL(toggled(bool)), oldCheckBox, SLOT(setChecked(bool))); connect(oldCheckBox, SIGNAL(toggled(bool)), checkBox, SLOT(setChecked(bool))); } break; } case T_Font: { FontButton* fontButton = new FontButton(this); inputWidget = fontButton; if (!oldarg) { connect(fontButton, SIGNAL(fontChanged(QFont)), this, SIGNAL(changed())); argument = inputWidget; } else { FontButton* oldFontButton = (FontButton*) oldarg; connect(fontButton, SIGNAL(fontChanged(QFont)), oldFontButton, SLOT(setFont(QFont))); connect(oldFontButton, SIGNAL(fontChanged(QFont)), fontButton, SLOT(setFont(QFont))); } } break; case T_Enum: { int i; FcitxConfigEnum *e = &codesc->configEnum; QComboBox* combobox = new QComboBox(this); inputWidget = combobox; for (i = 0; i < e->enumCount; i ++) { combobox->addItem(QString::fromUtf8(dgettext(m_cfdesc->domain, e->enumDesc[i]))); } if (!oldarg) { connect(combobox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed())); argument = inputWidget; } else { QComboBox* oldComboBox = (QComboBox*) oldarg; connect(combobox, SIGNAL(currentIndexChanged(int)), oldComboBox, SLOT(setCurrentIndex(int))); connect(oldComboBox, SIGNAL(currentIndexChanged(int)), combobox, SLOT(setCurrentIndex(int))); } } break; case T_Hotkey: { FcitxQtKeySequenceWidget* keyseq1 = new FcitxQtKeySequenceWidget(); FcitxQtKeySequenceWidget* keyseq2 = new FcitxQtKeySequenceWidget(); QHBoxLayout* hbox = new QHBoxLayout(); hbox->setMargin(0); QWidget* widget = new QWidget(this); keyseq1->setMultiKeyShortcutsAllowed(false); keyseq1->setModifierOnlyAllowed(codesc2->constrain.hotkeyConstrain.allowModifierOnly); keyseq1->setModifierlessAllowed(!codesc2->constrain.hotkeyConstrain.disallowNoModifer); keyseq1->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); keyseq2->setMultiKeyShortcutsAllowed(false); keyseq2->setModifierOnlyAllowed(codesc2->constrain.hotkeyConstrain.allowModifierOnly); keyseq1->setModifierlessAllowed(!codesc2->constrain.hotkeyConstrain.disallowNoModifer); keyseq2->setModifierlessAllowed(true); keyseq2->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); hbox->addWidget(keyseq1); hbox->addWidget(keyseq2); widget->setLayout(hbox); inputWidget = widget; if (!oldarg) { connect(keyseq1, SIGNAL(keySequenceChanged(QKeySequence,FcitxQtModifierSide)), this, SIGNAL(changed())); connect(keyseq2, SIGNAL(keySequenceChanged(QKeySequence,FcitxQtModifierSide)), this, SIGNAL(changed())); argument = hbox; } else { QHBoxLayout* hbox = static_cast(oldarg); FcitxQtKeySequenceWidget* oldkeyseq1 = static_cast(hbox->itemAt(0)->widget()); FcitxQtKeySequenceWidget* oldkeyseq2 = static_cast(hbox->itemAt(1)->widget()); connect(oldkeyseq1, SIGNAL(keySequenceChanged(QKeySequence, FcitxQtModifierSide)), keyseq1, SLOT(setKeySequence(QKeySequence, FcitxQtModifierSide))); connect(oldkeyseq2, SIGNAL(keySequenceChanged(QKeySequence, FcitxQtModifierSide)), keyseq2, SLOT(setKeySequence(QKeySequence, FcitxQtModifierSide))); connect(keyseq1, SIGNAL(keySequenceChanged(QKeySequence, FcitxQtModifierSide)), oldkeyseq1, SLOT(setKeySequence(QKeySequence, FcitxQtModifierSide))); connect(keyseq2, SIGNAL(keySequenceChanged(QKeySequence, FcitxQtModifierSide)), oldkeyseq2, SLOT(setKeySequence(QKeySequence, FcitxQtModifierSide))); } } break; case T_File: { KUrlRequester* requester = new KUrlRequester(this); inputWidget = requester; if (!oldarg) { connect(requester, SIGNAL(urlSelected(KUrl)), this, SIGNAL(changed())); argument = inputWidget; } else { KUrlRequester* oldrequester = static_cast(oldarg); connect(requester, SIGNAL(urlSelected(KUrl)), oldrequester, SLOT(setUrl(KUrl))); connect(oldrequester, SIGNAL(urlSelected(KUrl)), requester, SLOT(setUrl(KUrl))); } } break; case T_Char: case T_String: { QLineEdit* lineEdit = new QLineEdit(this); inputWidget = lineEdit; argument = inputWidget; if (codesc->type == T_Char) lineEdit->setMaxLength(1); else if (codesc->type == T_String && codesc2->constrain.stringConstrain.maxLength) { lineEdit->setMaxLength(codesc2->constrain.stringConstrain.maxLength); } if (!oldarg) { connect(lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); argument = inputWidget; } else { QLineEdit* oldLineEdit = static_cast(oldarg); connect(lineEdit, SIGNAL(textChanged(QString)), oldLineEdit, SLOT(setText(QString))); connect(oldLineEdit, SIGNAL(textChanged(QString)), lineEdit, SLOT(setText(QString))); } } break; case T_I18NString: inputWidget = NULL; argument = NULL; break; } if (inputWidget && !tooltip.isEmpty()) inputWidget->setToolTip(tooltip); if (argument) { m_argMap[name] = argument; newarg = argument; } } QWidget* ConfigWidget::createSimpleConfigUi(bool skipAdvance) { int row = 0; VerticalScrollArea *scrollarea = new VerticalScrollArea; scrollarea->setFrameStyle(QFrame::NoFrame); scrollarea->setWidgetResizable(true); QWidget* form = new QWidget; QGridLayout* gridLayout = new QGridLayout; scrollarea->setWidget(form); form->setLayout(gridLayout); do { if (!m_cfdesc) break; if (!m_config->isValid()) break; HASH_FOREACH(cgdesc, m_cfdesc->groupsDesc, FcitxConfigGroupDesc) { if (cgdesc->optionsDesc == NULL) continue; else { int count = 0; HASH_FOREACH(codesc, cgdesc->optionsDesc, FcitxConfigOptionDesc) { FcitxConfigOptionDesc2* codesc2 = (FcitxConfigOptionDesc2*) codesc; if (!skipAdvance || !codesc2->advance) count++; } if (!count) continue; } QLabel* grouplabel = new QLabel(QString("%1").arg(QString::fromUtf8(dgettext(m_cfdesc->domain, cgdesc->groupName)))); gridLayout->addWidget(grouplabel, row++, 0, 1, 3); HASH_FOREACH(codesc, cgdesc->optionsDesc, FcitxConfigOptionDesc) { FcitxConfigOptionDesc2* codesc2 = (FcitxConfigOptionDesc2*) codesc; if (skipAdvance && codesc2->advance) continue; QString s, tooltip; QWidget* inputWidget = NULL; void* argument = NULL; createConfigOptionWidget(cgdesc, codesc, s, tooltip, inputWidget, argument); if (inputWidget) { QLabel* label = new QLabel(s); if (!tooltip.isEmpty()) label->setToolTip(tooltip); gridLayout->addWidget(label, row, 1, Qt::AlignCenter | Qt::AlignRight); gridLayout->addWidget(inputWidget, row, 2); if (argument) m_config->bind(cgdesc->groupName, codesc->optionName, SyncFilterFunc, argument); row++; } } } } while(0); QStringList keys = m_parser->getSubConfigKeys(); if (keys.length() != 0) { int labelrow = row; row ++; Q_FOREACH(const QString & key, keys) { SubConfig* subconfig = m_parser->getSubConfig(key); if (!subconfig) { continue; } if (!subconfig->isValid()) { delete subconfig; continue; } QLabel* label = new QLabel(QString::fromUtf8( dgettext(m_parser->domain().toUtf8().constData(), subconfig->name().toUtf8().constData() ) )); gridLayout->addWidget(label, row, 1, Qt::AlignCenter | Qt::AlignRight); gridLayout->addWidget(new SubConfigWidget(subconfig, this), row, 2); row++; } if (row != labelrow + 1) { QLabel* grouplabel = new QLabel(i18n("Other")); gridLayout->addWidget(grouplabel, labelrow, 0, 1, 3); } } QSpacerItem* verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); if (row >= 2) { QSpacerItem* horizontalSpacer = new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Minimum); gridLayout->addItem(horizontalSpacer, 2, 0, 1, 1); } gridLayout->addItem(verticalSpacer, row, 1, 1, 1); return scrollarea; } QWidget* ConfigWidget::createFullConfigUi() { QTabWidget* tabWidget = new QTabWidget(this); do { if (!m_cfdesc) break; if (!m_config->isValid()) break; HASH_FOREACH(cgdesc, m_cfdesc->groupsDesc, FcitxConfigGroupDesc) { if (cgdesc->optionsDesc == NULL) continue; QWidget* main = new QWidget(this); QVBoxLayout* mainLayout = new QVBoxLayout; main->setLayout(mainLayout); VerticalScrollArea *scrollarea = new VerticalScrollArea; scrollarea->setFrameStyle(QFrame::NoFrame); scrollarea->setWidgetResizable(true); QWidget* form = new QWidget; QFormLayout* formLayout = new QFormLayout; scrollarea->setWidget(form); form->setLayout(formLayout); HASH_FOREACH(codesc, cgdesc->optionsDesc, FcitxConfigOptionDesc) { QString s, tooltip; QWidget* inputWidget = NULL; void* argument = NULL; createConfigOptionWidget(cgdesc, codesc, s, tooltip, inputWidget, argument); if (inputWidget) { QLabel* label = new QLabel(s, this); if (!tooltip.isEmpty()) label->setToolTip(tooltip); formLayout->addRow(label, inputWidget); if (argument) m_config->bind(cgdesc->groupName, codesc->optionName, SyncFilterFunc, argument); } } mainLayout->addWidget(scrollarea); tabWidget->addTab(main, QString::fromUtf8(dgettext(m_cfdesc->domain, cgdesc->groupName))); } } while(0); QStringList keys = m_parser->getSubConfigKeys(); if (keys.length()) { QList subConfigs; Q_FOREACH(const QString & key, keys) { SubConfig* subconfig = m_parser->getSubConfig(key); if (!subconfig) { continue; } if (!subconfig->isValid()) { delete subconfig; continue; } subConfigs << subconfig; } if (subConfigs.length() > 0) { QWidget* main = new QWidget(this); QVBoxLayout* mainLayout = new QVBoxLayout; main->setLayout(mainLayout); QScrollArea *scrollarea = new QScrollArea; scrollarea->setFrameStyle(QFrame::NoFrame); scrollarea->setWidgetResizable(true); QWidget* form = new QWidget; QFormLayout* formLayout = new QFormLayout; scrollarea->setWidget(form); form->setLayout(formLayout); Q_FOREACH(SubConfig* subconfig, subConfigs) { formLayout->addRow( QString::fromUtf8( dgettext(m_parser->domain().toUtf8().constData(), subconfig->name().toUtf8().constData() ) ), new SubConfigWidget(subconfig, this)); } scrollarea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scrollarea->setMinimumWidth(form->sizeHint().width() + 20); mainLayout->addWidget(scrollarea); tabWidget->addTab(main, i18n("Other")); } } return tabWidget; } void ConfigWidget::setupConfigUi() { QVBoxLayout* layout = new QVBoxLayout(this); layout->addLayout(m_switchLayout); setLayout(layout); checkCanUseSimple(); if (m_cfdesc) { bindtextdomain(m_cfdesc->domain, LOCALEDIR); bind_textdomain_codeset(m_cfdesc->domain, "UTF-8"); FILE *fp; fp = FcitxXDGGetFileWithPrefix(m_prefix.toLocal8Bit().constData(), m_name.toLocal8Bit().constData(), "r", NULL); m_config->load(fp); if (fp) fclose(fp); } if (m_simpleUiType != CW_NoShow) { if (m_simpleUiType == CW_Simple) m_simpleWidget = createSimpleConfigUi(true); else m_simpleWidget = createFullConfigUi(); m_switchLayout->addWidget(m_simpleWidget); } if (m_fullUiType != CW_NoShow) { if (m_fullUiType == CW_Simple) m_fullWidget = createSimpleConfigUi(false); else m_fullWidget = createFullConfigUi(); m_switchLayout->addWidget(m_fullWidget); } if (m_simpleWidget && m_fullWidget) { m_advanceCheckBox = new QCheckBox(this); layout->addWidget(m_advanceCheckBox); m_advanceCheckBox->setCheckState(Qt::Unchecked); m_advanceCheckBox->setText(i18n("Show &Advance option")); connect(m_advanceCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleSimpleFull())); toggleSimpleFull(); } if (m_config) m_config->sync(); } void ConfigWidget::toggleSimpleFull() { if (m_advanceCheckBox->isChecked()) { m_simpleWidget->hide(); m_fullWidget->show(); } else { m_simpleWidget->show(); m_fullWidget->hide(); } } void ConfigWidget::checkCanUseSimple() { int count = 0; int simpleCount = 0; if (m_cfdesc) { HASH_FOREACH(cgdesc, m_cfdesc->groupsDesc, FcitxConfigGroupDesc) { if (cgdesc->optionsDesc == NULL) continue; else { HASH_FOREACH(codesc, cgdesc->optionsDesc, FcitxConfigOptionDesc) { FcitxConfigOptionDesc2* codesc2 = (FcitxConfigOptionDesc2*) codesc; if (!codesc2->advance) simpleCount++; count ++; } } } } /* if option is quite few */ if (count + m_parser->getSubConfigKeys().length() <= 10) { m_fullUiType = CW_Simple; } else { m_fullUiType = CW_Full; } if (simpleCount + m_parser->getSubConfigKeys().length() <= 10) { m_simpleUiType = CW_Simple; } else m_simpleUiType = CW_Full; if (count == simpleCount) m_simpleUiType = CW_NoShow; } QDialog* ConfigWidget::configDialog(QWidget* parent, FcitxConfigFileDesc* cfdesc, const QString& prefix, const QString& name, const QString& subconfig, const QString& addonName) { QDialog* dialog; dialog = new QDialog(parent); ConfigWidget* configPage = new ConfigWidget( cfdesc, prefix, name, subconfig, addonName, dialog ); dialog->setWindowIcon(QIcon::fromTheme("fcitx")); QVBoxLayout* dialogLayout = new QVBoxLayout; dialog->setLayout(dialogLayout); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); dialogLayout->addWidget(configPage); dialogLayout->addWidget(buttonBox); connect(buttonBox, &QDialogButtonBox::clicked, configPage, [configPage, buttonBox](QAbstractButton* button) { configPage->buttonClicked(buttonBox->standardButton(button)); }); connect(buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject); return dialog; } QDialog* ConfigWidget::configDialog(QWidget* parent, FcitxAddon* addonEntry) { if (!addonEntry) return NULL; QDialog* dialog; FcitxConfigFileDesc* cfdesc = Global::instance()->GetConfigDesc(QString::fromUtf8(addonEntry->name).append(".desc")); if (cfdesc || strlen(addonEntry->subconfig) != 0) { dialog = configDialog( parent, cfdesc, QString::fromUtf8("conf"), QString::fromUtf8(addonEntry->name).append(".config") , QString::fromUtf8(addonEntry->subconfig), QString::fromUtf8(addonEntry->name) ); return dialog; } return NULL; } void SyncFilterFunc(FcitxGenericConfig* gconfig, FcitxConfigGroup *group, FcitxConfigOption *option, void *value, FcitxConfigSync sync, void *arg) { Q_UNUSED(gconfig); Q_UNUSED(group); Q_UNUSED(value); FcitxConfigOptionDesc *codesc = option->optionDesc; if (!codesc) return; if (sync == Raw2Value) { switch (codesc->type) { case T_I18NString: break; case T_Integer: { int i = *(int*) value; QSpinBox* spinbox = static_cast(arg); spinbox->setValue(i); } break; case T_Color: { FcitxConfigColor* rawcolor = (FcitxConfigColor*) value; QColor color(QColor::fromRgbF(rawcolor->r, rawcolor->g, rawcolor->b)); ColorButton* colorButton = static_cast(arg); colorButton->setColor(color); } break; case T_Boolean: { boolean *bl = (boolean*) value; QCheckBox* checkBox = static_cast(arg); checkBox->setChecked(*bl); } break; case T_Font: { char** fontname = (char**) value; FontButton *fontButton = static_cast(arg); QFont font = FontButton::parseFont(QString::fromUtf8(*fontname)); fontButton->setFont(font); } break; case T_Enum: { int index = *(int*) value; QComboBox* combobox = static_cast(arg); combobox->setCurrentIndex(index); } break; case T_Hotkey: { FcitxHotkey* hotkey = (FcitxHotkey*) value; QHBoxLayout* hbox = static_cast(arg); FcitxQtKeySequenceWidget* keyseq[2]; keyseq[0] = static_cast(hbox->itemAt(0)->widget()); keyseq[1] = static_cast(hbox->itemAt(1)->widget()); int j; for (j = 0; j < 2; j ++) { FcitxQtModifierSide side = MS_Unknown; if (hotkey[j].sym == FcitxKey_Control_L || hotkey[j].sym == FcitxKey_Alt_L || hotkey[j].sym == FcitxKey_Shift_L || hotkey[j].sym == FcitxKey_Super_L) { side = MS_Left; } if (hotkey[j].sym == FcitxKey_Control_R || hotkey[j].sym == FcitxKey_Alt_R || hotkey[j].sym == FcitxKey_Shift_R || hotkey[j].sym == FcitxKey_Super_R) { side = MS_Right; } keyseq[j]->setKeySequence(HotkeyToKeySequence(&hotkey[j]), side); } } break; case T_File: { char** filename = (char**) value; KUrlRequester* urlrequester = static_cast(arg); urlrequester->setUrl(QString::fromUtf8(*filename)); } break; case T_Char: { char* string = (char*) value; char temp[2] = { *string, '\0' }; QLineEdit* lineEdit = static_cast(arg); lineEdit->setText(QString::fromUtf8(temp)); } break; case T_String: { char** string = (char**) value; QLineEdit* lineEdit = static_cast(arg); lineEdit->setText(QString::fromUtf8(*string)); } break; } } else { if (codesc->type != T_I18NString && option->rawValue) { free(option->rawValue); option->rawValue = NULL; } switch (codesc->type) { case T_I18NString: break; case T_Integer: { int* i = (int*) value; QSpinBox* spinbox = static_cast(arg); *i = spinbox->value(); } break; case T_Color: { QColor color; ColorButton* colorButton = static_cast(arg); color = colorButton->color(); FcitxConfigColor* rawcolor = (FcitxConfigColor*) value; rawcolor->r = color.redF(); rawcolor->g = color.greenF(); rawcolor->b = color.blueF(); } break; case T_Boolean: { QCheckBox* checkBox = static_cast(arg); boolean* bl = (boolean*) value; *bl = checkBox->isChecked(); } break; case T_Font: { FontButton *fontButton = static_cast(arg); const QString font = fontButton->fontName(); char** fontname = (char**) value; fcitx_utils_string_swap(fontname, font.toUtf8().constData()); } break; case T_Enum: { QComboBox* combobox = static_cast(arg); int* index = (int*) value; *index = combobox->currentIndex(); } break; case T_Hotkey: { QHBoxLayout* hbox = static_cast(arg); FcitxQtKeySequenceWidget* keyseq[2]; keyseq[0] = static_cast(hbox->itemAt(0)->widget()); keyseq[1] = static_cast(hbox->itemAt(1)->widget()); int j = 0; FcitxHotkey* hotkey = (FcitxHotkey*) value; for (j = 0; j < 2 ; j ++) { if (KeySequenceToHotkey(keyseq[j]->keySequence(), keyseq[j]->modifierSide(), &hotkey[j])) { char* keystring = FcitxHotkeyGetKeyString(hotkey[j].sym, hotkey[j].state); fcitx_utils_string_swap(&hotkey[j].desc, keystring); fcitx_utils_free(keystring); } else { fcitx_utils_string_swap(&hotkey[j].desc, NULL); } } } break; case T_File: { KUrlRequester* urlrequester = static_cast(arg); char** filename = (char**) value; fcitx_utils_string_swap(filename, urlrequester->url().toLocalFile().toUtf8().constData()); } break; case T_Char: { QLineEdit* lineEdit = static_cast(arg); char* c = (char*) value; *c = lineEdit->text()[0].toLatin1(); } break; case T_String: { QLineEdit* lineEdit = static_cast(arg); char** string = (char**) value; fcitx_utils_string_swap(string, lineEdit->text().toUtf8().constData()); } break; } } } bool KeySequenceToHotkey(const QKeySequence& keyseq, FcitxQtModifierSide side, FcitxHotkey* hotkey) { if (keyseq.count() != 1) return false; int sym = 0; FcitxQtKeySequenceWidget::keyQtToFcitx(keyseq[0], side, sym, hotkey->state); hotkey->sym = (FcitxKeySym) sym; return true; } QKeySequence HotkeyToKeySequence(FcitxHotkey* hotkey) { uint state = hotkey->state; FcitxKeySym keyval = hotkey->sym; return QKeySequence(FcitxQtKeySequenceWidget::keyFcitxToQt((int) keyval, state)); } } kcm-fcitx-master/src/configwidget.h000066400000000000000000000072571433634536200176710ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITXCONFIGPAGE_H #define FCITXCONFIGPAGE_H // Qt #include // KDE #include #include #include // Fcitx #include #include #include class QCheckBox; class QVBoxLayout; class QStandardItemModel; struct _FcitxConfigFileDesc; class QTabWidget; namespace Fcitx { class DummyConfig; class Global; class SubConfigParser; class ColorButton : public KColorButton { Q_OBJECT public: explicit ColorButton(QWidget* parent = 0) : KColorButton(parent) { } public slots: void setColor(const QColor& color) { KColorButton::setColor(color); } }; class ConfigWidget : public QWidget { Q_OBJECT enum UIType { CW_Simple = 0x1, CW_Full = 0x2, CW_NoShow = 0x0 }; public: explicit ConfigWidget(struct _FcitxConfigFileDesc* cfdesc, const QString& prefix, const QString& name, const QString& subconfig = QString(), const QString& addonName = QString(), QWidget* parent = NULL); explicit ConfigWidget(FcitxAddon* addonEntry, QWidget* parent = 0); virtual ~ConfigWidget(); static QDialog* configDialog(QWidget* parent, _FcitxConfigFileDesc* cfdesc, const QString& prefix, const QString& name, const QString& subconfig = QString(), const QString& addonName = QString()); static QDialog* configDialog(QWidget* parent, FcitxAddon* addonEntry); DummyConfig* config() { return m_config; } Q_SIGNALS: void changed(); public Q_SLOTS: void buttonClicked(QDialogButtonBox::StandardButton); void load(); private Q_SLOTS: void toggleSimpleFull(); private: QWidget* createFullConfigUi(); QWidget* createSimpleConfigUi(bool skinAdvance); void setupConfigUi(); void createConfigOptionWidget(FcitxConfigGroupDesc* cgdesc, FcitxConfigOptionDesc* codesc, QString& label, QString& tooltip, QWidget*& inputWidget, void*& newarg); void checkCanUseSimple(); struct _FcitxConfigFileDesc* m_cfdesc; QString m_prefix; QString m_name; QString m_addonName; QVBoxLayout* m_switchLayout; QWidget* m_simpleWidget; QWidget* m_fullWidget; QCheckBox* m_advanceCheckBox; DummyConfig* m_config; SubConfigParser* m_parser; UIType m_simpleUiType; UIType m_fullUiType; QMap m_argMap; }; } #endif kcm-fcitx-master/src/dummyconfig.cpp000066400000000000000000000104251433634536200200630ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include "dummyconfig.h" namespace Fcitx { DummyConfig::DummyConfig(FcitxConfigFileDesc* cfdesc) : m_cfdesc(cfdesc), m_cfile(NULL) { m_config.configFile = NULL; /* malloc necessary value */ HASH_FOREACH(cgdesc, m_cfdesc->groupsDesc, FcitxConfigGroupDesc) { HASH_FOREACH(codesc, cgdesc->optionsDesc, FcitxConfigOptionDesc) { QString name("%1/%2"); name = name.arg(cgdesc->groupName, codesc->optionName); if (m_dummyValue.contains(name)) continue; void* value = NULL; switch (codesc->type) { #define OPTION_TYPE_CASE(NAME, TYPE) \ case T_##NAME: \ value = fcitx_utils_new(TYPE); \ break; OPTION_TYPE_CASE(Integer, int); OPTION_TYPE_CASE(Boolean, boolean); OPTION_TYPE_CASE(Char, char); OPTION_TYPE_CASE(Color, FcitxConfigColor); OPTION_TYPE_CASE(Enum, int); OPTION_TYPE_CASE(File, char*); OPTION_TYPE_CASE(Font, char*); OPTION_TYPE_CASE(Hotkey, FcitxHotkeys); OPTION_TYPE_CASE(String, char*); OPTION_TYPE_CASE(I18NString, char*); default: break; } if (value) m_dummyValue[name] = value; } } } DummyConfig::~DummyConfig() { FcitxConfigFree(&m_config); foreach(void* value, m_dummyValue) { free(value); } } FcitxGenericConfig* DummyConfig::genericConfig() { return &m_config; } void DummyConfig::load(FILE* fp) { if (!m_config.configFile) { m_config.configFile = FcitxConfigParseConfigFileFp(fp, m_cfdesc); HASH_FOREACH(cgdesc, m_cfdesc->groupsDesc, FcitxConfigGroupDesc) { HASH_FOREACH(codesc, cgdesc->optionsDesc, FcitxConfigOptionDesc) { QString name("%1/%2"); name = name.arg(cgdesc->groupName, codesc->optionName); if (!m_dummyValue.contains(name)) continue; // assert(m_dummyValue[name]); FcitxConfigBindValue(m_config.configFile, cgdesc->groupName, codesc->optionName, m_dummyValue[name], NULL, NULL); } } } else { m_config.configFile = FcitxConfigParseIniFp(fp, m_config.configFile); } } void DummyConfig::bind(char* group, char* option, FcitxSyncFilter filter, void* arg) { if (!m_config.configFile) return; QString name("%1/%2"); name = name.arg(group, option); if (!m_dummyValue.contains(name)) return; // assert(m_dummyValue[name]); FcitxConfigBindValue(m_config.configFile, group, option, m_dummyValue[name], filter, arg); } bool DummyConfig::isValid() { return (m_config.configFile != NULL); } void DummyConfig::sync() { FcitxConfigBindSync(&m_config); } }kcm-fcitx-master/src/dummyconfig.h000066400000000000000000000037331433634536200175340ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef DUMMYCONFIG_H #define DUMMYCONFIG_H #include #include #include #include namespace Fcitx { class DummyConfig { public: DummyConfig(FcitxConfigFileDesc* cfdesc); ~DummyConfig(); FcitxGenericConfig* genericConfig(); void load(FILE* fp); void bind(char* group, char* option, FcitxSyncFilter filter = NULL, void* arg = NULL); bool isValid(); void sync(); private: QMap m_dummyValue; FcitxConfigFileDesc* m_cfdesc; FcitxConfigFile* m_cfile; FcitxGenericConfig m_config; }; } #endif // DUMMYCONFIG_Hkcm-fcitx-master/src/erroroverlay.cpp000066400000000000000000000102661433634536200203000ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011 by Dario Freddi * * * * 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 "erroroverlay.h" #include "global.h" #include #include #include #include #include ErrorOverlay::ErrorOverlay(QWidget *baseWidget, QWidget *parent) : QWidget(parent ? parent : baseWidget->window()), m_BaseWidget(baseWidget), m_enable(false) { setVisible(false); // Build the UI QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(10); QLabel *pixmap = new QLabel(); pixmap->setPixmap(QIcon::fromTheme("dialog-error").pixmap(64)); QLabel *message = new QLabel(i18n("Cannot connect to Fcitx by DBus, is Fcitx running?")); pixmap->setAlignment(Qt::AlignHCenter); message->setAlignment(Qt::AlignHCenter); layout->addStretch(); layout->addWidget(pixmap); layout->addWidget(message); layout->addStretch(); setLayout(layout); // Draw the transparent overlay background QPalette p = palette(); p.setColor(backgroundRole(), QColor(0, 0, 0, 128)); p.setColor(foregroundRole(), Qt::white); setPalette(p); setAutoFillBackground(true); m_BaseWidget->installEventFilter(this); // Destory overlay with the base widget. connect(m_BaseWidget, SIGNAL(destroyed()), this, SLOT(deleteLater())); connect(Fcitx::Global::instance(), SIGNAL(connectStatusChanged(bool)), this, SLOT(onConnectStatusChanged(bool))); onConnectStatusChanged(Fcitx::Global::instance()->inputMethodProxy() != 0); } ErrorOverlay::~ErrorOverlay() { } void ErrorOverlay::onConnectStatusChanged(bool connected) { if (m_enable != !connected) { m_enable = !connected; setVisible(!connected); if (!connected) reposition(); } } void ErrorOverlay::reposition() { if (!m_BaseWidget) { return; } // reparent to the current top level widget of the base widget if needed // needed eg. in dock widgets if (parentWidget() != m_BaseWidget->window()) { setParent(m_BaseWidget->window()); } // follow base widget visibility // needed eg. in tab widgets if (!m_BaseWidget->isVisible()) { hide(); return; } show(); // follow position changes const QPoint topLevelPos = m_BaseWidget->mapTo(window(), QPoint(0, 0)); const QPoint parentPos = parentWidget()->mapFrom(window(), topLevelPos); move(parentPos); // follow size changes // TODO: hide/scale icon if we don't have enough space resize(m_BaseWidget->size()); } bool ErrorOverlay::eventFilter(QObject * object, QEvent * event) { if (m_enable && object == m_BaseWidget && (event->type() == QEvent::Move || event->type() == QEvent::Resize || event->type() == QEvent::Show || event->type() == QEvent::Hide || event->type() == QEvent::ParentChange)) { reposition(); } return QWidget::eventFilter(object, event); } kcm-fcitx-master/src/erroroverlay.h000066400000000000000000000035511433634536200177440ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011 by Dario Freddi * * * * 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 . * ***************************************************************************/ #ifndef ERROROVERLAY_H #define ERROROVERLAY_H #include #include class ErrorOverlay : public QWidget { Q_OBJECT public: explicit ErrorOverlay(QWidget *baseWidget, QWidget *parent = 0); virtual ~ErrorOverlay(); public slots: void onConnectStatusChanged(bool connected); protected: bool eventFilter(QObject *object, QEvent *event) override; private: void reposition(); private: QPointer m_BaseWidget; bool m_enable; }; #endif // ERROROVERLAY_H kcm-fcitx-master/src/fcitx-skin.knsrc000066400000000000000000000001261433634536200201540ustar00rootroot00000000000000[KNewStuff3] Categories=Fcitx Theme InstallPath=.config/fcitx/skin Uncompress=archive kcm-fcitx-master/src/fontbutton.cpp000066400000000000000000000074651433634536200177560ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include "fontbutton.h" #include "ui_fontbutton.h" FontButton::FontButton(QWidget* parent): QWidget(parent) ,m_ui(new Ui::FontButton) { m_ui->setupUi(this); connect(m_ui->fontSelectButton, SIGNAL(clicked(bool)), this, SLOT(selectFont())); } FontButton::~FontButton() { delete m_ui; } const QFont& FontButton::font() { return m_font; } QString FontButton::fontName() { return m_ui->fontPreviewLabel->text(); } QFont FontButton::parseFont(const QString& string) { QStringList list = string.split(" ", QString::SkipEmptyParts); bool bold = false; bool italic = false; while(!list.empty()) { if (list.last() == "Bold") { bold = true; list.pop_back(); } else if (list.last() == "Italic") { italic = true; list.pop_back(); } else break; } QString family = list.join(" "); QFont font; font.setFamily(family); font.setBold(bold); font.setItalic(italic); return font; } void FontButton::setFont(const QFont& font) { m_font = font; QString style; #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0) if (!font.styleName().isEmpty()) { style = font.styleName(); } else #endif { QStringList styles; if (font.bold()) styles << "Bold"; if (font.italic()) styles << "Italic"; style = styles.join(" "); } m_ui->fontPreviewLabel->setText(QString("%1 %2").arg(m_font.family(), style)); m_ui->fontPreviewLabel->setFont(m_font); if (font.family() != m_font.family()) { emit fontChanged(m_font); } } void FontButton::selectFont() { QDialog dialog(NULL); KFontChooser* chooser = new KFontChooser(&dialog); chooser->enableColumn(KFontChooser::SizeList, false); chooser->setFont(m_font); QVBoxLayout* dialogLayout = new QVBoxLayout; dialog.setLayout(dialogLayout); QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); dialogLayout->addWidget(chooser); dialogLayout->addWidget(buttonBox); connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); if (dialog.exec() == QDialog::Accepted) { setFont(chooser->font()); } } kcm-fcitx-master/src/fontbutton.h000066400000000000000000000036251433634536200174150ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FONTBUTTON_H #define FONTBUTTON_H #include namespace Ui { class FontButton; }; class FontButton : public QWidget { Q_OBJECT public: explicit FontButton(QWidget* parent = 0); virtual ~FontButton(); const QFont& font(); QString fontName(); static QFont parseFont(const QString& string); public slots: void setFont(const QFont& font); signals: void fontChanged(const QFont& font); private slots: void selectFont(); private: Ui::FontButton* m_ui; QFont m_font; }; #endif // FONTBUTTON_Hkcm-fcitx-master/src/fontbutton.ui000066400000000000000000000027171433634536200176040ustar00rootroot00000000000000 FontButton 0 0 400 186 0 0 Form 0 0 0 QFrame::StyledPanel QFrame::Sunken Qt::AlignCenter Select &Font... kcm-fcitx-master/src/global.cpp000066400000000000000000000105221433634536200170000ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Fcitx #include #include #include #include // self #include "global.h" namespace Fcitx { Global* Global::inst = NULL; Global* Global::instance() { if (!inst) inst = new Global; return inst; } void Global::deInit() { if (inst) { inst->deleteLater(); inst = 0; } } Global::Global() : m_hash(new QHash), m_connection(new FcitxQtConnection(this)), m_inputmethod(0), m_keyboard(0) { connect(m_connection, SIGNAL(connected()), this, SLOT(connected())); connect(m_connection, SIGNAL(disconnected()), this, SLOT(disconnected())); m_connection->startConnection(); } Global::~Global() { QHash::iterator iter; for (iter = m_hash->begin(); iter != m_hash->end(); iter ++) { FcitxConfigFreeConfigFileDesc(iter.value()); } delete m_hash; } void Global::connected() { if (m_inputmethod) delete m_inputmethod; if (m_keyboard) delete m_keyboard; m_inputmethod = new FcitxQtInputMethodProxy( m_connection->serviceName(), "/inputmethod", *m_connection->connection(), this ); m_keyboard = new FcitxQtKeyboardProxy( m_connection->serviceName(), "/keyboard", *m_connection->connection(), this ); #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0) m_inputmethod->setTimeout(3000); m_keyboard->setTimeout(3000); #endif emit connectStatusChanged(true); } void Global::disconnected() { if (m_inputmethod) delete m_inputmethod; m_inputmethod = 0; if (m_keyboard) delete m_keyboard; m_keyboard = 0; emit connectStatusChanged(false); } FcitxConfigFileDesc* Global::GetConfigDesc(const QString& name) { if (m_hash->count(name) <= 0) { FILE* fp = FcitxXDGGetFileWithPrefix("configdesc", name.toLatin1().constData(), "r", NULL); FcitxConfigFileDesc* cfdesc = FcitxConfigParseConfigFileDescFp(fp); if (cfdesc) m_hash->insert(name, cfdesc); return cfdesc; } else return (*m_hash) [name]; } QString Global::testWrapper(const QString &path) const { char* qtguiwrapper[] = { fcitx_utils_get_fcitx_path_with_filename ("libdir", "fcitx/libexec/fcitx-qt5-gui-wrapper"), fcitx_utils_get_fcitx_path_with_filename ("libdir", "fcitx/libexec/fcitx-qt-gui-wrapper") }; QString wrapper; for (int i = 0; i < FCITX_ARRAY_SIZE(qtguiwrapper); i++) { if (qtguiwrapper[i]) { QStringList args; args << QLatin1String("--test"); args << path; int exit_status =QProcess::execute(QString::fromLocal8Bit(qtguiwrapper[i]), args); if (exit_status == 0) { wrapper = QString::fromLatin1(qtguiwrapper[i]); break; } } } return wrapper; } } kcm-fcitx-master/src/global.h000066400000000000000000000050301433634536200164430ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef KCM_FCITX_GLOBAL_H #define KCM_FCITX_GLOBAL_H // Qt #include // Fcitx #include #include #include class FcitxQtKeyboardProxy; class FcitxQtInputMethodProxy; class FcitxQtConnection; namespace Fcitx { class Global : public QObject { Q_OBJECT public: static Global* instance(); static void deInit(); virtual ~Global(); FcitxConfigFileDesc* GetConfigDesc(const QString& name); FcitxQtConnection* connection() { return m_connection; } FcitxQtInputMethodProxy* inputMethodProxy() { return (m_inputmethod && m_inputmethod->isValid()) ? m_inputmethod : 0; } FcitxQtKeyboardProxy* keyboardProxy() { return (m_keyboard && m_keyboard->isValid()) ? m_keyboard : 0; } QString testWrapper(const QString &path) const; signals: void connectStatusChanged(bool connected); private slots: void connected(); void disconnected(); private: Global(); QHash* m_hash; FcitxQtConnection* m_connection; FcitxQtInputMethodProxy* m_inputmethod; FcitxQtKeyboardProxy* m_keyboard; static Global* inst; }; } #endif kcm-fcitx-master/src/imconfigdialog.cpp000066400000000000000000000136521433634536200205220ustar00rootroot00000000000000#include #include #include #include #include #include #include #include #include #include #include "imconfigdialog.h" #include "global.h" #include "configwidget.h" #include "keyboardlayoutwidget.h" Fcitx::IMConfigDialog::IMConfigDialog(const QString& imName, const FcitxAddon* addon, QWidget* parent): QDialog(parent) ,m_imName(imName) ,m_layoutCombobox(0) ,m_configPage(0) ,m_layoutWidget(nullptr) { QWidget* widget = new QWidget(this); QVBoxLayout* l = new QVBoxLayout(this); widget->setLayout(l); if (!imName.startsWith("fcitx-keyboard") && Global::instance()->keyboardProxy()) { QDBusPendingReply< FcitxQtKeyboardLayoutList > layoutList = Global::instance()->keyboardProxy()->GetLayouts(); layoutList.waitForFinished(); if (!layoutList.isError()) { m_layoutList = layoutList.value(); m_layoutCombobox = new QComboBox(this); QDBusPendingReply< QString, QString > res = Global::instance()->keyboardProxy()->GetLayoutForIM(imName); res.waitForFinished(); QString imLayout = qdbus_cast(res.argumentAt(0)); QString imVariant = qdbus_cast(res.argumentAt(1)); QLabel* label; label = new QLabel(i18n("Keyboard Layout:")); int idx = 1; int select = 0; if (imName == "default") m_layoutCombobox->addItem(i18n("Default")); else m_layoutCombobox->addItem(i18n("Input Method Default")); foreach (const FcitxQtKeyboardLayout& layout, layoutList.value()) { if (imLayout == layout.layout() && imVariant == layout.variant()) select = idx; m_layoutCombobox->addItem(layout.name()); idx ++; } m_layoutCombobox->setCurrentIndex(select); l->addWidget(label); l->addWidget(m_layoutCombobox); connect(m_layoutCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(layoutComboBoxChanged())); if (QX11Info::isPlatformX11()) { m_layoutWidget = new KeyboardLayoutWidget(this); m_layoutWidget->setMinimumSize(QSize(400, 200)); m_layoutWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); l->addWidget(m_layoutWidget); } layoutComboBoxChanged(); } } else { if (QX11Info::isPlatformX11()) { KeyboardLayoutWidget* layoutWidget = new KeyboardLayoutWidget(this); layoutWidget->setMinimumSize(QSize(400, 200)); layoutWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QString layoutstring = imName.mid(strlen("fcitx-keyboard-")); int p = layoutstring.indexOf("-"); QString layout, variant; if (p < 0) { layout = layoutstring; } else { layout = layoutstring.mid(0, p); variant = layoutstring.mid(p + 1); } layoutWidget->setKeyboardLayout(layout, variant); l->addWidget(layoutWidget); } } FcitxConfigFileDesc* cfdesc = NULL; if (addon) { cfdesc = Global::instance()->GetConfigDesc(QString::fromUtf8(addon->name).append(".desc")); if (cfdesc || strlen(addon->subconfig) != 0) { if (m_layoutCombobox) { QLabel* label = new QLabel(i18n("Input Method Setting:")); label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); l->addWidget(label); } m_configPage = new ConfigWidget( cfdesc, QString::fromUtf8("conf"), QString::fromUtf8(addon->name).append(".config") , QString::fromUtf8(addon->subconfig), QString::fromUtf8(addon->name), this ); l->addWidget(m_configPage); } } setWindowIcon(QIcon::fromTheme("fcitx")); auto dialogLayout = new QVBoxLayout; setLayout(dialogLayout); auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults); dialogLayout->addWidget(widget); dialogLayout->addWidget(buttonBox); connect(buttonBox, &QDialogButtonBox::clicked, this, [this, buttonBox](QAbstractButton* button) { this->onButtonClicked(buttonBox->standardButton(button)); }); connect(buttonBox, &QDialogButtonBox::accepted, this, &Fcitx::IMConfigDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &Fcitx::IMConfigDialog::reject); } void Fcitx::IMConfigDialog::onButtonClicked(QDialogButtonBox::StandardButton code) { if (m_layoutCombobox && Global::instance()->keyboardProxy()) { if (code == QDialogButtonBox::Ok) { int idx = m_layoutCombobox->currentIndex(); if (idx == 0) Global::instance()->keyboardProxy()->SetLayoutForIM(m_imName, "", ""); else Global::instance()->keyboardProxy()->SetLayoutForIM(m_imName, m_layoutList.at(idx - 1).layout(), m_layoutList.at(idx - 1).variant()); } else if (code == QDialogButtonBox::RestoreDefaults) m_layoutCombobox->setCurrentIndex(0); } if (m_configPage) m_configPage->buttonClicked(code); } void Fcitx::IMConfigDialog::layoutComboBoxChanged() { if (!m_layoutCombobox || !m_layoutWidget) { return; } int idx = m_layoutCombobox->currentIndex(); if (idx != 0) { m_layoutWidget->setKeyboardLayout(m_layoutList.at(idx - 1).layout(), m_layoutList.at(idx - 1).variant()); m_layoutWidget->show(); } else { m_layoutWidget->hide(); } } kcm-fcitx-master/src/imconfigdialog.h000066400000000000000000000040671433634536200201670ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef IM_CONFIG_DIALOG_H #define IM_CONFIG_DIALOG_H #include #include #include #include class KeyboardLayoutWidget; class QComboBox; namespace Fcitx { class ConfigWidget; class IMConfigDialog: public QDialog { Q_OBJECT public: explicit IMConfigDialog(const QString& imName, const FcitxAddon* addon, QWidget* parent = 0); private slots: void onButtonClicked(QDialogButtonBox::StandardButton code); void layoutComboBoxChanged(); private: QString m_imName; QComboBox* m_layoutCombobox; ConfigWidget* m_configPage; FcitxQtKeyboardLayoutList m_layoutList; KeyboardLayoutWidget* m_layoutWidget; }; } #endif kcm-fcitx-master/src/impage.cpp000066400000000000000000000657341433634536200170210ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include #include // KDE #include #include #include // self #include "impage.h" #include "impage_p.h" #include "ui_impage.h" #include "module.h" #include "global.h" #include "configwidget.h" #include "imconfigdialog.h" #include "erroroverlay.h" #define MARGIN 0 namespace Fcitx { static QString languageName(const QString& langCode) { if (langCode.isEmpty()) { return i18n("Unknown"); } else if (langCode == "*") return i18n("Multilingual"); else { QLocale locale(langCode); if (locale.language() == QLocale::C) { // return lang code seems to be a better solution other than indistinguishable "unknown" return langCode; } const bool hasCountry = langCode.indexOf("_") != -1 && locale.country() != QLocale::AnyCountry; QString languageName; if (hasCountry) { languageName = locale.nativeLanguageName(); } if (languageName.isEmpty()) { languageName = i18nd("iso_639", QLocale::languageToString(locale.language()).toUtf8()); } if (languageName.isEmpty()) { languageName = i18n("Other"); } QString countryName; // QLocale will always assign a default country for us, check if our lang code if (langCode.indexOf("_") != -1 && locale.country() != QLocale::AnyCountry) { countryName = locale.nativeCountryName(); if (countryName.isEmpty()) { countryName = QLocale::countryToString(locale.country()); } } if (countryName.isEmpty()) { return languageName; } else { return i18nc("%1 is language name, %2 is country name", "%1 (%2)", languageName, countryName); } } } IMPage::Private::AvailIMModel::AvailIMModel(QObject* parent) : QAbstractItemModel(parent) { } IMPage::Private::AvailIMModel::~AvailIMModel() { } QModelIndex IMPage::Private::AvailIMModel::index(int row, int column, const QModelIndex& parent) const { // return language index if (!parent.isValid()) { if (column > 0 || row >= filteredIMEntryList.count()) { return QModelIndex(); } else { return createIndex(row, column, static_cast(0)); } } // return im index if (parent.column() > 0 || parent.row() >= filteredIMEntryList.count() || row >= filteredIMEntryList[parent.row()].second.size()) { return QModelIndex(); } return createIndex(row, column, parent.row() + 1); } QVariant IMPage::Private::AvailIMModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (!index.parent().isValid()) { if (index.column() > 0 || index.row() >= filteredIMEntryList.count()) { return QVariant(); } switch (role) { case Qt::DisplayRole: return languageName(filteredIMEntryList[index.row()].first); case FcitxLanguageRole: return filteredIMEntryList[index.row()].first; case FcitxIMUniqueNameRole: return QString(); case FcitxRowTypeRole: return LanguageType; default: return QVariant(); } } if (index.column() > 0 || index.parent().column() > 0 || index.parent().row() >= filteredIMEntryList.count()) { return QVariant(); } const FcitxQtInputMethodItemList& imEntryList = filteredIMEntryList[index.parent().row()].second; if (index.row() >= imEntryList.count()) { return QVariant(); } const FcitxQtInputMethodItem& imEntry = imEntryList[index.row()]; switch (role) { case Qt::DisplayRole: return imEntry.name(); case FcitxRowTypeRole: return IMType; case FcitxIMUniqueNameRole: return imEntry.uniqueName(); case FcitxLanguageRole: return imEntry.langCode(); } return QVariant(); } QModelIndex IMPage::Private::AvailIMModel::parent(const QModelIndex& child) const { if (!child.isValid()) { return QModelIndex(); } auto row = child.internalId(); if (row && row - 1 >= filteredIMEntryList.count()) { return QModelIndex(); } return createIndex(row - 1, 0, -1); } int IMPage::Private::AvailIMModel::rowCount(const QModelIndex& parent) const { if (!parent.isValid()) { return filteredIMEntryList.count(); } if (parent.internalId() > 0) { return 0; } if (parent.column() > 0 || parent.row() >= filteredIMEntryList.count()) { return 0; } return filteredIMEntryList[parent.row()].second.count(); } int IMPage::Private::AvailIMModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent); return 1; } void IMPage::Private::AvailIMModel::filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, const QString& selection) { beginResetModel(); QMap languageMap; filteredIMEntryList.clear(); int langRow = -1; int imRow = -1; Q_FOREACH(const FcitxQtInputMethodItem & im, imEntryList) { if (!im.enabled()) { int idx; if (!languageMap.contains(im.langCode())) { idx = filteredIMEntryList.count(); languageMap[im.langCode()] = idx; filteredIMEntryList.append(QPair(im.langCode(), FcitxQtInputMethodItemList())); } else { idx = languageMap[im.langCode()]; } filteredIMEntryList[idx].second.append(im); if (im.uniqueName() == selection) { langRow = idx; imRow = filteredIMEntryList[idx].second.count() - 1; } } } endResetModel(); if (imRow >= 0) { emit select(index(imRow, 0, index(langRow, 0))); } } IMPage::Private::IMModel::IMModel(QObject* parent) : QAbstractListModel(parent) { } IMPage::Private::IMModel::~IMModel() { } QModelIndex IMPage::Private::IMModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent); return createIndex(row, column, (row < filteredIMEntryList.count()) ? (void*) &filteredIMEntryList.at(row) : 0); } QVariant IMPage::Private::IMModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || index.row() >= filteredIMEntryList.size()) { return QVariant(); } const FcitxQtInputMethodItem& imEntry = filteredIMEntryList.at(index.row()); switch (role) { case Qt::DisplayRole: return imEntry.name(); case FcitxRowTypeRole: return IMType; case FcitxIMUniqueNameRole: return imEntry.uniqueName(); case FcitxLanguageRole: return imEntry.langCode(); default: return QVariant(); } } int IMPage::Private::IMModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } return filteredIMEntryList.count(); } void IMPage::Private::IMModel::filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, const QString& selection) { beginResetModel(); QSet languageSet; filteredIMEntryList.clear(); int row = 0, selectionRow = -1; Q_FOREACH(const FcitxQtInputMethodItem & im, imEntryList) { if (im.enabled()) { filteredIMEntryList.append(im); if (im.uniqueName() == selection) selectionRow = row; row ++; } } endResetModel(); if (selectionRow >= 0) { emit select(index(selectionRow, 0)); } else if (row > 0) { emit select(index(row - 1, 0)); } } IMPage::Private::IMProxyModel::IMProxyModel(QAbstractItemModel* sourceModel) : QSortFilterProxyModel(sourceModel) ,m_showOnlyCurrentLanguage(true) { } IMPage::Private::IMProxyModel::~IMProxyModel() { } void IMPage::Private::IMProxyModel::setFilterText(const QString& text) { if (m_filterText != text) { m_filterText = text; invalidate(); } } void IMPage::Private::IMProxyModel::setShowOnlyCurrentLanguage(bool show) { if (m_showOnlyCurrentLanguage != show) { m_showOnlyCurrentLanguage = show; invalidate(); } } void IMPage::Private::IMProxyModel::filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, const QString& selection) { m_languageSet.clear(); Q_FOREACH(const FcitxQtInputMethodItem & im, imEntryList) { if (im.enabled()) { m_languageSet.insert(im.langCode().left(2)); } } invalidate(); } bool IMPage::Private::IMProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { const QModelIndex index = sourceModel()->index(source_row, 0, source_parent); if (index.data(FcitxRowTypeRole) == LanguageType) { return filterLanguage(index); } return filterIM(index); } bool IMPage::Private::IMProxyModel::filterLanguage(const QModelIndex& index) const { if (!index.isValid()) { return false; } int childCount = index.model()->rowCount(index); if (childCount == 0) return false; for (int i = 0; i < childCount; ++i) { if (filterIM(index.model()->index(i, 0, index))) { return true; } } return false; } bool IMPage::Private::IMProxyModel::filterIM(const QModelIndex& index) const { QString uniqueName = index.data(FcitxIMUniqueNameRole).toString(); QString name = index.data(Qt::DisplayRole).toString(); QString langCode = index.data(FcitxLanguageRole).toString(); if (uniqueName == "fcitx-keyboard-us") return true; bool flag = true; QString lang = langCode.left(2); flag = flag && (m_showOnlyCurrentLanguage ? !lang.isEmpty() && (QLocale().name().startsWith(lang) || m_languageSet.contains(lang)) : true ); if (!m_filterText.isEmpty()) { flag = flag && (name.contains(m_filterText, Qt::CaseInsensitive) || uniqueName.contains(m_filterText, Qt::CaseInsensitive) || langCode.contains(m_filterText, Qt::CaseInsensitive) || languageName(langCode).contains(m_filterText, Qt::CaseInsensitive)); } return flag; } bool IMPage::Private::IMProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { int result = compareCategories(left, right); if (result < 0) { return true; } else if (result > 0) { return false; } QString l = left.data(Qt::DisplayRole).toString(); QString r = right.data(Qt::DisplayRole).toString(); return QCollator().compare(l, r) < 0; } int IMPage::Private::IMProxyModel::compareCategories(const QModelIndex& left, const QModelIndex& right) const { QString l = left.data(FcitxLanguageRole).toString(); QString r = right.data(FcitxLanguageRole).toString(); if (l == r) return 0; if (QLocale().name() == l) return -1; if (QLocale().name() == r) return 1; bool fl = QLocale().name().startsWith(l.left(2)); bool fr = QLocale().name().startsWith(r.left(2)); if (fl == fr) { return l.size() == r.size() ? l.compare(r) : l.size() - r.size(); } return fl ? -1 : 1; } IMPage::IMPage(Module* parent): QWidget(parent) ,m_ui(new Ui::IMPage) ,d(new Private(this)) { m_ui->setupUi(this); // m_ui->infoIconLabel->setPixmap(QIcon::fromTheme("dialog-information").pixmap(KIconLoader::SizeSmallMedium)); m_ui->addIMButton->setIcon(QIcon::fromTheme("go-next")); m_ui->removeIMButton->setIcon(QIcon::fromTheme("go-previous")); m_ui->moveUpButton->setIcon(QIcon::fromTheme("go-up")); m_ui->moveDownButton->setIcon(QIcon::fromTheme("go-down")); m_ui->configureButton->setIcon(QIcon::fromTheme("configure")); d->module = parent; d->addIMButton = m_ui->addIMButton; d->removeIMButton = m_ui->removeIMButton; d->moveUpButton = m_ui->moveUpButton; d->moveDownButton = m_ui->moveDownButton; d->configureButton = m_ui->configureButton; d->availIMView = m_ui->availIMView; d->currentIMView = m_ui->currentIMView; d->defaultLayoutButton = m_ui->defaultLayoutButton; d->onlyCurrentLanguageCheckBox = m_ui->onlyCurrentLanguageCheckBox; d->filterTextEdit = m_ui->filterTextEdit; d->filterTextEdit->setClearButtonEnabled(true); d->filterTextEdit->setPlaceholderText(i18n("Search Input Method")); d->availIMModel = new Private::AvailIMModel(d); connect(d, SIGNAL(updateIMList(FcitxQtInputMethodItemList,QString)), d->availIMModel, SLOT(filterIMEntryList(FcitxQtInputMethodItemList,QString))); d->availIMProxyModel = new Private::IMProxyModel(d->availIMModel); d->availIMProxyModel->setSourceModel(d->availIMModel); connect(d, SIGNAL(updateIMList(FcitxQtInputMethodItemList,QString)), d->availIMProxyModel, SLOT(filterIMEntryList(FcitxQtInputMethodItemList,QString))); d->availIMView->setItemDelegate(new IMDelegate); d->availIMView->setModel(d->availIMProxyModel); d->currentIMModel = new Private::IMModel(this); connect(d, SIGNAL(updateIMList(FcitxQtInputMethodItemList,QString)), d->currentIMModel, SLOT(filterIMEntryList(FcitxQtInputMethodItemList,QString))); d->currentIMView->setModel(d->currentIMModel); d->currentIMView->setSelectionMode(QAbstractItemView::SingleSelection); connect(d->filterTextEdit, SIGNAL(textChanged(QString)), this, SLOT(filterTextChanged(QString))); connect(d->onlyCurrentLanguageCheckBox, SIGNAL(toggled(bool)), this, SLOT(onlyLanguageChanged(bool))); connect(d->availIMView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), d, SLOT(availIMSelectionChanged())); connect(d->currentIMView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), d, SLOT(currentIMCurrentChanged())); connect(d->addIMButton, SIGNAL(clicked(bool)), d, SLOT(clickAddIM())); connect(d->removeIMButton, SIGNAL(clicked(bool)), d, SLOT(clickRemoveIM())); connect(d->moveUpButton, SIGNAL(clicked(bool)), d, SLOT(moveUpIM())); connect(d->moveDownButton, SIGNAL(clicked(bool)), d, SLOT(moveDownIM())); connect(d->configureButton, SIGNAL(clicked(bool)), d, SLOT(configureIM())); connect(d, SIGNAL(changed()), this, SIGNAL(changed())); connect(d->availIMModel, SIGNAL(select(QModelIndex)), d, SLOT(selectAvailIM(QModelIndex))); connect(d->availIMProxyModel, SIGNAL(layoutChanged()), d->availIMView, SLOT(expandAll())); connect(d->currentIMModel, SIGNAL(select(QModelIndex)), d, SLOT(selectCurrentIM(QModelIndex))); connect(d->defaultLayoutButton, SIGNAL(clicked(bool)), d, SLOT(selectDefaultLayout())); connect(d->availIMView, SIGNAL(doubleClicked(QModelIndex)), d, SLOT(doubleClickAvailIM(QModelIndex))); connect(d->currentIMView, SIGNAL(doubleClicked(QModelIndex)), d, SLOT(doubleClickCurrentIM(QModelIndex))); connect(Global::instance(), SIGNAL(connectStatusChanged(bool)), d, SLOT(onConnectStatusChanged(bool))); new ErrorOverlay(this); if (Global::instance()->connection()) { d->fetchIMList(); } } void IMPage::filterTextChanged(const QString & text) { d->availIMProxyModel->setFilterText(text); } void IMPage::onlyLanguageChanged(bool checked) { d->availIMProxyModel->setShowOnlyCurrentLanguage(checked); } void IMPage::save() { d->save(); } void IMPage::load() { d->fetchIMList(); } void IMPage::defaults() { if (Global::instance()->inputMethodProxy()) { Global::instance()->inputMethodProxy()->ResetIMList(); } d->fetchIMList(); } IMPage::Private::Private(QObject* parent) : QObject(parent) ,availIMModel(0) { } IMPage::Private::~Private() { } void IMPage::Private::availIMSelectionChanged() { if (!availIMView->currentIndex().isValid()) addIMButton->setEnabled(false); else addIMButton->setEnabled(true); } void IMPage::Private::currentIMCurrentChanged() { if (!currentIMView->currentIndex().isValid()) { removeIMButton->setEnabled(false); moveUpButton->setEnabled(false); moveDownButton->setEnabled(false); configureButton->setEnabled(false); } else { if (currentIMView->currentIndex().row() == 0) moveUpButton->setEnabled(false); else moveUpButton->setEnabled(true); if (currentIMView->currentIndex().row() == currentIMModel->rowCount() - 1) moveDownButton->setEnabled(false); else moveDownButton->setEnabled(true); removeIMButton->setEnabled(true); configureButton->setEnabled(true); } } void IMPage::Private::selectCurrentIM(const QModelIndex& index) { currentIMView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); } void IMPage::Private::doubleClickCurrentIM(const QModelIndex& index) { removeIM(index); } void IMPage::Private::doubleClickAvailIM(const QModelIndex& index) { addIM(index); } void IMPage::Private::selectDefaultLayout() { QPointer configDialog(new IMConfigDialog("default", NULL)); configDialog->exec(); delete configDialog; } void IMPage::Private::selectAvailIM(const QModelIndex& index) { availIMView->selectionModel()->setCurrentIndex( availIMProxyModel->mapFromSource(index), QItemSelectionModel::ClearAndSelect ); } void IMPage::Private::clickAddIM() { addIM(availIMView->currentIndex()); } void IMPage::Private::clickRemoveIM() { removeIM(currentIMView->currentIndex()); } void IMPage::Private::addIM(const QModelIndex& index) { if (index.isValid()) { const QString uniqueName =index.data(FcitxIMUniqueNameRole).toString(); for (int i = 0; i < m_list.size(); i ++) { if (uniqueName == m_list[i].uniqueName()) { m_list[i].setEnabled(true); std::stable_sort(m_list.begin(), m_list.end()); emit updateIMList(m_list, uniqueName); emit changed(); break; } } } } void IMPage::Private::removeIM(const QModelIndex& index) { if (index.isValid()) { const QString uniqueName =index.data(FcitxIMUniqueNameRole).toString(); for (int i = 0; i < m_list.size(); i ++) { if (uniqueName == m_list[i].uniqueName()) { m_list[i].setEnabled(false); std::stable_sort(m_list.begin(), m_list.end()); emit updateIMList(m_list, uniqueName); emit changed(); break; } } } } void IMPage::Private::moveDownIM() { QModelIndex curIndex = currentIMView->currentIndex(); if (curIndex.isValid()) { QModelIndex nextIndex = currentIMModel->index(curIndex.row() + 1, 0); int i = 0, curIMIdx = -1, nextIMIdx = -1; for (i = 0; i < m_list.size(); i ++) { if (curIndex.data(FcitxIMUniqueNameRole) == m_list[i].uniqueName()) curIMIdx = i; if (nextIndex.data(FcitxIMUniqueNameRole) == m_list[i].uniqueName()) nextIMIdx = i; } if (curIMIdx >= 0 && nextIMIdx >= 0 && curIMIdx != nextIMIdx) { m_list.swapItemsAt(curIMIdx, nextIMIdx); std::stable_sort(m_list.begin(), m_list.end()); emit updateIMList(m_list, curIndex.data(FcitxIMUniqueNameRole).toString()); emit changed(); } } } void IMPage::Private::configureIM() { QModelIndex curIndex = currentIMView->currentIndex(); if (!curIndex.isValid()) { return; } if (!Global::instance()->inputMethodProxy()) { return; } const QString uniqueName = curIndex.data(FcitxIMUniqueNameRole).toString(); QDBusPendingReply< QString > result = Global::instance()->inputMethodProxy()->GetIMAddon(uniqueName); result.waitForFinished(); if (result.isValid()) { FcitxAddon* addonEntry = module->findAddonByName(result.value()); QPointer configDialog(new IMConfigDialog(uniqueName, addonEntry)); configDialog->exec(); delete configDialog; } } void IMPage::Private::moveUpIM() { QModelIndex curIndex = currentIMView->currentIndex(); if (curIndex.isValid() && curIndex.row() > 0) { QModelIndex nextIndex = currentIMModel->index(curIndex.row() - 1, 0); int i = 0, curIMIdx = -1, nextIMIdx = -1; for (i = 0; i < m_list.size(); i ++) { if (curIndex.data(FcitxIMUniqueNameRole) == m_list[i].uniqueName()) curIMIdx = i; if (nextIndex.data(FcitxIMUniqueNameRole) == m_list[i].uniqueName()) nextIMIdx = i; } if (curIMIdx >= 0 && nextIMIdx >= 0 && curIMIdx != nextIMIdx) { m_list.swapItemsAt(curIMIdx, nextIMIdx); std::stable_sort(m_list.begin(), m_list.end()); emit updateIMList(m_list, curIndex.data(FcitxIMUniqueNameRole).toString()); emit changed(); } } } void IMPage::Private::save() { if (Global::instance()->inputMethodProxy()) Global::instance()->inputMethodProxy()->setIMList(m_list); } void IMPage::Private::fetchIMList() { if (Global::instance()->inputMethodProxy()) { m_list = Global::instance()->inputMethodProxy()->iMList(); std::stable_sort(m_list.begin(), m_list.end()); emit updateIMList(m_list, QString()); } } const FcitxQtInputMethodItemList& IMPage::Private::getIMList() { return m_list; } int IMPage::Private::dependantLayoutValue(int value, int width, int totalWidth) const { if (availIMView->layoutDirection() == Qt::LeftToRight) { return value; } return totalWidth - width - value; } void IMPage::Private::onConnectStatusChanged(bool connected) { fetchIMList(); } IMPage::~IMPage() { delete m_ui; } IMDelegate::IMDelegate(QObject* parent) : QStyledItemDelegate(parent) { } IMDelegate::~IMDelegate() { } const int SPACING = 4; void IMDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.data(FcitxRowTypeRole).toInt() == IMType) { QStyledItemDelegate::paint(painter, option, index); return; } painter->save(); painter->setRenderHint(QPainter::Antialiasing); const QString category = index.model()->data(index, Qt::DisplayRole).toString(); QRect optRect = option.rect; optRect.translate(SPACING, SPACING); optRect.setWidth(optRect.width() - SPACING * 2); optRect.setHeight(optRect.height() - SPACING * 2); QFont font(QApplication::font()); font.setBold(true); const QFontMetrics fontMetrics = QFontMetrics(font); QColor outlineColor = option.palette.text().color(); outlineColor.setAlphaF(0.35); //BEGIN: top left corner { painter->save(); painter->setPen(outlineColor); const QPointF topLeft(optRect.topLeft()); QRectF arc(topLeft, QSizeF(4, 4)); arc.translate(0.5, 0.5); painter->drawArc(arc, 1440, 1440); painter->restore(); } //END: top left corner //BEGIN: left vertical line { QPoint start(optRect.topLeft()); start.ry() += 3; QPoint verticalGradBottom(optRect.topLeft()); verticalGradBottom.ry() += fontMetrics.height() + 5; QLinearGradient gradient(start, verticalGradBottom); gradient.setColorAt(0, outlineColor); gradient.setColorAt(1, Qt::transparent); painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); } //END: left vertical line //BEGIN: horizontal line { QPoint start(optRect.topLeft()); start.rx() += 3; QPoint horizontalGradTop(optRect.topLeft()); horizontalGradTop.rx() += optRect.width() - 6; painter->fillRect(QRect(start, QSize(optRect.width() - 6, 1)), outlineColor); } //END: horizontal line //BEGIN: top right corner { painter->save(); painter->setPen(outlineColor); QPointF topRight(optRect.topRight()); topRight.rx() -= 4; QRectF arc(topRight, QSizeF(4, 4)); arc.translate(0.5, 0.5); painter->drawArc(arc, 0, 1440); painter->restore(); } //END: top right corner //BEGIN: right vertical line { QPoint start(optRect.topRight()); start.ry() += 3; QPoint verticalGradBottom(optRect.topRight()); verticalGradBottom.ry() += fontMetrics.height() + 5; QLinearGradient gradient(start, verticalGradBottom); gradient.setColorAt(0, outlineColor); gradient.setColorAt(1, Qt::transparent); painter->fillRect(QRect(start, QSize(1, fontMetrics.height() + 5)), gradient); } //END: right vertical line //BEGIN: text { QRect textRect(option.rect); textRect.setTop(textRect.top() + 7); textRect.setLeft(textRect.left() + 7); textRect.setHeight(fontMetrics.height()); textRect.setRight(textRect.right() - 7); painter->save(); painter->setFont(font); QColor penColor(option.palette.text().color()); penColor.setAlphaF(0.6); painter->setPen(penColor); painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, category); painter->restore(); } //END: text painter->restore(); } QSize IMDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { if (index.data(FcitxRowTypeRole).toInt() == IMType) { return QStyledItemDelegate::sizeHint(option, index); } else { QFont font(QApplication::font()); font.setBold(true); QFontMetrics fontMetrics(font); const int height = fontMetrics.height() + 1 /* 1 pixel-width gradient */ + 11 /* top and bottom separation */ + SPACING; return QSize(0, height); } } } kcm-fcitx-master/src/impage.h000066400000000000000000000036601433634536200164540ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITX_IM_PAGE_H #define FCITX_IM_PAGE_H // Qt #include #include #include // self namespace Ui { class IMPage; } namespace Fcitx { class Module; class IMPage : public QWidget { Q_OBJECT public: IMPage(Module* parent = 0); virtual ~IMPage(); Q_SIGNALS: void changed(); public Q_SLOTS: void save(); void load(); void filterTextChanged(const QString& text); void onlyLanguageChanged(bool); void defaults(); private: Ui::IMPage* m_ui; class Private; Private* d; }; } #endif kcm-fcitx-master/src/impage.ui000066400000000000000000000207051433634536200166410ustar00rootroot00000000000000 IMPage 0 0 1062 648 Form Qt::Horizontal QSizePolicy::Fixed 20 20 Keyboard layout to use when no input method active Select default keyboard layout Qt::Horizontal 40 20 Qt::Horizontal QSizePolicy::Fixed 20 20 Available Input Method: 0 false false true true false Only &Show Current Language true false Qt::Vertical 20 40 false false Qt::Vertical 20 40 Current Input Method: Qt::Vertical 20 40 false false Qt::Vertical 20 40 0 0 Qt::Horizontal 0 0 22 22 22 22 The first input method will be inactive state. Usually you need to put <b>Keyboard</b> or <b>Keyboard - <i>layout name</i></b> in the first place. Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter true <b>Default keyboard layout:</b> <b>Select Input Method:</b> kcm-fcitx-master/src/impage_p.h000066400000000000000000000144321433634536200167720ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef __FCITX_IM_PAGE_P_H__ #define __FCITX_IM_PAGE_P_H__ // Qt #include #include #include #include #include // Fcitx #include // self #include "impage.h" enum { FcitxRowTypeRole = 0x324da8fc, FcitxLanguageRole, FcitxIMUniqueNameRole }; enum { LanguageType, IMType }; class QTreeView; class QCheckBox; class QListView; class QPushButton; class QLineEdit; namespace Fcitx { class IMPage::Private : public QObject { Q_OBJECT public: Private(QObject* parent); virtual ~Private(); void fetchIMList(); const FcitxQtInputMethodItemList& getIMList(); int dependantLayoutValue(int value, int width, int totalWidth) const; class IMModel; class AvailIMModel; class IMProxyModel; class IMDelegate; QPushButton* addIMButton; QPushButton* removeIMButton; QPushButton* moveUpButton; QPushButton* moveDownButton; QPushButton* configureButton; QListView* currentIMView; QTreeView* availIMView; QLineEdit* filterTextEdit; AvailIMModel* availIMModel; IMProxyModel* availIMProxyModel; IMModel* currentIMModel; QCheckBox* onlyCurrentLanguageCheckBox; Module* module; QPushButton* defaultLayoutButton; Q_SIGNALS: void updateIMList(const FcitxQtInputMethodItemList& list, const QString& selection); void changed(); public Q_SLOTS: void availIMSelectionChanged(); void currentIMCurrentChanged(); void clickAddIM(); void clickRemoveIM(); void addIM(const QModelIndex& index); void removeIM(const QModelIndex& index); void moveUpIM(); void moveDownIM(); void configureIM(); void save(); void doubleClickCurrentIM(const QModelIndex& index); void doubleClickAvailIM(const QModelIndex& index); void selectCurrentIM(const QModelIndex& index); void selectAvailIM(const QModelIndex& index); void selectDefaultLayout(); void onConnectStatusChanged(bool connected); private: FcitxQtInputMethodItemList m_list; }; class IMDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit IMDelegate(QObject* parent = 0); virtual ~IMDelegate(); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE; }; class IMPage::Private::IMProxyModel : public QSortFilterProxyModel { Q_OBJECT public: IMProxyModel(QAbstractItemModel* sourceModel); virtual ~IMProxyModel(); void setFilterText(const QString& text); void setShowOnlyCurrentLanguage(bool checked); public Q_SLOTS: void filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, const QString& selection = QString()); protected: virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const Q_DECL_OVERRIDE; virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const Q_DECL_OVERRIDE; int compareCategories(const QModelIndex& left, const QModelIndex& right) const; private: bool filterLanguage(const QModelIndex& index) const; bool filterIM(const QModelIndex& index) const; bool m_showOnlyCurrentLanguage; QString m_filterText; QSet< QString > m_languageSet; }; class IMPage::Private::AvailIMModel : public QAbstractItemModel { Q_OBJECT void m_languageSet(); public: AvailIMModel(QObject* parent = 0); virtual ~AvailIMModel(); virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; virtual QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; virtual int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE; virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; Q_SIGNALS: void select(QModelIndex index); void updateIMListFinished(); public Q_SLOTS: void filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, const QString& selection = QString()); private: QList > filteredIMEntryList; }; class IMPage::Private::IMModel : public QAbstractListModel { Q_OBJECT public: IMModel(QObject* parent = 0); virtual ~IMModel(); QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; Q_SIGNALS: void select(QModelIndex index); public Q_SLOTS: void filterIMEntryList(const FcitxQtInputMethodItemList& imEntryList, const QString& selection = QString()); private: FcitxQtInputMethodItemList filteredIMEntryList; }; } #endif kcm-fcitx-master/src/kcm_fcitx.desktop.in000066400000000000000000000005141433634536200210030ustar00rootroot00000000000000[Desktop Entry] Exec=kcmshell5 kcm_fcitx Icon=fcitx Type=Service X-KDE-ServiceTypes=KCModule X-KDE-Library=kcm_fcitx X-KDE-ParentApp=kcontrol X-KDE-System-Settings-Parent-Category=regionalsettings _Name=Input Method _Comment=Configure Input Method _X-KDE-Keywords=keyboard,input,im,fcitx Categories=Qt;KDE;X-KDE-settings-fcitx; kcm-fcitx-master/src/main.cpp000066400000000000000000000031031433634536200164610ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // KDE #include // self #include "module.h" K_PLUGIN_FACTORY(KcmFcitxFactory, registerPlugin();) K_EXPORT_PLUGIN(KcmFcitxFactory("kcm_fcitx")) #include "main.moc" kcm-fcitx-master/src/module.cpp000066400000000000000000000157471433634536200170430ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2010~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include #include // KDE #include #include // system #include // Fcitx #include #include #include #include #include #include #include // self #include "config.h" #include "ui_module.h" #include "module.h" #include "addonselector.h" #include "configwidget.h" #include "global.h" #include "subconfigparser.h" #include "skinpage.h" #include "impage.h" #include "imconfigdialog.h" #include "uipage.h" #include "configpage.h" #include "erroroverlay.h" K_PLUGIN_FACTORY_DECLARATION(KcmFcitxFactory); namespace Fcitx { const UT_icd addonicd = {sizeof(FcitxAddon), 0, 0, FcitxAddonFree}; Module::Module(QWidget *parent, const QVariantList &args) : KCModule(parent, args), ui(new Ui::Module), addonSelector(0), m_addons(0), m_configPage(0), m_skinPage(0), m_imPage(0), m_uiPage(0) { bindtextdomain("fcitx", LOCALEDIR); bind_textdomain_codeset("fcitx", "UTF-8"); FcitxLogSetLevel(FCITX_NONE); FcitxQtInputMethodItem::registerMetaType(); FcitxQtKeyboardLayout::registerMetaType(); KAboutData *about = new KAboutData("kcm_fcitx", i18n("Fcitx Configuration Module"), VERSION_STRING_FULL, i18n("Configure Fcitx"), KAboutLicense::GPL_V2, i18n("Copyright 2012 Xuetian Weng"), QString(), QString(), "wengxt@gmail.com"); about->addAuthor(i18n("Xuetian Weng"), i18n("Author"), "wengxt@gmail.com"); setAboutData(about); if (FcitxAddonGetConfigDesc() != NULL) { utarray_new(m_addons, &addonicd); FcitxAddonsLoad(m_addons); } Global::instance(); ui->setupUi(this); { m_imPage = new IMPage(this); ui->pageWidget->addTab(m_imPage, i18n("Input Method")); connect(m_imPage, SIGNAL(changed()), this, SLOT(changed())); } { FcitxConfigFileDesc* configDesc = Global::instance()->GetConfigDesc("config.desc"); if (configDesc) { m_configPage = new ConfigPage; ui->pageWidget->addTab(m_configPage, i18n("Global Config")); connect(m_configPage, SIGNAL(changed()), this, SLOT(changed())); } } { if (Global::instance()->inputMethodProxy()) { m_uiPage = new UIPage(this); ui->pageWidget->addTab(m_uiPage, i18n("Appearance")); connect(m_uiPage, SIGNAL(changed()), this, SLOT(changed())); } } { if (FcitxAddonGetConfigDesc() != NULL) { addonSelector = new AddonSelector(this); ui->pageWidget->addTab(addonSelector, i18n("Addon Config")); } } if (m_addons) { for (FcitxAddon* addon = (FcitxAddon *) utarray_front(m_addons); addon != NULL; addon = (FcitxAddon *) utarray_next(m_addons, addon)) { this->addonSelector->addAddon(addon); } } if (args.size() != 0) { m_arg = args[0].toString(); } } Module::~Module() { delete ui; if (addonSelector) { delete addonSelector; } if (m_addons) { utarray_free(m_addons); } Global::deInit(); } FcitxAddon* Module::findAddonByName(const QString& name) { if (!m_addons) { return NULL; } FcitxAddon* addon = NULL; for (addon = (FcitxAddon *) utarray_front(m_addons); addon != NULL; addon = (FcitxAddon *) utarray_next(m_addons, addon)) { if (QString::fromUtf8(addon->name) == name) break; } return addon; } SkinPage* Module::skinPage() { if (!m_skinPage) { m_skinPage = new SkinPage(this); ui->pageWidget->addTab(m_skinPage, i18n("Manage Skin")); connect(m_skinPage, SIGNAL(changed()), this, SLOT(changed())); } return m_skinPage; } void Module::load() { QDialog* configDialog = NULL; if (!m_arg.isEmpty()) { do { if (!Global::instance()->inputMethodProxy()) break; QDBusPendingReply< QString > result = Global::instance()->inputMethodProxy()->GetIMAddon(m_arg); result.waitForFinished(); if (!result.isValid() || result.value().isEmpty()) break; FcitxAddon* addonEntry = findAddonByName(result.value()); if (!addonEntry) break; configDialog = new IMConfigDialog(m_arg, addonEntry, 0); } while(0); if (!configDialog) { FcitxAddon* addonEntry = findAddonByName(m_arg); if (addonEntry) configDialog = ConfigWidget::configDialog(0, addonEntry); } if (configDialog) { configDialog->setAttribute(Qt::WA_DeleteOnClose); configDialog->open(); } m_arg = QString(); } if (m_imPage) m_imPage->load(); if (m_skinPage) m_skinPage->load(); if (m_configPage) m_configPage->load(); } void Module::save() { if (m_imPage) m_imPage->save(); if (m_skinPage) m_skinPage->save(); if (m_configPage) m_configPage->save(); if (m_uiPage) m_uiPage->save(); } void Module::defaults() { if (m_configPage) { m_configPage->defaults(); } if (m_imPage) { m_imPage->defaults(); } markAsChanged(); } } kcm-fcitx-master/src/module.h000066400000000000000000000052031433634536200164720ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef MODULE_H #define MODULE_H // KDE #include // Fcitx #include #include class QFile; namespace Ui { class Module; } namespace Fcitx { class ConfigPage; class UIPage; class IMPage; class SkinPage; class ConfigWidget; class AddonSelector; class Module : public KCModule { Q_OBJECT public: /** * Constructor. * * @param parent Parent widget of the module * @param args Arguments for the module */ Module(QWidget *parent, const QVariantList &args = QVariantList()); /** * Destructor. */ ~Module(); /** * Overloading the KCModule load() function. */ void load() override; /** * Overloading the KCModule save() function. */ void save() override; /** * Overloading the KCModule defaults() function. */ void defaults() override; FcitxAddon* findAddonByName(const QString& name); SkinPage* skinPage(); private: /** * UI */ Ui::Module *ui; /** * Addon Selector */ AddonSelector* addonSelector; /** * addon array */ UT_array* m_addons; ConfigPage* m_configPage; SkinPage* m_skinPage; IMPage* m_imPage; UIPage* m_uiPage; QString m_arg; }; } #endif // MODULE_H kcm-fcitx-master/src/module.ui000066400000000000000000000010741433634536200166620ustar00rootroot00000000000000 Module 0 0 Form kcm-fcitx-master/src/skinpage.cpp000066400000000000000000000720551433634536200173520ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include #include #include // Fcitx #include // self #include "module.h" #include "global.h" #include "configwidget.h" #include "skinpage.h" #include "skinpage_p.h" CONFIG_BINDING_BEGIN(SkinData) CONFIG_BINDING_REGISTER("SkinFont", "FontSize", inputbar.fontSize) CONFIG_BINDING_REGISTER("SkinFont", "InputColor", inputbar.inputColor) CONFIG_BINDING_REGISTER("SkinFont", "IndexColor", inputbar.indexColor) CONFIG_BINDING_REGISTER("SkinFont", "FirstCandColor", inputbar.firstCandColor) CONFIG_BINDING_REGISTER("SkinFont", "OtherColor", inputbar.otherColor) CONFIG_BINDING_REGISTER("SkinFont", "RespectDPI", inputbar.respectDPI) CONFIG_BINDING_REGISTER("SkinInputBar", "BackImg", inputbar.backImg) CONFIG_BINDING_REGISTER("SkinInputBar", "MarginTop", inputbar.marginTop) CONFIG_BINDING_REGISTER("SkinInputBar", "MarginBottom", inputbar.marginBottom) CONFIG_BINDING_REGISTER("SkinInputBar", "MarginLeft", inputbar.marginLeft) CONFIG_BINDING_REGISTER("SkinInputBar", "MarginRight", inputbar.marginRight) CONFIG_BINDING_REGISTER("SkinInputBar", "CursorColor", inputbar.cursorColor) CONFIG_BINDING_REGISTER("SkinInputBar", "InputPos", inputbar.iInputPos) CONFIG_BINDING_REGISTER("SkinInputBar", "OutputPos", inputbar.iOutputPos) CONFIG_BINDING_REGISTER("SkinInputBar", "BackArrow", inputbar.backArrow) CONFIG_BINDING_REGISTER("SkinInputBar", "ForwardArrow", inputbar.forwardArrow) CONFIG_BINDING_REGISTER("SkinInputBar", "BackArrowX", inputbar.iBackArrowX) CONFIG_BINDING_REGISTER("SkinInputBar", "BackArrowY", inputbar.iBackArrowY) CONFIG_BINDING_REGISTER("SkinInputBar", "ForwardArrowX", inputbar.iForwardArrowX) CONFIG_BINDING_REGISTER("SkinInputBar", "ForwardArrowY", inputbar.iForwardArrowY) CONFIG_BINDING_REGISTER("SkinInputBar", "FillVertical", inputbar.fillV) CONFIG_BINDING_REGISTER("SkinInputBar", "FillHorizontal", inputbar.fillH) CONFIG_BINDING_REGISTER("SkinMainBar", "BackImg", mainbar.backImg) CONFIG_BINDING_REGISTER("SkinMainBar", "Logo", mainbar.logo) CONFIG_BINDING_REGISTER("SkinMainBar", "Eng", mainbar.eng) CONFIG_BINDING_REGISTER("SkinMainBar", "Active", mainbar.active) CONFIG_BINDING_REGISTER("SkinMainBar", "MarginLeft", mainbar.marginLeft) CONFIG_BINDING_REGISTER("SkinMainBar", "MarginRight", mainbar.marginRight) CONFIG_BINDING_REGISTER("SkinMainBar", "MarginTop", mainbar.marginTop) CONFIG_BINDING_REGISTER("SkinMainBar", "MarginBottom", mainbar.marginBottom) CONFIG_BINDING_REGISTER("SkinMainBar", "FillVertical", mainbar.fillV) CONFIG_BINDING_REGISTER("SkinMainBar", "FillHorizontal", mainbar.fillH) CONFIG_BINDING_REGISTER("SkinMainBar", "Placement", mainbar.placement) /* CONFIG_BINDING_REGISTER("SkinTrayIcon","Active", ) CONFIG_BINDING_REGISTER("SkinTrayIcon","Inactive", ) */ CONFIG_BINDING_END() static inline void FreePlacement(void* arg) { SkinPlacement* sp = (SkinPlacement*) arg; free(sp->name); } namespace Fcitx { const int margin = 5; static const UT_icd place_icd = {sizeof(SkinPlacement), NULL, NULL, FreePlacement}; void ParsePlacement(UT_array* sps, char* placment) { UT_array* array = fcitx_utils_split_string(placment, ';'); char** str; utarray_clear(sps); for (str = (char**) utarray_front(array); str != NULL; str = (char**) utarray_next(array, str)) { char* s = *str; char* p = strchr(s, ':'); if (p == NULL) continue; int len = p - s; SkinPlacement sp; sp.name = strndup(s, len); int ret = sscanf(p + 1, "%d,%d", &sp.x, &sp.y); if (ret != 2) continue; utarray_push_back(sps, &sp); } fcitx_utils_free_string_list(array); } SkinPage::Private::SkinModel::SkinModel(Private* p, QObject* parent) : QAbstractListModel(parent), d(p) { } QVariant SkinPage::Private::SkinModel::data(const QModelIndex& index, int role) const { SkinInfo* skin = static_cast(index.internalPointer()); switch (role) { case PixmapRole: return skin->pixmap; case PathRole: return skin->path; } return QVariant(); } QModelIndex SkinPage::Private::SkinModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent); return createIndex(row, column, (row < m_skins.count()) ? (void*) &m_skins.at(row) : 0); } int SkinPage::Private::SkinModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return m_skins.count(); } bool SkinPage::Private::SkinModel::setData(const QModelIndex& index, const QVariant& value, int role) { return QAbstractItemModel::setData(index, value, role); } const QList& SkinPage::Private::SkinModel::skinList() const { return m_skins; } void SkinPage::Private::SkinModel::setSkinList(const QStringList& list) { beginRemoveRows(QModelIndex(), 0, m_skins.size()); m_skins.clear(); endRemoveRows(); QStringList sortedList = list; std::sort(sortedList.begin(), sortedList.end()); Q_FOREACH(const QString & im, sortedList) { beginInsertRows(QModelIndex(), m_skins.size(), m_skins.size()); SkinInfo info; info.path = im; info.pixmap = drawSkinPreview(im); m_skins.push_back(info); endInsertRows(); } } QPixmap SkinPage::Private::SkinModel::drawSkinPreview(const QString& path) { FcitxConfigFileDesc* cfdesc = Global::instance()->GetConfigDesc("skin.desc"); FILE* fp = NULL; FcitxConfigFile* cfile = NULL; QDir dir; if (cfdesc) fp = FcitxXDGGetFileWithPrefix("", path.toLocal8Bit().constData(), "r", NULL); if (fp) { cfile = FcitxConfigParseConfigFileFp(fp, cfdesc); fclose(fp); } QString skinName = path.section('/', 1, 1); if (cfile) { QString skinDir = path.section('/', 0, 1); SkinData skin; memset(&skin, 0, sizeof(SkinData)); SkinDataConfigBind(&skin, cfile, cfdesc); FcitxConfigBindSync(&skin.config); int marginLeft = skin.inputbar.marginLeft; int marginRight = skin.inputbar.marginRight; int marginTop = skin.inputbar.marginTop; int marginBottom = skin.inputbar.marginBottom; // Draw Demo string: QString inputExample = skinName; QString numberStr[2]; QString candStr[2]; QString spaceStr = " "; for (int i = 0; i < 2; i++) { numberStr[i] = QString("%1.").arg(i + 1); } candStr[0] = i18n("First candidate"); candStr[1] = i18n("Other candidate"); int offset = marginLeft; QFont inputFont(qApp->font()); int fontHeight = 0; if (skin.inputbar.respectDPI) { inputFont.setPointSize(fontHeight); QFontMetrics metrics(inputFont); fontHeight = metrics.height(); } else { inputFont.setPixelSize(skin.inputbar.fontSize); fontHeight = skin.inputbar.fontSize; } QFontMetrics metrics(inputFont); // inputPos & outputPos is the LeftTop position of the text. int inputPos; if (skin.inputbar.respectDPI) inputPos = marginTop + skin.inputbar.iInputPos; else inputPos = marginTop + skin.inputbar.iInputPos - fontHeight; int outputPos; if (skin.inputbar.respectDPI) outputPos = marginTop + skin.inputbar.iInputPos + fontHeight + skin.inputbar.iOutputPos; else outputPos = marginTop + skin.inputbar.iOutputPos - fontHeight; QPixmap inputBarPixmap = LoadImage(skinDir.toLocal8Bit().constData(), skin.inputbar.backImg); int resizeWidth = 0; int resizeHeight; if (skin.inputbar.respectDPI) resizeHeight = skin.inputbar.iInputPos + skin.inputbar.iOutputPos + fontHeight * 2; else resizeHeight = skin.inputbar.iOutputPos; for (int i = 0; i < 2; i++) { resizeWidth += metrics.horizontalAdvance(numberStr[i]); resizeWidth += metrics.horizontalAdvance(candStr[i]); }; int totalWidth = marginLeft + marginRight + resizeWidth; int totalHeight = marginTop + marginBottom + resizeHeight; QPixmap inputBarDestPixmap(totalWidth, totalHeight); inputBarDestPixmap.fill(Qt::transparent); DrawResizableBackground(inputBarDestPixmap, inputBarPixmap, marginLeft, marginRight, marginTop, marginBottom, resizeWidth, resizeHeight, skin.inputbar.fillV, skin.inputbar.fillH ); QPixmap backArrowPixmap = LoadImage(skinDir.toLocal8Bit().constData(), skin.inputbar.backArrow); QPixmap forwardArrowPixmap = LoadImage(skinDir.toLocal8Bit().constData(), skin.inputbar.forwardArrow); DrawWidget(inputBarDestPixmap, backArrowPixmap, totalWidth - skin.inputbar.iBackArrowX, skin.inputbar.iBackArrowY ); DrawWidget(inputBarDestPixmap, forwardArrowPixmap, totalWidth - skin.inputbar.iForwardArrowX, skin.inputbar.iForwardArrowY ); QPainter textPainter(&inputBarDestPixmap); textPainter.setFont(inputFont); QColor inputColor = ConvertColor(skin.inputbar.inputColor); QColor indexColor = ConvertColor(skin.inputbar.indexColor); QColor firstCandColor = ConvertColor(skin.inputbar.firstCandColor); QColor otherColor = ConvertColor(skin.inputbar.otherColor); textPainter.setPen(inputColor); textPainter.drawText(marginLeft, inputPos, metrics.horizontalAdvance(inputExample), fontHeight, Qt::AlignVCenter, inputExample); // Draw candidate number: textPainter.setPen(indexColor); for (int i = 0; i < 2; i++) { textPainter.drawText(offset, outputPos, metrics.horizontalAdvance(numberStr[i]), fontHeight, Qt::AlignVCenter, numberStr[i]); offset = offset + metrics.horizontalAdvance(numberStr[i]) + metrics.horizontalAdvance(candStr[i]) + metrics.horizontalAdvance(spaceStr); } offset = marginLeft + metrics.horizontalAdvance(numberStr[0]); textPainter.setPen(firstCandColor); textPainter.drawText(offset, outputPos, metrics.horizontalAdvance(candStr[0]), fontHeight, Qt::AlignVCenter, candStr[0]); offset = offset + metrics.horizontalAdvance(candStr[0]) + metrics.horizontalAdvance(spaceStr) + metrics.horizontalAdvance(numberStr[1]); textPainter.setPen(otherColor); textPainter.drawText(offset, outputPos, metrics.horizontalAdvance(candStr[1]), fontHeight, Qt::AlignVCenter, candStr[1]); textPainter.end(); /*Just define it for convenient: * mainbar->backImg == inputbar.mainbar.backImg; */ SkinMainBar *mainbar = &skin.mainbar; UT_array placement; utarray_init(&placement, &place_icd); ParsePlacement(&placement, mainbar->placement); QPixmap mainBarPixmap = LoadImage(skinDir.toLocal8Bit().constData(), mainbar->backImg); const int widgetCount = 2; QPixmap mainBarWidgetPixmap[widgetCount]; mainBarWidgetPixmap[0] = LoadImage(skinDir.toLocal8Bit().constData(), mainbar->logo); mainBarWidgetPixmap[1] = LoadImage(skinDir.toLocal8Bit().constData(), mainbar->active); marginLeft = mainbar->marginLeft; marginRight = mainbar->marginRight; marginTop = mainbar->marginTop; marginBottom = mainbar->marginBottom; QPixmap mainBarDestPixmap; if (utarray_len(&placement) != 0) { mainBarDestPixmap = QPixmap(mainBarPixmap.width(), mainBarPixmap.height()); DrawResizableBackground(mainBarDestPixmap, mainBarPixmap, 0, 0, 0, 0, mainBarPixmap.width(), mainBarPixmap.height(), F_RESIZE, F_RESIZE ); SkinPlacement* sp; for (sp = (SkinPlacement*) utarray_front(&placement); sp != NULL; sp = (SkinPlacement*) utarray_next(&placement, sp)) { if (strcmp(sp->name, "logo") == 0) { DrawWidget(mainBarDestPixmap, mainBarWidgetPixmap[0], sp->x, sp->y); } else if (strcmp(sp->name, "im") == 0) { DrawWidget(mainBarDestPixmap, mainBarWidgetPixmap[1], sp->x, sp->y); } } } else { resizeWidth = 0; resizeHeight = 0; for (int i = 0; i < widgetCount; i++) { resizeWidth += mainBarWidgetPixmap[i].width(); if (mainBarWidgetPixmap[i].height() > resizeHeight) resizeHeight = mainBarWidgetPixmap[i].height(); } mainBarDestPixmap = QPixmap(marginLeft + resizeWidth + marginRight, marginTop + resizeHeight + marginBottom); DrawResizableBackground(mainBarDestPixmap, mainBarPixmap, marginLeft, marginRight, marginTop, marginBottom, resizeWidth, resizeHeight, mainbar->fillV, mainbar->fillH ); offset = marginLeft; for (int i = 0; i < widgetCount; i++) { DrawWidget(mainBarDestPixmap, mainBarWidgetPixmap[i], offset, marginTop); offset += mainBarWidgetPixmap[i].width(); } } // destPixmap includes both inputbar and mainbar int maxHeight = qMax(mainBarDestPixmap.height(), inputBarDestPixmap.height()); QPixmap destPixmap(inputBarDestPixmap.width() + 20 + mainBarDestPixmap.width(), maxHeight); destPixmap.fill(Qt::transparent); DrawWidget(destPixmap, inputBarDestPixmap, 0, 0); DrawWidget(destPixmap, mainBarDestPixmap, inputBarDestPixmap.width() + 20, maxHeight - mainBarDestPixmap.height()); FcitxConfigFree(&skin.config); utarray_done(&placement); return destPixmap; // return inputBarDestPixmap; } else { QFont inputFont(qApp->font()); QFontMetrics fm(inputFont); QString errmsg = i18n("Skin %1 Cannot be loaded").arg(skinName); int w = fm.horizontalAdvance(errmsg); QPixmap destPixmap(w, fm.height()); destPixmap.fill(Qt::transparent); QPainter textPainter(&destPixmap); textPainter.setPen(qApp->palette().color(QPalette::Active, QPalette::Text)); textPainter.setFont(inputFont); textPainter.drawText(0, 0, w, fm.height(), Qt::AlignVCenter, errmsg); textPainter.end(); return destPixmap; } } QColor SkinPage::Private::SkinModel::ConvertColor(FcitxConfigColor floatColor) { /** * 0-1 to 0-255 */ return QColor(qBound(0, int(floatColor.r * 256), 255), qBound(0, int(floatColor.g * 256), 255), qBound(0, int(floatColor.b * 256), 255)); } QPixmap SkinPage::Private::SkinModel::LoadImage(const char* skinDir, const char* fileName) { char* image = NULL; FILE* fp = FcitxXDGGetFileWithPrefix(skinDir, fileName, "r", &image); QPixmap pixmap; if (fp) { fclose(fp); pixmap = QPixmap(QString::fromLocal8Bit(image)); } if (image) free(image); return pixmap; } void SkinPage::Private::SkinModel::DrawWidget( QPixmap &destPixmap, QPixmap &widgetPixmap, int x, int y ) { QPainter painter(&destPixmap); painter.drawPixmap(x, y, widgetPixmap); painter.end(); } void SkinPage::Private::SkinModel::DrawResizableBackground( QPixmap &destPixmap, QPixmap &backgroundPixmap, int marginLeft, int marginRight, int marginTop, int marginBottom, int resizeWidth, int resizeHeight, FillRule fillV, FillRule fillH ) { int originWidth = backgroundPixmap.width() - marginLeft - marginRight; int originHeight = backgroundPixmap.height() - marginTop - marginBottom; if (resizeWidth <= 0) resizeWidth = 1; if (resizeHeight <= 0) resizeHeight = 1; if (originWidth <= 0) originWidth = 1; if (originHeight <= 0) originHeight = 1; destPixmap = QPixmap(resizeWidth + marginLeft + marginRight, resizeHeight + marginTop + marginBottom); destPixmap.fill(Qt::transparent); QPainter painter(&destPixmap); /* 画背景 */ /* 九宫格 * 7 8 9 * 4 5 6 * 1 2 3 */ /* part 1 */ painter.drawPixmap( QRect(0, marginTop + resizeHeight, marginLeft, marginBottom), backgroundPixmap, QRect(0, marginTop + originHeight, marginLeft, marginBottom) ); /* part 3 */ painter.drawPixmap( QRect(marginLeft + resizeWidth, marginTop + resizeHeight, marginRight, marginBottom), backgroundPixmap, QRect(marginLeft + originWidth, marginTop + originHeight, marginRight, marginBottom) ); /* part 7 */ painter.drawPixmap( QRect(0 , 0, marginLeft, marginTop), backgroundPixmap, QRect(0, 0, marginLeft, marginTop) ); /* part 9 */ painter.drawPixmap( QRect(marginLeft + resizeWidth, 0, marginRight, marginTop), backgroundPixmap, QRect(marginLeft + originWidth, 0, marginRight, marginTop) ); /* part 2 & 8 */ { if (fillH == F_COPY) { int repaint_times = resizeWidth / originWidth; int remain_width = resizeWidth % originWidth; int i = 0; for (i = 0; i < repaint_times; i++) { painter.drawPixmap( QRect(marginLeft + i * originWidth, 0, originWidth, marginTop), backgroundPixmap, QRect(marginLeft, 0, originWidth, marginTop) ); painter.drawPixmap( QRect(marginLeft + i * originWidth, marginTop + resizeHeight, originWidth, marginBottom), backgroundPixmap, QRect(marginLeft, marginTop + originHeight, originWidth, marginBottom) ); } if (remain_width != 0) { painter.drawPixmap( QRect(marginLeft + repaint_times * originWidth, 0, remain_width, marginTop), backgroundPixmap, QRect(marginLeft, 0, remain_width, marginTop) ); painter.drawPixmap( QRect(marginLeft + repaint_times * originWidth, marginTop + resizeHeight, remain_width, marginBottom), backgroundPixmap, QRect(marginLeft, marginTop + originHeight, remain_width, marginBottom) ); } } else { painter.drawPixmap( QRect(marginLeft, 0, resizeWidth, marginTop), backgroundPixmap, QRect(marginLeft, 0, originWidth, marginTop) ); painter.drawPixmap( QRect(marginLeft, marginTop + resizeHeight, resizeWidth, marginBottom), backgroundPixmap, QRect(marginLeft, marginTop + originHeight, originWidth, marginBottom) ); } } /* part 4 & 6 */ { if (fillV == F_COPY) { int repaint_times = resizeHeight / originHeight; int remain_height = resizeHeight % originHeight; int i = 0; for (i = 0; i < repaint_times; i++) { painter.drawPixmap( QRect(0, marginTop + i * originHeight , marginLeft, originHeight), backgroundPixmap, QRect(0, marginTop , marginLeft, originHeight) ); painter.drawPixmap( QRect(marginLeft + resizeWidth, marginTop + i * originHeight , marginRight, originHeight), backgroundPixmap, QRect(marginLeft + originWidth, marginTop , marginRight, originHeight) ); } if (remain_height != 0) { painter.drawPixmap( QRect(0, marginTop + repaint_times * originHeight , marginLeft, remain_height), backgroundPixmap, QRect(0, marginTop , marginLeft, remain_height) ); painter.drawPixmap( QRect(marginLeft + resizeWidth, marginTop + repaint_times * originHeight , marginRight, remain_height), backgroundPixmap, QRect(marginLeft + originWidth, marginTop , marginRight, remain_height) ); } } else { painter.drawPixmap( QRect(0, marginTop , marginLeft, resizeHeight), backgroundPixmap, QRect(0, marginTop , marginLeft, originHeight) ); painter.drawPixmap( QRect(marginLeft + resizeWidth, marginTop , marginRight, resizeHeight), backgroundPixmap, QRect(marginLeft + originWidth, marginTop , marginRight, originHeight) ); } } /* part 5 */ { int repaintH = 0, repaintV = 0; int remainW = 0, remainH = 0; if (fillH == F_COPY) { repaintH = resizeWidth / originWidth + 1; remainW = resizeWidth % originWidth; } else { repaintH = 1; } if (fillV == F_COPY) { repaintV = resizeHeight / originHeight + 1; remainH = resizeHeight % originHeight; } else { repaintV = 1; } int i, j; for (i = 0; i < repaintH; i ++) { for (j = 0; j < repaintV; j ++) { int ow = originWidth, oh = originHeight, w, h; if (fillV == F_COPY) { if (j == repaintV - 1) { h = remainH; oh = remainH; } else h = originHeight; } else h = resizeHeight; if (fillH == F_COPY) { if (i == repaintH - 1) { w = remainW; ow = remainW; } else w = originWidth; } else w = resizeWidth; painter.drawPixmap( QRect(marginLeft + i * originWidth, marginTop + j * originHeight , w, h), backgroundPixmap, QRect(marginLeft, marginTop , ow, oh) ); } } } painter.end(); } SkinPage::Private::SkinDelegate::SkinDelegate(QObject* parent) : QStyledItemDelegate(parent) { } SkinPage::Private::SkinDelegate::~SkinDelegate() { } void SkinPage::Private::SkinDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { // highlight selected item QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &option, painter); QPixmap pixmap = index.model()->data(index, PixmapRole).value(); const QSize previewArea = option.rect.size() - QSize(2 * margin, 2 * margin); int offset = (previewArea.width() - pixmap.size().width()) / 2; painter->drawPixmap(option.rect.topLeft() + QPoint(margin + offset, margin), pixmap); } QSize SkinPage::Private::SkinDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(option) QPixmap pixmap = index.model()->data(index, PixmapRole).value(); return pixmap.size() + QSize(2 * margin, 2 * margin); } SkinPage::Private::Private(QObject* parent) : QObject(parent), m_parser("Skin:configfile:skin/*/fcitx_skin.conf:skin.desc", this), m_subConfig(0) { } SkinPage::Private::~Private() { if (m_subConfig) delete m_subConfig; } void SkinPage::Private::load() { if (!skinField) return; if (m_subConfig) delete m_subConfig; m_subConfig = m_parser.getSubConfig("Skin"); skinModel->setSkinList(m_subConfig->fileList().values()); QString skinName = skinField->text(); int row = 0, currentSkin = -1; Q_FOREACH(const SkinInfo & skin, skinModel->skinList()) { if (skin.path == QString("skin/%1/fcitx_skin.conf").arg(skinName)) { currentSkin = row; break; } row ++; } if (currentSkin >= 0) { skinView->selectionModel()->setCurrentIndex(skinModel->index(row, 0), QItemSelectionModel::ClearAndSelect); } } void SkinPage::Private::save() { } void SkinPage::Private::deleteSkin() { if (skinView->currentIndex().isValid()) { SkinInfo* skin = static_cast(skinView->currentIndex().internalPointer()); char* path = NULL; FILE* fp = FcitxXDGGetFileWithPrefix("", skin->path.toLocal8Bit().constData(), "r", &path); if (fp) fclose(fp); if (path) { QString p = QString::fromLocal8Bit(path); QFileInfo info(p); QDir dir = info.dir(); removeDir(dir.absolutePath()); free(path); } load(); } } bool SkinPage::Private::removeDir(const QString &dirName) { bool result = true; QDir dir(dirName); if (dir.exists(dirName)) { Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { if (info.isDir()) { result = removeDir(info.absoluteFilePath()); } else { result = QFile::remove(info.absoluteFilePath()); } if (!result) { return result; } } result = dir.rmdir(dirName); } return result; } void SkinPage::Private::configureSkin() { if (skinView->currentIndex().isValid()) { QItemSelectionModel* selectionModel = skinView->selectionModel(); QModelIndex ind = selectionModel->currentIndex(); if (!ind.isValid()) return; SkinInfo* skin = static_cast(ind.internalPointer()); FcitxConfigFileDesc* cfdesc = Global::instance()->GetConfigDesc("skin.desc"); if (cfdesc) { QPointer configDialog(ConfigWidget::configDialog( module, cfdesc, "", skin->path )); configDialog->exec(); delete configDialog; load(); } } } void SkinPage::Private::currentSkinChanged() { if (skinView->currentIndex().isValid()) { configureSkinButton->setEnabled(true); deleteSkinButton->setEnabled(true); if (skinField) { QString skinName = skinView->currentIndex().data(PathRole).toString().section('/', 1, 1); skinField->setText(skinName); } } else { configureSkinButton->setEnabled(false); deleteSkinButton->setEnabled(false); } emit changed(); } SkinPage::SkinPage(Module* module, QWidget* parent): QWidget(parent), m_module(module), d(new Private(this)), m_ui(new Ui::SkinPage) { m_ui->setupUi(this); d->configureSkinButton = m_ui->configureSkinButton; d->deleteSkinButton = m_ui->deleteSkinButton; d->configureSkinButton->setIcon(QIcon::fromTheme("configure")); d->skinView = m_ui->skinView; d->skinModel = new Private::SkinModel(d, this); d->skinDelegate = new Private::SkinDelegate(this); d->skinView->setModel(d->skinModel); d->skinView->setItemDelegate(d->skinDelegate); d->module = module; connect(d->deleteSkinButton, SIGNAL(clicked(bool)), d, SLOT(deleteSkin())); connect(d->configureSkinButton, SIGNAL(clicked(bool)), d, SLOT(configureSkin())); connect(d->skinView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), d, SLOT(currentSkinChanged())); } SkinPage::~SkinPage() { delete m_ui; } void SkinPage::load() { if (NULL == Global::instance()->GetConfigDesc("fcitx-classic-ui.desc")) { this->setEnabled(false); } disconnect(d, SIGNAL(changed()), this, SIGNAL(changed())); d->load(); connect(d, SIGNAL(changed()), this, SIGNAL(changed())); } void SkinPage::save() { d->save(); } void SkinPage::setSkinField(QLineEdit* lineEdit) { d->skinField = lineEdit; setEnabled(d->skinField != 0); if (d->skinField) { load(); } } } kcm-fcitx-master/src/skinpage.h000066400000000000000000000035511433634536200170120ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITX_SKIN_PAGE_H #define FCITX_SKIN_PAGE_H // Qt #include // self #include "ui_skinpage.h" namespace Fcitx { class Module; class SkinPage : public QWidget { Q_OBJECT public: SkinPage(Module* module, QWidget* parent = 0); virtual ~SkinPage(); void setSkinField(QLineEdit* lineEdit); public Q_SLOTS: void load(); void save(); Q_SIGNALS: void changed(); private: class Private; Module* m_module; Private* d; Ui::SkinPage* m_ui; }; } #endif kcm-fcitx-master/src/skinpage.ui000066400000000000000000000047051433634536200172020ustar00rootroot00000000000000 SkinPage 0 0 663 451 Form Qt::Horizontal 40 20 false &Configure Skin false &Delete Skin <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Notice:</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You need to use Classic UI to use skin function.</p></body></html> kcm-fcitx-master/src/skinpage_p.h000066400000000000000000000120131433634536200173220ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include // Fcitx #include #include // self #include "subconfigparser.h" #include "skinpage.h" enum FillRule { F_COPY = 0, F_RESIZE = 1 }; struct SkinPlacement { char *name; int x; int y; }; struct SkinMainBar { char* backImg; char* eng; char* logo; char* active; int marginTop; int marginBottom; int marginLeft; int marginRight; FillRule fillV; FillRule fillH; char* placement; }; struct SkinInputBar { int fontSize; FcitxConfigColor inputColor; FcitxConfigColor indexColor; FcitxConfigColor firstCandColor; FcitxConfigColor otherColor; boolean respectDPI; char* backImg; FcitxConfigColor cursorColor; int marginTop; int marginBottom; int marginLeft; int marginRight; char* backArrow; char* forwardArrow; int iBackArrowX; int iBackArrowY; int iForwardArrowX; int iForwardArrowY; int iInputPos; int iOutputPos; FillRule fillV; FillRule fillH; }; struct SkinData { FcitxGenericConfig config; SkinMainBar mainbar; SkinInputBar inputbar; }; namespace Fcitx { class SkinInfo { public: QString name; QString path; QPixmap pixmap; }; class SkinPage::Private : public QObject { enum { PixmapRole = 0x4532efd3, PathRole = 0x3F213873 }; Q_OBJECT public: Private(QObject* parent = 0); virtual ~Private(); class SkinModel; class SkinDelegate; SkinModel* skinModel; QListView* skinView; QPushButton* configureSkinButton; QPushButton* deleteSkinButton; SkinDelegate* skinDelegate; Module* module; QLineEdit* skinField; public Q_SLOTS: void load(); void deleteSkin(); void configureSkin(); void save(); void currentSkinChanged(); Q_SIGNALS: void changed(); private: bool removeDir(const QString &dirName); SubConfigParser m_parser; SubConfig* m_subConfig; }; class SkinPage::Private::SkinModel : public QAbstractListModel { Q_OBJECT public: SkinModel(Private* d, QObject* parent = 0); QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; void setSkinList(const QStringList& list); const QList& skinList() const; private: QPixmap drawSkinPreview(const QString& path); void DrawResizableBackground( QPixmap &destPixmap, QPixmap &backgroundPixmap, int marginLeft, int marginRight, int marginTop, int marginBottom, int resizeWidth, int resizeHeight, FillRule fillV, FillRule fillH ); void DrawWidget( QPixmap &destPixmap, QPixmap &widgetPixmap, int x, int y ); QPixmap LoadImage(const char* skinDir, const char* fileName); QColor ConvertColor(FcitxConfigColor floatColor); Private* d; QList m_skins; }; class SkinPage::Private::SkinDelegate : public QStyledItemDelegate { Q_OBJECT public: SkinDelegate(QObject* parent = 0); ~SkinDelegate(); void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; signals: void regeneratePreview(const QModelIndex& index, const QSize& size) const; }; } kcm-fcitx-master/src/subconfig.cpp000066400000000000000000000134771433634536200175330ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include // self #include "subconfig.h" #include "subconfigpattern.h" #include "global.h" namespace Fcitx { QStringList getFilesByPattern(QDir& currentdir, const QStringList& filePatternList, int index) { QStringList result; if (!currentdir.exists()) return result; const QString& filter = filePatternList.at(index); QStringList filters; filters << filter; QDir::Filters filterflag; if (index + 1 == filePatternList.size()) { filterflag = QDir::Files; } else { filterflag = QDir::Dirs | QDir::NoDotAndDotDot; } QStringList list = currentdir.entryList(filters, filterflag); if (index + 1 == filePatternList.size()) { Q_FOREACH(const QString & item, list) { result << currentdir.absoluteFilePath(item); } } else { Q_FOREACH(const QString & item, list) { QDir dir(currentdir.absoluteFilePath(item)); result << getFilesByPattern(dir, filePatternList, index + 1); } } return result; } QSet getFiles(const QStringList& filePatternList, bool user) { size_t size; char** xdgpath; if (user) xdgpath = FcitxXDGGetPathUserWithPrefix(&size, ""); else xdgpath = FcitxXDGGetPathWithPrefix(&size, ""); QSet result; for (size_t i = 0; i < size; i ++) { QDir dir(xdgpath[i]); QStringList list = getFilesByPattern(dir, filePatternList, 0); Q_FOREACH(const QString & str, list) { result.insert( dir.relativeFilePath(str)); } } FcitxXDGFreePath(xdgpath); return result; } void SubConfig::parseConfigFileSubConfig(const SubConfigPattern* pattern) { m_fileList = getFiles(pattern->filePatternList(), false); m_configdesc = pattern->configdesc(); } void SubConfig::parseNativeFileSubConfig(const SubConfigPattern* pattern) { m_mimetype = pattern->mimetype(); m_nativepath = pattern->nativepath(); m_filePatternList = pattern->filePatternList(); updateFileList(); } void SubConfig::parsePluginSubConfig(const SubConfigPattern* pattern) { m_nativepath = pattern->nativepath(); } void SubConfig::updateFileList() { if (m_type == SC_NativeFile) { m_fileList = getFiles(m_filePatternList, false); m_userFileList = getFiles(m_filePatternList, true); } } void SubConfig::parseProgramSubConfig(const SubConfigPattern* pattern) { QString program = pattern->program(); if (pattern->program()[0] != '/') { program = QStandardPaths::findExecutable(pattern->program()); if (program.isEmpty()) { char* path = fcitx_utils_get_fcitx_path_with_filename("bindir", program.toUtf8().constData()); if (path) { program = path; free(path); } } } else { program = pattern->program(); } QFileInfo info(program); if (!info.isExecutable()) program = QString(); m_progam = program; } SubConfig::SubConfig(const QString& name, SubConfigPattern* pattern) : m_name(name), m_type(pattern->type()) { switch (pattern->type()) { case SC_ConfigFile: parseConfigFileSubConfig(pattern); break; case SC_NativeFile: parseNativeFileSubConfig(pattern); break; case SC_Program: parseProgramSubConfig(pattern); break; case SC_Plugin: parsePluginSubConfig(pattern); break; default: break; } } SubConfigType SubConfig::type() { return m_type; } const QString& SubConfig::name() const { return m_name; } const QString& SubConfig::configdesc() const { return m_configdesc; } const QString& SubConfig::nativepath() const { return m_nativepath; } const QString& SubConfig::program() const { return m_progam; } QSet< QString >& SubConfig::fileList() { return m_fileList; } QSet< QString >& SubConfig::userFileList() { return m_userFileList; } const QString& SubConfig::mimetype() const { return m_mimetype; } bool SubConfig::isValid() const { switch (m_type) { case SC_ConfigFile: return true; case SC_NativeFile: return true; case SC_Program: return !m_progam.isEmpty(); case SC_Plugin: return !Global::instance()->testWrapper(m_nativepath).isEmpty(); default: break; } return false; } } kcm-fcitx-master/src/subconfig.h000066400000000000000000000051151433634536200171660ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITXSUBCONFIG_H #define FCITXSUBCONFIG_H // Qt #include #include #include #include namespace Fcitx { class SubConfigPattern; enum SubConfigType { SC_None, SC_ConfigFile, SC_NativeFile, SC_Program, SC_Plugin }; class SubConfig { public: explicit SubConfig(const QString& name, SubConfigPattern* pattern); SubConfigType type(); QSet< QString >& fileList(); QSet< QString >& userFileList(); const QString& name() const; const QString& configdesc() const; const QString& nativepath() const; const QString& mimetype() const; const QString& program() const; bool isValid() const; void updateFileList(); private: void parseProgramSubConfig(const SubConfigPattern* pattern); void parseNativeFileSubConfig(const SubConfigPattern* pattern); void parseConfigFileSubConfig(const SubConfigPattern* pattern); void parsePluginSubConfig(const SubConfigPattern* pattern); QString m_name; SubConfigType m_type; QSet< QString > m_fileList; QSet< QString > m_userFileList; QString m_configdesc; QString m_nativepath; QString m_mimetype; QString m_progam; QStringList m_filePatternList; }; } #endif kcm-fcitx-master/src/subconfigparser.cpp000066400000000000000000000067011433634536200207400ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include // Fcitx #include // self #include "config.h" #include "subconfigpattern.h" #include "subconfigparser.h" namespace Fcitx { SubConfigParser::SubConfigParser(const QString& subConfigString, QObject* parent) : QObject(parent) { /* * format like: name:type:XXXXXXX,name:type:XXXXXXX * valid value contains: * :domain * :native:path * :configfile:path:configdesc * :program:path */ QStringList subConfigList = subConfigString.split(','); Q_FOREACH(const QString & str, subConfigList) { int i = str.indexOf(':'); if (i < 0) continue; QString namestr = str.section(':', 0, 0); if (namestr.length() == 0) continue; QString typestr = str.section(':', 1, 1); if (typestr == "domain") { m_domain = namestr; continue; } SubConfigType type = parseType(typestr); if (type == SC_None) continue; if (m_subConfigMap.count(namestr) > 0) continue; QString patternstr = str.section(':', 2, -1); SubConfigPattern* pattern = SubConfigPattern::parsePattern(type, patternstr, this); if (pattern == NULL) continue; m_subConfigMap[namestr] = pattern; } } SubConfigType SubConfigParser::parseType(const QString& str) { if (str == "native") { return SC_NativeFile; } if (str == "configfile") { return SC_ConfigFile; } if (str == "program") { return SC_Program; } if (str == "plugin") { return SC_Plugin; } return SC_None; } QStringList SubConfigParser::getSubConfigKeys() { return m_subConfigMap.keys(); } SubConfig* SubConfigParser::getSubConfig(const QString& key) { if (m_subConfigMap.count(key) != 1) return NULL; SubConfigPattern* pattern = m_subConfigMap[key]; SubConfig* subconfig = new SubConfig(key, pattern); return subconfig; } const QString& SubConfigParser::domain() const { return m_domain; } } kcm-fcitx-master/src/subconfigparser.h000066400000000000000000000042441433634536200204050ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITXSUBCONFIGPARSER_H #define FCITXSUBCONFIGPARSER_H // Qt #include #include #include #include #include #include // self #include "subconfig.h" namespace Fcitx { class SubConfigPattern; class SubConfig; class SubConfigParser : public QObject { Q_OBJECT public: SubConfigParser(const QString& subConfigString, QObject* parent = NULL); SubConfig* getSubConfig(const QString& key); QStringList getSubConfigKeys(); const QString& domain() const; protected: SubConfigType parseType(const QString& str); QSet getFiles(const QString& key, bool user); QStringList getFilesByPattern(QDir& dir, SubConfigPattern* pattern, int index = 0); QMap m_subConfigMap; QString m_domain; }; } #endif kcm-fcitx-master/src/subconfigpattern.cpp000066400000000000000000000112021433634536200211110ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include // self #include "subconfigpattern.h" namespace Fcitx { QStringList SubConfigPattern::parseFilePattern(const QString& pattern) { do { if (pattern.length() == 0 || pattern[0] == '/') break; QStringList filePatternlist = pattern.split('/'); if (filePatternlist.length() == 0) break; Q_FOREACH(const QString & str, filePatternlist) { if (str.length() == 0) break; if (str == ".") break; if (str == "..") break; } return filePatternlist; } while(0); return QStringList(); } SubConfigPattern* SubConfigPattern::parsePattern(Fcitx::SubConfigType type, const QString& p, QObject* parent) { switch (type) { case SC_ConfigFile: { QString pattern = p.section(':', 0, 0); QString configdesc = p.section(':', 1, 1); if (configdesc.isEmpty()) return NULL; QStringList filePatternlist = parseFilePattern(pattern); if (filePatternlist.length() == 0) return NULL; SubConfigPattern* result = new SubConfigPattern(type, parent); result->m_configdesc = configdesc; result->m_filePatternlist = filePatternlist; return result; } break; case SC_NativeFile: { QString pattern = p.section(':', 0, 0); if (pattern.indexOf('*') > 0) return NULL; QString mimetype = p.section(':', 1, 1); QStringList filePatternlist = parseFilePattern(pattern); if (filePatternlist.length() == 0) return NULL; SubConfigPattern* result = new SubConfigPattern(type, parent); if (!mimetype.isEmpty()) result->m_mimetype = mimetype; result->m_nativepath = pattern; result->m_filePatternlist = filePatternlist; return result; } break; case SC_Program: { QString pattern = p.section(':', 0, 0); if (pattern.isEmpty()) return NULL; SubConfigPattern* result = new SubConfigPattern(type, parent); result->m_progam = pattern; return result; } break; case SC_Plugin: { QString pattern = p.section(':', 0, 0); if (pattern.isEmpty()) return NULL; SubConfigPattern* result = new SubConfigPattern(type, parent); result->m_nativepath = pattern; return result; } break; default: return NULL; } return NULL; } SubConfigPattern::SubConfigPattern(Fcitx::SubConfigType type, QObject* parent) : QObject(parent) { m_type = type; } const QStringList& SubConfigPattern::filePatternList() const { return m_filePatternlist; } const QString& SubConfigPattern::configdesc() const { return m_configdesc; } const QString& SubConfigPattern::nativepath() const { return m_nativepath; } const QString& SubConfigPattern::program() const { return m_progam; } const QString& SubConfigPattern::mimetype() const { return m_mimetype; } SubConfigType SubConfigPattern::type() const { return m_type; } } kcm-fcitx-master/src/subconfigpattern.h000066400000000000000000000043361433634536200205700ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITXSUBCONFIGPATTERN_H #define FCITXSUBCONFIGPATTERN_H // Qt #include #include // self #include "subconfig.h" namespace Fcitx { class SubConfigPattern : public QObject { Q_OBJECT public: static SubConfigPattern* parsePattern(SubConfigType type, const QString& pattern, QObject* parent = NULL); const QStringList& filePatternList() const; const QString& configdesc() const; SubConfigType type() const; const QString& nativepath() const; const QString& program() const; const QString& mimetype() const; private: SubConfigPattern(Fcitx::SubConfigType type, QObject* parent = 0); static QStringList parseFilePattern(const QString& p); QStringList m_filePatternlist; QString m_configdesc; QString m_nativepath; QString m_mimetype; QString m_progam; SubConfigType m_type; }; } #endif kcm-fcitx-master/src/subconfigwidget.cpp000066400000000000000000000215201433634536200207230ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ // Qt #include #include #include #include #include // KDE #include #include #include #include #include // Fcitx #include // self #include "global.h" #include "configwidget.h" #include "subconfigparser.h" #include "subconfigwidget.h" #include "subconfigwidget_p.h" namespace Fcitx { ConfigFile::ConfigFile(const QString& path) : m_path(path) { } QString ConfigFile::name() { return m_path; } const QString& ConfigFile::path() const { return m_path; } ConfigFileItemModel::ConfigFileItemModel(QObject* parent): QAbstractListModel(parent) { } ConfigFileItemModel::~ConfigFileItemModel() { Q_FOREACH(ConfigFile * file, m_files) { delete file; } } QModelIndex ConfigFileItemModel::index(int row, int column, const QModelIndex& parent) const { Q_UNUSED(parent); return createIndex(row, column, (row < m_files.count()) ? (void*) m_files.at(row) : 0); } int ConfigFileItemModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return m_files.size(); } QVariant ConfigFileItemModel::data(const QModelIndex& index, int role) const { if (!index.isValid() || !index.internalPointer()) { return QVariant(); } ConfigFile *configfile = static_cast(index.internalPointer()); if (role == Qt::DisplayRole) return configfile->name(); return QVariant(); } void ConfigFileItemModel::addConfigFile(ConfigFile* configfile) { beginInsertRows(QModelIndex(), m_files.count(), m_files.count()); m_files << configfile; endInsertRows(); } SubConfigWidget::SubConfigWidget(SubConfig* subconfig, QWidget* parent) : QWidget(parent), m_subConfig(subconfig) { switch (subconfig->type()) { case SC_ConfigFile: { QVBoxLayout* hbox = new QVBoxLayout; setLayout(hbox); m_listView = new QListView; m_listView->setSelectionMode(QAbstractItemView::SingleSelection); m_model = new ConfigFileItemModel(this); Q_FOREACH(const QString & file, subconfig->fileList()) { m_model->addConfigFile(new ConfigFile(file)); } m_listView->setModel(m_model); hbox->addWidget(m_listView); QPushButton* pushButton = new QPushButton; pushButton->setIcon(QIcon::fromTheme("configure")); connect(pushButton, SIGNAL(clicked()), this, SLOT(openSubConfig())); hbox->addWidget(pushButton); } break; case SC_NativeFile: { QVBoxLayout* hbox = new QVBoxLayout; setLayout(hbox); QPushButton* pushButton = new QPushButton; pushButton->setIcon(QIcon::fromTheme("document-open")); connect(pushButton, SIGNAL(clicked()), this, SLOT(openNativeFile())); hbox->addWidget(pushButton); } break; case SC_Program: { QVBoxLayout* hbox = new QVBoxLayout; setLayout(hbox); QPushButton* pushButton = new QPushButton; pushButton->setIcon(QIcon::fromTheme("system-run")); if (subconfig->program().isNull()) pushButton->setEnabled(false); else connect(pushButton, SIGNAL(clicked()), this, SLOT(openProgram())); hbox->addWidget(pushButton); } break; case SC_Plugin: { QVBoxLayout* hbox = new QVBoxLayout; setLayout(hbox); QPushButton* pushButton = new QPushButton; pushButton->setIcon(QIcon::fromTheme("configure")); connect(pushButton, SIGNAL(clicked()), this, SLOT(openPlugin())); hbox->addWidget(pushButton); } break; default: break; } } SubConfigWidget::~SubConfigWidget() { delete m_subConfig; } void SubConfigWidget::openSubConfig() { QItemSelectionModel* selectionModel = m_listView->selectionModel(); QModelIndex ind = selectionModel->currentIndex(); if (!ind.isValid()) return; ConfigFile* configfile = static_cast(ind.internalPointer()); FcitxConfigFileDesc* cfdesc = Global::instance()->GetConfigDesc(m_subConfig->configdesc()); if (cfdesc) { QPointer configDialog(ConfigWidget::configDialog( NULL, cfdesc, "", configfile->path() )); configDialog->exec(); delete configDialog; } } bool SubConfigWidget::launchGuiWrapper(const QString &path) { QString wrapper = Global::instance()->testWrapper(path); if (!wrapper.isEmpty()) { QStringList args; args << path; return QProcess::startDetached(wrapper, args); } return false; } void SubConfigWidget::openPlugin() { launchGuiWrapper(m_subConfig->nativepath()); } void SubConfigWidget::openNativeFile() { char *newpath = NULL; if (launchGuiWrapper(m_subConfig->nativepath())) { return; } /* this configuration file doesn't have user version */ if (m_subConfig->userFileList().size() == 0) { /* still if system version doesn't exit either, let's create an empty text file for user */ if (m_subConfig->fileList().size() == 0) { FILE* fp = FcitxXDGGetFileUserWithPrefix("", m_subConfig->nativepath().toLocal8Bit().constData(), "w", &newpath); if (fp) { fclose(fp); m_subConfig->updateFileList(); } } else { switch(KMessageBox::questionYesNoCancel( NULL, i18n("User config doesn't exisits, do you want to open system file or copy system file to user file?"), i18n("What to do"), KGuiItem(i18n("Copy")), KGuiItem(i18n("View system")))) { case KMessageBox::Yes: { char* src = NULL; FILE* fp = FcitxXDGGetFileWithPrefix("", m_subConfig->fileList().begin()->toLocal8Bit().constData(), "r", &src); if (fp) fclose(fp); FcitxXDGGetFileUserWithPrefix("", m_subConfig->nativepath().toLocal8Bit().constData(), NULL, &newpath); QFile file(src); free(src); if (!file.copy(newpath)) { KMessageBox::error(NULL, i18n("Copy failed"), i18n("Copy failed")); } m_subConfig->updateFileList(); } break; case KMessageBox::No: { FILE* fp = FcitxXDGGetFileWithPrefix("", m_subConfig->fileList().begin()->toLocal8Bit().constData(), "r", &newpath); if (fp) fclose(fp); } break; default: return; } } } else { FILE* fp = FcitxXDGGetFileWithPrefix("", m_subConfig->userFileList().begin()->toLocal8Bit().constData(), "r", &newpath); if (fp) fclose(fp); } if (newpath) { #if KIO_VERSION < QT_VERSION_CHECK(5, 31, 0) KRun::runUrl(QUrl(newpath), m_subConfig->mimetype().isEmpty() ? "text/plain" : m_subConfig->mimetype(), NULL); #else KRun::runUrl(QUrl(newpath), m_subConfig->mimetype().isEmpty() ? "text/plain" : m_subConfig->mimetype(), NULL, KRun::RunFlags()); #endif free(newpath); } } void SubConfigWidget::openProgram() { KRun::runCommand(m_subConfig->program(), NULL); } } kcm-fcitx-master/src/subconfigwidget.h000066400000000000000000000037041433634536200203740ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITXCONFIGPAGE_P_H #define FCITXCONFIGPAGE_P_H // Qt #include class QListView; namespace Fcitx { class ConfigFileItemModel; class SubConfig; class SubConfigWidget : public QWidget { Q_OBJECT public: SubConfigWidget(SubConfig* subconfig, QWidget* parent = 0); virtual ~SubConfigWidget(); private slots: void openSubConfig(); void openNativeFile(); void openProgram(); void openPlugin(); private: bool launchGuiWrapper(const QString &path); SubConfig* m_subConfig; ConfigFileItemModel* m_model; QListView* m_listView; }; } #endif kcm-fcitx-master/src/subconfigwidget_p.h000066400000000000000000000042131433634536200207070ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2011~2011 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITXSUBCONFIGWIDGET_P_H #define FCITXSUBCONFIGWIDGET_P_H // Qt #include namespace Fcitx { class ConfigFile { public: ConfigFile(const QString& path); QString name(); const QString& path() const; private: QString m_path; }; class ConfigFileItemModel : public QAbstractListModel { Q_OBJECT public: ConfigFileItemModel(QObject* parent = 0); virtual ~ConfigFileItemModel(); QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; void addConfigFile(ConfigFile* configfile); private: QList m_files; }; } #endif kcm-fcitx-master/src/test/000077500000000000000000000000001433634536200160135ustar00rootroot00000000000000kcm-fcitx-master/src/test/CMakeLists.txt000066400000000000000000000020371433634536200205550ustar00rootroot00000000000000include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_BINARY_DIR}/src) kde4_add_executable(testconfigpage testconfigpage.cpp ../global.cpp ../configwidget.cpp ../subconfig.cpp ../subconfigparser.cpp ../subconfigpattern.cpp ../subconfigwidget.cpp ../dummyconfig.cpp ../verticalscrollarea.cpp ../fontbutton.cpp ../plugindialog.cpp ) target_link_libraries(testconfigpage ${KDE4_KDEUI_LIBRARY} ${KDE4_KIO_LIBS} ${FCITX4_FCITX_UTILS_LIBRARIES} ${FCITX4_FCITX_CONFIG_LIBRARIES} ${FCITX_QT_LIBRARIES} ) kde4_add_executable(testdummyconfig testdummyconfig.cpp ../global.cpp ../dummyconfig.cpp ../verticalscrollarea.cpp ) target_link_libraries(testdummyconfig ${KDE4_KDEUI_LIBRARY} ${KDE4_KIO_LIBS} ${FCITX4_FCITX_UTILS_LIBRARIES} ${FCITX4_FCITX_CONFIG_LIBRARIES} ${FCITX_QT_LIBRARIES} ) kde4_add_executable(testfontbutton testfontbutton.cpp ../fontbutton.cpp ) target_link_libraries(testfontbutton ${KDE4_KDEUI_LIBRARY} ) kcm-fcitx-master/src/test/testconfigpage.cpp000066400000000000000000000005551433634536200215260ustar00rootroot00000000000000#include #include "configwidget.h" #include "global.h" int main(int argc, char* argv[]) { QApplication a(argc, argv); FcitxConfigFileDesc* cfdesc = Fcitx::Global::instance()->GetConfigDesc("config.desc"); Fcitx::ConfigWidget configPage(cfdesc, "", "config"); configPage.load(); configPage.show(); a.exec(); return 0; }kcm-fcitx-master/src/test/testdummyconfig.cpp000066400000000000000000000007461433634536200217470ustar00rootroot00000000000000#include #include #include "dummyconfig.h" #include "global.h" int main(int argc, char* argv[]) { QCoreApplication a(argc, argv); FcitxConfigFileDesc* cfdesc = Fcitx::Global::instance()->GetConfigDesc("config.desc"); Fcitx::DummyConfig* dummyConfig = new Fcitx::DummyConfig(cfdesc); dummyConfig->load(NULL); delete dummyConfig; Fcitx::Global::deInit(); QTimer::singleShot(0, &a, SLOT(quit())); a.exec(); return 0; } kcm-fcitx-master/src/test/testfontbutton.cpp000066400000000000000000000030531433634536200216220ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include "fontbutton.h" int main(int argc, char* argv[]) { QApplication a(argc, argv); FontButton button; button.show(); a.exec(); return 0; }kcm-fcitx-master/src/uipage.cpp000066400000000000000000000051001433634536200170060ustar00rootroot00000000000000#include "uipage.h" #include "module.h" #include "configwidget.h" #include "global.h" #include "skinpage.h" #include "dummyconfig.h" #include #include #include #include #include Fcitx::UIPage::UIPage(Fcitx::Module* parent) : QWidget(parent) ,m_module(parent) ,m_layout(new QVBoxLayout(this)) ,m_label(new QLabel(i18n("Cannot load currently used user interface info"), this)) ,m_widget(0) { setLayout(m_layout); m_layout->addWidget(m_label); if (Global::instance()->inputMethodProxy()) { QDBusPendingReply< QString > reply = Global::instance()->inputMethodProxy()->GetCurrentUI(); QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(getUIFinished(QDBusPendingCallWatcher*))); } } void Fcitx::UIPage::getUIFinished(QDBusPendingCallWatcher* watcher) { QDBusPendingReply reply(*watcher); if (!reply.isValid()) return; QString name = reply.value(); FcitxAddon* addon = m_module->findAddonByName(name); if (addon) { FcitxConfigFileDesc* cfdesc = Global::instance()->GetConfigDesc(QString::fromUtf8(addon->name).append(".desc")); bool configurable = (bool)(cfdesc != NULL || strlen(addon->subconfig) != 0); if (configurable) { m_label->hide(); m_widget = new ConfigWidget(addon, this); m_layout->addWidget(m_widget); connect(m_widget, SIGNAL(changed()), this, SIGNAL(changed())); } else { m_label->setText(i18n("No configuration options for %1.").arg(QString::fromUtf8(addon->generalname))); } if (name == "fcitx-classic-ui") { do { FcitxConfigOption* option = FcitxConfigFileGetOption(m_widget->config()->genericConfig()->configFile, "ClassicUI", "SkinType"); // this should not happen, but ,we just protect it if (!option) break; // this should not happen, but ,we just protect it QLineEdit* lineEdit = static_cast(option->filterArg); if (!lineEdit) break; m_module->skinPage()->setSkinField(lineEdit); } while(0); } } } void Fcitx::UIPage::load() { if (m_widget) m_widget->load(); } void Fcitx::UIPage::save() { if (m_widget) m_widget->buttonClicked(QDialogButtonBox::Ok); } Fcitx::UIPage::~UIPage() { } kcm-fcitx-master/src/uipage.h000066400000000000000000000036771433634536200164740ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef FCITX_UI_PAGE_H #define FCITX_UI_PAGE_H // Qt #include #include // self #include class QLabel; class QVBoxLayout; namespace Fcitx { class ConfigWidget; class Module; class UIPage : public QWidget { Q_OBJECT public: UIPage(Module* parent = 0); virtual ~UIPage(); Q_SIGNALS: void changed(); public Q_SLOTS: void save(); void load(); void getUIFinished(QDBusPendingCallWatcher* watcher); private: Module* m_module; QVBoxLayout* m_layout; QLabel* m_label; ConfigWidget* m_widget; }; } #endif kcm-fcitx-master/src/verticalscrollarea.cpp000066400000000000000000000037321433634536200214260ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include "verticalscrollarea.h" namespace Fcitx { VerticalScrollArea::VerticalScrollArea(QWidget *parent) : QScrollArea(parent) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } void VerticalScrollArea::setWidget(QWidget* widget) { QScrollArea::setWidget(widget); widget->installEventFilter(this); } bool VerticalScrollArea::eventFilter(QObject *o, QEvent *e) { if(o == widget() && e->type() == QEvent::Resize) setMinimumWidth(widget()->minimumSizeHint().width() + verticalScrollBar()->width()); return false; } }kcm-fcitx-master/src/verticalscrollarea.h000066400000000000000000000033261433634536200210720ustar00rootroot00000000000000/*************************************************************************** * Copyright (C) 2012~2012 by CSSlayer * * * * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef VERTICALSCROLLAREA_H #define VERTICALSCROLLAREA_H #include namespace Fcitx { class VerticalScrollArea : public QScrollArea { Q_OBJECT public: explicit VerticalScrollArea(QWidget* parent = 0); void setWidget(QWidget *widget); protected: bool eventFilter(QObject* o, QEvent* e) override; }; } #endif // VERTICALSCROLLAREA_H