pax_global_header00006660000000000000000000000064132125220760014512gustar00rootroot0000000000000052 comment=ea044b7bf96dee194b276d081788af400e5c3519 qlipper-5.1.1/000077500000000000000000000000001321252207600131725ustar00rootroot00000000000000qlipper-5.1.1/CHANGELOG000066400000000000000000000144621321252207600144130ustar00rootroot000000000000005.1.1 / 2017-12-08 ================== * Increase version (forgotten in previous release) * travis: Fix the build 5.1.0 / 2017-12-07 ================== * Updated CHANGELOG * Added .gitignore and .gitattributes * build: Require Qt v5.6 * Added Lithuanian translation * added Polish translation to CMakeLists * added Polish translation * Make LXQt-Autostart optional * Added merged autostart to CMakeLists.txt * Added Catalan translation to CMake list * Add Catalan translation * Synchronized Chinese (simplified) translation from latest source * Added Chinese (simplified) translation to CMake list * Added Chinese (simplified) translation * Updated *_da.desktop files and removed *_da_DK.desktop files * systray: Don't display clipboard items in context menu * travis-ci: Update the PPA for pulling Qt * Add ability to change tray icon. * preferences: Cleanup&sort items in preferences dialog * main: Use std::lock_guard * fixup...do the locking correctly * build: Require C++11 * Allow only one instance of application * build: Remove QtSingleApplication as not used * Add instant clipboards synchronization * Fix build with ENABLE_NETWORK_CLIPBOARD_SHARING enabled. * qlipperitem: Handle different type as equal * Update desktop entries and Replace fr_FR by fr * Update Greek translation (el) Remove country variant from language code * CMake: Adds Runtime and Devel install COMPONENTs * Coding style changes * Updates the build system to use the Targets infrastructure * lxqt-qlipper-autostart: added X-LXQt-Need-Tray key * Drops hardcoded /etc/xdg paths * Updated german translation, replaced Qt4 by Qt in all xsession/translations * Renames some .desktop files * Updates translations infrastructure * Update the required minimum cmake version * remove dead template lines switch OnlyShowIn from Razor -> LXQt stringchanges LxQt -> LXQt * Support lxqt-session and add necessary xdg autostart desktop entry files. * Add default configuration files for lxde-qt session 5.0.0 / 2016-11-02 ================== * Added CHANGELOG * Make history items synchronization configurable * model: Update model behaviour * model: Fix setting current item * Travis: Adds Clang to the compiler list * signalhandler: Quit gracefully on unix signals * travis-ci: Initial configuration file * Bump copyright year in about to 2016 * Merge pull request #37 from ufleisch/emacs * Do not prevent Emacs from using clipboard, only store mime data, #35. * Merge pull request #33 from palinek/gimp_crash_fix * item: Workaround possible gimp crash * windows: executable icon * compilation fix on windows. QXT_GUI_EXPORT commented out * Merge pull request #29 from stefonarch/patch-1 * Merge pull request #28 from pmattern/transl-de * Update qlipper_it.ts * Add German translation * Merge pull request #27 from agaida/patch-1 * Fix Qt5.5 compilation * Merge pull request #23 from palinek/clip_wrap_gtk_fix * use QClipboard wrapper to fix multiple issues * Merge pull request #21 from palinek/prim_synchr * added option to synchronize primary selection & clipboard * Merge branch 'master' of github.com:pvanek/qlipper * implemented #14 Option to flush the list when closing the session * Merge pull request #18 from stefonarch/master * prova * Merge pull request #16 from paulolieuthier/master * change the adress in prefrences dialog to github * translation loading fixed (ts files use underscore in names) * increase max-items-count in the config * Install the app icon to the hicolor theme * fixed missing global keyboard shortcut in Qt5 * Merge pull request #11 from luis-pereira/make-it-compile * Make it build * Remove reference to non existent source file * qt5 migration initial changes (broken, uncompilable) * larger icon for #16 Please ship a larger icon for Qlipper * Merge pull request #3 from kensington/master * Include system QtSingleApplication headers when using external build. 2.0.2 / 2013-07-29 ================== * version bump * Merge pull request #1 from siduction/master * Added qxt search path for debian based systems * mail address changed * fixed: #13: please use libxqt from system, not bundled * Czech language file update. * fix build on new linuxes * build fixes * Moc only Q_OBJECT classes * Replaces QApplication by QtSingleApplication * Adds qtsingleapplications files to the build system * Refactors ENABLE_NETWORK stuff * Adds QtSolutions LICENSE * Import part of qtsingleapplication from QtSolutions * fix for prefs gui (init showcase) * make network support optional (and experimental) * Merge branch 'master' of gitorious.org:qlipper/qlipper * fix non-ascii characters restoring from saved history * compilation fixes for linux * accept only data from differen machines (not own broadcasts) * optional network broadcast implemented * cmake build based now; so long qmake * Merge branch 'master' of gitorious.org:qlipper/qlipper * fixed #8: Left mouse menu is hidden behind systray. * fixes for "platform specific" features (missing mode) * icon displaying and storage * version bump * another os2 try * another fixes for os2 * qxt fixes for OS2 * reimplementation of clipboard handling and backend storage - it can keep all mimetypes now (office, media...) * install fix * make release for buggy qmake * bold font optimization * highlight current clipboard fix; do not copy sticky to dynamic is it's not necessary * highlight current item * fix for trimmed vs trim only end of lines * serbian translations by Mladen Pejaković * fixed Issue 6: qlipper won't paste copied text after application exits * don't display window decoration for standalone menu * fix for empty models for free window * potential fix for Issue 7: Does not compile under Windows XP * licensing * fix for settings to enum reading * proper image/url handling * size prefs window on mac * better src code organization * translations; mac files; etc. * show menu on all mouse clicks * tooltips * version mark; TODO resolved * close shortcut window too * preferences simplified; icon drawing * prefs; tunning * progress: sticky and dynamic save/restore; mac timer; preferences * progress in implementation: sticky, icons... * initial revision of qlipper rework qlipper-5.1.1/CMakeLists.txt000066400000000000000000000235171321252207600157420ustar00rootroot00000000000000# CMakeLists.txt # ------------------------------------------------------- # An initial version of the cmake build for qlipper. # WORK IN PROGRESS. USE qmake STILL FOR NOW, PLEASE! # Currently tested on unix only. # ------------------------------------------------------- # UNIX - usage (for OSX see below) # 1. cd qlipper/root/dir # 2. mkdir build # 3. cd build # 4. cmake ../qlipper-git -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=debug (or release, by default) # 5. make # 6. make install # ------------------------------------------------------- # WINDOWS - usage # You have to have MinGW installed (it works with MinGW). If you use different compiler, then "make" steps will differ. # You have to have CMake installed. # I recommend using cmake-gui to generate and configure MakeFiles like this. # 1. Run cmake-gui and select folder which contains top-level CMakelists.txt file into "Where the is source code" box. This can be also done in command line via simpler cmake.exe. # 2. Select folder which you want to contain compiled binaries into "Where to build the binaries" box. # 3. Hit Configure button (make any changes to variables first) and select MinGW Makefiles as generator. Choose "Specify native compilers". # 4. Now input path to C++ compiler. For example "C:/QtSDK/mingw/bin/g++.exe", then hit "Finish". # 5. Project will configure now, hit "Configure" button again. Then hit "Generate" button and close cmake-gui. # 6. Run your command line as ADMINISTRATOR and navigate to your "Where to build the binaries" folder. # 7. Run "mingw32-make.exe" command. Note that -j3 parameter may speed-up building. Your files gets compiled now. # 8. Run "mingw32-make.exe install" command. Your files gets copied into directory specified by CMAKE_INSTALL_PREFIX variable. # 9. You are done. # 10. Run "make install" to install application to CMAKE_INSTALL_PREFIX (which is se to C:\Program Files\qlipper\ by default - can be changed in step 3). # ------------------------------------------------------- # MAC OS X # 1. cd qlipper/root/dir # 2. mkdir build # 3. cd build # 4. cmake ../qlipper-git -DCMAKE_INSTALL_PREFIX=../release -DCMAKE_BUILD_TYPE=debug (or release, by default) # 5. make # 6. make install # now is the qlipper.app bundle created. But it can run only in current machine. # If you need "redistributable" binary call: # 7. make bundle # It will copy all dependecies (libs/resources) into bundle tree # ------------------------------------------------------- CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0) project(qlipper) set(QLIPPER_VERSION 5.1.1) option(ENABLE_NETWORK_CLIPBOARD_SHARING "Enables experimental network support for clipboard sharing" OFF) option(ENABLE_LXQT_AUTOSTART "Enables autostart for LXQt" OFF) option(USE_SYSTEM_QXT "Use system Qxt Library for global shortcuts; off for Qt5" OFF) LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) find_package(Qt5Widgets "5.6" REQUIRED) find_package(Qt5LinguistTools REQUIRED) if (USE_SYSTEM_QXT) find_package(Qxt) message(STATUS "Use system Qxt Library: " ${USE_SYSTEM_QXT}) if (USE_SYSTEM_QXT AND NOT QXT_FOUND) message(FATAL_ERROR "System Qxt not found") endif () endif() set(EXE_NAME "qlipper") if (APPLE) set(EXE_NAME "QLipper") endif (APPLE) add_definitions(-DIS_CMAKE) add_definitions(-DQLIPPER_VERSION="${QLIPPER_VERSION}") if (ENABLE_NETWORK_CLIPBOARD_SHARING) add_definitions(-DENABLE_NETWORK_CLIPBOARD_SHARING) endif (ENABLE_NETWORK_CLIPBOARD_SHARING) # source code and compilation set (QLIPPER_HEADERS qkeysequencewidget/qkeysequencewidget.h qkeysequencewidget/qkeysequencewidget_p.h qmenuview/qmenuview.h qmenuview/qmenuview_p.h src/qlippermodel.h src/qlipperpreferencesdialog.h src/qlippersystray.h src/qlippernetwork.h src/clipboardwrap.h ) set (QLIPPER_SOURCES qkeysequencewidget/qkeysequencewidget.cpp qmenuview/qmenuview.cpp src/main.cpp src/qlipperitem.cpp src/qlippermodel.cpp src/qlipperpreferences.cpp src/qlipperpreferencesdialog.cpp src/qlippersystray.cpp src/qlippernetwork.cpp src/clipboardwrap.cpp ) if (WIN32) set(QLIPPER_SOURCES ${QLIPPER_SOURCES} src/icons/qlipper.rc) endif (WIN32) if (UNIX) list(APPEND QLIPPER_HEADERS src/signalhandler.h) list(APPEND QLIPPER_SOURCES src/signalhandler.cpp) endif (UNIX) if (NOT QXT_FOUND) set (HAVE_QXT 1) if (APPLE) set (QLIPPER_SOURCES ${QLIPPER_SOURCES} qxt/qxtglobalshortcut_mac.cpp) elseif (WIN32) set (QLIPPER_SOURCES ${QLIPPER_SOURCES} qxt/qxtglobalshortcut_win.cpp) elseif (UNIX) set (QLIPPER_SOURCES ${QLIPPER_SOURCES} qxt/qxtglobalshortcut_x11.cpp) include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS}) else () set (HAVE_QXT 0) add_definitions(-DNO_QXT) endif () if (HAVE_QXT) set (QLIPPER_SOURCES ${QLIPPER_SOURCES} qxt/qxtglobalshortcut.cpp ) set (QLIPPER_HEADERS ${QLIPPER_HEADERS} qxt/qxtglobalshortcut.h ) endif (HAVE_QXT) endif (NOT QXT_FOUND) if (APPLE) set (QLIPPER_SOURCES ${QLIPPER_SOURCES} macosx/qlipper.icns) FIND_LIBRARY(CARBON_LIBRARY Carbon REQURED) MESSAGE(STATUS "CARBON_LIBRARY: ${CARBON_LIBRARY}") elseif (UNIX) FIND_PACKAGE(X11 REQUIRED) MESSAGE(STATUS "X11_X11_LIB: ${X11_X11_LIB}") endif () set (QLIPPER_FORMS src/qlipperpreferencesdialog.ui ) set (QLIPPER_RESOURCES src/qlipper.qrc ) set (QLIPPER_TRANSLATIONS ts/qlipper_ca.ts ts/qlipper_cs.ts ts/qlipper_de.ts ts/qlipper_lt.ts ts/qlipper_pl.ts ts/qlipper_sr.ts ts/qlipper_it.ts ts/qlipper_zh_CN.ts ) QT5_WRAP_UI( QLIPPER_UI ${QLIPPER_FORMS} ) QT5_WRAP_CPP( QLIPPER_MOC ${QLIPPER_HEADERS} ) QT5_ADD_RESOURCES( QLIPPER_RCC ${QLIPPER_RESOURCES} ) QT5_ADD_TRANSLATION( QLIPPER_QM ${QLIPPER_TRANSLATIONS} ) include_directories ( ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/qkeysequencewidget ${CMAKE_CURRENT_SOURCE_DIR}/qxt ${CMAKE_CURRENT_SOURCE_DIR}/qmenuview ) if (NOT QXT_FOUND) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/qxt) endif (NOT QXT_FOUND) add_executable( ${EXE_NAME} WIN32 MACOSX_BUNDLE ${QLIPPER_SOURCES} ${QLIPPER_UI} ${QLIPPER_MOC} ${QLIPPER_RCC} ${QLIPPER_QM} ) set_property(TARGET ${EXE_NAME} PROPERTY CXX_STANDARD 11) set_property(TARGET ${EXE_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) target_link_libraries( ${EXE_NAME} Qt5::Widgets ) # single app and optional network features #target_link_libraries( ${EXE_NAME} ${QT_QTNETWORK_LIBRARY}) if (APPLE) target_link_libraries(${EXE_NAME} ${CARBON_LIBRARY}) elseif (UNIX) target_link_libraries(${EXE_NAME} ${X11_X11_LIB}) endif () if (QXT_FOUND) target_link_libraries(${EXE_NAME} ${QXT_CORE_LIB} ${QXT_GUI_LIB}) endif (QXT_FOUND) # installation if (APPLE) # mac's bundle install SET_TARGET_PROPERTIES(${EXE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/macosx/Info.plist.in") SET(MACOSX_BUNDLE_ICON_FILE qlipper.icns) SET(MACOSX_BUNDLE_INFO_STRING "${EXE_NAME} ${QLIPPER_VERSION}") SET(MACOSX_BUNDLE_GUI_IDENTIFIER "cz.yarpen.qlipper") SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${QLIPPER_VERSION}") SET(MACOSX_BUNDLE_BUNDLE_NAME "${EXE_NAME}") SET(MACOSX_BUNDLE_SHORT_VERSION_STRING "${QLIPPER_VERSION}") SET(MACOSX_BUNDLE_BUNDLE_VERSION "${QLIPPER_VERSION}") SET(MACOSX_BUNDLE_COPYRIGHT "(c) Petr Vanek") SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/macosx/qlipper.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) INSTALL(TARGETS ${EXE_NAME} BUNDLE DESTINATION ${CMAKE_INSTALL_PREFIX}) install(FILES ${QLIPPER_QM} DESTINATION ${CMAKE_INSTALL_PREFIX}/${EXE_NAME}.app/Contents/Resources/translations) # create a "transportable" bundle - all libs into the bundle: "make bundle" after make install configure_file(macosx/bundle.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/bundle.cmake @ONLY) add_custom_target(bundle ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/bundle.cmake) elseif (WIN32) install(TARGETS ${EXE_NAME} RUNTIME DESTINATION ./) install(FILES ${QLIPPER_QM} DESTINATION ./translations) elseif (UNIX) install(TARGETS ${EXE_NAME} RUNTIME DESTINATION bin) install(FILES qlipper.desktop DESTINATION share/applications) install(FILES src/icons/qlipper.png DESTINATION share/icons/hicolor/128x128/apps) install(FILES ${QLIPPER_QM} DESTINATION share/qlipper/translations) add_definitions(-DTRANSLATION_DIR="${CMAKE_INSTALL_PREFIX}/share/qlipper/translations") endif () # make dist custom target SET(CPACK_PACKAGE_NAME "qlipper") SET(CPACK_PACKAGE_VERSION ${QLIPPER_VERSION}) SET(CPACK_SOURCE_GENERATOR "TBZ2") SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") SET(CPACK_IGNORE_FILES "/CVS/;/\\\\.svn/;/\\\\.git/;\\\\.swp$;\\\\.#;/#;\\\\.tar.gz$;/CMakeFiles/;CMakeCache.txt;\\\\.qm$;/build/;/release/;\\\\.diff$;.DS_Store'") SET(CPACK_SOURCE_IGNORE_FILES ${CPACK_IGNORE_FILES}) INCLUDE(CPack) # simulate autotools' "make dist" add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) # make lupdate # it generates new translation files add_custom_target(lupdate ${QT_QMAKE_EXECUTABLE} -project -o ${CMAKE_CURRENT_BINARY_DIR}/qlipper.pro COMMAND ${QT_LUPDATE_EXECUTABLE} -noobsolete ${CMAKE_CURRENT_BINARY_DIR}/qlipper.pro WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) # lrelease add_custom_target(lrelease ${QT_QMAKE_EXECUTABLE} -project -o ${CMAKE_CURRENT_BINARY_DIR}/qlipper.pro COMMAND ${QT_LRELEASE_EXECUTABLE} -compress ${CMAKE_CURRENT_BINARY_DIR}/qlipper.pro WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) # merged from lxqt-common if (ENABLE_LXQT_AUTOSTART) set(LXQTBT_MINIMUM_VERSION "0.3.2") find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED) include(LXQtConfigVars) include(LXQtTranslateDesktop) add_subdirectory(lxqt-autostart) endif () qlipper-5.1.1/COPYING000066400000000000000000000354351321252207600142370ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU 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 qlipper-5.1.1/README000066400000000000000000000005741321252207600140600ustar00rootroot00000000000000Lightweight and cross-platform clipboard history applet. Petr Vanek This application is a part of QtDesktop project so you can download prebuilt binary packages from its repository. It's improved version of original Qlipper which is available only as a download from qt-apps.org. This SW can be used on Linux, BSD, MS Windows, and Mac OS X. License: GPLv2+ qlipper-5.1.1/cmake/000077500000000000000000000000001321252207600142525ustar00rootroot00000000000000qlipper-5.1.1/cmake/FindQxt.cmake000066400000000000000000000027131321252207600166340ustar00rootroot00000000000000# QXT_FOUND # QXT_INCLUDE_PATH # QXT_CORE_LIB # QXT_GUI_LIB IF (WIN32) FIND_PATH( QXT_INCLUDE_PATH QxtCore $ENV{PROGRAMFILES}/QxtCore PATHS/include/ DOC "The directory where QxtCore resides") FIND_LIBRARY( QXT_CORE_LIB NAMES QxtCore PATHS/lib $ENV{PROGRAMFILES}/lib DOC "The Qxt core library") FIND_LIBRARY( QXT_GUI_LIB NAMES QxtGui PATHS/lib $ENV{PROGRAMFILES}/lib DOC "The Qxt gui library") ELSE (WIN32) FIND_PATH( QXT_INCLUDE_PATH QxtCore /usr/include /usr/include/qxt /usr/local/include /sw/include /opt/local/include DOC "The directory where QxtCore resides") FIND_LIBRARY( QXT_CORE_LIB NAMES QxtCore PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /sw/lib /opt/local/lib DOC "The Qxt core library") FIND_LIBRARY( QXT_GUI_LIB NAMES QxtGui PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /sw/lib /opt/local/lib DOC "The Qxt gui library") ENDIF (WIN32) IF (QXT_INCLUDE_PATH) SET( QXT_FOUND 1 CACHE STRING "Set to 1 if QXT is found, 0 otherwise") ELSE (QXT_INCLUDE_PATH) SET( QXT_FOUND 0 CACHE STRING "Set to 1 if QXT is found, 0 otherwise") ENDIF (QXT_INCLUDE_PATH) SET( QXT_LIBS ${QXT_CORE_LIB} ${QXT_GUI_LIB} ) MARK_AS_ADVANCED( QXT_FOUND ) qlipper-5.1.1/lxqt-autostart/000077500000000000000000000000001321252207600162065ustar00rootroot00000000000000qlipper-5.1.1/lxqt-autostart/CMakeLists.txt000066400000000000000000000007041321252207600207470ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) file(GLOB DESKTOP_FILES_IN *.desktop.in) # Translations ********************************** lxqt_translate_desktop(DESKTOP_FILES SOURCES ${DESKTOP_FILES_IN} ) add_custom_target(autostart_desktop_files ALL DEPENDS ${DESKTOP_FILES}) #************************************************ install(FILES ${DESKTOP_FILES} DESTINATION "${LXQT_ETC_XDG_DIR}/autostart" COMPONENT Runtime ) qlipper-5.1.1/lxqt-autostart/lxqt-qlipper-autostart.desktop.in000066400000000000000000000002221321252207600246700ustar00rootroot00000000000000[Desktop Entry] Type=Application Name=Qlipper TryExec=qlipper Exec=qlipper OnlyShowIn=LXQt; X-LXQt-Need-Tray=true #TRANSLATIONS_DIR=translations qlipper-5.1.1/lxqt-autostart/translations/000077500000000000000000000000001321252207600207275ustar00rootroot00000000000000qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ar.desktop000066400000000000000000000000621321252207600274700ustar00rootroot00000000000000# Translations Name[ar]=ذاكرة الحافظة qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_cs.desktop000066400000000000000000000000421321252207600274710ustar00rootroot00000000000000# Translations Name[cs]=Schránka qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_cs_CZ.desktop000066400000000000000000000000451321252207600300700ustar00rootroot00000000000000# Translations Name[cs_CZ]=Schránka qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_da.desktop000066400000000000000000000000401321252207600274460ustar00rootroot00000000000000# Translations Name[da]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_de.desktop000066400000000000000000000001211321252207600274520ustar00rootroot00000000000000# Translations Name[de]=Zwischenablage Comment[de]=Verwaltung der Zwischenablage qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_el.desktop000066400000000000000000000000401321252207600274620ustar00rootroot00000000000000# Translations Name[el]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_eo.desktop000066400000000000000000000000401321252207600274650ustar00rootroot00000000000000# Translations Name[eo]=Qlipilo qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_es.desktop000066400000000000000000000000401321252207600274710ustar00rootroot00000000000000# Translations Name[es]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_es_VE.desktop000066400000000000000000000000431321252207600300660ustar00rootroot00000000000000# Translations Name[es_VE]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_eu.desktop000066400000000000000000000000401321252207600274730ustar00rootroot00000000000000# Translations Name[eu]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_fi.desktop000066400000000000000000000000401321252207600274600ustar00rootroot00000000000000# Translations Name[fi]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_fr.desktop000066400000000000000000000000401321252207600274710ustar00rootroot00000000000000# Translations Name[fr]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_hu.desktop000066400000000000000000000000171321252207600275020ustar00rootroot00000000000000# Translations qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ia.desktop000066400000000000000000000000171321252207600274570ustar00rootroot00000000000000# Translations qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_id_ID.desktop000066400000000000000000000000431321252207600300350ustar00rootroot00000000000000# Translations Name[id_ID]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_it_IT.desktop000066400000000000000000000000431321252207600300750ustar00rootroot00000000000000# Translations Name[it_IT]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ja.desktop000066400000000000000000000000401321252207600274540ustar00rootroot00000000000000# Translations Name[ja]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ko.desktop000066400000000000000000000000171321252207600274770ustar00rootroot00000000000000# Translations qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_lt.desktop000066400000000000000000000000401321252207600275010ustar00rootroot00000000000000# Translations Name[lt]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_nl.desktop000066400000000000000000000000411321252207600274740ustar00rootroot00000000000000# Translations Name[nl]=Qlembord qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_pl_PL.desktop000066400000000000000000000000431321252207600300730ustar00rootroot00000000000000# Translations Name[pl_PL]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_pt.desktop000066400000000000000000000000401321252207600275050ustar00rootroot00000000000000# Translations Name[pt]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_pt_BR.desktop000066400000000000000000000000431321252207600300730ustar00rootroot00000000000000# Translations Name[pt_BR]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ro_RO.desktop000066400000000000000000000000431321252207600301050ustar00rootroot00000000000000# Translations Name[ro_RO]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ru.desktop000066400000000000000000000000461321252207600275160ustar00rootroot00000000000000# Translations Name[ru]=Qлиппер qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_ru_RU.desktop000066400000000000000000000000431321252207600301210ustar00rootroot00000000000000# Translations Name[ru_RU]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_sl.desktop000066400000000000000000000000401321252207600275000ustar00rootroot00000000000000# Translations Name[sl]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_sr.desktop000066400000000000000000000000511321252207600275100ustar00rootroot00000000000000# Translations Name[sr]=Кјулипер qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_sr@ijekavian.desktop000066400000000000000000000000441321252207600314740ustar00rootroot00000000000000Name[sr@ijekavian]=Кјулипер qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_sr@ijekavianlatin.desktop000066400000000000000000000000411321252207600325210ustar00rootroot00000000000000Name[sr@ijekavianlatin]=Kjuliper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_sr@latin.desktop000066400000000000000000000000471321252207600306450ustar00rootroot00000000000000# Translations Name[sr@latin]=Kjuliper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_th_TH.desktop000066400000000000000000000000431321252207600300730ustar00rootroot00000000000000# Translations Name[th_TH]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_tr.desktop000066400000000000000000000000401321252207600275070ustar00rootroot00000000000000# Translations Name[tr]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_uk.desktop000066400000000000000000000000401321252207600275010ustar00rootroot00000000000000# Translations Name[uk]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_zh_CN.GB2312.desktop000066400000000000000000000000171321252207600306660ustar00rootroot00000000000000# Translations qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_zh_CN.desktop000066400000000000000000000000431321252207600300660ustar00rootroot00000000000000# Translations Name[zh_CN]=Qlipper qlipper-5.1.1/lxqt-autostart/translations/lxqt-qlipper-autostart_zh_TW.desktop000066400000000000000000000000451321252207600301220ustar00rootroot00000000000000# Translations Name[zh_TW]=剪貼簿 qlipper-5.1.1/macosx/000077500000000000000000000000001321252207600144645ustar00rootroot00000000000000qlipper-5.1.1/macosx/Info.plist.in000066400000000000000000000026541321252207600170500ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable ${MACOSX_BUNDLE_EXECUTABLE_NAME} CFBundleGetInfoString ${MACOSX_BUNDLE_INFO_STRING} CFBundleIconFile ${MACOSX_BUNDLE_ICON_FILE} CFBundleIdentifier ${MACOSX_BUNDLE_GUI_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString ${MACOSX_BUNDLE_LONG_VERSION_STRING} CFBundleName ${MACOSX_BUNDLE_BUNDLE_NAME} CFBundlePackageType APPL CFBundleShortVersionString ${MACOSX_BUNDLE_SHORT_VERSION_STRING} CFBundleSignature ???? CFBundleVersion ${MACOSX_BUNDLE_BUNDLE_VERSION} CSResourcesFileMapped LSRequiresCarbon NSHumanReadableCopyright ${MACOSX_BUNDLE_COPYRIGHT} NOTE Icon is disabled from dock. Only systray is used. LSUIElement 1 qlipper-5.1.1/macosx/bundle.cmake.in000066400000000000000000000033051321252207600173450ustar00rootroot00000000000000# # This is evil! I don't know why it works this way. # But it works. # # First - collect all Qt and app plugins. Then call that bloody # cmake FIXUP_BUNDLE macro which copis all files into MacOS directory. # So it's moved back to plugins tree where its expected by a) Qt b) app # # I hate it. # # qt_menu.nib is mandatory for mac if (@QT_USE_FRAMEWORKS@) file(COPY @QT_LIBRARY_DIR@/QtGui.framework/Resources/qt_menu.nib DESTINATION @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/Resources) else () file(COPY @QT_LIBRARY_DIR@/Resources/qt_menu.nib DESTINATION @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/Resources) endif () # the qt.conf is mandatory too file(WRITE @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/Resources/qt.conf "[Paths] Plugins = plugins") # copy all (required) Qt plugs into bundle message(STATUS "Searching for Qt plugs in: @QT_PLUGINS_DIR@/*@CMAKE_SHARED_LIBRARY_SUFFIX@") file(COPY @QT_PLUGINS_DIR@/ DESTINATION @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/plugins/ REGEX "(designer|script|debug|sql|dbg|phonon|bearer|gl|svg|accessible|race)" EXCLUDE) # try to FIXUP_BUNDLE - to change otool -L paths # currently it creates lots of false warnings when plugins are compiled as dylibs # warning: cannot resolve item 'libtepsonic_lastfmscrobbler.dylib' # etc. Ignore it. message(STATUS "Searching for plugs in bundle: @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/plugins/*@CMAKE_SHARED_LIBRARY_SUFFIX@") file(GLOB_RECURSE inplugs @CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app/Contents/plugins/*@CMAKE_SHARED_LIBRARY_SUFFIX@) include(BundleUtilities) fixup_bundle(@CMAKE_INSTALL_PREFIX@/@EXE_NAME@.app "${inplugs}" @CMAKE_INSTALL_PREFIX@/Contents/plugins/) qlipper-5.1.1/macosx/qlipper.icns000066400000000000000000000643241321252207600170270ustar00rootroot00000000000000icnshis32 ~zwegwn{sRdk@p~羲xzBsV<*Iy8tz9v׆:xݱ;zwư;Wrǵ;mfԞ;@=[;;Fc:;Gm@;Bt~ty{{| }{+D883(' (&9 |lkѢ|_˔W^RvBӍFݕEDEUE&ݴEjcrEagyDbh}Jae 1l]P?1-. /.%]3 on ÷ݷr ٥l țukW ٧[ Y ZZU Z+Z}ZxXzax~ ?scP@;< >:.t?" s8mk rE C E E E E E E E D E 9f il32 v|gq SddahVqnPaQalEaankYQGX`nI79VlP`ۅqR`̀wT`{V`W`WaWamW ==TnW==XsƃW==\{W==bW==e~W==?kTUVW==)  =( v|gq ~xuhzkeܕnRVcӃcڀڇcϴcdƵddd ccodccqѓdccrdccwdccydccb|cdccC(  cB3# v|gq ¯ʭ䯆chϚ~ٝ~~ {{{{ة{{{{{{{{w{{S2   {R?+ l8mkIr -9<==<=>>=>>=4oF$'=AA@@@????@4 it328 v|gq SddahVqnPaQalEaankYQGX`nI79VlP`ۅqR`̀wT`{V`W`WaWamW ==TnW==XsƃW==\{W==bW==e~W==?kTUVW==)  =( v|gq ~xuhzkeܕnRVcӃcڀڇcϴcdƵddd ccodccqѓdccrdccwdccydccb|cdccC(  cB3# v|gq ¯ʭ䯆chϚ~ٝ~~ {{{{ة{{{{{{{{w{{S2   {R?+ t8mk@Ir -9<==<=>>=>>=4oF$'=AA@@@????@4 ic08 jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2R \ PXX`XX`XX`XXXPPXdKakadu-v5.2.1 )3ӝO)M)ZB3h-$I' Pvm\U|"Oǂ|P>D)Ze?.^IvE4 R Dr@>A Kdou)FbH2ׁ$$>0J**v#}3>`(Kd~)FcgY%J0dhXJ|a@A*~LW{#؜;B?>%?@N_Ĕ9$CfTV*~|>@@Lg$*Xpް@@>A:K';Z#_!Ja]ַU[qdAb$5Xyv|^R0mBS^|A=hȿ UFYVnNNBw#4{& z\RAxmu5XF8Y1x%3kerA@>Ap#U'C&Ȇ" GFJ6QxZy'xQ5hd`R:Z)UêԾwvU6Ȃ=j;{o j>}X"EYrxk?QSVDHo>QJ:ۦZM{fGJ<1Ϡ:v(abzu? SB|d#%kn(Uh76BWkaC1Gt/bsDBY2My45ߛb&uȸmWJ '}Ud ̆nwhW]IXGL^`+]8U*6#XgEi}!A}<c+!Kh -ʞGOQZ7a&כ;j4Xi瓫S'nBAn>9uY518O𱗢z~^vMF-T,a$kY<Ira%JT4Q[ [5m<exU;CHs9kb4MdІgWܛ1 "0[BKA?9?K! ~A p'}Pbi#@ObGݯ4 ,䔂5xDF98JĊ5GdlLǭ3H ?zݹ?1{@b͛V:2c.q \Y'7FJMmL/c@c ,`|D)1yA )x7rr$tGݺ94V>0ʲ Q!ԃ0->($$tbʓC9lh`ʲ10ğv%+6 FD0dR)&>?>+LC{C8/F܅,Rv@x+U#o|>A0Hд{Xj]жR՚>A Щ[ vBhzySFqhJ4({]<&g&sv3C`1==h𦘘 s1ꯓxCVi:AyZV+92ˏ[?xsN(f0گMmv9̜^k$ K| >AW`."Rdu1#J(gF*0@>AG3'Ff8}xw9NʢOr47hvE]'qh|}0G;%>+ !ӉȻb8>76z[.|rGdL %}'}}A=i GrMtݔZR[}K v2 sK@y̐*-FȚDLaSB{\ŕSk$Pi!)WuX/'⭬UK:^ 5ohxܮ(g%J<9EPkDy7FaXf~R7P֗1/~qW`O'?8|2tJQl-1ث2 dit@ռ"22]PnJAv1eDqs7yXnGrǚPh Q5>%_o~qW|'O_ 2qs_\V(dQSv h{F"x;RJ (4ݛ_A#* ~ b#]rg@ m)%`#8aa+Ixه,dL*'tE=$'"W.J+؆) dܜVᅴpDrn7; 9oS C;։,Pݪ>Xi瓫S'nBAn>9uY518O𱗢z~^vMF-T,a$kY<Ira%JT4Q[ [5m<exU;CHs9kb4MdІgWܛ1 "0[A~B$rKx2 ?_K@p'}Pbi#@ObGݯ4 ,䔂5xDF98JĊ5GdlLǭ3H ?zݹ?1{@b͛V:2c.q \Y'7FJMmL/c@c ,`|D)1y All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.qlipper-5.1.1/qkeysequencewidget/qkeysequencewidget.cpp000066400000000000000000000342701321252207600235200ustar00rootroot00000000000000/****************************************************************************** Copyright (c) 2010, Artem Galichkin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include #include #include #include #include "qkeysequencewidget_p.h" #include "qkeysequencewidget.h" /*! Creates a QKeySequenceWidget object wuth \a parent and empty \a keySequence */ QKeySequenceWidget::QKeySequenceWidget(QWidget *parent) : QWidget(parent), d_ptr(new QKeySequenceWidgetPrivate()) { Q_D(QKeySequenceWidget); d->q_ptr = this; d->init(QKeySequence(), QString()); _connectingSlots(); } /*! Creates a QKeySequenceWidget object wuth \a parent and keysequence \a keySequence and string for \a noneString */ QKeySequenceWidget::QKeySequenceWidget(QKeySequence seq, QString noneString, QWidget *parent) : QWidget(parent), d_ptr(new QKeySequenceWidgetPrivate()) { Q_D(QKeySequenceWidget); d->q_ptr = this; qDebug() << "q_prt " << this; d->init(seq, noneString); _connectingSlots(); } /*! Creates a QKeySequenceWidget object wuth \a parent and keysequence \a keySequence */ QKeySequenceWidget::QKeySequenceWidget(QKeySequence seq, QWidget *parent) : QWidget(parent), d_ptr(new QKeySequenceWidgetPrivate()) { qDebug() << "widget constructor"; Q_D(QKeySequenceWidget); d->q_ptr = this; qDebug() << "q_prt " << this; d->init(seq, QString()); _connectingSlots(); } /*! Creates a QKeySequenceWidget object wuth \a parent and string for \a noneString */ QKeySequenceWidget::QKeySequenceWidget(QString noneString, QWidget *parent) : QWidget(parent), d_ptr(new QKeySequenceWidgetPrivate()) { qDebug() << "widget constructor"; Q_D(QKeySequenceWidget); d->q_ptr = this; qDebug() << "q_prt " << this; d->init(QKeySequence(), noneString); _connectingSlots(); } /*! Destroy a QKeySequenceWidget object */ QKeySequenceWidget::~QKeySequenceWidget() { delete d_ptr; } QSize QKeySequenceWidget::sizeHint() const { return d_ptr->shortcutButton->sizeHint(); } /*! Setting tooltip text to sequence button \param tip Text string */ void QKeySequenceWidget::setToolTip(const QString &tip) { d_ptr->setToolTip(tip); } /*! Setting mode of Clear Buttorn display. \param show Position of clear button \a ClearButtornShow \sa clearButtonShow */ void QKeySequenceWidget::setClearButtonShow(QKeySequenceWidget::ClearButtonShow show) { d_ptr->showClearButton = show; d_ptr->updateView(); } /*! Return mode of clear button dosplay. \param show Display mode of clear button (NoShow, ShowLeft or ShorRight) \sa setClearButtonShow */ QKeySequenceWidget::ClearButtonShow QKeySequenceWidget::clearButtonShow() const { return static_cast(d_ptr->showClearButton); } /*! Set the key sequence. \param key Key sequence \sa clearKeySequence */ void QKeySequenceWidget::setKeySequence(const QKeySequence& key) { if (d_ptr->isRecording == false) { d_ptr->oldSequence = d_ptr->currentSequence; } d_ptr->doneRecording(); d_ptr->currentSequence = key; d_ptr->doneRecording(); } /*! Get current key sequence. \return Current key sequence \sa setKeySequence \sa clearKeySequence */ QKeySequence QKeySequenceWidget::keySequence() const { return d_ptr->currentSequence; } /*! Clear key sequence. \sa setKeySequence */ void QKeySequenceWidget::clearKeySequence() { setKeySequence(QKeySequence()); } // slot for capture key sequence starting (private) void QKeySequenceWidget::captureKeySequence() { d_ptr->startRecording(); } /*! Set string for display when key sequence is undefined. \param text Text string \sa noneText */ void QKeySequenceWidget::setNoneText(const QString text) { d_ptr->noneSequenceText = text; d_ptr->updateDisplayShortcut(); } /*! Get string for display when key sequence is undefined. \return Text string \sa setNoneText */ QString QKeySequenceWidget::noneText() const { return d_ptr->noneSequenceText; } /*! Set custom icon for clear buttom. \param icon QIcon object \sa clearButtonIcon */ void QKeySequenceWidget::setClearButtonIcon(const QIcon &icon) { d_ptr->clearButton->setIcon(icon); } /*! Get clear buttom icon. \return QIcon object \sa setClearButtonIcon */ QIcon QKeySequenceWidget::clearButtonIcon() const { return d_ptr->clearButton->icon(); } // connection internal signals & slots void QKeySequenceWidget::_connectingSlots() { // connect signals to slots connect(d_ptr->clearButton, SIGNAL(clicked()), this, SLOT(clearKeySequence())); connect(&d_ptr->modifierlessTimeout, SIGNAL(timeout()), this, SLOT(doneRecording())); connect(d_func()->shortcutButton, SIGNAL(clicked()), this, SLOT(captureKeySequence())); } // Private class implementation QKeySequenceWidgetPrivate::QKeySequenceWidgetPrivate() : layout(NULL), clearButton(NULL), shortcutButton(NULL) { Q_Q(QKeySequenceWidget); Q_UNUSED(q); } QKeySequenceWidgetPrivate::~QKeySequenceWidgetPrivate() { } void QKeySequenceWidgetPrivate::init(const QKeySequence keySeq, const QString noneStr) { Q_Q(QKeySequenceWidget); Q_UNUSED(q); layout = new QHBoxLayout(q_func()); layout->setMargin(0); layout->setSpacing(1); clearButton = new QToolButton(q_func()); clearButton->setText("x"); layout->addWidget(clearButton); shortcutButton = new QShortcutButton(this, q_func()); if (noneStr.isNull() == true) { noneSequenceText = "..."; } else { noneSequenceText = noneStr; } q_ptr->clearKeySequence(); currentSequence = keySeq; shortcutButton->setFocusPolicy(Qt::StrongFocus); layout->addWidget(shortcutButton); showClearButton = QKeySequenceWidget::ShowRight; clearButton->setIcon(QIcon::fromTheme("dialog-cancel", QIcon(":/icons/dialog-cancel.png"))); // unfocused clear button afyer created (small hack) clearButton->setFocusPolicy(Qt::NoFocus); // update ui updateDisplayShortcut(); updateView(); } // set tooltip only for seqyence button void QKeySequenceWidgetPrivate::setToolTip(const QString &tip) { shortcutButton->setToolTip(tip); clearButton->setToolTip(""); } // update the location of widgets void QKeySequenceWidgetPrivate::updateView() { qDebug() << "update view "; switch(showClearButton) { case QKeySequenceWidget::ShowLeft: clearButton->setVisible(true); layout->setDirection(QBoxLayout::LeftToRight); break; case QKeySequenceWidget::ShowRight: clearButton->setVisible(true); layout->setDirection(QBoxLayout::RightToLeft); break; case QKeySequenceWidget::NoShow: clearButton->setVisible(false); break; default: layout->setDirection(QBoxLayout::LeftToRight); } } void QKeySequenceWidgetPrivate::startRecording() { numKey = 0; modifierKeys = 0; oldSequence = currentSequence; currentSequence = QKeySequence(); isRecording = true; shortcutButton->setDown(true); shortcutButton->grabKeyboard(); if (!QWidget::keyboardGrabber()) { qWarning() << "Failed to grab the keyboard! Most likely qt's nograb option is active"; } // update Shortcut display updateDisplayShortcut(); } void QKeySequenceWidgetPrivate::doneRecording() { modifierlessTimeout.stop(); isRecording = false; shortcutButton->releaseKeyboard(); shortcutButton->setDown(false); // if sequence is not changed if (currentSequence == oldSequence) { // update Shortcut display updateDisplayShortcut(); return; } // key sequnce is changed emit q_ptr->keySequenceChanged(currentSequence); // update Shortcut display updateDisplayShortcut(); } inline void QKeySequenceWidgetPrivate::cancelRecording() { currentSequence = oldSequence; doneRecording(); } inline void QKeySequenceWidgetPrivate::controlModifierlessTimout() { if (numKey != 0 && !modifierKeys) { // No modifier key pressed currently. Start the timout modifierlessTimeout.start(600); } else { // A modifier is pressed. Stop the timeout modifierlessTimeout.stop(); } } inline void QKeySequenceWidgetPrivate::keyNotSupported() { Q_EMIT q_ptr->keyNotSupported(); } void QKeySequenceWidgetPrivate::updateDisplayShortcut() { // empty string if no non-modifier was pressed QString str = currentSequence.toString(QKeySequence::NativeText); str.replace('&', QLatin1String("&&")); // TODO -- check it if (isRecording == true) { if (modifierKeys) { if (str.isEmpty() == false) str.append(","); if ((modifierKeys & Qt::META) ) str += "Meta + "; if ((modifierKeys & Qt::CTRL) ) str += "Ctrl + "; if ((modifierKeys & Qt::ALT) ) str += "Alt + "; if ((modifierKeys & Qt::SHIFT) ) str += "Shift + "; } // make it clear that input is still going on str.append("..."); } // if is noting if (str.isEmpty() == true) { str = noneSequenceText; } shortcutButton->setText(str); } // QKeySequenceButton implementation QSize QShortcutButton::sizeHint() const { return QPushButton::sizeHint(); } bool QShortcutButton::event(QEvent *e) { if (d->isRecording == true && e->type() == QEvent::KeyPress) { keyPressEvent(static_cast(e)); return true; } if (d->isRecording && e->type() == QEvent::ShortcutOverride) { e->accept(); return true; } if (d->isRecording == true && e->type() == QEvent::FocusOut) { d->cancelRecording(); return true; } return QPushButton::event(e); } void QShortcutButton::keyPressEvent(QKeyEvent *keyEvent) { qDebug() << "key pressed"; int keyQt = keyEvent->key(); // Qt sometimes returns garbage keycodes, I observed -1, // if it doesn't know a key. // We cannot do anything useful with those (several keys have -1, // indistinguishable) // and QKeySequence.toString() will also yield a garbage string. if (keyQt == -1) { // keu moy supported in Qt d->cancelRecording(); d->keyNotSupported(); } //get modifiers key uint newModifiers = keyEvent->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); // block autostart capturing on key_return or key space press if (d->isRecording == false && (keyQt == Qt::Key_Return || keyQt == Qt::Key_Space)) { return; } // We get events even if recording isn't active. if (d->isRecording == false) { return QPushButton::keyPressEvent(keyEvent); } keyEvent->accept(); d->modifierKeys = newModifiers; // switching key type switch(keyQt) { case Qt::Key_AltGr: //or else we get unicode salad return; case Qt::Key_Shift: case Qt::Key_Control: case Qt::Key_Alt: case Qt::Key_Meta: case Qt::Key_Menu: //unused (yes, but why?) // TODO - check it key d->controlModifierlessTimout(); d->updateDisplayShortcut(); break; default: { } // We now have a valid key press. if (keyQt) { if ((keyQt == Qt::Key_Backtab) && (d->modifierKeys & Qt::SHIFT)) { keyQt = Qt::Key_Tab | d->modifierKeys; } else //if (d->isShiftAsModifierAllowed(keyQt)) { keyQt |= d->modifierKeys; } if (d->numKey == 0) { d->currentSequence = QKeySequence(keyQt); } d->numKey++; // increment nuber of pressed keys if (d->numKey >= 4) { d->doneRecording(); return; } d->controlModifierlessTimout(); d->updateDisplayShortcut(); } } } void QShortcutButton::keyReleaseEvent(QKeyEvent *keyEvent) { qDebug() << "key released"; if (keyEvent->key() == -1) { // ignore garbage, see keyPressEvent() return; } // if not recording mode if (d->isRecording == false) { return QPushButton::keyReleaseEvent(keyEvent); } keyEvent->accept(); uint newModifiers = keyEvent->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); // if a modifier that belongs to the shortcut was released... if ((newModifiers & d->modifierKeys) < d->modifierKeys) { d->modifierKeys = newModifiers; d->controlModifierlessTimout(); d->updateDisplayShortcut(); } } qlipper-5.1.1/qkeysequencewidget/qkeysequencewidget.h000066400000000000000000000111361321252207600231610ustar00rootroot00000000000000/****************************************************************************** Copyright (c) 2010, Artem Galichkin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #ifndef QKEYSEQUENCEWIDGET_H #define QKEYSEQUENCEWIDGET_H #include "qkeysequencewidget_p.h" #include #include class QKeySequenceWidgetPrivate; /*! \class QKeySequenceWidget \brief The QKeySequenceWidget is a widget to input a QKeySequence. This widget lets the user choose a QKeySequence, which is usually used as a shortcut key. The recording is initiated by calling captureKeySequence() or the user clicking into the widget. \code // create new QKeySequenceWidget with empty sequence QKeySequenceWidget *keyWidget = new QKeySequenceWidget; // Set sequence as "Ctrl+Alt+Space" keyWidget->setJeySequence(QKeySequence("Ctrl+Alt+Space")); // set clear button position is left setClearButtonShow(QKeySequenceWidget::ShowLeft); // set cutom clear button icon setClearButtonIcon(QIcon("/path/to/icon.png")); // connecting keySequenceChanged signal to slot connect(keyWidget, SIGNAL(keySequenceChanged(QKeySequence)), this, SLOT(slotKeySequenceChanged(QKeySequence))); \endcode */ class QKeySequenceWidget : public QWidget { Q_OBJECT Q_DECLARE_PRIVATE(QKeySequenceWidget); Q_PRIVATE_SLOT(d_func(), void doneRecording()) Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence) Q_PROPERTY(QKeySequenceWidget::ClearButtonShow clearButton READ clearButtonShow WRITE setClearButtonShow) Q_PROPERTY(QString noneText READ noneText WRITE setNoneText) Q_PROPERTY(QIcon clearButtonIcon READ clearButtonIcon WRITE setClearButtonIcon) private: QKeySequenceWidgetPrivate * const d_ptr; void _connectingSlots(); private Q_SLOTS: void captureKeySequence(); public: explicit QKeySequenceWidget(QWidget *parent = 0); explicit QKeySequenceWidget(QKeySequence seq, QWidget *parent = 0); explicit QKeySequenceWidget(QString noneString, QWidget *parent = 0); explicit QKeySequenceWidget(QKeySequence seq, QString noneString, QWidget *parent = 0); virtual ~QKeySequenceWidget(); QSize sizeHint() const; void setToolTip(const QString &tip); QKeySequence keySequence() const; QString noneText() const; QIcon clearButtonIcon() const; /*! \brief Modes of sohow ClearButton */ enum ClearButton { NoShow = 0x00, /**< Hide ClearButton */ ShowLeft = 0x01, /**< ClearButton isow is left */ ShowRight = 0x02 /**< ClearButton isow is left */ }; Q_DECLARE_FLAGS(ClearButtonShow, ClearButton); Q_FLAGS(ClearButtonShow) QKeySequenceWidget::ClearButtonShow clearButtonShow() const; Q_SIGNALS: void keySequenceChanged(const QKeySequence &seq); void keyNotSupported(); public Q_SLOTS: void setKeySequence(const QKeySequence &key); void clearKeySequence(); void setNoneText(const QString text); void setClearButtonIcon(const QIcon& icon); void setClearButtonShow(QKeySequenceWidget::ClearButtonShow show); }; #endif // QKEYSEQUENCEWIDGET_H qlipper-5.1.1/qkeysequencewidget/qkeysequencewidget_p.h000066400000000000000000000073031321252207600235010ustar00rootroot00000000000000/****************************************************************************** Copyright (c) 2010, Artem Galichkin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #ifndef QKEYSEQUENCEWIDGET_P_H #define QKEYSEQUENCEWIDGET_P_H #include #include #include #include #include #include #include #include "qkeysequencewidget.h" class QShortcutButton; class QKeySequenceWidget; class QKeySequenceWidgetPrivate // : public QObject { //Q_OBJECT Q_DECLARE_PUBLIC(QKeySequenceWidget); public: QKeySequenceWidget * q_ptr; QKeySequenceWidgetPrivate(); virtual ~QKeySequenceWidgetPrivate(); void init(const QKeySequence keySeq, const QString noneStr); void updateView(); void startRecording(); void doneRecording(); inline void cancelRecording(); inline void controlModifierlessTimout(); inline void keyNotSupported(); void updateDisplayShortcut(); // members QKeySequence currentSequence; QKeySequence oldSequence; QString noneSequenceText; QTimer modifierlessTimeout; quint32 numKey; quint32 modifierKeys; void setToolTip(const QString& tip); QHBoxLayout *layout; QToolButton *clearButton; QShortcutButton *shortcutButton; int showClearButton; bool isRecording; }; class QShortcutButton : public QPushButton { Q_OBJECT public: explicit QShortcutButton(QKeySequenceWidgetPrivate *p, QWidget *parent = 0) : QPushButton(parent) , d(p) { qDebug() << "qShortcut button Create"; qDebug() << "parent----" << parent; qDebug() << "visible " << isVisible(); setMinimumWidth(QPushButton::minimumWidth()); QPushButton::setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); } virtual ~QShortcutButton() { qDebug() << "qShortcut button delete"; } virtual QSize sizeHint() const; protected: // Reimplemented for internal reasons. virtual bool event(QEvent *e); virtual void keyPressEvent(QKeyEvent *keyEvent); virtual void keyReleaseEvent(QKeyEvent *keyEvent); private: QKeySequenceWidgetPrivate * const d; }; #endif // QKEYSEQUENCEWIDGET_P_H qlipper-5.1.1/qlipper.desktop000066400000000000000000000021611321252207600162410ustar00rootroot00000000000000[Desktop Entry] Terminal=false TryExec=qlipper Exec=qlipper Icon=qlipper Type=Application Categories=Qt;Utility; StartupNotify=false Name=Qlipper Name[fr]=Qlipper Name[lt]=Qlipper Name[sr]=Кјулипер Name[sr@ijekavian]=Кјулипер Name[sr@ijekavianlatin]=Kjuliper Name[sr@latin]=Kjuliper GenericName=Clipboard Tool GenericName[de]=Zwischenablage GenericName[fr]=Presse-papiers GenericName[lt]=Iškarpinės įrankis GenericName[sr]=Алатка за клипборд GenericName[sr@ijekavian]=Алатка за клипборд GenericName[sr@ijekavianlatin]=Alatka za klipbord GenericName[sr@latin]=Alatka za klipbord Comment=Clipboard history tool Comment[de]=Anwendung zur Handhabung der Zwischenablage Comment[fr]=Un outil d'historique du presse-papiers Comment[lt]=Iškarpinės istorijos įrankis Comment[sr]=Алатка за историјат исецања и налепљивања Comment[sr@ijekavian]=Алатка за историјат исецања и налепљивања Comment[sr@ijekavianlatin]=Alatka za istorijat isecanja i nalepljivanja Comment[sr@latin]=Alatka za istorijat isecanja i nalepljivanja qlipper-5.1.1/qmenuview/000077500000000000000000000000001321252207600152125ustar00rootroot00000000000000qlipper-5.1.1/qmenuview/qmenuview.cpp000066400000000000000000000137331321252207600177450ustar00rootroot00000000000000/* XINX Copyright (C) 2007-2011 by Ulrich Van Den Hekke xinx@shadoware.org This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful. but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * This class is inspired from the Nokia class MenuModel, used in the browser * application in demos. */ // Xinx header #include "qmenuview_p.h" Q_DECLARE_METATYPE(QModelIndex); /* QMenuViewPrivate */ QMenuViewPrivate::QMenuViewPrivate(QMenuView* menu) : _menu(menu) { } QMenuViewPrivate::~QMenuViewPrivate() { } QAction * QMenuViewPrivate::makeAction(const QModelIndex &index) { QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); QAction * action = new QAction(icon, index.data().toString(), this); action->setEnabled(index.flags().testFlag(Qt::ItemIsEnabled)); // improvements for Qlipper (petr vanek action->setFont(qvariant_cast(index.data(Qt::FontRole))); action->setToolTip(index.data(Qt::ToolTipRole).toString()); // end of qlipper improvements QVariant v; v.setValue(index); action->setData(v); return action; } void QMenuViewPrivate::triggered(QAction *action) { QVariant v = action->data(); if (v.canConvert()) { QModelIndex idx = qvariant_cast(v); emit _menu->triggered(idx); } } void QMenuViewPrivate::hovered(QAction *action) { QVariant v = action->data(); if (v.canConvert()) { QModelIndex idx = qvariant_cast(v); QString hoveredString = idx.data(Qt::StatusTipRole).toString(); if (!hoveredString.isEmpty()) emit _menu->hovered(hoveredString); } } void QMenuViewPrivate::aboutToShow() { QMenu * menu = qobject_cast(sender()); if (menu) { QVariant v = menu->menuAction()->data(); if (v.canConvert()) { QModelIndex idx = qvariant_cast(v); _menu->createMenu(idx, menu, menu); disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); return; } } _menu->clear(); if (_menu->prePopulated()) _menu->addSeparator(); _menu->createMenu(m_root, _menu, _menu); _menu->postPopulated(); } /* QMenuView */ /*! * \ingroup Components * \class QMenuView * \since 0.9.0.0 * * \brief The QMenuView provides a menu based view on a QAbstractItemModel class. * * \bc 0.10.0.0 * * This class is used to transform a hierarchical model based on the class * QAbstractItemModel into a menu. It can be used to create an action menu, history, * or snipets menu. * * \image html qmenuview.png * \image latex qmenuview.png * * When the model is defined, the structure of the menu is automatically generated. This * class ignores call to QAbstractItemModel::beginInsertRows() and QAbstractItemModel::endInsertRows(). * Menu is generated when the user opens it. */ /*! * \brief Creates the new menu view based on a QMenu object. * \param parent The parent object of the menu. */ QMenuView::QMenuView(QWidget * parent) : QMenu(parent), d(new QMenuViewPrivate(this)) { connect(this, SIGNAL(triggered(QAction*)), d.data(), SLOT(triggered(QAction*))); connect(this, SIGNAL(hovered(QAction*)), d.data(), SLOT(hovered(QAction*))); connect(this, SIGNAL(aboutToShow()), d.data(), SLOT(aboutToShow())); } //! Destroy the menu. QMenuView::~QMenuView() { setModel(0); } /*! * \fn void QMenuView::hovered(const QString &text) const * \brief The signal when a menu action is highlighted. * * \p text is the Qt::StatusTipRole of the index that caused the signal to be emitted. * * Often this is used to update status information. * * \sa triggered() */ /*! * \fn void QMenuView::triggered(const QModelIndex & index) const * \brief This signal is emitted when an action in this menu is triggered. * * \p index is the index's action that caused the signal to be emitted. * * \sa hovered() */ //! Add any actions before the tree, return true if any actions are added. bool QMenuView::prePopulated() { return false; } //! Add any actions after the tree void QMenuView::postPopulated() { } /*! * \brief Set the new model to \p model. * \param model The new model to use for the creation of menus. */ void QMenuView::setModel(QAbstractItemModel * model) { d->m_model = model; } /*! * \brief Return the current model of the menu. */ QAbstractItemModel * QMenuView::model() const { return d->m_model; } /*! * \brief Change the root index to \p index. * * This can be used to show only a part of the QAbstractItemModel. * \param index The index to use to show the menu. if QModelIndex(), all the model is show. */ void QMenuView::setRootIndex(const QModelIndex & index) { d->m_root = index; } /*! * \brief Returns the current root index. * * Default root index is QModelIndex() */ QModelIndex QMenuView::rootIndex() const { return d->m_root; } //! Puts all of the children of parent into menu void QMenuView::createMenu(const QModelIndex &parent, QMenu *parentMenu, QMenu *menu) { if (! menu) { QIcon icon = qvariant_cast(parent.data(Qt::DecorationRole)); QVariant v; v.setValue(parent); menu = new QMenu(parent.data().toString(), this); menu->setIcon(icon); parentMenu->addMenu(menu); menu->menuAction()->setData(v); menu->setEnabled(parent.flags().testFlag(Qt::ItemIsEnabled)); connect(menu, SIGNAL(aboutToShow()), d.data(), SLOT(aboutToShow())); return; } int end = d->m_model->rowCount(parent); for (int i = 0; i < end; ++i) { QModelIndex idx = d->m_model->index(i, 0, parent); if (d->m_model->hasChildren(idx)) { createMenu(idx, menu); } else { menu->addAction(d->makeAction(idx)); } } } qlipper-5.1.1/qmenuview/qmenuview.h000066400000000000000000000031451321252207600174060ustar00rootroot00000000000000/* XINX Copyright (C) 2007-2011 by Ulrich Van Den Hekke xinx@shadoware.org This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful. but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #pragma once #ifndef _QMENUVIEW_H_ #define _QMENUVIEW_H_ // Qt header #include #include //#include #define COMPONENTSEXPORT class QMenuViewPrivate; class COMPONENTSEXPORT QMenuView : public QMenu { Q_OBJECT public: QMenuView(QWidget * parent = 0); virtual ~QMenuView(); virtual void setModel(QAbstractItemModel * model); QAbstractItemModel * model() const; virtual void setRootIndex(const QModelIndex & index); QModelIndex rootIndex() const; protected: virtual bool prePopulated(); virtual void postPopulated(); void createMenu(const QModelIndex &parent, QMenu *parentMenu = 0, QMenu *menu = 0); signals: void hovered(const QString &text) const; void triggered(const QModelIndex & index) const; private: QScopedPointer d; friend class QMenuViewPrivate; }; #endif /* _QMENUVIEW_H_ */ qlipper-5.1.1/qmenuview/qmenuview_p.h000066400000000000000000000024021321252207600177200ustar00rootroot00000000000000/* XINX Copyright (C) 2007-2011 by Ulrich Van Den Hekke xinx@shadoware.org This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful. but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #pragma once #ifndef _QMENUVIEW_P_H_ #define _QMENUVIEW_P_H_ // Qt header #include #include #include "qmenuview.h" //#include //! \private class QMenuViewPrivate : public QObject { Q_OBJECT public: QMenuViewPrivate(QMenuView * menu); virtual ~QMenuViewPrivate(); QAction *makeAction(const QModelIndex &index); QMenuView * _menu; QAbstractItemModel * m_model; QPersistentModelIndex m_root; public slots: void aboutToShow(); void triggered(QAction *action); void hovered(QAction *action); }; #endif /* _QMENUVIEW_P_H_ */ qlipper-5.1.1/qxt/000077500000000000000000000000001321252207600140065ustar00rootroot00000000000000qlipper-5.1.1/qxt/qxtglobal.h000066400000000000000000000156171321252207600161660ustar00rootroot00000000000000 /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #ifndef QXTGLOBAL_H #define QXTGLOBAL_H #include #define QXT_VERSION 0x000700 #define QXT_VERSION_STR "0.7.0" //--------------------------global macros------------------------------ #ifndef QXT_NO_MACROS #ifndef _countof #define _countof(x) (sizeof(x)/sizeof(*x)) #endif #endif // QXT_NO_MACROS //--------------------------export macros------------------------------ #define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_CORE) # define QXT_CORE_EXPORT Q_DECL_EXPORT # else # define QXT_CORE_EXPORT Q_DECL_IMPORT # endif #else # define QXT_CORE_EXPORT #endif // BUILD_QXT_CORE #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_GUI) # define QXT_GUI_EXPORT Q_DECL_EXPORT # else # define QXT_GUI_EXPORT Q_DECL_IMPORT # endif #else # define QXT_GUI_EXPORT #endif // BUILD_QXT_GUI #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_NETWORK) # define QXT_NETWORK_EXPORT Q_DECL_EXPORT # else # define QXT_NETWORK_EXPORT Q_DECL_IMPORT # endif #else # define QXT_NETWORK_EXPORT #endif // BUILD_QXT_NETWORK #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_SQL) # define QXT_SQL_EXPORT Q_DECL_EXPORT # else # define QXT_SQL_EXPORT Q_DECL_IMPORT # endif #else # define QXT_SQL_EXPORT #endif // BUILD_QXT_SQL #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_WEB) # define QXT_WEB_EXPORT Q_DECL_EXPORT # else # define QXT_WEB_EXPORT Q_DECL_IMPORT # endif #else # define QXT_WEB_EXPORT #endif // BUILD_QXT_WEB #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_BERKELEY) # define QXT_BERKELEY_EXPORT Q_DECL_EXPORT # else # define QXT_BERKELEY_EXPORT Q_DECL_IMPORT # endif #else # define QXT_BERKELEY_EXPORT #endif // BUILD_QXT_BERKELEY #if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN) # if defined(BUILD_QXT_ZEROCONF) # define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT # else # define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT # endif #else # define QXT_ZEROCONF_EXPORT #endif // QXT_ZEROCONF_EXPORT #if defined(BUILD_QXT_CORE) || defined(BUILD_QXT_GUI) || defined(BUILD_QXT_SQL) || defined(BUILD_QXT_NETWORK) || defined(BUILD_QXT_WEB) || defined(BUILD_QXT_BERKELEY) || defined(BUILD_QXT_ZEROCONF) # define BUILD_QXT #endif QXT_CORE_EXPORT const char* qxtVersion(); #ifndef QT_BEGIN_NAMESPACE #define QT_BEGIN_NAMESPACE #endif #ifndef QT_END_NAMESPACE #define QT_END_NAMESPACE #endif #ifndef QT_FORWARD_DECLARE_CLASS #define QT_FORWARD_DECLARE_CLASS(Class) class Class; #endif /**************************************************************************** ** This file is derived from code bearing the following notice: ** The sole author of this file, Adam Higerd, has explicitly disclaimed all ** copyright interest and protection for the content within. This file has ** been placed in the public domain according to United States copyright ** statute and case law. In jurisdictions where this public domain dedication ** is not legally recognized, anyone who receives a copy of this file is ** permitted to use, modify, duplicate, and redistribute this file, in whole ** or in part, with no restrictions or conditions. In these jurisdictions, ** this file shall be copyright (C) 2006-2008 by Adam Higerd. ****************************************************************************/ #define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d; #define QXT_DECLARE_PUBLIC(PUB) friend class PUB; #define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this); #define QXT_D(PUB) PUB##Private& d = qxt_d() #define QXT_P(PUB) PUB& p = qxt_p() template class QxtPrivate { public: virtual ~QxtPrivate() {} inline void QXT_setPublic(PUB* pub) { qxt_p_ptr = pub; } protected: inline PUB& qxt_p() { return *qxt_p_ptr; } inline const PUB& qxt_p() const { return *qxt_p_ptr; } inline PUB* qxt_ptr() { return qxt_p_ptr; } inline const PUB* qxt_ptr() const { return qxt_p_ptr; } private: PUB* qxt_p_ptr; }; template class QxtPrivateInterface { friend class QxtPrivate; public: QxtPrivateInterface() { pvt = new PVT; } ~QxtPrivateInterface() { delete pvt; } inline void setPublic(PUB* pub) { pvt->QXT_setPublic(pub); } inline PVT& operator()() { return *static_cast(pvt); } inline const PVT& operator()() const { return *static_cast(pvt); } inline PVT * operator->() { return static_cast(pvt); } inline const PVT * operator->() const { return static_cast(pvt); } private: QxtPrivateInterface(const QxtPrivateInterface&) { } QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } QxtPrivate* pvt; }; #endif // QXT_GLOBAL qlipper-5.1.1/qxt/qxtglobalshortcut.cpp000066400000000000000000000170031321252207600203040ustar00rootroot00000000000000#include "qxtglobalshortcut.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include "qxtglobalshortcut_p.h" #include #include #ifndef Q_OS_MAC int QxtGlobalShortcutPrivate::ref = 0; # if QT_VERSION < QT_VERSION_CHECK(5,0,0) QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0; # endif #endif // Q_OS_MAC QHash, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts; QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) { #ifndef Q_OS_MAC if (ref == 0) { # if QT_VERSION < QT_VERSION_CHECK(5,0,0) prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter); # else QAbstractEventDispatcher::instance()->installNativeEventFilter(this); #endif } ++ref; #endif // Q_OS_MAC } QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate() { #ifndef Q_OS_MAC --ref; if (ref == 0) { QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance(); if (ed != 0) { # if QT_VERSION < QT_VERSION_CHECK(5,0,0) ed->setEventFilter(prevEventFilter); # else ed->removeNativeEventFilter(this); # endif } } #endif // Q_OS_MAC } bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut) { Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]); mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods); const quint32 nativeKey = nativeKeycode(key); const quint32 nativeMods = nativeModifiers(mods); const bool res = registerShortcut(nativeKey, nativeMods); if (res) shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p()); else qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString(); return res; } bool QxtGlobalShortcutPrivate::unsetShortcut() { bool res = false; const quint32 nativeKey = nativeKeycode(key); const quint32 nativeMods = nativeModifiers(mods); if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p()) res = unregisterShortcut(nativeKey, nativeMods); if (res) shortcuts.remove(qMakePair(nativeKey, nativeMods)); else qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString(); key = Qt::Key(0); mods = Qt::KeyboardModifiers(0); return res; } void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods) { QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods)); if (shortcut && shortcut->isEnabled()) emit shortcut->activated(); } /*! \class QxtGlobalShortcut \inmodule QxtWidgets \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey". A global shortcut triggers even if the application is not active. This makes it easy to implement applications that react to certain shortcuts still if some other application is active or if the application is for example minimized to the system tray. Example usage: \code QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window); connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility())); shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12")); \endcode \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication. */ /*! \fn QxtGlobalShortcut::activated() This signal is emitted when the user types the shortcut's key sequence. \sa shortcut */ /*! Constructs a new QxtGlobalShortcut with \a parent. */ QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent) : QObject(parent) { QXT_INIT_PRIVATE(QxtGlobalShortcut); } /*! Constructs a new QxtGlobalShortcut with \a shortcut and \a parent. */ QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent) : QObject(parent) { QXT_INIT_PRIVATE(QxtGlobalShortcut); setShortcut(shortcut); } /*! Destructs the QxtGlobalShortcut. */ QxtGlobalShortcut::~QxtGlobalShortcut() { if (qxt_d().key != 0) qxt_d().unsetShortcut(); } /*! \property QxtGlobalShortcut::shortcut \brief the shortcut key sequence \bold {Note:} Notice that corresponding key press and release events are not delivered for registered global shortcuts even if they are disabled. Also, comma separated key sequences are not supported. Only the first part is used: \code qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B")); Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A")); \endcode */ QKeySequence QxtGlobalShortcut::shortcut() const { return QKeySequence(qxt_d().key | qxt_d().mods); } bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut) { if (qxt_d().key != 0) qxt_d().unsetShortcut(); return qxt_d().setShortcut(shortcut); } /*! \property QxtGlobalShortcut::enabled \brief whether the shortcut is enabled A disabled shortcut does not get activated. The default value is \c true. \sa setDisabled() */ bool QxtGlobalShortcut::isEnabled() const { return qxt_d().enabled; } void QxtGlobalShortcut::setEnabled(bool enabled) { qxt_d().enabled = enabled; } /*! Sets the shortcut \a disabled. \sa enabled */ void QxtGlobalShortcut::setDisabled(bool disabled) { qxt_d().enabled = !disabled; } qlipper-5.1.1/qxt/qxtglobalshortcut.h000066400000000000000000000053611321252207600177550ustar00rootroot00000000000000#ifndef QXTGLOBALSHORTCUT_H /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #define QXTGLOBALSHORTCUT_H #include "qxtglobal.h" #include #include class QxtGlobalShortcutPrivate; class /*QXT_GUI_EXPORT*/ QxtGlobalShortcut : public QObject { Q_OBJECT QXT_DECLARE_PRIVATE(QxtGlobalShortcut) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) public: explicit QxtGlobalShortcut(QObject* parent = 0); explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0); virtual ~QxtGlobalShortcut(); QKeySequence shortcut() const; bool setShortcut(const QKeySequence& shortcut); bool isEnabled() const; public Q_SLOTS: void setEnabled(bool enabled = true); void setDisabled(bool disabled = true); Q_SIGNALS: void activated(); }; #endif // QXTGLOBALSHORTCUT_H qlipper-5.1.1/qxt/qxtglobalshortcut_mac.cpp000066400000000000000000000217051321252207600211300ustar00rootroot00000000000000#include /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include "qxtglobalshortcut_p.h" #include #include #include #include typedef QPair Identifier; static QMap keyRefs; static QHash keyIDs; static quint32 hotKeySerial = 0; static bool qxt_mac_handler_installed = false; OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data) { Q_UNUSED(nextHandler); Q_UNUSED(data); if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) { EventHotKeyID keyID; GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); Identifier id = keyIDs.key(keyID.id); QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first); } return noErr; } quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) { quint32 native = 0; if (modifiers & Qt::ShiftModifier) native |= shiftKey; if (modifiers & Qt::ControlModifier) native |= cmdKey; if (modifiers & Qt::AltModifier) native |= optionKey; if (modifiers & Qt::MetaModifier) native |= controlKey; if (modifiers & Qt::KeypadModifier) native |= kEventKeyModifierNumLockMask; return native; } quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) { UTF16Char ch; // Constants found in NSEvent.h from AppKit.framework switch (key) { case Qt::Key_Return: return kVK_Return; case Qt::Key_Enter: return kVK_ANSI_KeypadEnter; case Qt::Key_Tab: return kVK_Tab; case Qt::Key_Space: return kVK_Space; case Qt::Key_Backspace: return kVK_Delete; case Qt::Key_Control: return kVK_Command; case Qt::Key_Shift: return kVK_Shift; case Qt::Key_CapsLock: return kVK_CapsLock; case Qt::Key_Option: return kVK_Option; case Qt::Key_Meta: return kVK_Control; case Qt::Key_F17: return kVK_F17; case Qt::Key_VolumeUp: return kVK_VolumeUp; case Qt::Key_VolumeDown: return kVK_VolumeDown; case Qt::Key_F18: return kVK_F18; case Qt::Key_F19: return kVK_F19; case Qt::Key_F20: return kVK_F20; case Qt::Key_F5: return kVK_F5; case Qt::Key_F6: return kVK_F6; case Qt::Key_F7: return kVK_F7; case Qt::Key_F3: return kVK_F3; case Qt::Key_F8: return kVK_F8; case Qt::Key_F9: return kVK_F9; case Qt::Key_F11: return kVK_F11; case Qt::Key_F13: return kVK_F13; case Qt::Key_F16: return kVK_F16; case Qt::Key_F14: return kVK_F14; case Qt::Key_F10: return kVK_F10; case Qt::Key_F12: return kVK_F12; case Qt::Key_F15: return kVK_F15; case Qt::Key_Help: return kVK_Help; case Qt::Key_Home: return kVK_Home; case Qt::Key_PageUp: return kVK_PageUp; case Qt::Key_Delete: return kVK_ForwardDelete; case Qt::Key_F4: return kVK_F4; case Qt::Key_End: return kVK_End; case Qt::Key_F2: return kVK_F2; case Qt::Key_PageDown: return kVK_PageDown; case Qt::Key_F1: return kVK_F1; case Qt::Key_Left: return kVK_LeftArrow; case Qt::Key_Right: return kVK_RightArrow; case Qt::Key_Down: return kVK_DownArrow; case Qt::Key_Up: return kVK_UpArrow; default: ; } if (key == Qt::Key_Escape) ch = 27; else if (key == Qt::Key_Return) ch = 13; else if (key == Qt::Key_Enter) ch = 3; else if (key == Qt::Key_Tab) ch = 9; else ch = key; CFDataRef currentLayoutData; TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); if (currentKeyboard == NULL) return 0; currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); CFRelease(currentKeyboard); if (currentLayoutData == NULL) return 0; UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData); UCKeyboardTypeHeader* table = header->keyboardTypeList; uint8_t *data = (uint8_t*)header; // God, would a little documentation for this shit kill you... for (quint32 i=0; i < header->keyboardTypeCount; i++) { UCKeyStateRecordsIndex* stateRec = 0; if (table[i].keyStateRecordsIndexOffset != 0) { stateRec = reinterpret_cast(data + table[i].keyStateRecordsIndexOffset); if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0; } UCKeyToCharTableIndex* charTable = reinterpret_cast(data + table[i].keyToCharTableIndexOffset); if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue; for (quint32 j=0; j < charTable->keyToCharTableCount; j++) { UCKeyOutput* keyToChar = reinterpret_cast(data + charTable->keyToCharTableOffsets[j]); for (quint32 k=0; k < charTable->keyToCharTableSize; k++) { if (keyToChar[k] & kUCKeyOutputTestForIndexMask) { long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; if (stateRec && idx < stateRec->keyStateRecordCount) { UCKeyStateRecord* rec = reinterpret_cast(data + stateRec->keyStateRecordOffsets[idx]); if (rec->stateZeroCharData == ch) return k; } } else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE) { if (keyToChar[k] == ch) return k; } } // for k } // for j } // for i return 0; } bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) { if (!qxt_mac_handler_installed) { EventTypeSpec t; t.eventClass = kEventClassKeyboard; t.eventKind = kEventHotKeyPressed; InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL); } EventHotKeyID keyID; keyID.signature = 'cute'; keyID.id = ++hotKeySerial; EventHotKeyRef ref = 0; bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref); if (rv) { keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id); keyRefs.insert(keyID.id, ref); } return rv; } bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) { Identifier id(nativeMods, nativeKey); if (!keyIDs.contains(id)) return false; EventHotKeyRef ref = keyRefs.take(keyIDs[id]); keyIDs.remove(id); return !UnregisterEventHotKey(ref); } qlipper-5.1.1/qxt/qxtglobalshortcut_p.h000066400000000000000000000066541321252207600203020ustar00rootroot00000000000000#ifndef QXTGLOBALSHORTCUT_P_H /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #define QXTGLOBALSHORTCUT_P_H #include "qxtglobalshortcut.h" #include #include #include #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) #include #endif class QxtGlobalShortcutPrivate : public QxtPrivate #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) && !defined(Q_OS_MAC) ,public QAbstractNativeEventFilter #endif { public: QXT_DECLARE_PUBLIC(QxtGlobalShortcut) QxtGlobalShortcutPrivate(); ~QxtGlobalShortcutPrivate(); bool enabled; Qt::Key key; Qt::KeyboardModifiers mods; bool setShortcut(const QKeySequence& shortcut); bool unsetShortcut(); static bool error; #ifndef Q_OS_MAC static int ref; #if QT_VERSION < QT_VERSION_CHECK(5,0,0) static QAbstractEventDispatcher::EventFilter prevEventFilter; static bool eventFilter(void* message); #else virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result); #endif // QT_VERSION < QT_VERSION_CHECK(5,0,0) #endif // Q_OS_MAC static void activateShortcut(quint32 nativeKey, quint32 nativeMods); private: static quint32 nativeKeycode(Qt::Key keycode); static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); static bool registerShortcut(quint32 nativeKey, quint32 nativeMods); static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods); static QHash, QxtGlobalShortcut*> shortcuts; }; #endif // QXTGLOBALSHORTCUT_P_H qlipper-5.1.1/qxt/qxtglobalshortcut_win.cpp000066400000000000000000000164201321252207600211630ustar00rootroot00000000000000#include "qxtglobalshortcut_p.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include #if QT_VERSION < QT_VERSION_CHECK(5,0,0) bool QxtGlobalShortcutPrivate::eventFilter(void* message) { #else bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType, void * message, long * result) { Q_UNUSED(eventType); Q_UNUSED(result); #endif MSG* msg = static_cast(message); if (msg->message == WM_HOTKEY) { const quint32 keycode = HIWORD(msg->lParam); const quint32 modifiers = LOWORD(msg->lParam); activateShortcut(keycode, modifiers); } #if QT_VERSION < QT_VERSION_CHECK(5,0,0) return prevEventFilter ? prevEventFilter(message) : false; #else return false; #endif } quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) { // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN quint32 native = 0; if (modifiers & Qt::ShiftModifier) native |= MOD_SHIFT; if (modifiers & Qt::ControlModifier) native |= MOD_CONTROL; if (modifiers & Qt::AltModifier) native |= MOD_ALT; if (modifiers & Qt::MetaModifier) native |= MOD_WIN; // TODO: resolve these? //if (modifiers & Qt::KeypadModifier) //if (modifiers & Qt::GroupSwitchModifier) return native; } quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) { switch (key) { case Qt::Key_Escape: return VK_ESCAPE; case Qt::Key_Tab: case Qt::Key_Backtab: return VK_TAB; case Qt::Key_Backspace: return VK_BACK; case Qt::Key_Return: case Qt::Key_Enter: return VK_RETURN; case Qt::Key_Insert: return VK_INSERT; case Qt::Key_Delete: return VK_DELETE; case Qt::Key_Pause: return VK_PAUSE; case Qt::Key_Print: return VK_PRINT; case Qt::Key_Clear: return VK_CLEAR; case Qt::Key_Home: return VK_HOME; case Qt::Key_End: return VK_END; case Qt::Key_Left: return VK_LEFT; case Qt::Key_Up: return VK_UP; case Qt::Key_Right: return VK_RIGHT; case Qt::Key_Down: return VK_DOWN; case Qt::Key_PageUp: return VK_PRIOR; case Qt::Key_PageDown: return VK_NEXT; case Qt::Key_F1: return VK_F1; case Qt::Key_F2: return VK_F2; case Qt::Key_F3: return VK_F3; case Qt::Key_F4: return VK_F4; case Qt::Key_F5: return VK_F5; case Qt::Key_F6: return VK_F6; case Qt::Key_F7: return VK_F7; case Qt::Key_F8: return VK_F8; case Qt::Key_F9: return VK_F9; case Qt::Key_F10: return VK_F10; case Qt::Key_F11: return VK_F11; case Qt::Key_F12: return VK_F12; case Qt::Key_F13: return VK_F13; case Qt::Key_F14: return VK_F14; case Qt::Key_F15: return VK_F15; case Qt::Key_F16: return VK_F16; case Qt::Key_F17: return VK_F17; case Qt::Key_F18: return VK_F18; case Qt::Key_F19: return VK_F19; case Qt::Key_F20: return VK_F20; case Qt::Key_F21: return VK_F21; case Qt::Key_F22: return VK_F22; case Qt::Key_F23: return VK_F23; case Qt::Key_F24: return VK_F24; case Qt::Key_Space: return VK_SPACE; case Qt::Key_Asterisk: return VK_MULTIPLY; case Qt::Key_Plus: return VK_ADD; case Qt::Key_Comma: return VK_SEPARATOR; case Qt::Key_Minus: return VK_SUBTRACT; case Qt::Key_Slash: return VK_DIVIDE; case Qt::Key_MediaNext: return VK_MEDIA_NEXT_TRACK; case Qt::Key_MediaPrevious: return VK_MEDIA_PREV_TRACK; case Qt::Key_MediaPlay: return VK_MEDIA_PLAY_PAUSE; case Qt::Key_MediaStop: return VK_MEDIA_STOP; // couldn't find those in VK_* //case Qt::Key_MediaLast: //case Qt::Key_MediaRecord: case Qt::Key_VolumeDown: return VK_VOLUME_DOWN; case Qt::Key_VolumeUp: return VK_VOLUME_UP; case Qt::Key_VolumeMute: return VK_VOLUME_MUTE; // numbers case Qt::Key_0: case Qt::Key_1: case Qt::Key_2: case Qt::Key_3: case Qt::Key_4: case Qt::Key_5: case Qt::Key_6: case Qt::Key_7: case Qt::Key_8: case Qt::Key_9: return key; // letters case Qt::Key_A: case Qt::Key_B: case Qt::Key_C: case Qt::Key_D: case Qt::Key_E: case Qt::Key_F: case Qt::Key_G: case Qt::Key_H: case Qt::Key_I: case Qt::Key_J: case Qt::Key_K: case Qt::Key_L: case Qt::Key_M: case Qt::Key_N: case Qt::Key_O: case Qt::Key_P: case Qt::Key_Q: case Qt::Key_R: case Qt::Key_S: case Qt::Key_T: case Qt::Key_U: case Qt::Key_V: case Qt::Key_W: case Qt::Key_X: case Qt::Key_Y: case Qt::Key_Z: return key; default: return 0; } } bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) { return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey); } bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) { return UnregisterHotKey(0, nativeMods ^ nativeKey); } qlipper-5.1.1/qxt/qxtglobalshortcut_x11.cpp000066400000000000000000000174261321252207600210060ustar00rootroot00000000000000#include "qxtglobalshortcut_p.h" /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in the ** documentation and/or other materials provided with the distribution. ** * Neither the name of the LibQxt project nor the ** names of its contributors may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ** DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** ** *****************************************************************************/ #include #if QT_VERSION < QT_VERSION_CHECK(5,0,0) # include #else # include # include # include #endif #include namespace { const QVector maskModifiers = QVector() << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask); typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event); class QxtX11ErrorHandler { public: static bool error; static int qxtX11ErrorHandler(Display *display, XErrorEvent *event) { Q_UNUSED(display); switch (event->error_code) { case BadAccess: case BadValue: case BadWindow: if (event->request_code == 33 /* X_GrabKey */ || event->request_code == 34 /* X_UngrabKey */) { error = true; //TODO: //char errstr[256]; //XGetErrorText(dpy, err->error_code, errstr, 256); } } return 0; } QxtX11ErrorHandler() { error = false; m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler); } ~QxtX11ErrorHandler() { XSetErrorHandler(m_previousErrorHandler); } private: X11ErrorHandler m_previousErrorHandler; }; bool QxtX11ErrorHandler::error = false; class QxtX11Data { public: QxtX11Data() { #if QT_VERSION < QT_VERSION_CHECK(5,0,0) m_display = QX11Info::display(); #else QPlatformNativeInterface *native = qApp->platformNativeInterface(); void *display = native->nativeResourceForScreen(QByteArray("display"), QGuiApplication::primaryScreen()); m_display = reinterpret_cast(display); #endif } bool isValid() { return m_display != 0; } Display *display() { Q_ASSERT(isValid()); return m_display; } Window rootWindow() { return DefaultRootWindow(display()); } bool grabKey(quint32 keycode, quint32 modifiers, Window window) { QxtX11ErrorHandler errorHandler; for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) { XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True, GrabModeAsync, GrabModeAsync); } if (errorHandler.error) { ungrabKey(keycode, modifiers, window); return false; } return true; } bool ungrabKey(quint32 keycode, quint32 modifiers, Window window) { QxtX11ErrorHandler errorHandler; foreach (quint32 maskMods, maskModifiers) { XUngrabKey(display(), keycode, modifiers | maskMods, window); } return !errorHandler.error; } private: Display *m_display; }; } // namespace #if QT_VERSION < QT_VERSION_CHECK(5,0,0) bool QxtGlobalShortcutPrivate::eventFilter(void *message) { XEvent *event = static_cast(message); if (event->type == KeyPress) { XKeyEvent *key = reinterpret_cast(event); unsigned int keycode = key->keycode; unsigned int keystate = key->state; #else bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType, void *message, long *result) { Q_UNUSED(result); xcb_key_press_event_t *kev = 0; if (eventType == "xcb_generic_event_t") { xcb_generic_event_t *ev = static_cast(message); if ((ev->response_type & 127) == XCB_KEY_PRESS) kev = static_cast(message); } if (kev != 0) { unsigned int keycode = kev->detail; unsigned int keystate = 0; if(kev->state & XCB_MOD_MASK_1) keystate |= Mod1Mask; if(kev->state & XCB_MOD_MASK_CONTROL) keystate |= ControlMask; if(kev->state & XCB_MOD_MASK_4) keystate |= Mod4Mask; if(kev->state & XCB_MOD_MASK_SHIFT) keystate |= ShiftMask; #endif activateShortcut(keycode, // Mod1Mask == Alt, Mod4Mask == Meta keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); } #if QT_VERSION < QT_VERSION_CHECK(5,0,0) return prevEventFilter ? prevEventFilter(message) : false; #else return false; #endif } quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) { // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask quint32 native = 0; if (modifiers & Qt::ShiftModifier) native |= ShiftMask; if (modifiers & Qt::ControlModifier) native |= ControlMask; if (modifiers & Qt::AltModifier) native |= Mod1Mask; if (modifiers & Qt::MetaModifier) native |= Mod4Mask; // TODO: resolve these? //if (modifiers & Qt::MetaModifier) //if (modifiers & Qt::KeypadModifier) //if (modifiers & Qt::GroupSwitchModifier) return native; } quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) { QxtX11Data x11; if (!x11.isValid()) return 0; KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data()); if (keysym == NoSymbol) keysym = static_cast(key); return XKeysymToKeycode(x11.display(), keysym); } bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) { QxtX11Data x11; return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow()); } bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) { QxtX11Data x11; return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow()); } qlipper-5.1.1/src/000077500000000000000000000000001321252207600137615ustar00rootroot00000000000000qlipper-5.1.1/src/clipboardwrap.cpp000066400000000000000000000044001321252207600173140ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2015 Palo Kisa 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 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 "clipboardwrap.h" #include #include #include QScopedPointer ClipboardWrap::m_instance(0); namespace { class WorkGuard { public: WorkGuard(bool & guard) : mGuard(guard) { mGuard = false; } ~WorkGuard() { mGuard = true; } private: bool & mGuard; }; } ClipboardWrap * ClipboardWrap::Instance() { //instance can't be created in static initilization time because QApplication object doesn't exist in that time if (m_instance.isNull()) m_instance.reset(new ClipboardWrap); return m_instance.data(); } ClipboardWrap::ClipboardWrap() : m_clip(QApplication::clipboard()) , m_shouldEmit(true) , m_timer(new QTimer) { connect(m_clip, &QClipboard::changed, this, &ClipboardWrap::onChanged); connect(m_timer.data(), &QTimer::timeout, this, &ClipboardWrap::emitChanged); //Note: the timer is here as a workaround for signal flood for primary selection // from GTK apps m_timer->setInterval(0); m_timer->setSingleShot(true); } ClipboardWrap::~ClipboardWrap() { } void ClipboardWrap::emitChanged() { emit changed(m_change); } void ClipboardWrap::onChanged(QClipboard::Mode mode) { if (m_shouldEmit) { m_change = mode; m_timer->start(); } } void ClipboardWrap::setMimeData(QMimeData * src, QClipboard::Mode mode) { WorkGuard g(m_shouldEmit); return m_clip->setMimeData(src, mode); } qlipper-5.1.1/src/clipboardwrap.h000066400000000000000000000027221321252207600167660ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2015 Palo Kisa 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 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 CLIPBOARDWRAP_H #define CLIPBOARDWRAP_H #include #include class QTimer; class ClipboardWrap : public QObject { Q_OBJECT class Creator; friend class Creator; public: static ClipboardWrap *Instance(); ~ClipboardWrap(); void setMimeData(QMimeData * src, QClipboard::Mode mode = QClipboard::Clipboard); signals: void changed(QClipboard::Mode mode); private slots: void onChanged(QClipboard::Mode mode); void emitChanged(); private: ClipboardWrap(); static QScopedPointer m_instance; QClipboard * m_clip; bool m_shouldEmit; QClipboard::Mode m_change; QScopedPointer m_timer; }; #endif // CLIPBOARDWRAP_H qlipper-5.1.1/src/icons/000077500000000000000000000000001321252207600150745ustar00rootroot00000000000000qlipper-5.1.1/src/icons/application-exit.png000066400000000000000000000033401321252207600210540ustar00rootroot00000000000000PNG  IHDR szz pHYs^tIME kbKGDmIDATxW[lTU]ޙR>JUbĆ"HH0 ["9=g̙ kSY+͋AMSLhU:;3}}f9-I4Zuu eԨ}'O&ޡ rzM0^]h65 Pшn6\߉D]=R |֏P!|uh‘A'͜938S"? ep;MJ29g{[1b*;Vś_@ h`#obrV$WO j (_{O}E,)ą!b6=IΙqX)d>[kBaB&ۖSU,bz {w ;UD2Il/&e"RD[Oq XKY(Uasze 'WQ-lm%e1pgU1P, w׆h zZ̲yPH" Ȥ !@@{RA|ϞGDLop:>  ?͓"*8c1!oj07:,Gb /pC>Z2YDÜ.ЭWh4W{Q#(Ep%MsШ x .1=6tl,Ϧ {t ENXqitDu8>Ў0n/ye{f7vDhIENDB`qlipper-5.1.1/src/icons/configure.png000066400000000000000000000026521321252207600175700ustar00rootroot00000000000000PNG  IHDR szzsRGB pHYs^tIME)%FUbKGD*IDATxڽV[PSW5h"be4"2EBCx"Ũ!!ommVU:-XEZ|ؖ)Y?3k}]{a#\]gX+Tx+ߴ;_[{~6c wX]ߏALxxNdɉZVr{zLx^PkT֕exl%0j^S]x%hA%pX+˷ogx\ֻg|dm~DUH^~?NY,cPyF7}ϋ=\il*R+֌&aUm<R{kw?K&^C孺sƝϻIG; U؜ۛ-?XL}4g 5]Pռpb9 ^fZi91NHJ8%zދ|QW_gNn(; V3D{6ZDeuo?3g0w\D?6T|Yj6B:u-tK LH0W=vMFgY.򱯩9`2 hE a}ޭ5DD"kx[P^(b gJ3p8D[EIpVwOn"x׏44DigƲbQCG܎Gq#k~/q* #0m4T@&˿FX%%ӕ?]j%asj}fɢ%* ˅Bxzy".>e.zp<ٰٔqR S ((sppHa<+ ާǏ6bBD vvv* =+~ya 77BJj D$i^{Ξ'$V:h2 3T b"߅ȊD\7> r]ZT`Qkr7 t|V$$&@* "CA5-2\TkG0`^$ 'Px1[TʷhEѱSJھ}!Q{mmmAwG_:4ǩץBG?4Gv/<4\_22:cbm\| ?vٳzz~/:i*p?aDobD7oX Ũ#94hD(誊IsH!zeϞ+ka¦50QgGqr9[G߻`IWyMU Q }|Z/oX5bZu!z 0v씩3N^"w|$A~`e^߷Zx†K50KN Sywّz0kH |a-PDcZp dGUx&,c՗ZwW.;`iހKDoC؟Hy|wY 6.VIE>ùe&)XzaҊp3oVH݊wӰE(|:3B8\ɩ3Uy&-YB<| ;%n/. 4+'ct o6~=t(A>W0&.J (n,Y%Lt~]8Be)$!n7\>7tꀯTeD*Le2J5Cfu"5ʌƤI+6MgV27/c_T^+H@3T,$F-%dZxR G>藛7=Ҿi9jt6Tzrd) @5=?vWjcr1Q@[Mib( o, xYeE xMmrɰHv=@G h[ʽ w9R8Ͼxj:%ޠ\^nZ4yeD*[*,8!.LKDZ-|k J O.+Fdx+F 'O@"m𯁡\֏1F }Y }6}K'쮪Ѩ @vKL 1_蓚x.+@\[eZhI X{*+n4,ɜXr68|$R EIކs+_j~fEяnLQ쪝NDy I -HVGP- r RypE-3!6Ѱ`M/ޮ2x- -p1p`,lds&e{F<˦Y MJ!noW=zqy1x3i  GiZߚ5AEz$ , eѣ̌/K6\pClBHq r3@rj#oa:ϣIENDB`qlipper-5.1.1/src/icons/edit-clear-history.png000066400000000000000000000037571321252207600213260ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<lIDATxՖ{PSWDZ;ul"ʄʖqvZ,j%HE  y'7B VwE@إu)XyXP_ω ),39{~{>9s~xTi`J9i~eNC)sp37Ѡܘf 8V L8+>߹NO3u$4){)d2 | 1d2_Y,.3U6̤QGjܝ_JwXta#Ú` 8qVmfd ZR *XHd"".p,`qxyy4Bi-Ȱ߇ 7sdb?ɿCjMS|BIf-SF-h*PiPBB DUGm:ܠ;pRž^U3 Xֹ‚s&Pn d#pcmᾤtԝ5!矝 VH٭ݰkkZḇw[ 1PJy+u mCT>;ᕭ@7gA~J?4u U{Db LP ֢ *;{绬myD4nD vV}uwYySPGi.GJo>0Bn y_(1W)wVv ipb²^]lA9SB\ x0_qŏ@E4dyz]w XvgksY~tm*!/Q+z~Eq=[ 򩹪錁{"eVƒ-檠XUj9))  $ypY4G!m>PV>PQN. }{hu \6E6<}if& 9 AY3R=.6Wm?Zb֔Fq6 oM꬏6K[itt+_455 F땕mR\®HUI6Րc&O[|k>0^F6p^pU ا\GW'NlNmEPh6,-ci> Bl41boKbHl3'b8ni 6E%sT%(id-ulyݐo6\p9; )e+$$~ L6!dnJ3`wH*ɸ {|{R!m{*m a! >l_J'Z-[N(11Y?bMW5DeHtÊà@e|eZV0|ès!9- 5X!>d A}9hw|[xY7X_PE< a8jh?.c"g8G`^D&|$?wC p~8?Ǚ]7H "-F DZ RZH;aFAziL_AQ7IENDB`qlipper-5.1.1/src/icons/help-about.png000066400000000000000000000031441321252207600176440ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATxW[lTEvv-ъHIH4<` b (1(>-.4b#.*;vwmz&)v /~ɷ3;;s䜳L#jLQB(qd00(A!Vc ƈ1KL c[JfOPɕV2 kCvTM O47&v.׼@2cKyh*M/jU0t44h`"@EO2WG8k2!#6+}pھLƁ }iXZ#@my-/ ]Bֆ;`XCJ3j:y|8GYؔ0$\!Pݳo:xtmp"x s͖!(C0zS>߈c8C)p5P B7uC""f{ԙ>ص{8Lݐ)"~ Z`0JȀ } OU8\Rͽ81w1­`9G>0xHD]~'QD-amt]Mƀ  {5f1F@XH,0"HHj-.P鬍q7 .* qxwO=3L,f:Ea41 A3;a۶4N|pZEآE:Ύ= : Rj(6opx+' c eE=eq"TܯzrFٗR6}JD*6"ޠ9iX%QWB' e EޙsdoC>}؀)&j' Ar MsUm5:T]xh>XsѪjDR|(R ׀eS E׆cF.:[F0p@ ri d^q1cDZ2ʃ0pbbpAsׅl5urw&g6ѵɅBYw 檇YpQ7? 6eO6IENDB`qlipper-5.1.1/src/icons/image-x-generic.png000066400000000000000000000030201321252207600205360ustar00rootroot00000000000000PNG  IHDR szzsRGBbKGD pHYs^tIME  ٲIDATXoWwfe]ѺkvX}!44II( E|?ʟJ[hD*ZV_ jIqS'm;^z3sÎ7k; UKt5wf9}s{ƧX,/,,szXt\.̌nM.9뮡XmNoihq{H3yk5ϯ:|lefDSI xY SզLVR._v&9[8 josb1XzzٳgGժv3̭qlLJ8j5=s:qjn߆nh|ɤ=#կ=x.{x[obmU c?<0 \TQk76r#v9E 1Л<{(d'l>H>i)bx3 S199yn8 ƹ`[IENDB`qlipper-5.1.1/src/icons/knotes.png000066400000000000000000000031571321252207600171130ustar00rootroot00000000000000PNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATx͗{lEǿ3{G{}-}Rʫ%F(i)DфQcbbF"ńA!A)Em"JMD "QBi)mxi!7M{7Dr @J?NE3*F <^'PCϥE u/{Fyck\HK$8vq{FVNJ@r":\ \ݵsިNΙ(5.JkO+vӗmI.(y.h&JF'@7O3v8J^$%Kfa,m\]]~߄s6$rRJzt2.A^b׋ 4u #oZKz*I (='} Ì}1eB?o˽8\Ƅ"!% ?;-"'SϴiPvd5|'ʓ"k%@=ٝ$2kBlqaS AoN{Sݎt*zNzd_{"#cLl@ y%8K,g!]`0=%fBwsqp̫QލAƝPub]h%Ƞk! ,2 n|`Z)9kpA B Nb[ Ѿ,@("d]Qy jHOpNq ]8;ѕpҀ!(!P8T@W!dp bL^<$@͇ fFJOMG J._Dü;STNuw\ N'TDNvP0X2FA )<\X@  nA +HBYS<%;} 2wդA9s6!3F'v3[NWfd٠Kl|M*ō9 8{jd Bd]*{V*>#ggVY@)b/K&",j6a8up$sOm lٌ00->p4F$'xLvO;68nbBr`En.A  9kkӶ5s "~W; C=ՄW!N=x:QT60 `k! ZwoAЄ͸'~T( v¶vL0!85KWVl`[efEEih4N+--Q s@f]ӕUv|'bqM&@fz+잰(l<{,tGEQnp8z[ZZڐ;M]Z 5-p: V0D{ AUϥGNtu$''?~\Yaaaui ,ks4wt9?cP(vwwBB >^ot>w4IENDB`qlipper-5.1.1/src/icons/qlipper.ico000066400000000000000000002040761321252207600172550ustar00rootroot00000000000000 ((      '3=@>2+%  -IZjnk\SJ@0)# #Bi\\\}}}IIIwlYOE=.'! /U]]]yyy333~shULC;*$ 333;ghhh|p]RH>/'   ***333@@@UUU ggg3331S XXX ym\RH!!!@---2555,<<<'FFF#]]]jjjzzz  jjU|LqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqLqJnGjA`6Q4LW|8HO-&8,B0H4N8S;X>\@`CcEfFhHjIlJmJnKoRxa| 'k]yj&ZgTil|W y|XwSc[rtd??? iFmv Qdd}zfrw}/555 G|v3bmTim~a*MYK a| [hb{Q ")_8"v@TX4u[l yQ1 7lG- EFEd?"www  [8 uttwR, =?>iD&Y4 tttvxxuL,|||344f@  W/ dfej?!uuu())W2 pG)SVT_=  ! wN( xxx~g<DFER0  jD&NPOT0 kD VXXZ1 pE&^``W9pH(gih_: xO(|||qtsd9 tF%{|{\6 sJ)~~~`: qF!W-c7 vvuj> g8 {zwa6 ~~~876[2 R.sB!lllc: }}}#""Y3 I%l@ ZZZ_8 V1E#g= HHH\4 R.wB zzzc9 |||333X3 I,p@ iiib9 {{{Y2 I$l@ VVV`9  W1F#h> BBB^7 V1yF#tttf= ---]6 K' rC!ccce; Z3 I%mA QQQa9  W2~G#h> <<<\4 dQ.w0un@ C~vvvU3 fg###rrr---A&'1B=ERUXBBBxC& JU)#/1.(# {    $$ -,d hoh޶ MUKXXs}n3]30Y<ݿ] BkoE k  llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll```RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR```6Fr46r⭭???????}qlipper-5.1.1/src/icons/qlipper.png000066400000000000000000000171221321252207600172610ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATx]i}wϱXZjA !@!\8>$*LH[BUH*c'8e;1 $,$@$9wf:_O{glۃ+ozf{A֮]{X,.i}љt (Uy?w)G&!S M5Bqdk/3@-.PNd_+ο P>g}ˇVږb&(YFGGQڶo_6U7t>?OUښ^|e P;wn#M@'LB`8/{K/3@m:{yǏ5ME 785'r4?Lfgc5>Hd4MЅxD6ncj G|?U8fjjIc(Ml"3~8{cl]5{p(QOk5,'6T(%jj$jULKbL]4ztxfcLya_cط^cDaθUˊ`&>+"Tm3$$>-@賈b~}q߶f,|8i0HM-QIJ:܂`ɪfE3dk0ǥA7с-XJs6CX]kM(S/w0UiK>ifsDL %6Ś~@Μzjz T2>ω/Zjkt8 A_dEji.?TJ:n`:t(ff|e \!MްQ>E$3a̠E,dhv SCE-gsNP]A6wV$Rb3QF&y:ou Q mf jZ#h6 EP,axRZY}T2ꮳ\plhl4@c&(AP*M BI(Qm] `tr=*&/:i 0FFFL)od{.2cE#CT3@!s9\ȖiKA.^hJW\ FlF!j` $̙3A҂kqIϸ}rfb ĽT #R|ePz$2W{ėj n3Y$mFt+тeZ+ˠ2uGYPfNuJ\Ez|+n U{[YTy@|I IfWe/K!9g'`j8W~|A%g}1?fdQ$})adF+KE?@ ZyL࣐rSWwPpPEUޜ DcLãDGQ)뮻mذa;f2TL}gA$k7D <4&7|O9]bWRidArL8dKta/zGn:oYs̩kk޽)x_ ]ATSKl B-1jѣtD4S| fo׿|U\qUW5wi71|Ei&g _f@ ;έZ-@ϱ±ߠ'5JVPK=u=knH4v?+=0}H\A0>xqtiM6MЭQV+SLurt"Ax'Pw wPRA2 x"@!!̛7k.lIӦMOp͛wirAj7giWqX2 -K92׷Ҳe߅~3{Nf8gKXŎ9\,C>H`hwy4kL1 T[1x5tU{{{p{{;l2M>Lgp ̄aFr 4fSx&Ο?o,o4es*0:k7xc#H~P n3 jׇ~dz;t\/g/<\3qVp3@#BAaqp>@ȎW!4M}<-_fL ^0-0@&z3j~g 83qLd{h֬Y2pܫ{K.mp| fHQ_T 뭟;wϞ=Z*?3M0Z3h>^x} D%? bjp@DVe0 a9uMRJ' eqf+o +$? "L@(C483pχ:::u<~0 fp fxy|P [~@ 4,Bl$\#<i;TyKC-)Gs!.Mss._| W?#L(Y/{" غk$d*%,8xCuY)K9Ͻ?|0-\x s gM&Ҵp/{π+xZҴ6A&{0 X7Hyia(܂GsIMD[ٹ]ȧӭpV8T; + 'U5˨RAVGխ)Ieq)$ `(B9={ҮfJx?$ڭpM%}/x~ iYvt w`~jٶR(waM9~TI&n,%? MW)^|$t XD (|CΙnDuAQ\h`&{o>@ |%xQl>9 s bqU;A>LH^WP /"8bc@I `% + =SE$\ھR(L@@;`̙tiS/zh 4" 'Ыf~hܹLp~Ð~;eW% "63ljM0UxY?`բ< -$.4: ? PPs'!^reViFa|@9Ҫzy[PJ07Z0 b``Ʈ]M=*>oS(D4kw0@y|0===t]B; ZǪS 0y L "K-^{dڰS2a|k֬FpŠ@$H]?>4C%j ܪK }$ו+͹%r/̀J+SZY r!A `F0_~)bLkI4]eAn3KP6?hR"ا|s/;:dGp-ON>+~%Q)wê!Q<{cpԤ 3` ͅ+~3b::7tv.gxy,9Du!|iػԅ\~"=Kl5bP1ل0X+~~9na ;[A;IrqH'NPܐPwKşsWpMza3ȖY|e |;H[3Ϗ1(0Fd`,t[`M~o?=BMjuYq",ޥ_~B1)`sْ?2ǡ>wpwQ/S}\O`D8x1a{Sdlr 0$?gjˢwZl.E_!":= npdal/.6 W.v ;{"5Mk˗S#>}g+w1%|Cj?wϦC_ _3/(L%idx;?`6?vddrW_5,Sb~ 3İjk1ĬpnP91`Gp/3@<x"*S[CBY 0,lӲA0`:~v!"J$%MT,K=/&~?A` _3W :ַ%_j.%GGtZ{ʻ # 1/_5A!Og < 3ˤ1aG,݃!ájZݍ瓜RiIplqڷv#$@hn[ag$rS X J#2s H;?044$Ҿi @RJzy_|eD# ܔg}61O=f_+ ff&ӹsnyc)1m$j{fsuϖ-?ڸiZ?Ĕ}dFjKsNɗMHH`^ff<ӨTq`㉭aI| %R̕,f1Ӣ 3ó?EOL?q7A;;ӹRK͗lYM'F/4h[K*.#WW+5<$]cYtzʏ|NmEZ_vk-?ϛ^җ5@7IŎ<w hY5u"6T#6Q!?oA/O?^Gw}@=%Ms[n^LYeQ}m>{s3$?'4jZn;&^^浤hVcDB?MnYGo_G=GӴ>rDp&[ 8p?Qg\ѧ;l_ `0:_:{'z/,3{zўhcT=I:-JO7жO;BsO'ZR*C-ghrYSz膕sR۸qiN?۾ONi}=|~w>/NQOҰ+oCOnc~j.:\ HN዇O/Z*K4 }R%v@ ӎ`E;&BڊHAQ0i9">!0Fyigs^nýJhc$ӦsFx3Y >,kpK-n OYu37bCt%Đ }6`6+> W /鿎]8e0b 1mDKIZ C3#\/.,qa.| Ltu4 ;ky%^nΎ!\U_DOü3't©Xg;?W@ ,>9w=% 1Q 9*Vzʧt Ś؁yKt:9Qf,LJix9 #KB)U ]ŭ_^Ҏ=`PT-E"X%5 eYV@$wL6Cc'6>Lc~%wHs9Y\iR_/?Ջ?k˽GGYё{m迂%sdv.@GGJ$ Z}ot f3_AMA*I4G?` x0>QG+apĦh 7ykT|tV?GCcccc󹼇 +?:8p.yYS^5 STٿSE;2u$;")޿oIENDB` qlipper-5.1.1/src/icons/text-enriched.png000066400000000000000000000034551321252207600203540ustar00rootroot00000000000000PNG  IHDR szzsRGBbKGD pHYs^tIME -0HIDATXýmTξj|TK#6%aB)DXP0!i ih~ _4E4F%j;s};3ή;B{3s_y9x2:4@qk0ɺu`pp˗"i Q@! f QRYбp!@s#xYq#$Et|h:>}t͛6LhE0H6J*Sd꣮2kA7G"Y0@ų"RT(/GtP`$TT\z CEOݬ-s(\|_D1JbQ 1?IBFR ZuvtwwӒЦ@% Wg 5$Bz>d2Ġ:^I5Ja(a/y;/aHH^u%"P0S}='V[Y5f㨥ZHk à=rFYD槁Ta> + tttE7n֭[5"aq%0˲prђϑ9><a~hG{{;-p}h<,8X'm7㌘ޜgzI=O0[H_X)֭X0d+Da(e  b)ΝKe@&}e\CC455nW|9 9fܸqT T띝ضMoo/--8K[{(˵PvI})VDGQ,8<ϣ)&"0$JQL&&&⾐Lz.?e= Ƕ}oHP(ߏ8ܼO-v}~;"lf0ȢT*qAerEFF4g!J?>gy 0'CC\C ,{fZ2|(3*;}r\a׮]{g+ƴ.u}u $}q[LӔ|~L޽+W\qLS&e8ֆӽ`COxYhς(9/AL Oڵ1"<ǶmLӴ9ŋ};'t:MOOmmd!'@hDb(>0ix˲f__߼g܆|l{l5C!"Da)61ZZ[Yh{_|?@{[[@ 꽦ֱ"DZd%;vxի'ڧ$_ZR,5kּ7%Xt6j R TCfݯHRTIENDB`qlipper-5.1.1/src/icons/text-plain.png000066400000000000000000000036531321252207600176760ustar00rootroot00000000000000PNG  IHDR szzsRGBbKGD pHYs^tIME  +IDATXýWMl}=3aքFDv RHP$@a 8K)H^p3q͞"Y6KǦ=oa ̮|Ҩk{^}%PիW7ugnkk (4k KFЅ4 hBT귪FB R)P$lg%~5=h$RB4i̠@FB:F % @<@<.b PRK{H~S*kZ]$R]mE3tM"ÕC2JVb7oe@(+}J=dLӨ6R LDGGV@hڢ޴e ]LիzRhko H}(е~=R,aB`k׮bY!B(qxKbFǡ ]ס:4M?~%=q섹X4b]]]z-4<,`64MC*زe h&mB@DD~ڐR A}D2x @", @H$bp#L\. p]h$:;;P:!s4Mׯ Z $=ϣ8t]m/*a;Ay,IRJRTJ>d2$ .]ץ8+XF!DL&a&lۆJ(hjjBTݘH$hnnFRA.CCC2Lu'\.Ǚ844Į.>}5ʏ?m۶˗`__ݻwsddmӲBpEZEu2Ѷmrvfb?911!ƍ?q]vvv<ϣeY,J(=$XJ)Zw .$o˗/W}d[[IT,Ӥ9?__DQ(J@P+W}7nĩSPTB<^gT($HU(H& (dyرc|sݻǖ޿}-wq]/yR瑟Ղ8H$hjj0Mc0ˢB쳓<>+ N>d3@j]Xp(.4J RJO?=599JS=-+ ͡bTlYx8~ONJrmTS! ^]R!%%{7m>Os TCCݓ<йnݟcW?k!fM|~{|c2NO K*3dnrIENDB`qlipper-5.1.1/src/main.cpp000077500000000000000000000071351321252207600154220ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include "qlippersystray.h" #include "qlipperpreferences.h" int main(int argc, char **argv) { QApplication a(argc, argv); // Note1: Allow only one instance of qlipper. // Note2: We can't use QSystemSemaphore as it doesn't provide // non-blocking API. // Note2: On unix the underlying memory segment can outlive the // QSharedMemory object(s) if the application crashes. // So we're refreshing the "alive" timestamp each 5 sec. QSharedMemory single(QStringLiteral("qlipper")); QTimer refresh_timer; refresh_timer.setSingleShot(false); refresh_timer.setInterval(5000); QObject::connect(&refresh_timer, &QTimer::timeout, [&single] { std::lock_guard guard(single); time(static_cast(single.data())); }); if (single.create(sizeof(time_t))) { std::lock_guard guard(single); time(static_cast(single.data())); refresh_timer.start(); } else if (single.attach()) { std::lock_guard guard(single); time_t refresh = *static_cast(single.data()); if (refresh > time(nullptr) - 10) { qWarning("An instance of qlipper is already running!"); return 0; } time(static_cast(single.data())); refresh_timer.start(); } else { qWarning().noquote() << "Unable to create/attach shared memory(" << single.errorString() << "), singleinstance behaviour will not work"; } a.setApplicationName("qlipper"); a.setApplicationVersion(QLIPPER_VERSION); a.setOrganizationDomain("qlipper.org"); a.setOrganizationName("Qlipper"); QSettings::setDefaultFormat(QSettings::IniFormat); // for QByteArray to QString constructors // QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); a.setQuitOnLastWindowClosed(false); a.setWindowIcon(QIcon(QlipperPreferences::Instance()->getPathToIcon())); // potentially load translator QString fname(a.applicationName() + "_" + QLocale::system().name()); #ifdef Q_OS_WIN32 QString location = a.applicationDirPath() + "/translations"; #elif defined Q_OS_MAC QString location = a.applicationDirPath() + "../Resources/translations"; #elif defined Q_OS_UNIX QString location = TRANSLATION_DIR; #else // fallback QString location = a.applicationDirPath(); #endif QTranslator translator; if (translator.load(fname, location)) { a.installTranslator(&translator); } else { qDebug() << "Translator is not loaded" << fname << location; } // end of translators QlipperSystray s; s.show(); return a.exec(); } qlipper-5.1.1/src/qlipper.qrc000066400000000000000000000010351321252207600161430ustar00rootroot00000000000000 icons/qlipper.png icons/application-exit.png icons/configure.png icons/dialog-cancel.png icons/edit-clear-history.png icons/help-about.png icons/image-x-generic.png icons/text-enriched.png icons/text-plain.png icons/quickopen-file.png icons/knotes.png qlipper-5.1.1/src/qlipperitem.cpp000066400000000000000000000212311321252207600170170ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include "qlipperpreferences.h" #include "qlipperitem.h" #include "clipboardwrap.h" QlipperItem::QlipperItem() : m_valid(false) { } QlipperItem::QlipperItem(QClipboard::Mode mode) : m_mode(mode), m_valid(true), m_enforceHistory(false) { QClipboard * clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(mode); // qDebug() << "QlipperItem::QlipperItem(QClipboard::Mode mode)" << mode << clipboard->text(mode) << mimeData->hasImage(); // Clipboard can contain more possible values now: // - any mimetype which is not supported (qcolor, custom mime, ...). // in this case it will NOT be stored in the history but it will // be kept in the clipboard itself // - an empty clipboard. On X11 clipboard content is owned by the // application, so naturally closing the application drops // clipboard content. In this case the latest item should be set again. if (mimeData->formats().count() == 0) { m_valid = false; m_enforceHistory = true; } //Note: reading all provided image/.*bmp data can make gimp crash // workadound until someone fixes this in gimp -> just read/store only the image/bmp // and don't care about other bmps const bool has_bmp = mimeData->hasFormat(QStringLiteral("image/bmp")); const QRegExp re_bmp(QStringLiteral("^image/.+-bmp$")); foreach (QString format, mimeData->formats()) { //qDebug() << format << mimeData->data(format); // For a simple text copy in Emacs, a lot of formats are stored: // "TIMESTAMP", "MULTIPLE", "text/plain", "COMPOUND_TEXT", "TARGETS", // "LENGTH", "DELETE", "FILE_NAME", "CHARACTER_POSITION", "LINE_NUMBER", // "COLUMN_NUMBER", "OWNER_OS", "HOST_NAME", "USER", "CLASS", "NAME", // "ATOM", "INTEGER", "SAVE_TARGETS". // When mimeData->data("MULTIPLE") is called, Emacs is no longer able to // copy to the clipboard and complains with // "Selection owner couldn't convert: MULTIPLE". // When mimeData->data("DELETE") is called, "Binary:" will be displayed // in the clipboard history instead of the copied text. // Since mimeData->data() seems to have such side effects and is not // cheap at all, it is better to call it just for the real MIME types, // i.e. those containing a '/'. if (format.contains(QLatin1Char('/')) && (!has_bmp || !re_bmp.exactMatch(format))) m_content[format] = mimeData->data(format); } m_display = mimeData->text(); if (mimeData->hasHtml()) { m_contentType = QlipperItem::RichText; } else if (mimeData->hasUrls()) { QString s; foreach (QUrl i, mimeData->urls()) s += i.toString() + '\n'; m_display = s; m_contentType = QlipperItem::Url; } else if (mimeData->hasText()) { m_contentType = QlipperItem::PlainText; } else { // any binary stuff m_contentType = QlipperItem::Binary; } } QlipperItem::QlipperItem(QClipboard::Mode mode, QlipperItem::ContentType contentType, const ClipboardContent &content) : m_mode(mode), m_contentType(contentType), m_valid(true), m_content(content) { m_display = m_content["text/plain"]; } QlipperItem::QlipperItem(const QString &sticky) : m_mode(QClipboard::Clipboard), m_valid(true) { if (sticky.isEmpty()) { m_valid = false; } else { m_display = sticky; m_content["text/plain"] = sticky.toUtf8(); m_contentType = QlipperItem::Sticky; } } QClipboard::Mode QlipperItem::clipBoardMode() const { return m_mode; } void QlipperItem::toClipboard(const Actions & actions) const { if (!(actions & (ToCurrent | ToOther))) { return; } ClipboardWrap * clipboard = ClipboardWrap::Instance(); QMimeData *mime = new QMimeData(); ClipboardContentIterator it(m_content); while (it.hasNext()) { it.next(); mime->setData(it.key(), it.value()); } if (actions.testFlag(ToCurrent)) { clipboard->setMimeData(mime, m_mode); } if (actions.testFlag(ToOther)) { clipboard->setMimeData(mime, QClipboard::Clipboard == m_mode ? QClipboard::Selection : QClipboard::Clipboard); } } QString QlipperItem::displayRole() const { switch (m_contentType) { case QlipperItem::PlainText: case QlipperItem::RichText: case QlipperItem::Sticky: return m_display.left(QlipperPreferences::Instance()->displaySize()); case QlipperItem::Url: return QObject::tr("Url: %1").arg(m_display).left(QlipperPreferences::Instance()->displaySize()); case QlipperItem::Binary: return QObject::tr("Binary: %1").arg(m_display).left(QlipperPreferences::Instance()->displaySize()); } return ""; } QIcon QlipperItem::decorationRole() const { if (!QlipperPreferences::Instance()->platformExtensions()) { return iconForContentType(); } QPixmap pm; QString cacheKey = QString("%1_%2").arg(m_contentType).arg(m_mode); if (QPixmapCache::find(cacheKey, &pm)) return pm; pm = QPixmap(32, 32); QPainter p(&pm); QString theme; switch (m_mode) { case QClipboard::Clipboard: theme = "#004400"; break; case QClipboard::Selection: theme = "#000044"; break; case QClipboard::FindBuffer: theme = "#440000"; break; } pm.fill(QColor(theme)); QIcon icon = iconForContentType(); p.drawPixmap(0, 0, icon.pixmap(pm.size())); QPixmapCache::insert(cacheKey, pm); return pm; } QString QlipperItem::tooltipRole() const { QString m; QString t; switch (m_mode) { case QClipboard::Clipboard: m = QObject::tr("Clipboard"); break; case QClipboard::Selection: m = QObject::tr("Selection"); break; case QClipboard::FindBuffer: m = QObject::tr("Find Bufer"); break; } switch (m_contentType) { case QlipperItem::PlainText: t = QObject::tr("Plain Text"); break; case QlipperItem::RichText: t = QObject::tr("Rich Text"); break; case QlipperItem::Binary: t = QObject::tr("Binary Content"); break; case QlipperItem::Url: t = QObject::tr("URL"); break; case QlipperItem::Sticky: t = QObject::tr("Sticky Item (Plain Text)"); break; } return QString("%1: %2").arg(m).arg(t); } bool QlipperItem::operator==(const QlipperItem &other) const { // do not check contentType here as we need to compare sticky vs. rest of the world // Note2: If we're synchronizing clipboards, clipboard type/mode don't need to match return this->isValid() == other.isValid() && (this->clipBoardMode() == other.clipBoardMode() || QlipperPreferences::Instance()->shouldSynchronizeClipboards() ) && this->content() == other.content(); } QIcon QlipperItem::iconForContentType() const { QString theme; switch (m_contentType) { case QlipperItem::PlainText: theme = "text-plain"; break; case QlipperItem::RichText: theme = "text-enriched"; break; case QlipperItem::Binary: theme = "image-x-generic"; break; case QlipperItem::Url: theme = "quickopen-file"; break; case QlipperItem::Sticky: theme = "knotes"; break; } return QIcon::fromTheme(theme, QIcon(QString(":/icons/%1.png").arg(theme))); } QDebug operator<<(QDebug dbg, const QlipperItem &c) { dbg.nospace() << "QlipperItem(mode=" << c.clipBoardMode() << ", contentType=" << c.contentType() << ", text=" << c.content() << ")"; return dbg.space(); } qlipper-5.1.1/src/qlipperitem.h000066400000000000000000000043361321252207600164730ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 QLIPPERITEM_H #define QLIPPERITEM_H #include #include #include #include "qlippertypes.h" class QlipperItem { public: enum ContentType { PlainText, RichText, Binary, Url, Sticky }; enum Action { NoAction = 0 , ToCurrent = 1 , ToOther = 1 << 1 }; Q_DECLARE_FLAGS(Actions, Action) QlipperItem(); QlipperItem(QClipboard::Mode mode); QlipperItem(QClipboard::Mode mode, ContentType contentType, const ClipboardContent &content); QlipperItem(const QString & sticky); QClipboard::Mode clipBoardMode() const; ClipboardContent content() const { return m_content; } QString display() const { return m_display; } QlipperItem::ContentType contentType() const { return m_contentType; } bool isValid() const { return m_valid; } bool enforceHistory() const { return m_enforceHistory; } void toClipboard(const Actions & actions) const; QString displayRole() const; QIcon decorationRole() const; QString tooltipRole() const; bool operator==(const QlipperItem &other) const; private: QClipboard::Mode m_mode; ContentType m_contentType; bool m_valid; bool m_enforceHistory; ClipboardContent m_content; QString m_display; QIcon iconForContentType() const; }; Q_DECLARE_METATYPE(QlipperItem::ContentType) QDebug operator<<(QDebug dbg, const QlipperItem &c); #endif // QLIPPERITEM_H qlipper-5.1.1/src/qlippermodel.cpp000066400000000000000000000156021321252207600171660ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include "qlippermodel.h" #include "qlipperpreferences.h" #include "qlippernetwork.h" #include "clipboardwrap.h" QlipperModel::QlipperModel(QObject *parent) : QAbstractListModel(parent) { m_network = new QlipperNetwork(this); m_boldFont.setBold(true); m_sticky = QlipperPreferences::Instance()->getStickyItems(); m_dynamic = QlipperPreferences::Instance()->getDynamicItems(); // a little hack-a-magic to have almost if (m_sticky.count() + m_dynamic.count() == 0) { clipboard_changed(QClipboard::Clipboard); if (m_dynamic.count() == 0) { clearHistory(); } } #ifdef Q_WS_MAC m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(timer_timeout())); m_timer->start(1000); #endif connect(ClipboardWrap::Instance(), &ClipboardWrap::changed, this, &QlipperModel::clipboard_changed); } QlipperModel::~QlipperModel() { QlipperPreferences::Instance()->saveDynamicItems(m_dynamic); QlipperPreferences::Instance()->saveStickyItems(m_sticky); m_dynamic.clear(); m_sticky.clear(); } void QlipperModel::resetPreferences() { beginRemoveRows(QModelIndex(), 0, m_sticky.count() - 1); m_sticky.clear(); endRemoveRows(); QList sticky = QlipperPreferences::Instance()->getStickyItems(); beginInsertRows(QModelIndex(), 0, sticky.count() - 1); m_sticky = sticky; endInsertRows(); } int QlipperModel::rowCount(const QModelIndex&) const { return m_sticky.count() + m_dynamic.count(); } // TODO/FIXME: BETTER API! This is very confusing and potentially dangerous... QList QlipperModel::getList(int & row) const { if (m_sticky.count() > row) { return m_sticky; } else { row = row - m_sticky.count(); return m_dynamic; } } QVariant QlipperModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return ""; int row = index.row(); QList list = getList(row); switch (role) { case Qt::DisplayRole: return list.at(row).displayRole(); case Qt::DecorationRole: return list.at(row).decorationRole(); case Qt::ToolTipRole: return list.at(row).tooltipRole(); case Qt::FontRole: return m_currentIndex == index ? m_boldFont : m_normalFont; } return ""; } Qt::ItemFlags QlipperModel::flags(const QModelIndex & index) const { Q_UNUSED(index); return Qt::ItemIsEditable | Qt::ItemIsEnabled; } void QlipperModel::clipboard_changed(QClipboard::Mode mode) { if ((mode == QClipboard::Selection || mode == QClipboard::FindBuffer) && !QlipperPreferences::Instance()->platformExtensions()) { return; } QlipperItem item(mode); if (!item.isValid()) { // See QlipperItem constructor: On X11 clipboard content is owned by the // application, so naturally closing the application drops // clipboard content. In this case the latest item should be set again. for (QList::const_iterator i = m_dynamic.begin(), i_e = m_dynamic.end(); i_e != i; ++i) { if (i->clipBoardMode() == item.clipBoardMode()) { i->toClipboard(QlipperItem::ToCurrent); m_currentIndex = index(m_sticky.count() + (i - m_dynamic.begin())); break; } } return; } if (QlipperPreferences::Instance()->shouldSynchronizeClipboardsInstantly()) { item.toClipboard(QlipperItem::ToOther); } // evaluate sticky items... int i = m_sticky.indexOf(item); if (i != -1) { m_currentIndex = index(i); return; } int ix = m_dynamic.indexOf(item); if (ix == -1) { const int sticky_count = m_sticky.count(); beginInsertRows(QModelIndex(), sticky_count, sticky_count); m_dynamic.prepend(item); endInsertRows(); const int max_history = QlipperPreferences::Instance()->historyCount(); if (m_dynamic.count() > max_history) { beginRemoveRows(QModelIndex(), sticky_count + max_history - 1, sticky_count + m_dynamic.count() - 1); m_dynamic.erase(m_dynamic.begin() + (max_history - 1), m_dynamic.end()); endRemoveRows(); } ix = 0; } setCurrentDynamic(ix); } void QlipperModel::setCurrentDynamic(int ix) { // move if not already on top if (ix != 0) { const int sticky_count = m_sticky.count(); beginMoveRows(QModelIndex(), sticky_count + ix, sticky_count + ix, QModelIndex(), sticky_count); m_dynamic.move(ix, 0); endMoveRows(); } m_currentIndex = index(m_sticky.count()); m_network->sendData(m_dynamic.at(0).content()); if (QlipperPreferences::Instance()->synchronizeHistory()) { QlipperPreferences::Instance()->saveDynamicItems(m_dynamic); } } void QlipperModel::clearHistory() { const int sticky_count = m_sticky.count(); beginRemoveRows(QModelIndex(), sticky_count, sticky_count + m_dynamic.count() - 1); m_dynamic.clear(); endRemoveRows(); ClipboardContent tmp; tmp["text/plain"] = tr("Welcome to the Qlipper clipboard history applet").toUtf8(); QlipperItem item(QClipboard::Clipboard, QlipperItem::PlainText, tmp); beginInsertRows(QModelIndex(), sticky_count, sticky_count); m_dynamic.append(item); endInsertRows(); m_currentIndex = index(sticky_count); } void QlipperModel::indexTriggered(const QModelIndex & index) { if (!index.isValid()) return; int row = index.row(); QList list = getList(row); QlipperItem::Actions actions(QlipperItem::ToCurrent); actions |= QlipperPreferences::Instance()->shouldSynchronizeClipboards() ? QlipperItem::ToOther : QlipperItem::NoAction; list.at(row).toClipboard(actions); m_currentIndex = index; if (m_sticky.size() <= index.row()) { setCurrentDynamic(row); } } void QlipperModel::timer_timeout() { #ifdef Q_WS_MAC m_timer->stop(); clipboard_changed(QClipboard::Clipboard); m_timer->start(); #endif } qlipper-5.1.1/src/qlippermodel.h000066400000000000000000000043461321252207600166360ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 QLIPPERMODEL_H #define QLIPPERMODEL_H #include #include #include #include "qlipperitem.h" class QTimer; class QlipperNetwork; class QlipperModel : public QAbstractListModel { Q_OBJECT public: explicit QlipperModel(QObject *parent = 0); ~QlipperModel(); void resetPreferences(); public slots: void clearHistory(); void indexTriggered(const QModelIndex &); protected: int rowCount(const QModelIndex&) const; QVariant data(const QModelIndex&, int) const; Qt::ItemFlags flags(const QModelIndex & index) const; private: QList m_sticky; QList m_dynamic; QPersistentModelIndex m_currentIndex; QlipperNetwork *m_network; QFont m_normalFont; QFont m_boldFont; #ifdef Q_WS_MAC QTimer *m_timer; QVariant m_previousContent; #endif QList getList(int &row) const; void setCurrentDynamic(int ix); private slots: void clipboard_changed(QClipboard::Mode); /*! Mac OS X from Qt 4.3.x does not handle signals sent from QClipboard until the app window is activated (eg. by the global shortcuts. It leads into possible lost items. This timer-slot-update_if_required mechanism workarounds it. Until I'll find better solution. Now the timeout is a compromise between system load and history recording usability. See m_timer, m_previousContent */ void timer_timeout(); }; #endif // QLIPPERMODEL_H qlipper-5.1.1/src/qlippernetwork.cpp000066400000000000000000000061261321252207600175600ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 "qlippernetwork.h" #include "qlipperitem.h" #include "qlipperpreferences.h" #include #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING #include #endif QlipperNetwork::QlipperNetwork(QObject *parent) : QObject(parent) { setObjectName("qlipperNetwork"); #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING QString hostname(QHostInfo::localHostName()); if (hostname.isEmpty()) hostname = "unknown"; QString uname; #ifdef Q_OS_UNIX // Mac, linux, and the other unices. uname = qgetenv("USER"); #endif #ifdef Q_WS_WIN // Windows. uname = qgetenv("USERNAME"); #endif if (uname.isEmpty()) uname = "unknown"; m_id = uname + "@" + hostname; m_socket = new QUdpSocket(this); bool r = m_socket->bind(QlipperPreferences::Instance()->networkPort(), QUdpSocket::ShareAddress); connect(m_socket, SIGNAL(readyRead()), this, SLOT(readData())); if (!r) qDebug() << "socket bound:" << r << m_socket->error() << m_socket->errorString(); #endif } void QlipperNetwork::sendData(const ClipboardContent &value) { #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING if (!QlipperPreferences::Instance()->networkSend()) return; QByteArray serialized; QDataStream ds(&serialized, QIODevice::WriteOnly); ds << m_id << value; qDebug() << "SENDING:" << serialized; QByteArray data = qCompress(serialized); int r = m_socket->writeDatagram(data.data(), data.size(), QHostAddress::Broadcast, QlipperPreferences::Instance()->networkPort()); if (r == -1) qDebug() << "error to send" << m_socket->error() << m_socket->errorString(); #endif } void QlipperNetwork::readData() { #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING if (!QlipperPreferences::Instance()->networkReceive()) return; QString remoteId; while (m_socket->hasPendingDatagrams()) { QByteArray data; data.resize(m_socket->pendingDatagramSize()); m_socket->readDatagram(data.data(), data.size()); QByteArray value = qUncompress(data); QDataStream ds(value); ds >> remoteId; // ignore own data if (m_id == remoteId) continue; ClipboardContent c; ds >> c; qDebug() << "RECEIVED:" << c; QlipperItem item(QClipboard::Clipboard, QlipperItem::PlainText, c); item.toClipboard(); } #endif } qlipper-5.1.1/src/qlippernetwork.h000066400000000000000000000023461321252207600172250ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 QLIPPERNETWORK_H #define QLIPPERNETWORK_H #include #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING #include #endif #include "qlippertypes.h" class QlipperNetwork : public QObject { Q_OBJECT public: QlipperNetwork(QObject *parent=0); public slots: void sendData(const ClipboardContent &value); private: #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING QUdpSocket *m_socket; QString m_id; #endif private slots: void readData(); }; #endif qlipper-5.1.1/src/qlipperpreferences.cpp000077500000000000000000000135311321252207600203710ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 "qlipperpreferences.h" const QString QlipperPreferences::DEFAULT_ICON_PATH = QStringLiteral(":/icons/qlipper.png"); // allow to store ClipboardContent in the QSettings variant QDataStream &operator<<(QDataStream &out, const ClipboardContent &obj) { int size = obj.size(); out << size; ClipboardContentIterator it(obj); while (it.hasNext()) { it.next(); out << it.key() << it.value(); } return out; } // allow to read ClipboardContent from QSettings QDataStream &operator>>(QDataStream &in, ClipboardContent &obj) { int size; QString key; QByteArray value; in >> size; for (int i = 0; i < size; ++i) { in >> key >> value; obj[key] = value; } return in; } QlipperPreferences* QlipperPreferences::m_instance = 0; QlipperPreferences::QlipperPreferences() : QSettings() { qRegisterMetaType("ClipboardContent"); qRegisterMetaTypeStreamOperators("ClipboardContent"); } QlipperPreferences::~QlipperPreferences() { sync(); } QlipperPreferences *QlipperPreferences::Instance() { if (!m_instance) m_instance = new QlipperPreferences(); return m_instance; } QList QlipperPreferences::getStickyItems() { QList l; // // keys: // - value, QString // beginGroup("sticky"); int count = beginReadArray("items"); for (int i = 0; i < count; ++i) { setArrayIndex(i); QlipperItem item(value("text").toString()); if (item.isValid()) l.append(item); } endArray(); endGroup(); return l; } void QlipperPreferences::saveStickyItems(QList list) { beginGroup("sticky"); int i = 0; remove("items"); beginWriteArray("items"); foreach (QlipperItem item, list) { setArrayIndex(i); i++; setValue("text", item.display()); } endArray(); endGroup(); } QList QlipperPreferences::getDynamicItems() { QList l; // // keys: // - mode, QClipboard::Mode // - contentType, QlipperItem::ContentType // - content, QVariant // beginGroup("dynamic"); int count = beginReadArray("items"); for (int i = 0; i < count; ++i) { setArrayIndex(i); // qDebug() << "R" << qVariantValue(value("content")); QlipperItem item(static_cast(value("mode").toUInt()),//value("mode").value(), static_cast(value("contentType").toUInt()), // value("contentType").value(), value("content").value() ); if (item.isValid()) l.append(item); } endArray(); endGroup(); return l; } void QlipperPreferences::saveDynamicItems(QList list) { bool clearOnExit = clearItemsOnExit(); beginGroup("dynamic"); int i = 0; remove("items"); if (!clearOnExit) { beginWriteArray("items"); foreach (QlipperItem item, list) { setArrayIndex(i); i++; setValue("mode", item.clipBoardMode()); setValue("contentType", item.contentType()); setValue("content", qVariantFromValue(item.content())); } endArray(); } endGroup(); sync(); } QString QlipperPreferences::getPathToIcon() const { return value(QLatin1String("tray_icon_file"), DEFAULT_ICON_PATH).toString(); } void QlipperPreferences::savePathToIcon(const QString &path) { setValue(QLatin1String("tray_icon_file"), path); sync(); } bool QlipperPreferences::trim() { return value("trim", true).toBool(); } int QlipperPreferences::displaySize() const { return value("displaySize", 30).toInt(); } QString QlipperPreferences::shortcut() const { return value("shortcut", "CTRL+ALT+V").toString(); } int QlipperPreferences::historyCount() const { return value("historyCount", 10).toInt(); } bool QlipperPreferences::platformExtensions() const { return value("platformExtensions", false).toBool(); } QlipperPreferences::PSESynchronization QlipperPreferences::synchronizePSE() const { return static_cast(value("synchronizePSE", PSE_NO_SYNC).toInt()); } bool QlipperPreferences::clearItemsOnExit() const { return value("clearItemsOnExit", false).toBool(); } bool QlipperPreferences::synchronizeHistory() const { return value("synchronizeHistory", true).toBool(); } bool QlipperPreferences::networkSend() const { return value("networkSend", false).toBool(); } bool QlipperPreferences::networkReceive() const { return value("networkReceive", false).toBool(); } int QlipperPreferences::networkPort() const { return value("networkPort", 6666).toInt(); } bool QlipperPreferences::shouldSynchronizeClipboards() const { return platformExtensions() && PSE_NO_SYNC != synchronizePSE(); } bool QlipperPreferences::shouldSynchronizeClipboardsInstantly() const { return platformExtensions() && PSE_SYNC_INSTANTLY == synchronizePSE(); } qlipper-5.1.1/src/qlipperpreferences.h000077500000000000000000000040041321252207600200310ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 QLIPPERPREFERENCES_H #define QLIPPERPREFERENCES_H #include #include #include "qlipperitem.h" class QlipperPreferences : public QSettings { public: enum PSESynchronization { PSE_NO_SYNC = 0 , PSE_SYNC_ON_SELECTION = 1 , PSE_SYNC_INSTANTLY = 2 }; public: static const QString DEFAULT_ICON_PATH; static QlipperPreferences *Instance(); ~QlipperPreferences(); QList getStickyItems(); void saveStickyItems(QList list); QList getDynamicItems(); void saveDynamicItems(QList list); QString getPathToIcon() const; void savePathToIcon(const QString &path); bool trim(); int displaySize() const; QString shortcut() const; int historyCount() const; bool platformExtensions() const; PSESynchronization synchronizePSE() const; bool clearItemsOnExit() const; bool synchronizeHistory() const; bool networkSend() const; bool networkReceive() const; int networkPort() const; bool shouldSynchronizeClipboards() const; bool shouldSynchronizeClipboardsInstantly() const; private: QlipperPreferences(); static QlipperPreferences* m_instance; }; #endif // QLIPPERPREFERENCES_H qlipper-5.1.1/src/qlipperpreferencesdialog.cpp000077500000000000000000000165501321252207600215550ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "qlipperitem.h" #include "qlipperpreferences.h" #include "qlipperpreferencesdialog.h" QlipperPreferencesDialog::QlipperPreferencesDialog(QWidget *parent) : QDialog(parent) { setupUi(this); QlipperPreferences *s = QlipperPreferences::Instance(); historyComboBox->setValue(s->historyCount()); displaySizeComboBox->setValue(s->displaySize()); trimCheckBox->setChecked(s->trim()); shortcutWidget->setKeySequence(QKeySequence(s->shortcut())); const bool pse = s->platformExtensions(); platformExtensionsCheckBox->setChecked(pse); synchronizePSE->setEnabled(pse); synchronizePSE->setCurrentIndex(s->synchronizePSE()); clearItemsOnExit->setChecked(s->clearItemsOnExit()); synchronizeHistory->setChecked(s->synchronizeHistory()); networkSendCheckBox->setChecked(s->networkSend()); networkReceiveCheckBox->setChecked(s->networkReceive()); portSpinBox->setValue(s->networkPort()); #ifndef ENABLE_NETWORK_CLIPBOARD_SHARING toolBox->setItemEnabled(2, false); #endif foreach(QlipperItem item, QlipperPreferences::Instance()->getStickyItems()) { listWidget->addItem(item.display()); } connect(stickyAddButton, SIGNAL(clicked()), this, SLOT(stickyAddButton_clicked())); connect(stickyRemoveButton, SIGNAL(clicked()), this, SLOT(stickyRemoveButton_clicked())); connect(stickyUpButton, SIGNAL(clicked()), this, SLOT(stickyUpButton_clicked())); connect(stickyDownButton, SIGNAL(clicked()), this, SLOT(stickyDownButton_clicked())); connect(listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(listWidget_currentRowChanged(int))); if (listWidget->count()) listWidget->setCurrentRow(0); else { stickyUpButton->setEnabled(false); stickyDownButton->setEnabled(false); stickyRemoveButton->setEnabled(false); } // Setup icon image machinery. // Setup menu & actions for icon selection. QMenu *iconMenu = new QMenu(tr("Icon selection"), this); QAction *actLoadFromFile = new QAction(tr("Load icon from file..."), this); QAction *actUseDefault = new QAction(QIcon(QlipperPreferences::DEFAULT_ICON_PATH), tr("Use default icon"), this); iconMenu->addAction(actLoadFromFile); iconMenu->addAction(actUseDefault); temporarilyRembemberNewTrayIcon(s->getPathToIcon()); buttonIconImage->setMenu(iconMenu); connect(actLoadFromFile, &QAction::triggered, this, &QlipperPreferencesDialog::selectIconFromFile); connect(actUseDefault, &QAction::triggered, this, &QlipperPreferencesDialog::useDefaultIcon); resize(sizeHint()); } void QlipperPreferencesDialog::accept() { QlipperPreferences *s = QlipperPreferences::Instance(); s->setValue("historyCount", historyComboBox->value()); s->setValue("displaySize", displaySizeComboBox->value()); s->setValue("trim", trimCheckBox->isChecked()); s->setValue("platformExtensions", platformExtensionsCheckBox->isChecked()); s->setValue("synchronizePSE", synchronizePSE->currentIndex()); s->setValue("shortcut", shortcutWidget->keySequence().toString()); s->setValue("clearItemsOnExit", clearItemsOnExit->isChecked()); s->setValue("synchronizeHistory", synchronizeHistory->isChecked()); s->setValue("networkReceive", networkReceiveCheckBox->isChecked()); s->setValue("networkSend", networkSendCheckBox->isChecked()); s->setValue("networkPort", portSpinBox->value()); QList list; for (int i = 0; i < listWidget->count(); ++i) { QlipperItem item(listWidget->item(i)->text()); list.append(item); } QlipperPreferences::Instance()->saveStickyItems(list); QlipperPreferences::Instance()->savePathToIcon(getNewTrayIcon()); QDialog::accept(); } void QlipperPreferencesDialog::selectIconFromFile() { QScopedPointer dialog(new QFileDialog(this, tr("Select icon file"), QString(), tr("Images (*.bmp *.jpg *.jpeg *.png *.svg *.tga)"))); dialog->setFileMode(QFileDialog::ExistingFile); dialog->setOptions(QFileDialog::ReadOnly); dialog->setViewMode(QFileDialog::Detail); dialog->setLabelText(QFileDialog::Accept, tr("Select icon")); dialog->setLabelText(QFileDialog::Reject, tr("Cancel")); //: Label to describe the folder for icon file selection dialog. dialog->setLabelText(QFileDialog::LookIn, tr("Look in:")); dialog->setLabelText(QFileDialog::FileName, tr("Icon name:")); dialog->setLabelText(QFileDialog::FileType, tr("Icon type:")); if (dialog->exec() == QDialog::Accepted && !dialog->selectedFiles().isEmpty()) { temporarilyRembemberNewTrayIcon(dialog->selectedFiles().value(0)); } } void QlipperPreferencesDialog::useDefaultIcon() { temporarilyRembemberNewTrayIcon(QlipperPreferences::DEFAULT_ICON_PATH); } void QlipperPreferencesDialog::stickyAddButton_clicked() { bool ok; QString s = QInputDialog::getText(this, tr("Add New Sticky Item"), tr("Add New Sticky Item"), QLineEdit::Normal, "", &ok); if (ok && !s.isEmpty()) { listWidget->addItem(s); listWidget->setCurrentRow(listWidget->count()-1); } } void QlipperPreferencesDialog::stickyRemoveButton_clicked() { QListWidgetItem * item = listWidget->takeItem(listWidget->currentRow()); if (item) delete item; } void QlipperPreferencesDialog::stickyUpButton_clicked() { int row = listWidget->currentRow(); if (row == 0) return; QListWidgetItem * item = listWidget->takeItem(row); if (!item) return; listWidget->insertItem(row-1, item); listWidget->setCurrentRow(row-1); } void QlipperPreferencesDialog::stickyDownButton_clicked() { int row = listWidget->currentRow(); if (row == listWidget->count()-1) return; QListWidgetItem * item = listWidget->takeItem(row); if (!item) return; listWidget->insertItem(row+1, item); listWidget->setCurrentRow(row+1); } void QlipperPreferencesDialog::listWidget_currentRowChanged(int row) { int count = listWidget->count(); stickyUpButton->setEnabled(count && row != 0); stickyDownButton->setEnabled(count && row != count-1); stickyRemoveButton->setEnabled(count); } void QlipperPreferencesDialog::temporarilyRembemberNewTrayIcon(const QString &path) { buttonIconImage->setIcon(QIcon(path)); buttonIconImage->setProperty("tray_icon", path); } QString QlipperPreferencesDialog::getNewTrayIcon() const { return buttonIconImage->property("tray_icon").toString(); } qlipper-5.1.1/src/qlipperpreferencesdialog.h000077500000000000000000000027031321252207600212150ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 QLIPPERPREFERENCESDIALOG_H #define QLIPPERPREFERENCESDIALOG_H #include "ui_qlipperpreferencesdialog.h" class QlipperPreferencesDialog : public QDialog, private Ui::QlipperPreferencesDialog { Q_OBJECT public: explicit QlipperPreferencesDialog(QWidget *parent = 0); private slots: void accept(); void selectIconFromFile(); void useDefaultIcon(); void stickyAddButton_clicked(); void stickyRemoveButton_clicked(); void stickyUpButton_clicked(); void stickyDownButton_clicked(); void listWidget_currentRowChanged(int); private: void temporarilyRembemberNewTrayIcon(const QString &path); QString getNewTrayIcon() const; }; #endif // QLIPPERPREFERENCESDIALOG_H qlipper-5.1.1/src/qlipperpreferencesdialog.ui000077500000000000000000000310201321252207600213750ustar00rootroot00000000000000 QlipperPreferencesDialog 0 0 358 430 Qlipper Preferences Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok 0 0 0 340 302 Preferences Clipboard Entries Count: The maximum count of dynamic items in the menu Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter entries 1 99 5 Maximum Display Size: How long is the preview text in the menu Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter characters 10 200 Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Trim Whitespaces for Every Line Keyboard Shortcut: Change global keyboard shortcut to invoke the menu on screen Tray icon image: Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 20 20 QToolButton::InstantPopup Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Use Platform Specific Extensions (Advanced) No synchronization of clipboard & PSE Synchronize clipboard & PSE when item selected Synchronize clipboard & PSE instantly Clear Items on Exit Synchronize history to storage instantly Qt::Vertical 20 96 0 0 340 302 Sticky Items Sticky items are unchanged, always on top snippets in the menu true Qt::Vertical 20 32 Add new item to the end of the list &Add Remove current item &Remove Move item up &Up Move item down &Down Qt::Vertical 20 32 0 0 340 302 Network Send Content to Network Receive Content from Network Port: 0 0 1 9999 Qt::Vertical 20 68 QKeySequenceWidget QWidget
qkeysequencewidget.h
1
buttonBox accepted() QlipperPreferencesDialog accept() 271 291 157 274 buttonBox rejected() QlipperPreferencesDialog reject() 303 291 286 274 platformExtensionsCheckBox clicked(bool) synchronizePSE setEnabled(bool) 20 20 20 20
qlipper-5.1.1/src/qlippersystray.cpp000077500000000000000000000127721321252207600176140ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "qmenuview.h" #include "qlippermodel.h" #include "qxtglobalshortcut.h" #include "qlipperpreferences.h" #include "qlipperpreferencesdialog.h" #include "qlippersystray.h" QlipperSystray::QlipperSystray(QObject *parent) : QSystemTrayIcon(parent) #ifndef NO_QXT , m_shortcutMenu(0) #endif { setIcon(QIcon(QlipperPreferences::Instance()->getPathToIcon())); m_model = new QlipperModel(this); m_contextMenu = new QMenu(); m_contextMenu->addAction(QIcon::fromTheme("edit-clear-hstory", QIcon(":/icons/edit-clear-history.png")), tr("C&lear clipboard history") , m_model, &QlipperModel::clearHistory); m_contextMenu->addAction(QIcon::fromTheme("configure", QIcon(":/icons/configure.png")), tr("&Configure...") , this, &QlipperSystray::editPreferences); m_contextMenu->addSeparator(); m_contextMenu->addAction(QIcon::fromTheme("help-about", QIcon(":/icons/help-about.png")), tr("&About Qlipper...") , this, &QlipperSystray::showAbout); m_contextMenu->addAction(QIcon::fromTheme("application-exit", QIcon(":/icons/application-exit.png")), tr("&Quit") , qApp, &QCoreApplication::quit); setContextMenu(m_contextMenu); #ifndef NO_QXT m_shortcutMenu = new QMenuView(); m_shortcutMenu->setModel(m_model); m_shortcutMenu->setWindowTitle(tr("Qlipper - a clipboard history applet")); // Windows API does not handle well some combinations of flags in custom widgets. #ifndef Q_OS_WIN32 // This flag is mandatory to get focus when user activates global_key. // OK, window gets a decoration but it works. Menu is displayed without the // the decoration if is the systray icon clicked. m_shortcutMenu->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint); #endif connect(m_shortcutMenu, SIGNAL(triggered(QModelIndex)), m_model, SLOT(indexTriggered(QModelIndex))); connect(m_shortcutMenu, SIGNAL(triggered(QModelIndex)), m_shortcutMenu, SLOT(close())); m_shortcut = new QxtGlobalShortcut(this); connect(m_shortcut, SIGNAL(activated()), this, SLOT(shortcut_activated())); m_shortcut->setShortcut(QlipperPreferences::Instance()->shortcut()); #else qWarning() << "Global keyboard shortcut is not compiled in."; #endif connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(systray_activated(QSystemTrayIcon::ActivationReason))); } QlipperSystray::~QlipperSystray() { #ifndef NO_QXT m_contextMenu->deleteLater(); if (m_shortcutMenu) m_shortcutMenu->deleteLater(); #endif m_model->deleteLater(); } void QlipperSystray::shortcut_activated() { #ifndef NO_QXT if (m_shortcutMenu->isVisible()) m_shortcutMenu->hide(); else { m_shortcutMenu->popup(QCursor::pos()); // activateWindow and raise are mandatory to get proper focus for keyboard after global_key. m_shortcutMenu->activateWindow(); m_shortcutMenu->raise(); } #endif } void QlipperSystray::editPreferences() { QlipperPreferencesDialog d; if (!d.exec()) return; #ifndef NO_QXT m_shortcut->setShortcut(QlipperPreferences::Instance()->shortcut()); #endif m_model->resetPreferences(); // Set new icon. const QString icon_path = QlipperPreferences::Instance()->getPathToIcon(); setIcon(QIcon(icon_path)); } void QlipperSystray::showAbout() { #ifndef NO_QXT QString globalKeySupport = tr("Yes"); #else QString globalKeySupport = tr("No"); #endif #ifdef ENABLE_NETWORK_CLIPBOARD_SHARING QString enableNetwork = tr("Yes (experimental)"); #else QString enableNetwork = tr("No"); #endif QMessageBox msgBox; //msgBox.setMinimumWidth(600); msgBox.setWindowIcon(QIcon(":/icons/qlipper.png")); msgBox.setIconPixmap (QPixmap(":/icons/qlipper.png")); msgBox.setWindowTitle(tr("About Qlipper")); msgBox.setText(QString("

Qlipper %1

").arg(qApp->applicationVersion())); msgBox.setInformativeText(tr("Lightweight, cross-platform clipboard history applet.

" "(c) 2010-2016 Petr Vanek <petr@yarpen.cz>

" "https://github.com/pvanek/qlipper/" "

" "Support for global keyboard shortcut: %1
" "Support for network clipboard sharing: %2").arg(globalKeySupport).arg(enableNetwork)); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.exec(); } void QlipperSystray::systray_activated(QSystemTrayIcon::ActivationReason reason) { #ifndef Q_WS_MAC if (reason == QSystemTrayIcon::Trigger) shortcut_activated(); #else Q_UNUSED(reason); #endif } qlipper-5.1.1/src/qlippersystray.h000066400000000000000000000026021321252207600172450ustar00rootroot00000000000000/* Qlipper - clipboard history manager Copyright (C) 2012 Petr Vanek 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 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 QLIPPERSYSTRAY_H #define QLIPPERSYSTRAY_H #include class QlipperModel; class QMenuView; #ifndef NO_QXT class QxtGlobalShortcut; #endif class QlipperSystray : public QSystemTrayIcon { Q_OBJECT public: explicit QlipperSystray(QObject *parent = 0); ~QlipperSystray(); private: QlipperModel *m_model; QMenu *m_contextMenu; #ifndef NO_QXT QMenuView *m_shortcutMenu; QxtGlobalShortcut *m_shortcut; #endif private slots: void shortcut_activated(); void editPreferences(); void showAbout(); void systray_activated(QSystemTrayIcon::ActivationReason reason); }; #endif // QLIPPERSYSTRAY_H qlipper-5.1.1/src/qlippertypes.h000066400000000000000000000004301321252207600166700ustar00rootroot00000000000000#ifndef QLIPPERTYPES_H #define QLIPPERTYPES_H #include #include typedef QHash ClipboardContent; typedef QHashIterator ClipboardContentIterator; Q_DECLARE_METATYPE(ClipboardContent); #endif // QLIPPERTYPES_H qlipper-5.1.1/src/signalhandler.cpp000066400000000000000000000035041321252207600173020ustar00rootroot00000000000000#include "signalhandler.h" #include #include #include #include #include #include #include #include #include Q_GLOBAL_STATIC(SignalHandler, signalHandlerFunc) void SignalHandler::signalHandler(int signo) { int ret = write(signalHandlerFunc()->mSignalSock[0], &signo, sizeof (int)); if (sizeof (int) != ret) qCritical() << QStringLiteral("unable to write into socketpair, %1").arg(strerror(errno)); } SignalHandler::SignalHandler() { if (0 != socketpair(AF_UNIX, SOCK_STREAM, 0, mSignalSock)) { qCritical() << QStringLiteral("unable to create socketpair for correct signal handling: %1)").arg(strerror(errno)); return; } mNotifier.reset(new QSocketNotifier(mSignalSock[1], QSocketNotifier::Read)); QObject::connect(mNotifier.data(), &QSocketNotifier::activated, this, &SignalHandler::socketActivated); listenToSignals(QList() << SIGINT << SIGTERM << SIGHUP); } SignalHandler::~SignalHandler() { close(mSignalSock[0]); close(mSignalSock[1]); } void SignalHandler::listenToSignals(QList const & signoList) { struct sigaction sa; sa.sa_handler = signalHandler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; for (QList::const_iterator i = signoList.begin(), i_e = signoList.end(); i != i_e; ++i) sigaction(*i, &sa, 0); } void SignalHandler::socketActivated() { int signo = 0; int ret = read(mSignalSock[1], &signo, sizeof (int)); if (sizeof (int) != ret) qCritical() << QStringLiteral("unable to read signal from socketpair, %1").arg(strerror(errno)); QApplication::quit(); } static void startup() { // just make the instantiation/creation happen signalHandlerFunc(); } Q_COREAPP_STARTUP_FUNCTION(startup) qlipper-5.1.1/src/signalhandler.h000066400000000000000000000007211321252207600167450ustar00rootroot00000000000000#if !defined(signalhandler_h) #define signalhandler_h #include class QSocketNotifier; class SignalHandler : public QObject { Q_OBJECT public: static void signalHandler(int signo); public: SignalHandler(); ~SignalHandler(); void listenToSignals(QList const & signoList); private slots: void socketActivated(); private: int mSignalSock[2]; QScopedPointer mNotifier; }; #endif // signalhandler_h qlipper-5.1.1/ts/000077500000000000000000000000001321252207600136205ustar00rootroot00000000000000qlipper-5.1.1/ts/qlipper_ca.ts000066400000000000000000000307761321252207600163240ustar00rootroot00000000000000 QObject Url: %1 URL: %1 Binary: %1 Binari: %1 Clipboard Porta-retalls Selection Selecció Find Bufer Memòria intermèdia de Find Plain Text Text pla Rich Text Text ric Binary Content Contingut en binari URL Sticky Item (Plain Text) Element exganxós (text pla) QlipperMenuView C&lear clipboard history Neteja l'historial del porta-reta&lls &Configure... &Configura... &About Qlipper... Qu&ant a Qlipper... &Quit &Surt QlipperModel Welcome to the Qlipper clipboard history applet Benvingut a la miniaplicació de l'historial del porta-retalls Qlipper QlipperPreferencesDialog Qlipper Preferences Preferències de Qlipper Preferences Preferències Keyboard Shortcut: Drecera de teclat: Change global keyboard shortcut to invoke the menu on screen Canvia la drecera de teclat global per a invocar el menú en pantalla Clipboard Entries Count: Nombre d'entrades del porta-retalls: The maximum count of dynamic items in the menu El nombre màxim d'ítems dinàmics al menú entries entrades Maximum Display Size: Mida màxima de la visualització: How long is the preview text in the menu Com de gran és el text de la vista prèvia al menú characters caràcters Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Utilitza les extensions del porta-retalls (seleccions de X11, memòria intermèdia de Find de l'OS X) Use Platform Specific Extensions (Advanced) Utilitza les extensions específiques de la plataforma (avançat) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) És útil per als blocs de text copiats més grans, per exemple des de terminals senzilles (minicom, etc.) Trim Whitespaces for Every Line Retalla els espas en blanc per a cada línia Sticky Items Elements enganxosos Sticky items are unchanged, always on top snippets in the menu Els elements enganxosos estan sense canviar, sempre en la part superior dels fragments al menú Add new item to the end of the list Afegeix l'ítem nou al final de la llista &Add &Afegeix Remove current item Suprimeix l'ítem actual &Remove Supr&imeix Move item up Mou l'ítem amunt &Up Am&unt Move item down Mou l'ítem avall &Down A&vall Network Xarxa Send Content to Network Envia el contingut a la xarxa Receive Content from Network Rep el contingut de la xarxa Port: Port: Add New Sticky Item Afegeix un element enganxós nou QlipperSystray Qlipper - a clipboard history applet Qlipper - una miniaplicació de l'historial del porta-retalls Yes No No Yes (experimental) Sí (experimental) About Qlipper Quant a Qlipper Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Miniaplicació de l'historial del porta-retalls, lleugera i de plataforma creuada.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Compatibilitat per a la drecera de teclat global: %1<br>Compatibilitat per a la compartició del porta-retalls de xarxa: %2 Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Miniaplicació de l'historial del porta-retalls, lleugera i de plataforma creuada.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Compatibilitat per a la drecera de teclat global: %1<br>Compatibilitat per a la compartició del porta-retalls de xarxa: %2 qlipper-5.1.1/ts/qlipper_cs.ts000066400000000000000000000275421321252207600163430ustar00rootroot00000000000000 QObject Url: %1 Binary: %1 Binární soubor: %1 Clipboard Clipboard Selection Selection Find Bufer Find Buffer Plain Text Čistý Text Rich Text Formátovaný Text Binary Content Binární Obsah URL Sticky Item (Plain Text) Permanentní Položka (Čistý Text) QlipperMenuView C&lear clipboard history &Smazat historii &Configure... &Nastavení... &About Qlipper... &O Programu... &Quit &Konec QlipperModel Welcome to the Qlipper clipboard history applet Vítá Vás Qlipper, správce systémové schránky QlipperPreferencesDialog Qlipper Preferences Nastavení Qlipperu Preferences Nastavení Keyboard Shortcut: Klávesová zkratka: Change global keyboard shortcut to invoke the menu on screen Změnit globální klávesovou zkratku na vyvolávání menu Clipboard Entries Count: Počet Položek Schránky: The maximum count of dynamic items in the menu Maximální počet dynamických položek v menu entries položek Maximum Display Size: Maximální Velikost Zobrazení: How long is the preview text in the menu Jak dlouho uchovat náhledový text v menu characters znaků Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Použít doplňková vylepšení schránky (X11 Výběry, OS X Buffer Pro Vyhledávání), je-li to možné Use Platform Specific Extensions (Advanced) Použit Platformově Závislá Rozšíření (Pokročilé) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Užitečné pro větší kusy textu kopírované například z terminálů (minicom, atd.) Trim Whitespaces for Every Line Odstranit Prázdné Znaky pro Každý Řádek Sticky Items Permanentní Položky Sticky items are unchanged, always on top snippets in the menu Permanentní položky se nemění, stále se budou nacházet na vrcholu menu Add new item to the end of the list Přidat novou položku na konec seznamu &Add Přid&at Remove current item Smazat vybranou položku &Remove S&mazat Move item up Posunout nahoru &Up &Nahoru Move item down Posunout dolu &Down &Dolů Network Síť Send Content to Network Odeslat Obsah po Síti Receive Content from Network Přijmout Obsah ze Sítě Port: Add New Sticky Item Přidat Novou Permanentní Položku QlipperSystray Qlipper - a clipboard history applet Qlipper - správce historie schránky Yes Ano No Ne Yes (experimental) Ano (experimentální) About Qlipper O Programu Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Odlehčení, multiplatformní správce systémové schránky.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Podpora pro globální klávesové zkratky: %1<br>Podpora pro sdílení schránky po síti: %2 qlipper-5.1.1/ts/qlipper_de.ts000066400000000000000000000313071321252207600163200ustar00rootroot00000000000000 QObject Url: %1 Shouldn't this be capitalized in English, too? URL: %1 Binary: %1 binäres Objekt: %1 Clipboard Clipboard Selection Selection Find Bufer Should be "Buffer" in English. Find Bufer Plain Text einfacher Text Rich Text Rich Text Binary Content binärer Inhalt URL URL Sticky Item (Plain Text) Haftnotiz (einfacher Text) QlipperMenuView C&lear clipboard history Speicher &löschen &Configure... &Konfiguration... &About Qlipper... &Über Qlipper... &Quit &Beenden QlipperModel Welcome to the Qlipper clipboard history applet Translation is cropped, but full text doesn't get displayed in the list most of the time anyway. Willkommen zu Qlipper QlipperPreferencesDialog Qlipper Preferences Qlipper Konfiguration Preferences Einstellungen Keyboard Shortcut: Tastenkürzel: Change global keyboard shortcut to invoke the menu on screen Tastenkürzel zum Aufrufen der Liste gespeicherter Objekte festlegen Clipboard Entries Count: Anzahl Listeneinträge: The maximum count of dynamic items in the menu Maximale Anzahl in der Liste mit gespeicherten Objekten gezeigter Einträge entries Einträge Maximum Display Size: Maximale Textlänge: How long is the preview text in the menu Maximale Länge einzelner Einträge in Liste gespeicherter Objekte characters Zeichen Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Erweiterte Funktionen wie "Selections" des X Window Systems oder "Find Buffer" unter Mac OS X verwenden, falls unterstützt Use Platform Specific Extensions (Advanced) Plattformspezifische Erweiterungen verwenden Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Nützlich beim Kopieren größerer Textbausteine, beispielsweise aus Terminalemulatoren Trim Whitespaces for Every Line Überschüssige Leerstellen in jeder Zeile entfernen Sticky Items Haftnotizen Sticky items are unchanged, always on top snippets in the menu Haftnotizen sind manuell eingebene Textelemente, die immer am Anfang der Liste gespeicherter Objekte angezeigt werden Add new item to the end of the list Haftnotiz hinzufügen &Add &Hinzufügen Remove current item Haftnotiz entfernen &Remove &Entfernen Move item up Haftnotiz nach oben verschieben &Up Nach &oben Move item down Haftnotiz nach unten verschieben &Down Nach &unten Network Netzwerk Send Content to Network Objekte ins Netzwerk versenden Receive Content from Network Objekte aus dem Netzwerk empfangen Port: Port: Add New Sticky Item Haftnotiz hinzufügen QlipperSystray Qlipper - a clipboard history applet Qlipper - eine Anwendung zur Handhabung der Zwischenablage Yes Ja No Nein Yes (experimental) Ja (experimentell) About Qlipper Über Qlipper Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Ressourcenschonende, plattformübergreifend einsetzbare Anwendung zur Handhabung der Zwischenablage.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Tastenkürzel unterstützt: %1<br>Austausch der Zwischenablage via Netzwerk unterstützt: %2 Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Odlehčení, multiplatformní správce systémové schránky.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Podpora pro globální klávesové zkratky: %1<br>Podpora pro sdílení schránky po síti: %2 qlipper-5.1.1/ts/qlipper_it.ts000066400000000000000000000254401321252207600163450ustar00rootroot00000000000000 QObject Url: %1 Binary: %1 Clipboard Appunti Selection Selezione Find Bufer Trova coso Plain Text Testo semplice Rich Text Testo formattato Binary Content Contenuto file binario URL Sticky Item (Plain Text) Voce permanente (testo semplice) QlipperMenuView C&lear clipboard history &Pulisci cronologia &Configure... &Configura... &About Qlipper... &A proposito di Qlipper... &Quit &Esci QlipperModel Welcome to the Qlipper clipboard history applet Benvenuto a Qlipper, l'applet per gli appunti QlipperPreferencesDialog Qlipper Preferences Preferenze di Qlipper Preferences Preferenze Keyboard Shortcut: Scorciatoia di tastiera: Change global keyboard shortcut to invoke the menu on screen Cambia scorciatoia gobale per mostrare il menu sullo schermo Clipboard Entries Count: Numero delle voci: The maximum count of dynamic items in the menu Il numero massimo delle voci da mostrare nel menu entries voci Maximum Display Size: Mostra i primi How long is the preview text in the menu Lunghezza della anteprima nel menu characters caratteri Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Use Platform Specific Extensions (Advanced) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Utile per bocchi di testi grandi copiati da dummy-terminals (minicom ecc) Trim Whitespaces for Every Line Rimuovi spazi vuoti per ogni riga Sticky Items Voci permanenti Sticky items are unchanged, always on top snippets in the menu Le voci permanenti rimangono invariati, sempre in cima nel menu Add new item to the end of the list Aggiungi nuova voce in fondo alla lista &Add &Aggiungi Remove current item Rimuovi voce corrente &Remove &Rimuovi Move item up Sposta voce in su &Up &Su Move item down Sposta voce in giù &Down &Giù Network Rete Send Content to Network Invia contenuto in rete Receive Content from Network Ricevi contenuto dalla rete Port: Porta: Add New Sticky Item Aggiungi nuova voce permanente QlipperSystray Qlipper - a clipboard history applet Qlipper - un applicazione per gli appunti Yes No No Yes (experimental) Sì (sperimentale) About Qlipper A proposito di qlipper Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 qlipper-5.1.1/ts/qlipper_lt.ts000066400000000000000000000267401321252207600163540ustar00rootroot00000000000000 QObject Url: %1 URL: %1 Binary: %1 Dvejetainė: %1 Clipboard Iškarpinė Selection Žymėjimas Find Bufer Rasti buferį Plain Text Grynasis tekstas Rich Text Raiškusis tekstas Binary Content Dvejetainės turinys URL URL Sticky Item (Plain Text) Lipnus elementas (Grynasis tekstas) QlipperMenuView C&lear clipboard history &Išvalyti iškarpinės istoriją &Configure... &Konfigūruoti... &About Qlipper... &Apie Qlipper... &Quit &Išeiti QlipperModel Welcome to the Qlipper clipboard history applet Sveiki atvykę į Qlipper iškarpinės istorijos programėlę QlipperPreferencesDialog Qlipper Preferences Qlipper nuostatos Preferences Nuostatos Keyboard Shortcut: Spartusis klavišas: Change global keyboard shortcut to invoke the menu on screen Keisti visuotinį spartųjį klavišą, kuris ekrane aktyvins meniu Clipboard Entries Count: Iškarpinės elementų skaičius: The maximum count of dynamic items in the menu Didžiausias meniu esančių dinaminių elementų skaičius entries elementų Maximum Display Size: Didžiausias rodomas dydis: How long is the preview text in the menu Kokio ilgio bus meniu esantis peržiūros tekstas characters simbolių Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Naudoti iškarpinės plėtinius, (X11 žymėjimus, OS X buferio radimą) kai tai palaikoma Use Platform Specific Extensions (Advanced) Naudoti platformai specifinius plėtinius (Išplėstinis) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Naudinga didesniems tekstų blokams nukopijuotiems, pvz., iš fiktyvių terminalų (minicom ir t.t.) Trim Whitespaces for Every Line Kiekvienoje eilutėje šalinti tarpus Sticky Items Lipnūs elementai Sticky items are unchanged, always on top snippets in the menu Lipnūs elementai yra nekeičiami, meniu jie yra visada fragmentų viršuje Add new item to the end of the list Pridėti naują elementą į sąrašo galą &Add &Pridėti Remove current item Šalinti esamą elementą &Remove Š&alinti Move item up Pakelti elementą &Up A&ukštyn Move item down Nuleisti elementą &Down Ž&emyn Network Tinklas Send Content to Network Siųsti turinį į tinklą Receive Content from Network Gauti turinį iš tinklo Port: Prievadas: Add New Sticky Item Pridėti naują lipnų elementą QlipperSystray Qlipper - a clipboard history applet Qlipper – iškarpinės istorijos programėlė Yes Taip No Ne Yes (experimental) Taip (eksperimentinis) About Qlipper Apie Qlipper Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Supaprastinta, daugiaplatformė iškarpinės istorijos programėlė.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Visuotinio sparčiojo klavišo palaikymas: %1<br>Tinklo iškarpinės bendrinimo palaikymas: %2 qlipper-5.1.1/ts/qlipper_pl.ts000066400000000000000000000265211321252207600163450ustar00rootroot00000000000000 QObject Url: %1 URL: %1 Binary: %1 Binaria: %1 Clipboard Schowek Selection Zaznaczenie Find Bufer Wyszukaj bufor Plain Text Czysty tekst Rich Text Tekst sformatowany Binary Content Zawartość binarna URL URL Sticky Item (Plain Text) Element przyklejony (czysty tekst) QlipperMenuView C&lear clipboard history &Wyczyść historię schowka &Configure... &Konfiguruj... &About Qlipper... O progr&amie Qlipper... &Quit &Wyjdź QlipperModel Welcome to the Qlipper clipboard history applet Witamy w aplecie historii schowka Qlipper QlipperPreferencesDialog Qlipper Preferences Ustawienia Qlipper Preferences Ustawienia Keyboard Shortcut: Skrót klawiszowy: Change global keyboard shortcut to invoke the menu on screen Zmień skrót klawiszowy wywołujący menu na ekran Clipboard Entries Count: Liczba elementów schowka: The maximum count of dynamic items in the menu Maksymalna liczba elementów w menu entries elementy(ów) Maximum Display Size: Maksymalny wyświetlany rozmiar: How long is the preview text in the menu Jak długi jest wyświetlany podgląd tekstu w menu characters znaki/ów Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Użyj rozszerzeń schowka (Zaznaczenia X11, Bufor wyszukiwania macOS), jeśli dostępne Use Platform Specific Extensions (Advanced) Używaj rozszerzeń dla określonej platformy (zaawansowane) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Przydatne przy kopiowaniu dużych tekstów. Trim Whitespaces for Every Line Usuwaj białe znaki w każdym wierszu Sticky Items Elementy przyklejone Sticky items are unchanged, always on top snippets in the menu Elementy przyklejone nie są zmieniane, zostają zawsze na górze menu Add new item to the end of the list Dodaj nowy element na koniec listy &Add Dod&aj Remove current item Usuń obecny element &Remove &Usuń Move item up Przesuń element w górę &Up &W górę Move item down Przesuń element w dół &Down W &dół Network Sieć Send Content to Network Prześlij zawartość przez sieć Receive Content from Network Otrzymuj zawartość przez sieć Port: Port: Add New Sticky Item Dodaj nowy przyklejony element QlipperSystray Qlipper - a clipboard history applet Qlipper – aplet historii schowka Yes Tak No Nie Yes (experimental) Tak (eksperymentalne) About Qlipper O programie Qlipper Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Lekki, wieloplatformowy aplet historii schowka systemowego.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p> Obsługa globalnego skrótu klawiszowego: %1<br> Możliwość udostępniana schowka w sieci: %2 qlipper-5.1.1/ts/qlipper_sr.ts000066400000000000000000000272651321252207600163640ustar00rootroot00000000000000 QObject Url: %1 Binary: %1 Clipboard Клипборд Selection Одабир Find Bufer Пронађи међуспремник Plain Text Rich Text Binary Content URL Sticky Item (Plain Text) QlipperMenuView C&lear clipboard history Очисти &историјат &Configure... &Подеси... &About Qlipper... &О програму... &Quit &Напусти QlipperModel Welcome to the Qlipper clipboard history applet Добродошли у Кјулипер, алатку за историјат клипборда QlipperPreferencesDialog Qlipper Preferences Подешавања Кјулипера Preferences Подешавања Keyboard Shortcut: Пречица тастатуре: Change global keyboard shortcut to invoke the menu on screen Промени глобалну пречицу за позивање менија на екрану Clipboard Entries Count: Број уноса клипборда: The maximum count of dynamic items in the menu Максималан број промењивих уноса на менију entries уноса Maximum Display Size: Максимална величина приказа: How long is the preview text in the menu Колико дуг је преглед текста на менију characters знакова Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported Користи проширења клипборда (Икс11 Одабири, ОС Икс Претрага Бафера) ако су подржана Use Platform Specific Extensions (Advanced) Користи проширења специфична за платформе (напредно) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) Корисно за веће блокове текста копиране са на пример лажних терминала (minicom, итд.) Trim Whitespaces for Every Line Уклони празан простор за сваку линију Sticky Items Лепљиве ставке Sticky items are unchanged, always on top snippets in the menu Лепљиве ставке се не мењају, увек су на врху у менију Add new item to the end of the list Додај нову ставку на крај списка &Add &Додај Remove current item Уклони тренутну ставку &Remove &Обнови Move item up Помери ставку горе &Up &Горе Move item down Помери ставку доле &Down До&ле Network Send Content to Network Receive Content from Network Port: Add New Sticky Item Додај нови лепљиви унос QlipperSystray Qlipper - a clipboard history applet Кјулипер - алатка за историјат клипборда Yes Да No Не Yes (experimental) About Qlipper О Кјулиперу Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 qlipper-5.1.1/ts/qlipper_zh_CN.ts000066400000000000000000000320511321252207600167260ustar00rootroot00000000000000 QObject Url: %1 Shouldn't this be capitalized in English, too? 网址: %1 Binary: %1 数据: %1 Clipboard 剪贴板 Selection 选区 Find Bufer Should be "Buffer" in English. 查找缓冲区 Plain Text 纯文本 Rich Text 富文本 Binary Content 数据内容 URL 网址 Sticky Item (Plain Text) 固定条目 (纯文本) QlipperMenuView C&lear clipboard history 清除剪贴板历史记录 (&L) &Configure... 配置 (&C) ... &About Qlipper... 关于 Qlipper (&A) ... &Quit 退出 (&Q) QlipperModel Welcome to the Qlipper clipboard history applet Translation is cropped, but full text doesn't get displayed in the list most of the time anyway. 欢迎使用 Qlipper QlipperPreferencesDialog Qlipper Preferences Qlipper 首选项 Preferences 首选项 Keyboard Shortcut: 键盘快捷键: Change global keyboard shortcut to invoke the menu on screen 更改全局快捷键以在屏幕上调用菜单 Clipboard Entries Count: 剪贴板条目数量: The maximum count of dynamic items in the menu 菜单中动态条目的最大数量 entries 条目 Maximum Display Size: 最大显示字符数目: How long is the preview text in the menu 菜单中预览文本的长度 characters 字符 Use clipboard extensions (X11 Selections, OS X Find Buffer) when it's supported 当支持时, 使用剪贴板扩展 (X11 的选区, OS X 的查找缓冲区) Use Platform Specific Extensions (Advanced) 使用平台相关扩展 (高级) Useful for bigger text blocks copied for example from dummy terminals (minicom, etc.) 适用于较大文本块, 如从虚拟终端 (如 minicom 等) 中复制文本时 Trim Whitespaces for Every Line 修整每行中的首尾空格 Synchronize clipboard && PSE when item selected 选择条目时保持剪贴板与平台相关扩展内容同步 Clear Items on Exit 退出时清除条目 Synchronize history to storage instantly 将历史记录立即同步到存储 Sticky Items 固定条目 Sticky items are unchanged, always on top snippets in the menu 固定条目固定不变, 并一直显示于菜单的最上方 Add new item to the end of the list 添加新条目至列表底部 &Add 添加 (&A) Remove current item 移除当前条目 &Remove 移除 (&R) Move item up 向上移动条目 &Up 上移 (&U) Move item down 向下移动条目 &Down 下移 (&D) Network 网络 Send Content to Network 将内容发送到网络 Receive Content from Network 从网络接收内容 Port: 端口: Add New Sticky Item 添加新固定条目 QlipperSystray Qlipper - a clipboard history applet Qlipper - 一个剪贴板历史记录小程序 Yes No Yes (experimental) 是 (实验性) About Qlipper 关于 Qlipper Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 轻量级跨平台剪贴板历史记录小程序<p>(c)&nbsp;2010-2016&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@yarpen.cz&gt;<p><a href="https://github.com/pvanek/qlipper/">https://github.com/pvanek/qlipper/</a><p>全局快捷键支持: %1<br>网络剪贴板共享支持: %2 Lightweight, cross-platform clipboard history applet.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Support for global keyboard shortcut: %1<br>Support for network clipboard sharing: %2 Odlehčení, multiplatformní správce systémové schránky.<p>(c)&nbsp;2010-2011&nbsp;Petr&nbsp;Vanek&nbsp;&lt;petr@scribus.info&gt;<p><a href="http://code.google.com/p/qlipper/">http://code.google.com/p/qlipper/</a><p>Podpora pro globální klávesové zkratky: %1<br>Podpora pro sdílení schránky po síti: %2