diff --git a/.gitignore b/.gitignore index 8e27f3e..dde7a7d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ /CopyQ-3.2.0.tar.gz /CopyQ-3.3.0.tar.gz /CopyQ-3.3.1.tar.gz +/CopyQ-3.4.0.tar.gz diff --git a/CopyQ-3.0.2/.gitignore b/CopyQ-3.0.2/.gitignore deleted file mode 100644 index 645d1d5..0000000 --- a/CopyQ-3.0.2/.gitignore +++ /dev/null @@ -1,49 +0,0 @@ -# Generated CMake files -CMakeFiles/ -CMakeCache.txt -*.cmake - -# Generated Visual Studio files -/plugins/Debug/ -/plugins/Release/ -/plugins/Win*/ -/Debug/ -/Release/ -/Win*/ -*.sln -*.suo -*.*sdf -*.vc?proj* - -# Generated Makefiles -/plugins/Makefile -/plugins/*/Makefile -/src/Makefile -/Makefile - -# Generated Qt files -/plugins/**/*.dir/ -/src/copyqcon.dir/ -/src/copyq.dir/ -/src/copyq_*.qm -/src/copyq_*.qm.rule -/src/qrc_copyq.cxx -/src/translations.qrc -/src/qrc_translations.cxx - -moc_* -ui_* -*.depends -*.o -*.dylib -*.moc -**/qrc_*.cpp -/.qmake.cache -/copyq.app -copyq.pro.user -.DS_Store -.qmake.stash -*.pyc -*.dmg -/build -*.qm diff --git a/CopyQ-3.0.2/.gitlab-ci.yml b/CopyQ-3.0.2/.gitlab-ci.yml deleted file mode 100644 index 496d086..0000000 --- a/CopyQ-3.0.2/.gitlab-ci.yml +++ /dev/null @@ -1,59 +0,0 @@ -# Use latest Ubuntu LTS docker image. -image: ubuntu:xenial - -variables: - BUILD_DIR: "build" - INSTALL_PREFIX: "copyq" - SCREENSHOT_DIR: "screenshots" - TESTS_LOG_DIR: "logs" - -build: - stage: build - - before_script: - - utils/gitlab/build-before_script.sh - - script: - - utils/gitlab/build-script.sh - - # Upload installed application. - artifacts: - paths: - - "$INSTALL_PREFIX" - - cache: - paths: - - build - -# Run simple tests (doesn't require GUI) -test: - stage: test - - before_script: - - utils/gitlab/test-before_script.sh - - script: - - utils/gitlab/test-script.sh - - dependencies: - - build - -# GUI tests (requires X11) -test_gui: - stage: test - - before_script: - - utils/gitlab/test_gui-before_script.sh - - script: - - utils/gitlab/test_gui-script.sh - - # Upload screenshots on failure. - artifacts: - when: on_failure - paths: - - "$SCREENSHOT_DIR" - - "$TESTS_LOG_DIR" - - dependencies: - - build diff --git a/CopyQ-3.0.2/.travis.yml b/CopyQ-3.0.2/.travis.yml deleted file mode 100644 index 2b83315..0000000 --- a/CopyQ-3.0.2/.travis.yml +++ /dev/null @@ -1,62 +0,0 @@ -language: cpp - -matrix: - include: - - os: osx - compiler: clang - - - os: linux - compiler: gcc - env: - - COMPILER=g++-4.8 - - GCOV=gcov-4.8 - addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 - - - os: linux - compiler: clang - env: - - COMPILER=clang++-3.6 - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.6 - packages: - - clang-3.6 - -cache: - apt: true - ccache: true - directories: - - $HOME/.wheelhouse - -before_install: - - utils/travis/before-install-${TRAVIS_OS_NAME}.sh - -install: - - utils/travis/install-${TRAVIS_OS_NAME}.sh - -script: - - utils/travis/script-${TRAVIS_OS_NAME}.sh - -after_success: - - utils/travis/after_success-${TRAVIS_OS_NAME}.sh - -deploy: - provider: releases - api_key: - secure: Vax27ifQsc8SlTsLYVbxVJANDAxDroegN6nOPXCN1MLaoh4W2DQ/iGGx+waIOSYig8Sh+AUz2JhCFuMLMVqwFoWY2rxNPBrxhTBjm3aDhylbB+mRECnbInNb0kS3qv4lNDN6lHD4B6K01FWUUiHX14s2JQx4ut+KuwMxxhxyO4Y= - file: 'build/*.dmg' - file_glob: true - skip_cleanup: true - overwrite: true - on: - condition: "$TRAVIS_OS_NAME = osx" - tags: true - all_branches: true - repo: hluk/CopyQ diff --git a/CopyQ-3.0.2/AUTHORS b/CopyQ-3.0.2/AUTHORS deleted file mode 100644 index 28f09d3..0000000 --- a/CopyQ-3.0.2/AUTHORS +++ /dev/null @@ -1,21 +0,0 @@ -Adam Batkin -Giacomo Margarito -Greg Carp -Ilya Plenne -Jörg Thalheim -Kim Jzhone -Kos Ivantsov -lightonflux -Lukas Holecek -Marjolein Hoekstra -Martin Lepadusch -Matt d'Entremont -Michal Čihař -Patricio M. Ros -Robert Orzanna -Ryan Wooden -Scott Kostyshak -Sebastian Schuberth -Tomas Nilzon -Wilfried Caruel -x2357 diff --git a/CopyQ-3.0.2/CHANGES b/CopyQ-3.0.2/CHANGES deleted file mode 100644 index 95a3278..0000000 --- a/CopyQ-3.0.2/CHANGES +++ /dev/null @@ -1,461 +0,0 @@ -v3.0.2 -- Added script functions for listing synchronized tabs and their paths -- Fixed showing window on current screen -- Fixed notification position with multiple screens -- Fixed rendering items when scrolling -- Fixed pasting from main window after switching tabs -- Fixed copy/paste to some apps on OS X -- Fixed focusing editor when closing completion popup on OS X -- Fixed setting temporary file template from script - -v3.0.1 -- Install themes on OS X -- Improve pasting to current window -- Fix crash when the first tab is not loaded -- Fix crash when reloading tab after closing editor -- Fix item rendering and UI elements for high DPI displays -- Fix window focus after closing menu or main window on OS X -- Fix opening main window on current space on OS X -- Fix pasting to some windows on OS X -- Fix navigating item list -- Fix getting boolean from checkbox in dialog() -- Fix default move action for drag'n'drop -- Fix exitting on logout when tray is disabled - -v3.0.0 -- Pinned and protected items -- Export/import tabs, configuration and commands in one file -- Create and modify commands from script -- Create temporary files from script -- Create notifications with buttons from script -- Take screenshots using script -- Allow to process lines on stdout from execute() scriptable using a function -- Safer and faster encrypt/decrypt commands (need to be re-added) -- Improved menu scriptable function -- Improved icon sharpness -- Improved plugin architecture -- Improved logging and displaying log -- Performance and memory consumption improvements -- Implemented copy() on OS X -- Fixed focusing menu and windows on OS X -- Fixed configuration folder path for portable version on Windows -- Fixed opening menu for a tab -- Fixed using correct GPG version for encryption -- Fixed tray menu position in KDE/Plasma - -v2.9.0 -- Set text style in editor -- Search in editor -- Quick help in completion popup menu for commands -- Easier text selection in item preview -- Show whole text and unscaled image in item preview -- Improved pasting to windows on Linux/X11 -- Fixed global shortcuts at application start on Linux/X11 -- Fixed closing application from installer on Windows -- Fixed showing item preview at start -- Fixed saving position of new tabs and tab lists - -v2.8.3 -- Search items from tray menu -- Added support for animated gifs (played when selected) -- Added special formats for automatic commands to sync and store clipboard -- Added auto-completion for command editor -- Added scriptable variables for MIME types -- Fix encryption with new OpenPGP -- Fix passing big data to commands on Windows - -v2.8.2 -- Simplify appearance of items with notes and tags -- Support for drag'n'dropping images to more applications -- Added list widget for custom dialog -- Fixed opening windows on current screen -- Fixed tray icon appearance on Linux -- Fixed focusing tray menu from command -- Fixed dialog button translation on Windows -- Fixed passing big data to commands - -v2.8.1 -- All Qt messages are logged -- Fixed and improved commands for Tags plugin -- Fixed removing last items when changing item limit -- Fixed library paths for OS X -- Fixed pasting items on Windows -- Fixed copying from script on Windows - -v2.8.0 -- Insert images in editor -- Show simple items options -- Item preview window -- Move to Qt 5 on Windows and newer Linux distros -- Faster item content listing -- Simple filter for Log dialog -- Smooth icons on OS X -- Fixed system icons -- Fixed pasting animated images -- Fixed occasional crashes when finalizing commands with Qt 5 -- Fixed opening log speed on Windows -- Lithuanian translation - -v2.7.1 -- Colorize items with command -- Drag'n'drop items in selection order -- Fixed item selection with "next" and "previous" commands -- Fixed encrypting/decrypting items on Windows -- Fixed occasional client crashes at exit -- Fixed editor command on OS X - -v2.7.0 -- Log accessible from GUI -- Performance and memory usage improvements -- Added scriptable function to set current tab (setCurrentTab()) -- Added scriptable function to modify new items (setData()) -- Appearance fixes -- Simplified window management -- Improved pasting to current window on Windows -- Window geometry fixes -- Command with Enter shortcut overrides item activate action - -v2.6.1 -- Moved configuration from registry on Windows -- Fixed shortcuts on Windows -- Fixed window geometry restoring - -v2.6.0 -- Show item notes in tray and window title -- Removed broken console executable on Windows -- Dutch translation -- Added env() and setEnv() to access and modify environment variables -- Access shortcut which activated command -- Fixed closing the application at shutdown on Windows -- Fixed some global shortcuts on Windows -- Fixed capturing some shortcuts - -v2.5.0 -- Smarter tab name matching (ignore key hints '&') -- Fixed omit passing global shortcuts to widgets -- Fixed autostart option on Ubuntu -- Fixed window geometry saving and restoring -- Fixed reading binary input on Windows -- Fixed clearing configuration - -v2.4.9 -- Added new light theme -- Added scriptable function focused() to test main window focus -- Customizable shortcuts for tab navigation -- Extended item selection -- Fixed tab expiration and updating context menu -- Fixed passing text to command from action dialog - -v2.4.8 -- New command to show main window under mouse cursor or at a position with custom size -- Hide clipboard content when "application/x-copyq-hidden" is "1" -- "Copy next/previous item" command waits for clipboard to be set -- Fixed updating window title and tray tool tip on X11 -- Fixed modifying multiple commands in Command dialog -- Fixed implicit date to string conversions - -v2.4.7 -- Separate dialog for command help -- Added scriptable function visible() to check main window visibility -- Linux: Install bitmap icons for menus -- Linux: Install AppData file -- Allow to search for specific MIME types stored in items -- Menu items and customizable shortcut for cycling item format -- Fixed icon alignment -- Fixed moving tabs with Qt 5 -- Fixed overriding socket file path (Linux and OS X) -- Fixed "Paste as Plain Text" command (Windows and OS X) -- Fixed tab tree layout and changing icons for tab groups -- Fixed URL encoding - -v2.4.6 -- Fixed crash when removing command -- Fixed encryption/decryption selected items -- Fixed reading from standard input -- GUI fixes for high-DPI displays - -v2.4.5 -- Option to save/restore history for filtering items -- Clipboard changes with unchanged content is ignored -- Notify about unsaved changes in command dialog -- Use application icons from current icon theme on Linux -- Simple error checking for user scripts -- Fix blocked system shutdown on Linux/X11 - -v2.4.4 -- Option to choose tab for storing clipboard -- Fixed overriding mouse selection (Linux/X11) -- Fixed window title updates from user commands -- Fixed toggling window visibility with Qt 5 -- Minor GUI improvements and user command fixes - -v2.4.3 -- Plugin for tagging items -- Plugins can provide script functions and commands -- Improved automatic commands execution -- Fixed gradients, transparency and other style improvements -- Fixed decryption with newer version of GnuPG -- Fixes for Qt 5 version - -v2.4.2 -- Send input data to execute() -- Better clipboard encoding guessing -- Set tab icon from commands using tabicon() -- Fixed window title encoding on Windows -- Fixed restoring window geometry -- Performance fixes -- Various bug and usability fixes -- New logo - -v2.4.1 -- Added scriptable classes File and Dir -- Added scriptable function settings() for saving custom user data -- Improved dialog() command -- Windows: Qt translated strings bundled with application -- Fixed %1 in command -- Fixed building with tests and Qt5 - -v2.4.0 -- Separate dialog for user commands and global shortcuts -- Search for item by row number -- Command highlighting -- More shortcuts can be mapped on Windows and X11 -- New "copy" command to copy from current window to clipboard -- New "dialog" command to show dialog with custom input fields -- Fixed crash on log out on Windows -- Fixed clipboard monitoring on Windows -- Fixed argument encoding from client on Windows -- Fixed log output when printing messages from multiple processes -- GUI fixes - -v2.3.0 -- Support for OS X -- Japanese translation -- Custom icons for tabs -- Show item count next to each tab name (optional) -- Added Process Manager for running and finished commands -- Scripting improvements -- Nicer format for copied user commands -- GUI fixes - -v2.2.0 -- Custom system shortcuts for any user command -- Drag'n'drop items to tabs -- Options to set position and maximum size for notifications -- Option to open windows on same desktop -- Weblate service for translations (https://hosted.weblate.org/projects/copyq/master/) -- Commands input and output is UTF-8 only (this fixes encoding issues on Windows) -- Scripting engine improvements -- Various GUI improvements and fixes -- Fix main window position in various X11 window managers -- Fix crashing with Oxygen GUI style -- Fix storing images from clipboard on Windows -- Various GUI improvements and fixes - -v2.1.0 -- French translation -- Save/load and copy/paste user commands -- Easier way to write longer commands and scripts -- Remove formats in clipboard and item content dialogs -- Command "toggle" focuses main window if unfocused (instead of closing) -- Choose log file and amount of information to log -- Lot of bugfixes and GUI improvements - -v2.0.1 -- Initial OS X support -- Configuration moved into installed directory in Windows -- Change language in configuration -- New tool bar with item actions -- Option to apply color theme in tabs, tool bar and menus -- Allow to match items using a command -- Focus output item of the last executed command -- Allow to cancel exit if there are active commands -- Removed option to hide menu bar (inconsistent behavior) -- Fix showing lock icon in encrypted items - -v2.0.0 -- Synchronize items with files on disk -- Faster tab loading and saving (data format was changed; only backward compatible) -- User can limit size of text items -- Opening external image editor fixed on Windows -- New logo and website -- Lot of other fixes - -v1.9.3 -- Item and tab encryption (using GnuPG) -- FakeVim plugin for editing items (Vim editor emulation) -- Drag'n'drop items from and to list -- Improved appearance for notes -- Improved search bar -- New GUI for application and system-wide shortcuts -- Option to unload tabs after an interval -- Fixed item sizes and disabling font anti-aliasing -- Major bug fixes (mainly for Windows) and performance improvements - -v1.9.2 -- Better performance -- GUI improvements and bugfixes - -v1.9.1 -- Notifications -- customizable theme, timeout and position on screen -- Optional notification for new clipboard content -- Autostart option on Linux -- Reset empty clipboard to previous content -- More user-friendly item editor -- Optional font antialiasing -- Changed layout of configuration dialog -- Other fixes - -v1.9.0 -- User notes -- Improved appearance settings with some example themes -- Tree view for tabs with groups -- Sessions, i.e. run multiple independent instances -- Lot of GUI improvements -- Compatibility with Qt5 -- Bugfixes (crashing on Unity, icon colors etc.) - -v1.8.3 -- Options to hide tab bar and main menu -- Automatic paste works with more applications under Linux/X11 -- Multi-monitor support -- Lot of GUI fixes and improvements - -v1.8.2 -- Added shortcut to paste current and copy next/previous item -- Bugfixes (paste to correct window, show tray menu on Unity, GUI and usability fixes) - -v1.8.1 -- Spanish translation -- Option and system-wide shortcuts to temporarily disable clipboard storing -- Option for main window transparency -- Custom action on item activation -- Various GUI improvements and bugfixes - -v1.8.0 -- New shortcuts: "Next/previous item to clipboard", "Paste as plain text" -- Show clipboard content in main window title and tray tooltip -- New options for commands (transform current item, close main window) -- GUI enhancements, faster application start with many tabs and items, lot of bugfixes - -v1.7.5 -- User-settable editor for images -- Command-line fixes for Windows -- Commands for items of specified format (MIME type) -- Tray menu fixes - -v1.7.4 -- Improved automatic paste from tray - -v1.7.3 -- Paste immediately after choosing tray item -- German translation -- Support for system-wide shortcuts on Qt 5 - -v1.7.2 -- Clipboard content visible in tray tooltip - -v1.7.1 -- Bugfixes for text encoding - -v1.7.0 -- Plugins for saving and displaying clipboard content -- Bugfixes (lot of refactoring and tests happened) - -v1.6.3 -- Some important bugfixes - -v1.6.2 -- Dialog for viewing item content -- Improved tray menu -- Minor GUI updates - -v1.6.1 -- Configurable tray menu -- Lot of fixes in GUI and bugfixes - -v1.6.0 -- Highlight text and copy text in items -- Interactive web view -- Commands for any MIME type -- e.g. it's possible to create QR Code image from an URL and save it in list -- Pipe commands using '|' character - -v1.5.0 -- Option to use WebKit to render HTML -- Wrap text with long lines -- Faster list rendering -- Icons from FontAwesome -- Desktop icon on Linux - -v1.4.1 -- Support for other languages -- right now supports only English and Czech (any help is welcome) -- New "insert" command -- More safe item saving - -v1.4.0 -- lot of GUI Improvements, faster interaction -- Automatic commands for matched windows (only on Linux and Windows) - -v1.3.3 -- GUI Improvements -- New system-wide shortcuts -- Item editing improved - -v1.3.2 -- Drag'n'Drop to clipboard -- "Always on Top" option -- Change tab bar position -- Fix parsing arguments - -v1.3.1 -- GUI improvements -- Mode for Vi navigation (h, j, k, l keys for movement) -- Better performance - -v1.3.0 -- Import/export items to/from a file (not compatible with older saved format) -- Use scripts to handle item history -- Improved performance - -v1.2.5 -- Save/load items to/from a file -- Sort selected items -- Easier tab browsing (left/right arrow keys) -- GUI improvements -- More shortcut combinations work on Linux - -v1.2.4 -- Improved commands -- Fixed and faster scrolling -- Better tab manipulation - -v1.2.3 -- Bugfixes and major clean-up - -v1.2.2 -- Performance improved - -v1.2.1 -- Save items from commands in other tabs -- Missing icons in Windows version - -v1.2.0 -- Appearance settings -- Tab manipulation from command line -- Copy/paste items from/to tabs -- Faster searching - -v1.1.0 -- Better performance -- New configuration options -- Improved command line - -v1.0.2 -- Improved Windows compatibility -- Global shortcuts -- Automatic commands - -v1.0.1 -- Compatibility with different platforms - diff --git a/CopyQ-3.0.2/CMakeLists.txt b/CopyQ-3.0.2/CMakeLists.txt deleted file mode 100644 index c164438..0000000 --- a/CopyQ-3.0.2/CMakeLists.txt +++ /dev/null @@ -1,202 +0,0 @@ -cmake_minimum_required(VERSION 2.8.6) -project(copyq) - -# C++11 -if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1) - set(CMAKE_CXX_STANDARD 11) -else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") -endif() - -if(CMAKE_BUILD_TYPE MATCHES Debug) - set(COPYQ_DEBUG ON) - add_definitions( -DCOPYQ_DEBUG ) -endif() - -OPTION(PEDANTIC "Enable all compiler warnings" OFF) - -# Options (cmake -LH) -OPTION(WITH_QT5 "Use Qt 5 (disable to use Qt 4 instead)" ON) -OPTION(WITH_TESTS "Run test cases from command line" ${COPYQ_DEBUG}) -OPTION(WITH_PLUGINS "Compile plugins" ON) -# Linux-specific options -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(PLUGIN_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_SHARED_MODULE_PREFIX}/copyq/plugins" CACHE PATH "Install path for plugins") - set(ICON_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps" CACHE PATH "Install path for icons") - set(ICON_INSTALL_PREFIX_TEMPLATE "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/%SIZE%/apps" CACHE PATH "Install path for icons (%SIZE% is icon size)") - set(THEME_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/copyq/themes" CACHE PATH "Install path for themes") - set(DESKTOP_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/applications" CACHE PATH "Install path for \"copyq.desktop\"") - set(APPDATA_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/appdata" CACHE PATH "Install path for \"copyq.appdata.xml\"") - set(TRANSLATION_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/copyq/translations" CACHE PATH "Install path for translations") -endif() - -set(CMAKE_AUTOMOC ON) - -if (WITH_QT5) - cmake_minimum_required(VERSION 2.8.8) - find_package(Qt5Widgets) - if (NOT Qt5Widgets_FOUND) - message(FATAL_ERROR "Qt 5 is unavailable. To compile with Qt 4 use -DWITH_QT5=OFF.") - endif() - message(STATUS "Building with Qt 5.") -else() - find_package(Qt4) - if (NOT QT4_FOUND) - # Try different executable name. - set(QT_QMAKE_EXECUTABLE "qmake-qt4") - find_package(Qt4) - if (NOT QT4_FOUND) - message(FATAL_ERROR "Qt 4 is unavailable. To compile with Qt 5 use -DWITH_QT5=ON.") - endif() - endif() - message(STATUS "Building with Qt 4.") -endif() - -set(copyq_ICON_PREFIX src/images/icon) -set(copyq_ICON_NORMAL src/images/icon.svg) -set(copyq_ICON_BUSY src/images/icon-running.svg) -set(copyq_DESKTOP shared/copyq.desktop) -set(copyq_APPDATA shared/copyq.appdata.xml) - -# Be more strict while compiling debugging version -if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-long-long") - set(CMAKE_CXX_FLAGS_DEBUG - "${CMAKE_CXX_FLAGS_DEBUG} -Wextra -Wall -pedantic -Wfloat-equal -Woverloaded-virtual -Wundef") -endif() - -if (PEDANTIC) - if (CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wall \ - -Wsuggest-override \ - -Wlogical-op \ - -Wnoexcept \ - -Wstrict-null-sentinel \ - ") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything \ - -Winconsistent-missing-override \ - ") - - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ - -Wno-c++98-compat \ - -Wno-c++98-compat-pedantic \ - -Wno-shadow-field-in-constructor \ - -Wno-weak-vtables \ - -Wno-disabled-macro-expansion \ - -fcomment-block-commands=retval \ - ") - - # Disable errors from moc-generated files. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ - -Wno-undefined-reinterpret-cast \ - -Wno-missing-prototypes \ - ") - - # Disable errors from qrc-generated files. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ - -Wno-exit-time-destructors \ - -Wno-global-constructors \ - ") - endif() - - set(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -pedantic -Werror \ - -Wcast-align \ - -Wcast-qual \ - -Wctor-dtor-privacy \ - -Wdisabled-optimization \ - -Wformat=2 \ - -Winit-self \ - -Wmissing-declarations \ - -Wmissing-include-dirs \ - -Wold-style-cast \ - -Woverloaded-virtual \ - -Wredundant-decls \ - -Wstrict-overflow=4 \ - -Wundef \ - ") - - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ - -Wno-padded \ - -Wno-switch-enum \ - ") - - # Disable Q_OBJECT macro warnings. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ - -Wno-unused-member-function \ - ") -endif() - -if(WITH_TESTS) - message(STATUS "Building with tests.") - - add_definitions( -DHAS_TESTS ) - - if (WITH_QT5) - list(APPEND copyq_Qt5_Modules Test) - else() - set(QT_USE_QTTEST TRUE) - endif() -endif() - -# Get application version. -if (EXISTS "version.txt") - file(STRINGS "version.txt" copyq_version) -endif() - -if (NOT copyq_version) - find_package(Git) - if(GIT_FOUND) - execute_process(COMMAND - "${GIT_EXECUTABLE}" describe - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - RESULT_VARIABLE copyq_git_describe_result - OUTPUT_VARIABLE copyq_git_describe_output - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(copyq_git_describe_result EQUAL 0) - set(copyq_version "${copyq_git_describe_output}") - endif() - endif() -endif() - -if (copyq_version) - message(STATUS "Building CopyQ version ${copyq_version}.") - add_definitions( -DCOPYQ_VERSION="${copyq_version}" ) -endif() - -if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - install(FILES ${copyq_ICON_NORMAL} DESTINATION ${ICON_INSTALL_PREFIX} RENAME copyq-normal.svg) - install(FILES ${copyq_ICON_BUSY} DESTINATION ${ICON_INSTALL_PREFIX} RENAME copyq-busy.svg) - install(FILES ${copyq_DESKTOP} DESTINATION ${DESKTOP_INSTALL_PREFIX}) - install(FILES ${copyq_APPDATA} DESTINATION ${APPDATA_INSTALL_PREFIX}) - - foreach (copyq_ICON_EXTENT 16 22 24 32 48 64 128) - set(copyq_ICON_SIZE "${copyq_ICON_EXTENT}x${copyq_ICON_EXTENT}") - string(REPLACE "%SIZE%" "${copyq_ICON_SIZE}" copyq_ICON_TARGET_PREFIX "${ICON_INSTALL_PREFIX_TEMPLATE}") - foreach (copyq_ICON_TYPE "" "-normal" "-busy") - install(FILES "${copyq_ICON_PREFIX}${copyq_ICON_TYPE}_${copyq_ICON_SIZE}.png" DESTINATION "${copyq_ICON_TARGET_PREFIX}" RENAME "copyq${copyq_ICON_TYPE}.png") - endforeach() - endforeach() - - set(copyq_THEME_INSTALL_PREFIX ${THEME_INSTALL_PREFIX}) - file(GLOB copyq_THEMES shared/themes/*.ini) - install(FILES ${copyq_THEMES} DESTINATION ${THEME_INSTALL_PREFIX}) - - add_definitions( -DCOPYQ_ICON_PREFIX="${ICON_INSTALL_PREFIX}/copyq" ) - add_definitions( -DCOPYQ_THEME_PREFIX="${THEME_INSTALL_PREFIX}" ) - add_definitions( -DCOPYQ_PLUGIN_PREFIX="${PLUGIN_INSTALL_PREFIX}" ) - add_definitions( -DCOPYQ_DESKTOP_PREFIX="${DESKTOP_INSTALL_PREFIX}" ) - add_definitions( -DCOPYQ_TRANSLATION_PREFIX="${TRANSLATION_INSTALL_PREFIX}" ) -endif() - -add_definitions( -DQT_NO_CAST_TO_ASCII ) - -add_subdirectory(src) - -if (WITH_PLUGINS) - add_subdirectory(plugins) -endif() - diff --git a/CopyQ-3.0.2/Doxyfile b/CopyQ-3.0.2/Doxyfile deleted file mode 100644 index e98e4f7..0000000 --- a/CopyQ-3.0.2/Doxyfile +++ /dev/null @@ -1,1716 +0,0 @@ -# Doxyfile 1.7.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = src/include src - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.cpp *.h - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = Ubuntu - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = YES - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = YES - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = svg - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/CopyQ-3.0.2/HACKING b/CopyQ-3.0.2/HACKING deleted file mode 100644 index e9594b5..0000000 --- a/CopyQ-3.0.2/HACKING +++ /dev/null @@ -1 +0,0 @@ -https://github.com/hluk/CopyQ/wiki/Development diff --git a/CopyQ-3.0.2/INSTALL b/CopyQ-3.0.2/INSTALL deleted file mode 100644 index d01cde8..0000000 --- a/CopyQ-3.0.2/INSTALL +++ /dev/null @@ -1,30 +0,0 @@ -Steps to build and install -========================== - -To build and install the application CMake is required (http://www.cmake.org/). - -On Ubuntu you'll need packages libqt4-dev, cmake, libxfixes-dev, -libxtst-dev (optional; auto-paste into some applications), -libqtwebkit-dev (optional; advanced HTML rendering). - -Build with following commands: - - cmake . - make - -To install run (sudo is required for root privileges on Linux): - - sudo make install - - -Building and Packaging for OS X -------------------------------- - -To build and install on OS X, you will need `qmake` version -5.2 or greater. Build with the following commands: - - ~/Qt/5.2.0/clang_64/bin/qmake CONFIG+=release WITH_WEBKIT=1 - make copyq.app - -This will produce a self-contained application bundle `copyq.app` -which can then be copied or moved into `/Applications`. diff --git a/CopyQ-3.0.2/LICENSE b/CopyQ-3.0.2/LICENSE deleted file mode 100644 index 94a9ed0..0000000 --- a/CopyQ-3.0.2/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/CopyQ-3.0.2/README.md b/CopyQ-3.0.2/README.md deleted file mode 100644 index 803014f..0000000 --- a/CopyQ-3.0.2/README.md +++ /dev/null @@ -1,210 +0,0 @@ -# CopyQ - -[![Translation Status](https://hosted.weblate.org/widgets/copyq/-/svg-badge.svg)](https://hosted.weblate.org/engage/copyq/?utm_source=widget) -[![Build Status](https://travis-ci.org/hluk/CopyQ.svg?branch=master)](https://travis-ci.org/hluk/CopyQ) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/hluk/copyq?branch=master&svg=true)](https://ci.appveyor.com/project/hluk/copyq) -[![Coverage Status](https://coveralls.io/repos/hluk/CopyQ/badge.svg?branch=master)](https://coveralls.io/r/hluk/CopyQ?branch=master) - -CopyQ is advanced clipboard manager with editing and scripting features. -- [Downloads](https://github.com/hluk/CopyQ/releases) -- [Web Site](https://hluk.github.io/CopyQ/) -- [Wiki](https://github.com/hluk/CopyQ/wiki) -- [Mailing List](https://groups.google.com/group/copyq) -- [Bug Reports](https://github.com/hluk/CopyQ/issues) -- [Donate](https://www.bountysource.com/teams/copyq) -- [Scripting Reference](https://github.com/hluk/CopyQ/blob/master/src/scriptable/README.md) - -## Overview - -CopyQ monitors system clipboard and saves its content in customized tabs. -Saved clipboard can be later copied and pasted directly into any application. - -Items can be: - -* edited with internal editor or with preferred text editor, -* moved to other tabs, -* drag'n'dropped to applications, -* marked with tag or a note, -* passed to or changed by custom commands, -* or simply removed. - -## Features - -* Support for Linux, Windows and OS X 10.9+ -* Store text, HTML, images or any other custom formats -* Quickly browse and filter items in clipboard history -* Sort, create, edit, remove, copy/paste, drag'n'drop items in tabs -* Add notes or tags to items -* System-wide shortcuts with customizable commands -* Paste items with shortcut or from tray or main window -* Fully customizable appearance -* Advanced command-line interface and scripting -* Ignore clipboard copied from some windows or containing some text -* Support for simple Vim-like editor and shortcuts -* Many more features - -## Install and Run - -To install CopyQ, use the binary package or installer provided for your system. For system-specific information, please see below. For unlisted systems, please follow the instructions in -[INSTALL](https://github.com/hluk/CopyQ/blob/master/INSTALL) to build the -application. - -### Windows - -On Windows you can install [Chocolatey package](https://chocolatey.org/packages/copyq). - -### Ubuntu - -Install and keep CopyQ always up to date by running the following three commands from the terminal: - -```bash -$ sudo add-apt-repository ppa:hluk/copyq -$ sudo apt update -$ sudo apt install copyq -``` - -### OS X - -On OS X you can use [Homebrew](https://brew.sh/) to install the app. - -```bash -brew cask install copyq -``` - -## Using the App - -To start the application double-click the program icon or run `copyq`. - -The list with clipboard history is accessible by clicking on system tray icon -or running `copyq toggle`. - -Copying text or image to clipboard will create new item in the list. - -Selected items can be: -* edited (`F2`), -* removed (`Delete`), -* sorted (`Ctrl+Shift+S`, `Ctrl+Shift+R`), -* moved around (with mouse or `Ctrl+Up/Down`) or -* copied back to clipboard (`Enter`, `Ctrl+V`). - -All items will be restored when application is started next time. - -To exit the application select Exit from tray menu or press Ctrl-Q keys in the -application window. - -Read more: -- [Basic Usage](https://github.com/hluk/CopyQ/wiki/Basic-Usage) -- [Keyboard](https://github.com/hluk/CopyQ/wiki/Keyboard) - -### Adding Funcionality - -To create custom action that can be executed -from menu, with shortcut or when clipboard changes: -- go to Command dialog (`F6` shortcut), -- click Add button and select predefined command or create new one, -- optionally change the command details (shortcut, name), -- click OK to save the command. - -One of very useful predefined commands there is "Show/hide main window". - -Read more: -- [Writing Commands](https://github.com/hluk/CopyQ/wiki/Writing-Commands-and-Adding-Functionality) -- [CopyQ Commands Repository](https://github.com/hluk/copyq-commands) - -### Command Line - -CopyQ has powerful command line and scripting interface. - -Note: The main application must be running to be able to issue commands using -command line. - -Print help for some useful command line arguments: - - copyq --help - copyq --help add - -Insert some texts to the history: - - copyq add "first item" "second item" "third item" - -Print content of the first three items: - - copyq read 0 1 2 - copyq separator "," read 0 1 2 - -Show current clipboard content: - - copyq clipboard - copyq clipboard text/html - copyq clipboard \? # lists formats in clipboard - -Copy text to the clipboard: - - copyq copy "Some Text" - -Load file content into clipboard: - - copyq copy - < file.txt - copyq copy text/html < index.html - copyq copy image/jpeg - < image.jpg - -Create an image items: - - copyq write image/gif - < image.gif - copyq write image/svg - < image.svg - -Read more: -- [Scripting](https://github.com/hluk/CopyQ/wiki/Scripting) -- [Scripting Reference](https://github.com/hluk/CopyQ/blob/master/src/scriptable/README.md) - -## Build from Source Code - -To build the application from source code, first install the required dependencies: -- [Git](https://git-scm.com/) -- [CMake](https://cmake.org/download/) -- [Qt](https://download.qt.io/archive/qt/) -- Optionally on Linux/X11: development files and libraries for [Xtst](https://t2-project.org/packages/libxtst.html) and [Xfixes](https://www.x.org/archive/X11R7.5/doc/man/man3/Xfixes.3.html) -- Optionally [QtWebKit](https://trac.webkit.org/wiki/QtWebKit) (more advanced HTML rendering) - -### Ubuntu - -#### Install Dependencies - -```bash -sudo apt install \ - git cmake \ - qtbase5-private-dev \ - qtscript5-dev \ - qttools5-dev \ - qttools5-dev-tools \ - libqt5svg5-dev \ - libxfixes-dev \ - libxtst-dev \ - libqt5svg5 -``` - -#### Build the App - -Change install prefix if needed: - -```bash -git clone https://github.com/hluk/CopyQ.git -cd CopyQ -cmake -DCMAKE_INSTALL_PREFIX=/usr/local . -make -``` - -#### Install the App - -```bash -sudo make install -``` - -## Contributions - -You can help translate the application (click the banner below) -or help [fix issues and implement new features](https://github.com/hluk/CopyQ/issues). - -[![Translations](https://hosted.weblate.org/widgets/copyq/-/287x66-white.png)](https://hosted.weblate.org/engage/copyq/?utm_source=widget) - -See also [Development](https://github.com/hluk/CopyQ/wiki/Development). diff --git a/CopyQ-3.0.2/appveyor.yml b/CopyQ-3.0.2/appveyor.yml deleted file mode 100644 index 69ccef5..0000000 --- a/CopyQ-3.0.2/appveyor.yml +++ /dev/null @@ -1,46 +0,0 @@ -# Configuration file for AppVeyor CI -configuration: Release - -cache: - - build - -environment: - VCINSTALLDIR: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ - - matrix: - - QTDIR: C:\Qt\5.7\mingw53_32 - CMAKE_GENERATOR: MinGW Makefiles - MINGW_PATH: C:\Qt\Tools\mingw530_32 - - - QTDIR: C:\Qt\5.7\msvc2015 - CMAKE_GENERATOR: Visual Studio 14 2015 - VC_VARS_ARCH: x86 - - - QTDIR: C:\Qt\5.7\msvc2015_64 - CMAKE_GENERATOR: Visual Studio 14 2015 Win64 - VC_VARS_ARCH: amd64 - -# Parameters for default build commands (build_script is used instead). -build: - -install: -- utils\appveyor\install.bat - -before_build: -- utils\appveyor\before_build.bat - -build_script: -- utils\appveyor\build_script.bat - -after_build: -- utils\appveyor\after_build.bat - -artifacts: -- path: 'copyq*.zip' - name: CopyQ Portable - -- path: 'copyq-*-setup.exe' - name: CopyQ Setup - -matrix: - fast_finish: true # set this flag to immediately finish build once one of the jobs fails. diff --git a/CopyQ-3.0.2/common.pri b/CopyQ-3.0.2/common.pri deleted file mode 100644 index 2ad2720..0000000 --- a/CopyQ-3.0.2/common.pri +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG += c++11 - -macx { - QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.9 - QMAKE_MAC_SDK = macosx # work around QTBUG-41238 - - # Only Intel binaries are accepted so force this - CONFIG += x86 -} diff --git a/CopyQ-3.0.2/copyq b/CopyQ-3.0.2/copyq deleted file mode 100755 index 548b1fc..0000000 Binary files a/CopyQ-3.0.2/copyq and /dev/null differ diff --git a/CopyQ-3.0.2/copyq.lang b/CopyQ-3.0.2/copyq.lang deleted file mode 100644 index 2d79208..0000000 --- a/CopyQ-3.0.2/copyq.lang +++ /dev/null @@ -1,22 +0,0 @@ -%lang(ar) /usr/share/copyq/locale/copyq_ar.qm -%lang(cs) /usr/share/copyq/locale/copyq_cs.qm -%lang(da) /usr/share/copyq/locale/copyq_da.qm -%lang(de) /usr/share/copyq/locale/copyq_de.qm -%lang(es) /usr/share/copyq/locale/copyq_es.qm -%lang(fr) /usr/share/copyq/locale/copyq_fr.qm -%lang(hu) /usr/share/copyq/locale/copyq_hu.qm -%lang(it) /usr/share/copyq/locale/copyq_it.qm -%lang(ja) /usr/share/copyq/locale/copyq_ja.qm -%lang(lt) /usr/share/copyq/locale/copyq_lt.qm -%lang(nb) /usr/share/copyq/locale/copyq_nb.qm -%lang(nl) /usr/share/copyq/locale/copyq_nl.qm -%lang(pl) /usr/share/copyq/locale/copyq_pl.qm -%lang(pt_BR) /usr/share/copyq/locale/copyq_pt_BR.qm -%lang(pt_PT) /usr/share/copyq/locale/copyq_pt_PT.qm -%lang(ru) /usr/share/copyq/locale/copyq_ru.qm -%lang(sk) /usr/share/copyq/locale/copyq_sk.qm -%lang(sv) /usr/share/copyq/locale/copyq_sv.qm -%lang(tr) /usr/share/copyq/locale/copyq_tr.qm -%lang(uk) /usr/share/copyq/locale/copyq_uk.qm -%lang(zh_CN) /usr/share/copyq/locale/copyq_zh_CN.qm -%lang(zh_TW) /usr/share/copyq/locale/copyq_zh_TW.qm diff --git a/CopyQ-3.0.2/copyq.pro b/CopyQ-3.0.2/copyq.pro deleted file mode 100644 index c77903d..0000000 --- a/CopyQ-3.0.2/copyq.pro +++ /dev/null @@ -1,69 +0,0 @@ -include("./common.pri") - -TEMPLATE = subdirs - -# generate cache file for build -cache() - -DEFINES += QT_NO_CAST_TO_ASCII -SUBDIRS += src \ - plugins -TRANSLATIONS = \ - translations/copyq_ar.ts \ - translations/copyq_cs.ts \ - translations/copyq_da.ts \ - translations/copyq_de.ts \ - translations/copyq_es.ts \ - translations/copyq_fr.ts \ - translations/copyq_hu.ts \ - translations/copyq_it.ts \ - translations/copyq_ja.ts \ - translations/copyq_lt.ts \ - translations/copyq_nb.ts \ - translations/copyq_nl.ts \ - translations/copyq_pl.ts \ - translations/copyq_pt_PT.ts \ - translations/copyq_pt_BR.ts \ - translations/copyq_ru.ts \ - translations/copyq_sk.ts \ - translations/copyq_sv.ts \ - translations/copyq_tr.ts \ - translations/copyq_uk.ts \ - translations/copyq_zh_CN.ts \ - translations/copyq_zh_TW.ts - -macx { - # Package the CopyQ plugins into the app bundle - package_plugins.commands = \ - mkdir -p copyq.app/Contents/PlugIns/copyq/ ; \ - cp plugins/*.dylib copyq.app/Contents/PlugIns/copyq/ - package_plugins.depends = sub-plugins sub-src - QMAKE_EXTRA_TARGETS += package_plugins - - # Package the Qt frameworks into the app bundle - package_frameworks.commands = \ - test -e copyq.app/Contents/Frameworks/QtCore.framework \ - || $$dirname(QMAKE_QMAKE)/macdeployqt copyq.app - package_frameworks.target = copyq.app/Contents/Frameworks/QtCore.framework - package_frameworks.depends = sub-src sub-plugins package_plugins - QMAKE_EXTRA_TARGETS += package_frameworks - - # Package the translations - package_translations.commands = \ - $$dirname(QMAKE_QMAKE)/lrelease $$_PRO_FILE_PWD_/copyq.pro && \ - mkdir -p copyq.app/Contents/Resources/translations && \ - cp $$_PRO_FILE_PWD_/translations/*.qm copyq.app/Contents/Resources/translations - QMAKE_EXTRA_TARGETS += package_translations - - # Package the themes - package_themes.commands = \ - mkdir -p copyq.app/Contents/Resources/themes && \ - cp $$_PRO_FILE_PWD_/shared/themes/*.ini copyq.app/Contents/Resources/themes - QMAKE_EXTRA_TARGETS += package_themes - - # Rename to CopyQ.app to make it look better - bundle_mac.depends = package_frameworks package_plugins package_translations package_themes - bundle_mac.target = CopyQ.app - bundle_mac.commands = mv copyq.app CopyQ.app - QMAKE_EXTRA_TARGETS += bundle_mac -} diff --git a/CopyQ-3.0.2/debian/changelog b/CopyQ-3.0.2/debian/changelog deleted file mode 100644 index d6809bf..0000000 --- a/CopyQ-3.0.2/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -copyq (2.9.0~xenial) xenial; urgency=medium - - * v2.9.0 - - -- Lukas Holecek Fri, 10 Mar 2017 10:10:00 +0200 diff --git a/CopyQ-3.0.2/debian/compat b/CopyQ-3.0.2/debian/compat deleted file mode 100644 index ec63514..0000000 --- a/CopyQ-3.0.2/debian/compat +++ /dev/null @@ -1 +0,0 @@ -9 diff --git a/CopyQ-3.0.2/debian/control b/CopyQ-3.0.2/debian/control deleted file mode 100644 index f925c66..0000000 --- a/CopyQ-3.0.2/debian/control +++ /dev/null @@ -1,45 +0,0 @@ -Source: copyq -Section: misc -Priority: optional -Maintainer: Lukas Holecek -Build-Depends: debhelper (>= 9), cmake - ,qtbase5-private-dev - ,qtscript5-dev - ,qttools5-dev - ,qttools5-dev-tools - ,libqt5svg5-dev - ,libxfixes-dev - ,libxtst-dev -Standards-Version: 3.9.7 -Homepage: https://hluk.github.io/CopyQ/ -Vcs-Browser: https://github.com/hluk/CopyQ -Vcs-Git: https://github.com/hluk/CopyQ.git - -Package: copyq -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends}, libqt5svg5 -Description: Advanced clipboard manager with editing and scripting features - CopyQ monitors system clipboard and saves its content in customized tabs. - Saved clipboard can be later copied and pasted directly into any application. - . - Items can be: - * edited with internal editor or with preferred text editor, - * moved to other tabs, - * drag'n'dropped to applications, - * marked with tag or a note, - * passed to or changed by custom commands, - * or simply removed. - . - Features: - * Support for Linux, Windows and OS X 10.9+ - * Store text, HTML, images or any other custom formats - * Quickly browse and filter items in clipboard history - * Sort, create, edit, remove, copy/paste, drag'n'drop items in tabs - * Add notes or tags to items - * System-wide shortcuts with customizable commands - * Paste items with shortcut or from tray or main window - * Fully customizable appearance - * Advanced command-line interface and scripting - * Ignore clipboard copied from some windows or containing some text - * Support for simple Vim-like editor and shortcuts - * Many more features diff --git a/CopyQ-3.0.2/debian/control-qt4 b/CopyQ-3.0.2/debian/control-qt4 deleted file mode 100644 index 91bb0dc..0000000 --- a/CopyQ-3.0.2/debian/control-qt4 +++ /dev/null @@ -1,41 +0,0 @@ -Source: copyq -Section: misc -Priority: optional -Maintainer: Lukas Holecek -Build-Depends: debhelper (>= 9), cmake - , libqt4-dev - , libxfixes-dev - , libxtst-dev -Standards-Version: 3.9.7 -Homepage: https://hluk.github.io/CopyQ/ -Vcs-Browser: https://github.com/hluk/CopyQ -Vcs-Git: https://github.com/hluk/CopyQ.git - -Package: copyq -Architecture: any -Depends: ${misc:Depends}, ${shlibs:Depends}, libqt4-xml, libqt4-network, libqt4-script, libqt4-svg -Description: Advanced clipboard manager with editing and scripting features - CopyQ monitors system clipboard and saves its content in customized tabs. - Saved clipboard can be later copied and pasted directly into any application. - . - Items can be: - * edited with internal editor or with preferred text editor, - * moved to other tabs, - * drag'n'dropped to applications, - * marked with tag or a note, - * passed to or changed by custom commands, - * or simply removed. - . - Features: - * Support for Linux, Windows and OS X 10.9+ - * Store text, HTML, images or any other custom formats - * Quickly browse and filter items in clipboard history - * Sort, create, edit, remove, copy/paste, drag'n'drop items in tabs - * Add notes or tags to items - * System-wide shortcuts with customizable commands - * Paste items with shortcut or from tray or main window - * Fully customizable appearance - * Advanced command-line interface and scripting - * Ignore clipboard copied from some windows or containing some text - * Support for simple Vim-like editor and shortcuts - * Many more features diff --git a/CopyQ-3.0.2/debian/copyright b/CopyQ-3.0.2/debian/copyright deleted file mode 100644 index 4cd4d09..0000000 --- a/CopyQ-3.0.2/debian/copyright +++ /dev/null @@ -1,124 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: CopyQ -Upstream-Contact: Lukas Holecek -Source: https://github.com/hluk/CopyQ -Files-Excluded: src/images/*.ttf - -Files: * -Copyright: 2009-2017 Lukas Holecek -License: GPL-3+ -Comment: - CopyQ 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. - . - CopyQ 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. - -Files: src/images/fontawesome-webfont.ttf -Copyright: Font Awesome by Dave Gandy - http://fontawesome.io -License: SIL OFL 1.1 -URL: http://scripts.sil.org/OFL - -Files: - src/gui/execmenu.* - src/gui/fancylineedit.* - src/gui/filterlineedit.* -Copyright: 2014 Digia Plc and/or its subsidiary(-ies). -License: LGPL-2.1 or LGPL-3 -Comment: - In addition, as a special exception, Digia gives you certain additional - rights. These rights are described in the Digia Qt LGPL Exception - version 1.1. - . - -------- - Digia Qt LGPL Exception version 1.1 - . - As a special exception to the GNU Lesser General Public License version - 2.1, the object code form of a "work that uses the Library" may - incorporate material from a header file that is part of the Library. You - may distribute such object code under terms of your choice, provided that - the incorporated material (i) does not exceed more than 5% of the total - size of the Library; and (ii) is limited to numerical parameters, data - structure layouts, accessors, macros, inline functions and templates. - -------- - http://doc.qt.io/qt-5/lgpl.html - -Files: qxt/* -Copyright: 2006-2011, the LibQxt project. -License: BSD-3-clause - 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. - -Files: debian/* -Copyright: Dmitry Smirnov -License: GPL-3+ - -License: GPL-3+ - 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, 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. - . - The complete text of the GNU General Public License can be found - in "/usr/share/common-licenses/GPL-3". - -License: LGPL-2.1 - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation. - . - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - . - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - . - The complete text of the GNU Lesser General Public License - can be found in "/usr/share/common-licenses/LGPL-2.1". - -License: LGPL-3 - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License version 3 - as published by the Free Software Foundation. - . - This package 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 Lesser General Public License - along with this program. If not, see - . - The complete text fo the GNU Lesser General Public License version 3 - can be found in "/usr/share/common-licenses/LGPL-3" diff --git a/CopyQ-3.0.2/debian/rules b/CopyQ-3.0.2/debian/rules deleted file mode 100644 index 26ccbb9..0000000 --- a/CopyQ-3.0.2/debian/rules +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/make -f - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -export DEB_BUILD_MAINT_OPTIONS = hardening=+all -export DEB_LDFLAGS_MAINT_APPEND += -Wl,--as-needed -export QT_SELECT=5 - -%: - dh $@ - -override_dh_auto_configure: - dh_auto_configure -- \ - -DCMAKE_VERBOSE_MAKEFILE=ON \ - -DCMAKE_BUILD_TYPE=Release \ - -DWITH_WEBKIT=1 diff --git a/CopyQ-3.0.2/debian/rules-qt4 b/CopyQ-3.0.2/debian/rules-qt4 deleted file mode 100644 index 5570df8..0000000 --- a/CopyQ-3.0.2/debian/rules-qt4 +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/make -f - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -export DEB_BUILD_MAINT_OPTIONS = hardening=+all -export DEB_LDFLAGS_MAINT_APPEND += -Wl,--as-needed - -%: - dh $@ - -override_dh_auto_configure: - dh_auto_configure -- \ - -DCMAKE_VERBOSE_MAKEFILE=ON \ - -DCMAKE_BUILD_TYPE=Release \ - -DWITH_QT5=OFF \ - -DWITH_WEBKIT=1 diff --git a/CopyQ-3.0.2/debugfiles.list b/CopyQ-3.0.2/debugfiles.list deleted file mode 100644 index d63427f..0000000 --- a/CopyQ-3.0.2/debugfiles.list +++ /dev/null @@ -1,55 +0,0 @@ -%dir /usr/lib/debug -%dir /usr/lib/debug/usr -%dir /usr/lib/debug/usr/bin -%dir /usr/lib/debug/usr/lib64 -%dir /usr/lib/debug/usr/lib64/copyq -%dir /usr/lib/debug/usr/lib64/copyq/plugins -%dir /usr/lib/debug/.build-id -%dir /usr/lib/debug/.build-id/39 -%dir /usr/lib/debug/.build-id/40 -%dir /usr/lib/debug/.build-id/50 -%dir /usr/lib/debug/.build-id/e9 -%dir /usr/lib/debug/.build-id/ec -%dir /usr/lib/debug/.build-id/25 -%dir /usr/lib/debug/.build-id/3c -%dir /usr/lib/debug/.build-id/92 -%dir /usr/lib/debug/.build-id/48 -%dir /usr/lib/debug/.build-id/ca -%dir /usr/lib/debug/.build-id/c9 -%dir /usr/lib/debug/.dwz -/usr/lib/debug/usr/bin/copyq.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemdata.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemencrypted.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemfakevim.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemimage.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemnotes.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitempinned.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemtags.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemtext.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemsync.so.debug -/usr/lib/debug/usr/lib64/copyq/plugins/libitemweb.so.debug -/usr/lib/debug/.build-id/39/6fb26cad0769eacd7af5a39c7fc2e9c51ea8d3 -/usr/lib/debug/.build-id/39/6fb26cad0769eacd7af5a39c7fc2e9c51ea8d3.debug -/usr/lib/debug/.build-id/40/556e992b3e12ba6de9d1882d30b7e73824ba79 -/usr/lib/debug/.build-id/40/556e992b3e12ba6de9d1882d30b7e73824ba79.debug -/usr/lib/debug/.build-id/50/851b8d260a05ae088cc78dcaa6a102464472b2 -/usr/lib/debug/.build-id/50/851b8d260a05ae088cc78dcaa6a102464472b2.debug -/usr/lib/debug/.build-id/e9/4627e58f07e29f32c365d4d028acbdd0e89921 -/usr/lib/debug/.build-id/e9/4627e58f07e29f32c365d4d028acbdd0e89921.debug -/usr/lib/debug/.build-id/ec/a114fc00cc483f6b814421f97ac456e0d12067 -/usr/lib/debug/.build-id/ec/a114fc00cc483f6b814421f97ac456e0d12067.debug -/usr/lib/debug/.build-id/25/d434b121abb4897672d69bb712ce1be3d655f9 -/usr/lib/debug/.build-id/25/d434b121abb4897672d69bb712ce1be3d655f9.debug -/usr/lib/debug/.build-id/3c/710c9050a1f474964b4a1386e82800e2c5e62d -/usr/lib/debug/.build-id/3c/710c9050a1f474964b4a1386e82800e2c5e62d.debug -/usr/lib/debug/.build-id/3c/0e7d1c8fdaa374d4ed98e50bfd758e379ae062 -/usr/lib/debug/.build-id/3c/0e7d1c8fdaa374d4ed98e50bfd758e379ae062.debug -/usr/lib/debug/.build-id/92/dc76b6c1c5f939a944e21c7a83618f5f77cc3d -/usr/lib/debug/.build-id/92/dc76b6c1c5f939a944e21c7a83618f5f77cc3d.debug -/usr/lib/debug/.build-id/48/9fe1d84c8799004869412a6e133a5e1a105b97 -/usr/lib/debug/.build-id/48/9fe1d84c8799004869412a6e133a5e1a105b97.debug -/usr/lib/debug/.build-id/ca/536be7713f249df8c76ab5378c30eed1944769 -/usr/lib/debug/.build-id/ca/536be7713f249df8c76ab5378c30eed1944769.debug -/usr/lib/debug/.build-id/c9/c11dd588b71df9b878fb201fe399e64a211f6e.debug -/usr/lib/debug/.dwz/copyq-3.0.2-1.fc27.x86_64 -/usr/src/debug/CopyQ-3.0.2 diff --git a/CopyQ-3.0.2/debuglinks.list b/CopyQ-3.0.2/debuglinks.list deleted file mode 100644 index e566d45..0000000 --- a/CopyQ-3.0.2/debuglinks.list +++ /dev/null @@ -1,23 +0,0 @@ -/usr/lib/debug/.build-id/39/6fb26cad0769eacd7af5a39c7fc2e9c51ea8d3 /usr/bin/copyq -/usr/lib/debug/.build-id/39/6fb26cad0769eacd7af5a39c7fc2e9c51ea8d3.debug /usr/lib/debug/usr/bin/copyq.debug -/usr/lib/debug/.build-id/40/556e992b3e12ba6de9d1882d30b7e73824ba79 /usr/lib64/copyq/plugins/libitemdata.so -/usr/lib/debug/.build-id/40/556e992b3e12ba6de9d1882d30b7e73824ba79.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemdata.so.debug -/usr/lib/debug/.build-id/50/851b8d260a05ae088cc78dcaa6a102464472b2 /usr/lib64/copyq/plugins/libitemencrypted.so -/usr/lib/debug/.build-id/50/851b8d260a05ae088cc78dcaa6a102464472b2.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemencrypted.so.debug -/usr/lib/debug/.build-id/e9/4627e58f07e29f32c365d4d028acbdd0e89921 /usr/lib64/copyq/plugins/libitemfakevim.so -/usr/lib/debug/.build-id/e9/4627e58f07e29f32c365d4d028acbdd0e89921.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemfakevim.so.debug -/usr/lib/debug/.build-id/ec/a114fc00cc483f6b814421f97ac456e0d12067 /usr/lib64/copyq/plugins/libitemimage.so -/usr/lib/debug/.build-id/ec/a114fc00cc483f6b814421f97ac456e0d12067.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemimage.so.debug -/usr/lib/debug/.build-id/25/d434b121abb4897672d69bb712ce1be3d655f9 /usr/lib64/copyq/plugins/libitemnotes.so -/usr/lib/debug/.build-id/25/d434b121abb4897672d69bb712ce1be3d655f9.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemnotes.so.debug -/usr/lib/debug/.build-id/3c/710c9050a1f474964b4a1386e82800e2c5e62d /usr/lib64/copyq/plugins/libitempinned.so -/usr/lib/debug/.build-id/3c/710c9050a1f474964b4a1386e82800e2c5e62d.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitempinned.so.debug -/usr/lib/debug/.build-id/3c/0e7d1c8fdaa374d4ed98e50bfd758e379ae062 /usr/lib64/copyq/plugins/libitemtags.so -/usr/lib/debug/.build-id/3c/0e7d1c8fdaa374d4ed98e50bfd758e379ae062.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemtags.so.debug -/usr/lib/debug/.build-id/92/dc76b6c1c5f939a944e21c7a83618f5f77cc3d /usr/lib64/copyq/plugins/libitemtext.so -/usr/lib/debug/.build-id/92/dc76b6c1c5f939a944e21c7a83618f5f77cc3d.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemtext.so.debug -/usr/lib/debug/.build-id/48/9fe1d84c8799004869412a6e133a5e1a105b97 /usr/lib64/copyq/plugins/libitemsync.so -/usr/lib/debug/.build-id/48/9fe1d84c8799004869412a6e133a5e1a105b97.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemsync.so.debug -/usr/lib/debug/.build-id/ca/536be7713f249df8c76ab5378c30eed1944769 /usr/lib64/copyq/plugins/libitemweb.so -/usr/lib/debug/.build-id/ca/536be7713f249df8c76ab5378c30eed1944769.debug /usr/lib/debug/usr/lib64/copyq/plugins/libitemweb.so.debug -/usr/lib/debug/.build-id/c9/c11dd588b71df9b878fb201fe399e64a211f6e.debug /usr/lib/debug/.dwz/copyq-3.0.2-1.fc27.x86_64 diff --git a/CopyQ-3.0.2/debugsources.list b/CopyQ-3.0.2/debugsources.list deleted file mode 100644 index fa89a0c..0000000 Binary files a/CopyQ-3.0.2/debugsources.list and /dev/null differ diff --git a/CopyQ-3.0.2/elfbins.list b/CopyQ-3.0.2/elfbins.list deleted file mode 100644 index a7be0e3..0000000 --- a/CopyQ-3.0.2/elfbins.list +++ /dev/null @@ -1,11 +0,0 @@ -.//usr/bin/copyq -.//usr/lib64/copyq/plugins/libitemdata.so -.//usr/lib64/copyq/plugins/libitemencrypted.so -.//usr/lib64/copyq/plugins/libitemfakevim.so -.//usr/lib64/copyq/plugins/libitemimage.so -.//usr/lib64/copyq/plugins/libitemnotes.so -.//usr/lib64/copyq/plugins/libitempinned.so -.//usr/lib64/copyq/plugins/libitemtags.so -.//usr/lib64/copyq/plugins/libitemtext.so -.//usr/lib64/copyq/plugins/libitemsync.so -.//usr/lib64/copyq/plugins/libitemweb.so diff --git a/CopyQ-3.0.2/gpl.txt b/CopyQ-3.0.2/gpl.txt deleted file mode 100644 index 94a9ed0..0000000 --- a/CopyQ-3.0.2/gpl.txt +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/CopyQ-3.0.2/install_manifest.txt b/CopyQ-3.0.2/install_manifest.txt deleted file mode 100644 index 71db68d..0000000 --- a/CopyQ-3.0.2/install_manifest.txt +++ /dev/null @@ -1,66 +0,0 @@ -/usr/share/icons/hicolor/scalable/apps/copyq-normal.svg -/usr/share/icons/hicolor/scalable/apps/copyq-busy.svg -/usr/share/applications/copyq.desktop -/usr/share/appdata/copyq.appdata.xml -/usr/share/icons/hicolor/16x16/apps/copyq.png -/usr/share/icons/hicolor/16x16/apps/copyq-normal.png -/usr/share/icons/hicolor/16x16/apps/copyq-busy.png -/usr/share/icons/hicolor/22x22/apps/copyq.png -/usr/share/icons/hicolor/22x22/apps/copyq-normal.png -/usr/share/icons/hicolor/22x22/apps/copyq-busy.png -/usr/share/icons/hicolor/24x24/apps/copyq.png -/usr/share/icons/hicolor/24x24/apps/copyq-normal.png -/usr/share/icons/hicolor/24x24/apps/copyq-busy.png -/usr/share/icons/hicolor/32x32/apps/copyq.png -/usr/share/icons/hicolor/32x32/apps/copyq-normal.png -/usr/share/icons/hicolor/32x32/apps/copyq-busy.png -/usr/share/icons/hicolor/48x48/apps/copyq.png -/usr/share/icons/hicolor/48x48/apps/copyq-normal.png -/usr/share/icons/hicolor/48x48/apps/copyq-busy.png -/usr/share/icons/hicolor/64x64/apps/copyq.png -/usr/share/icons/hicolor/64x64/apps/copyq-normal.png -/usr/share/icons/hicolor/64x64/apps/copyq-busy.png -/usr/share/icons/hicolor/128x128/apps/copyq.png -/usr/share/icons/hicolor/128x128/apps/copyq-normal.png -/usr/share/icons/hicolor/128x128/apps/copyq-busy.png -/usr/share/copyq/themes/dark.ini -/usr/share/copyq/themes/forest.ini -/usr/share/copyq/themes/light.ini -/usr/share/copyq/themes/paper.ini -/usr/share/copyq/themes/simple.ini -/usr/share/copyq/themes/solarized-dark.ini -/usr/share/copyq/themes/solarized-light.ini -/usr/share/copyq/themes/wine.ini -/usr/bin/copyq -/usr/share/copyq/locale/copyq_ar.qm -/usr/share/copyq/locale/copyq_cs.qm -/usr/share/copyq/locale/copyq_da.qm -/usr/share/copyq/locale/copyq_de.qm -/usr/share/copyq/locale/copyq_es.qm -/usr/share/copyq/locale/copyq_fr.qm -/usr/share/copyq/locale/copyq_hu.qm -/usr/share/copyq/locale/copyq_it.qm -/usr/share/copyq/locale/copyq_ja.qm -/usr/share/copyq/locale/copyq_lt.qm -/usr/share/copyq/locale/copyq_nb.qm -/usr/share/copyq/locale/copyq_nl.qm -/usr/share/copyq/locale/copyq_pl.qm -/usr/share/copyq/locale/copyq_pt_BR.qm -/usr/share/copyq/locale/copyq_pt_PT.qm -/usr/share/copyq/locale/copyq_ru.qm -/usr/share/copyq/locale/copyq_sk.qm -/usr/share/copyq/locale/copyq_sv.qm -/usr/share/copyq/locale/copyq_tr.qm -/usr/share/copyq/locale/copyq_uk.qm -/usr/share/copyq/locale/copyq_zh_CN.qm -/usr/share/copyq/locale/copyq_zh_TW.qm -/usr/lib64/copyq/plugins/libitemdata.so -/usr/lib64/copyq/plugins/libitemencrypted.so -/usr/lib64/copyq/plugins/libitemfakevim.so -/usr/lib64/copyq/plugins/libitemimage.so -/usr/lib64/copyq/plugins/libitemnotes.so -/usr/lib64/copyq/plugins/libitempinned.so -/usr/lib64/copyq/plugins/libitemtags.so -/usr/lib64/copyq/plugins/libitemtext.so -/usr/lib64/copyq/plugins/libitemsync.so -/usr/lib64/copyq/plugins/libitemweb.so \ No newline at end of file diff --git a/CopyQ-3.0.2/plugins/CMakeLists.txt b/CopyQ-3.0.2/plugins/CMakeLists.txt deleted file mode 100644 index 1790b47..0000000 --- a/CopyQ-3.0.2/plugins/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -macro (copyq_add_plugin) - set(copyq_pkg ${ARGV0}) - - file(GLOB copyq_plugin_SOURCES - ${copyq_plugin_${copyq_pkg}_SOURCES} - *.cpp - ../../src/item/itemwidget.cpp - ) - file(GLOB copyq_plugin_FORMS - ${copyq_plugin_${copyq_pkg}_FORMS} - *.ui - ) - - if (WITH_TESTS) - file(GLOB copyq_plugin_SOURCES ${copyq_plugin_SOURCES} tests/*.cpp) - endif (WITH_TESTS) - - include_directories(${CMAKE_CURRENT_BINARY_DIR} ../../src) - - if (WITH_QT5) - include_directories(${Qt5Widgets_INCLUDES}) - add_definitions(${Qt5Widgets_DEFINITIONS}) - qt5_wrap_ui(copyq_plugin_FORMS_HEADERS ${copyq_plugin_FORMS}) - qt5_add_resources(copyq_plugin_RCC ${copyq_plugin_${copyq_pkg}_RESOURCES}) - else() - include_directories(${QT_INCLUDES}) - add_definitions(${QT_DEFINITIONS}) - qt4_wrap_ui(copyq_plugin_FORMS_HEADERS ${copyq_plugin_FORMS}) - qt4_add_resources(copyq_plugin_RCC ${copyq_plugin_${copyq_pkg}_RESOURCES}) - endif() - - add_library(${copyq_pkg} MODULE - ${copyq_plugin_SOURCES} - ${copyq_plugin_FORMS_HEADERS} - ${copyq_plugin_RCC} - ) - - set_target_properties(${copyq_pkg} PROPERTIES - COMPILE_DEFINITIONS "${copyq_plugin_${copyq_pkg}_DEFINITIONS}") - - if (WITH_QT5) - qt5_use_modules(${copyq_pkg} Widgets ${copyq_Qt5_Modules} ${copyq_plugin_${copyq_pkg}_Qt5_Modules}) - else() - include(${QT_USE_FILE}) - endif() - - target_link_libraries(${copyq_pkg} ${QT_LIBRARIES} ${copyq_plugin_${copyq_pkg}_LIBRARIES}) - - if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - install(TARGETS ${copyq_pkg} DESTINATION ${PLUGIN_INSTALL_PREFIX}) - endif() -endmacro() - -set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/plugins) - -add_subdirectory("itemdata") -add_subdirectory("itemencrypted") -add_subdirectory("itemfakevim") -add_subdirectory("itemimage") -add_subdirectory("itemnotes") -add_subdirectory("itempinned") -add_subdirectory("itemtags") -add_subdirectory("itemtext") -add_subdirectory("itemsync") -add_subdirectory("itemweb") diff --git a/CopyQ-3.0.2/plugins/itemdata/CMakeLists.txt b/CopyQ-3.0.2/plugins/itemdata/CMakeLists.txt deleted file mode 100644 index c7a70be..0000000 --- a/CopyQ-3.0.2/plugins/itemdata/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set(copyq_plugin_itemdata_SOURCES - ../../src/common/log.cpp - ../../src/common/mimetypes.cpp - ../../src/common/textdata.cpp - ) - -copyq_add_plugin(itemdata) - diff --git a/CopyQ-3.0.2/plugins/itemdata/itemdata.cpp b/CopyQ-3.0.2/plugins/itemdata/itemdata.cpp deleted file mode 100644 index 299a49d..0000000 --- a/CopyQ-3.0.2/plugins/itemdata/itemdata.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - Copyright (c) 2014, Lukas Holecek - - This file is part of CopyQ. - - CopyQ 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. - - CopyQ 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 CopyQ. If not, see . -*/ - -#include "itemdata.h" -#include "ui_itemdatasettings.h" - -#include "common/contenttype.h" -#include "common/mimetypes.h" -#include "common/textdata.h" - -#include -#include -#include -#include -#include - -namespace { - -// Limit number of characters for performance reasons. -const int defaultMaxBytes = 256; - -QString hexData(const QByteArray &data) -{ - if ( data.isEmpty() ) - return QString(); - - QString result; - QString chars; - - int i = 0; - forever { - if (i > 0) { - if ( (i % 2) == 0 ) - result.append( QString(" ") ); - if ( (i % 16) == 0 ) { - result.append(" "); - result.append(chars); - result.append( QString("\n") ); - chars.clear(); - if (i >= data.size() ) - break; - } - } - if ( (i % 16) == 0 ) { - result.append( QString("%1: ").arg(QString::number(i, 16), 4, QChar('0')) ); - } - if (i < data.size() ) { - QChar c = data[i]; - result.append( QString("%1").arg(QString::number(c.unicode(), 16), 2, QChar('0')) ); - chars.append( c.isPrint() ? escapeHtml(QString(c)) : QString(".") ); - } else { - result.append( QString(" ") ); - } - - ++i; - } - - return result; -} - -QString stringFromBytes(const QByteArray &bytes, const QString &format) -{ - QTextCodec *codec = QTextCodec::codecForName("utf-8"); - if (format == QLatin1String("text/html")) - codec = QTextCodec::codecForHtml(bytes, codec); - return codec->toUnicode(bytes); -} - -bool emptyIntersection(const QStringList &lhs, const QStringList &rhs) -{ - for (const auto &l : lhs) { - if ( rhs.contains(l) ) - return false; - } - - return true; -} - -} // namespace - -ItemData::ItemData(const QModelIndex &index, int maxBytes, QWidget *parent) - : QLabel(parent) - , ItemWidget(this) -{ - setTextInteractionFlags(Qt::TextSelectableByMouse); - setContentsMargins(4, 4, 4, 4); - setTextFormat(Qt::RichText); - - QString text; - - const QVariantMap data = index.data(contentType::data).toMap(); - for ( const auto &format : data.keys() ) { - QByteArray bytes = data[format].toByteArray(); - const int size = bytes.size(); - bool trimmed = size > maxBytes; - if (trimmed) - bytes = bytes.left(maxBytes); - - bool hasText = format.startsWith("text/") || - format.startsWith("application/x-copyq-owner-window-title"); - const QString content = hasText ? escapeHtml(stringFromBytes(bytes, format)) : hexData(bytes); - text.append( QString("

") ); - text.append( QString("%1 (%2 bytes)

%3
") - .arg(format) - .arg(size) - .arg(content) ); - text.append( QString("

") ); - - if (trimmed) - text.append( QString("

...

") ); - } - - setText(text); -} - -void ItemData::highlight(const QRegExp &, const QFont &, const QPalette &) -{ -} - -void ItemData::mousePressEvent(QMouseEvent *e) -{ - QLabel::mousePressEvent(e); - e->ignore(); -} - -void ItemData::mouseDoubleClickEvent(QMouseEvent *e) -{ - if ( e->modifiers().testFlag(Qt::ShiftModifier) ) - QLabel::mouseDoubleClickEvent(e); - else - e->ignore(); -} - -void ItemData::contextMenuEvent(QContextMenuEvent *e) -{ - e->ignore(); -} - -ItemDataLoader::ItemDataLoader() -{ -} - -ItemDataLoader::~ItemDataLoader() = default; - -ItemWidget *ItemDataLoader::create(const QModelIndex &index, QWidget *parent, bool preview) const -{ - if ( index.data(contentType::isHidden).toBool() ) - return nullptr; - - const QStringList formats = index.data(contentType::data).toMap().keys(); - if ( emptyIntersection(formats, formatsToSave()) ) - return nullptr; - - const int bytes = preview ? 4096 : m_settings.value("max_bytes", defaultMaxBytes).toInt(); - return new ItemData(index, bytes, parent); -} - -QStringList ItemDataLoader::formatsToSave() const -{ - return m_settings.contains("formats") - ? m_settings["formats"].toStringList() - : QStringList() << mimeUriList << QString("text/xml"); -} - -QVariantMap ItemDataLoader::applySettings() -{ - Q_ASSERT(ui != nullptr); - m_settings["formats"] = ui->plainTextEditFormats->toPlainText().split( QRegExp("[;,\\s]+") ); - m_settings["max_bytes"] = ui->spinBoxMaxChars->value(); - return m_settings; -} - -QWidget *ItemDataLoader::createSettingsWidget(QWidget *parent) -{ - ui.reset(new Ui::ItemDataSettings); - QWidget *w = new QWidget(parent); - ui->setupUi(w); - - const QStringList formats = formatsToSave(); - ui->plainTextEditFormats->setPlainText( formats.join(QString("\n")) ); - ui->spinBoxMaxChars->setValue( m_settings.value("max_bytes", defaultMaxBytes).toInt() ); - - connect( ui->treeWidgetFormats, SIGNAL(itemActivated(QTreeWidgetItem*,int)), - SLOT(on_treeWidgetFormats_itemActivated(QTreeWidgetItem*,int)) ); - - return w; -} - -void ItemDataLoader::on_treeWidgetFormats_itemActivated(QTreeWidgetItem *item, int column) -{ - const QString mime = item->toolTip(column); - if ( !mime.isEmpty() ) - ui->plainTextEditFormats->appendPlainText(mime); -} - -Q_EXPORT_PLUGIN2(itemdata, ItemDataLoader) diff --git a/CopyQ-3.0.2/plugins/itemdata/itemdata.h b/CopyQ-3.0.2/plugins/itemdata/itemdata.h deleted file mode 100644 index 6a47720..0000000 --- a/CopyQ-3.0.2/plugins/itemdata/itemdata.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (c) 2014, Lukas Holecek - - This file is part of CopyQ. - - CopyQ 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. - - CopyQ 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 CopyQ. If not, see . -*/ - -#ifndef ITEMDATA_H -#define ITEMDATA_H - -#include "item/itemwidget.h" -#include "gui/icons.h" - -#include - -#include - -namespace Ui { -class ItemDataSettings; -} - -class QTreeWidgetItem; - -class ItemData : public QLabel, public ItemWidget -{ - Q_OBJECT - -public: - ItemData(const QModelIndex &index, int maxBytes, QWidget *parent); - -protected: - void highlight(const QRegExp &re, const QFont &highlightFont, - const QPalette &highlightPalette) override; - - QWidget *createEditor(QWidget *) const override { return nullptr; } - - void mousePressEvent(QMouseEvent *e) override; - - void mouseDoubleClickEvent(QMouseEvent *e) override; - - void contextMenuEvent(QContextMenuEvent *e) override; -}; - -class ItemDataLoader : public QObject, public ItemLoaderInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID COPYQ_PLUGIN_ITEM_LOADER_ID) - Q_INTERFACES(ItemLoaderInterface) - -public: - ItemDataLoader(); - ~ItemDataLoader(); - - ItemWidget *create(const QModelIndex &index, QWidget *parent, bool preview) const override; - - int priority() const override { return -20; } - - QString id() const override { return "itemdata"; } - QString name() const override { return tr("Data"); } - QString author() const override { return QString(); } - QString description() const override { return tr("Various data to save."); } - QVariant icon() const override { return QVariant(IconFileText); } - - QStringList formatsToSave() const override; - - QVariantMap applySettings() override; - - void loadSettings(const QVariantMap &settings) override { m_settings = settings; } - - QWidget *createSettingsWidget(QWidget *parent) override; - -private slots: - void on_treeWidgetFormats_itemActivated(QTreeWidgetItem *item, int column); - -private: - QVariantMap m_settings; - std::unique_ptr ui; -}; - -#endif // ITEMDATA_H diff --git a/CopyQ-3.0.2/plugins/itemdata/itemdata.pro b/CopyQ-3.0.2/plugins/itemdata/itemdata.pro deleted file mode 100644 index 4f8a0c7..0000000 --- a/CopyQ-3.0.2/plugins/itemdata/itemdata.pro +++ /dev/null @@ -1,10 +0,0 @@ -include(../plugins_common.pri) - -HEADERS += itemdata.h -SOURCES += itemdata.cpp \ - ../../src/common/log.cpp \ - ../../src/common/mimetypes.cpp \ - ../../src/common/textdata.cpp -FORMS += itemdatasettings.ui -TARGET = $$qtLibraryTarget(itemdata) - diff --git a/CopyQ-3.0.2/plugins/itemdata/itemdatasettings.ui b/CopyQ-3.0.2/plugins/itemdata/itemdatasettings.ui deleted file mode 100644 index 03d214d..0000000 --- a/CopyQ-3.0.2/plugins/itemdata/itemdatasettings.ui +++ /dev/null @@ -1,214 +0,0 @@ - - - ItemDataSettings - - - - 0 - 0 - 430 - 321 - - - - - 0 - 1 - - - - - - - Select formats to save in history. You can add a format from examples below or type in other (one per line). - - - true - - - - - - - - - Active &Formats: - - - plainTextEditFormats - - - - - - - &Examples (double click to add to active formats): - - - true - - - treeWidgetFormats - - - - - - - QAbstractItemView::NoEditTriggers - - - false - - - - 1 - - - - - Text - - - - Unformatted simple text - - - text/plain - - - - - Formatted text, web pages - - - text/html -text/richtext - - - - - XML - - - text/xml - - - - - List of URI (e.g. copied files, URLs) - - - text/uri-list - - - - - - Images - - - - Bitmap image - - - text/bmp - - - - - Vector graphics - - - image/svg+xml -image/x-inkscape-svg-compressed - - - - - Web image formats - - - image/png -image/jpeg -image/gif - - - - - Other - - - image/epx -image/ico -image/jp2 -image/jpx -image/tiff -image/pcx -image/ppm -image/rgb -image/rgba -image/tga -image/x-targa -image/x-tga -image/xpm -image/xbm - - - - - - - - - List of clipboard mime types that will be stored in history (in given display order) - - - true - - - QPlainTextEdit::NoWrap - - - - - - - - - - - &Maximum number of characters per format to display: - - - spinBoxMaxChars - - - - - - - 4096 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - diff --git a/CopyQ-3.0.2/plugins/itemencrypted/CMakeLists.txt b/CopyQ-3.0.2/plugins/itemencrypted/CMakeLists.txt deleted file mode 100644 index f6bf0a2..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(copyq_plugin_itemencrypted_SOURCES - ../../src/common/config.cpp - ../../src/common/log.cpp - ../../src/common/mimetypes.cpp - ../../src/common/shortcuts.cpp - ../../src/common/textdata.cpp - ../../src/gui/iconfont.cpp - ../../src/gui/iconwidget.cpp - ../../src/item/serialize.cpp - ) - -copyq_add_plugin(itemencrypted) - diff --git a/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.cpp b/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.cpp deleted file mode 100644 index 6375f99..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/* - Copyright (c) 2014, Lukas Holecek - - This file is part of CopyQ. - - CopyQ 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. - - CopyQ 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 CopyQ. If not, see . -*/ - -#include "itemencrypted.h" -#include "ui_itemencryptedsettings.h" - -#include "common/command.h" -#include "common/config.h" -#include "common/contenttype.h" -#include "common/log.h" -#include "common/mimetypes.h" -#include "common/shortcuts.h" -#include "common/textdata.h" -#include "gui/icons.h" -#include "gui/iconwidget.h" -#include "item/serialize.h" - -#ifdef HAS_TESTS -# include "tests/itemencryptedtests.h" -#endif - -#include -#include -#include -#include -#include -#include - -namespace { - -const char mimeEncryptedData[] = "application/x-copyq-encrypted"; - -const char dataFileHeader[] = "CopyQ_encrypted_tab"; -const char dataFileHeaderV2[] = "CopyQ_encrypted_tab v2"; - -const int maxItemCount = 10000; - -struct KeyPairPaths { - KeyPairPaths() - { - const QString path = getConfigurationFilePath(QString()); - sec = QDir::toNativeSeparators(path + ".sec"); - pub = QDir::toNativeSeparators(path + ".pub"); - } - - QString sec; - QString pub; -}; - -QString gpgExecutable() -{ - return "gpg2"; -} - -QStringList getDefaultEncryptCommandArguments(const QString &publicKeyPath) -{ - return QStringList() << "--trust-model" << "always" << "--recipient" << "copyq" - << "--charset" << "utf-8" << "--display-charset" << "utf-8" << "--no-tty" - << "--no-default-keyring" << "--keyring" << publicKeyPath; -} - -void startGpgProcess(QProcess *p, const QStringList &args) -{ - KeyPairPaths keys; - p->start(gpgExecutable(), getDefaultEncryptCommandArguments(keys.pub) + args); -} - -bool verifyProcess(QProcess *p) -{ - const int exitCode = p->exitCode(); - if ( p->exitStatus() != QProcess::NormalExit ) { - log( "ItemEncrypt ERROR: Failed to run GnuPG: " + p->errorString(), LogError ); - return false; - } - - if (exitCode != 0) { - const QString errors = p->readAllStandardError(); - if ( !errors.isEmpty() ) - log( "ItemEncrypt ERROR: GnuPG stderr:\n" + errors, LogError ); - return false; - } - - return true; -} - -bool waitOrTerminate(QProcess *p) -{ - if ( p->state() != QProcess::NotRunning && !p->waitForFinished() ) { - p->terminate(); - if ( !p->waitForFinished(5000) ) - p->kill(); - return false; - } - - return true; -} - -QString importGpgKey() -{ - KeyPairPaths keys; - - QProcess p; - p.start(gpgExecutable(), getDefaultEncryptCommandArguments(keys.pub) << "--import" << keys.sec); - if ( !waitOrTerminate(&p) ) - return "Failed to import private key (process timed out)."; - - if ( !verifyProcess(&p) ) - return "Failed to import private key (see log)."; - - return QString(); -} - -QString exportGpgKey() -{ - KeyPairPaths keys; - - // Private key already created or exported. - if ( QFile::exists(keys.sec) ) - return QString(); - - QProcess p; - p.start(gpgExecutable(), getDefaultEncryptCommandArguments(keys.pub) << "--export-secret-key" << "copyq"); - if ( !waitOrTerminate(&p) ) - return "Failed to export private key (process timed out)."; - - if ( !verifyProcess(&p) ) - return "Failed to export private key (see log)."; - - QFile secKey(keys.sec); - if ( !secKey.open(QIODevice::WriteOnly) ) - return "Failed to create private key."; - - if ( !secKey.setPermissions(QFile::ReadOwner | QFile::WriteOwner) ) - return "Failed to set permissions for private key."; - - const QByteArray secKeyData = p.readAllStandardOutput(); - secKey.write(secKeyData); - secKey.close(); - - return QString(); -} - -QByteArray readGpgOutput(const QStringList &args, const QByteArray &input = QByteArray()) -{ - QProcess p; - startGpgProcess( &p, args ); - p.write(input); - p.closeWriteChannel(); - p.waitForFinished(); - verifyProcess(&p); - return p.readAllStandardOutput(); -} - -bool keysExist() -{ - return !readGpgOutput( QStringList("--list-keys") ).isEmpty(); -} - -bool decryptMimeData(QVariantMap *detinationData, const QModelIndex &index) -{ - const QVariantMap data = index.data(contentType::data).toMap(); - if ( !data.contains(mimeEncryptedData) ) - return false; - - const QByteArray encryptedBytes = data.value(mimeEncryptedData).toByteArray(); - const QByteArray bytes = readGpgOutput( QStringList() << "--decrypt", encryptedBytes ); - - return deserializeData(detinationData, bytes); -} - -void encryptMimeData(const QVariantMap &data, const QModelIndex &index, QAbstractItemModel *model) -{ - const QByteArray bytes = serializeData(data); - const QByteArray encryptedBytes = readGpgOutput( QStringList("--encrypt"), bytes ); - QVariantMap dataMap; - dataMap.insert(mimeEncryptedData, encryptedBytes); - model->setData(index, dataMap, contentType::data); -} - -void startGenerateKeysProcess(QProcess *process, bool useTransientPasswordlessKey = false) -{ - const KeyPairPaths keys; - - auto args = QStringList() << "--batch" << "--gen-key"; - - QByteArray transientOptions; - if (useTransientPasswordlessKey) { - args << "--debug-quick-random"; - transientOptions = - "\n%no-protection" - "\n%transient-key"; - } - - startGpgProcess(process, args); - process->write( "\nKey-Type: RSA" - "\nKey-Usage: encrypt" - "\nKey-Length: 2048" - "\nName-Real: copyq" - + transientOptions + - "\n%secring " + keys.sec.toUtf8() + - "\n%pubring " + keys.pub.toUtf8() + - "\n%commit" - "\n" ); - process->closeWriteChannel(); -} - -QString exportImportGpgKeys() -{ - const auto error = exportGpgKey(); - if ( !error.isEmpty() ) - return error; - - return importGpgKey(); -} - -bool isGpgInstalled() -{ - QProcess p; - startGpgProcess(&p, QStringList("--version")); - p.closeWriteChannel(); - p.waitForFinished(); - - if (p.exitStatus() != QProcess::NormalExit || p.exitCode() != 0) - return false; - - const auto versionOutput = p.readAllStandardOutput(); - return versionOutput.contains(" 2."); -} - -} // namespace - -ItemEncrypted::ItemEncrypted(QWidget *parent) - : QWidget(parent) - , ItemWidget(this) -{ - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - - // Show small icon. - QWidget *iconWidget = new IconWidget(IconLock, this); - layout->addWidget(iconWidget); -} - -void ItemEncrypted::setEditorData(QWidget *editor, const QModelIndex &index) const -{ - // Decrypt before editing. - QTextEdit *textEdit = qobject_cast(editor); - if (textEdit != nullptr) { - QVariantMap data; - if ( decryptMimeData(&data, index) ) { - textEdit->setPlainText( getTextData(data, mimeText) ); - textEdit->selectAll(); - } - } -} - -void ItemEncrypted::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const -{ - // Encrypt after editing. - QTextEdit *textEdit = qobject_cast(editor); - if (textEdit != nullptr) - encryptMimeData( createDataMap(mimeText, textEdit->toPlainText()), index, model ); -} - -bool ItemEncryptedSaver::saveItems(const QString &, const QAbstractItemModel &model, QIODevice *file) -{ - const auto length = model.rowCount(); - if (length == 0) - return false; // No need to encode empty tab. - - QByteArray bytes; - - { - QDataStream stream(&bytes, QIODevice::WriteOnly); - stream.setVersion(QDataStream::Qt_4_7); - - stream << static_cast(length); - - for (int i = 0; i < length && stream.status() == QDataStream::Ok; ++i) { - QModelIndex index = model.index(i, 0); - const QVariantMap dataMap = index.data(contentType::data).toMap(); - stream << dataMap; - } - } - - bytes = readGpgOutput(QStringList("--encrypt"), bytes); - if ( bytes.isEmpty() ) { - emitEncryptFailed(); - COPYQ_LOG("ItemEncrypt ERROR: Failed to read encrypted data"); - return false; - } - - QDataStream stream(file); - stream << QString(dataFileHeaderV2); - stream.writeRawData( bytes.data(), bytes.size() ); - - if ( stream.status() != QDataStream::Ok ) { - emitEncryptFailed(); - COPYQ_LOG("ItemEncrypt ERROR: Failed to write encrypted data"); - return false; - } - - return true; -} - -void ItemEncryptedSaver::emitEncryptFailed() -{ - emit error( ItemEncryptedLoader::tr("Encryption failed!") ); -} - -bool ItemEncryptedScriptable::isEncrypted() -{ - const auto args = currentArguments(); - for (const auto &arg : args) { - bool ok; - const int row = arg.toInt(&ok); - if (ok) { - const auto result = call("read", QVariantList() << "?" << row); - if ( result.toByteArray().contains(mimeEncryptedData) ) - return true; - } - } - - return false; -} - -QByteArray ItemEncryptedScriptable::encrypt() -{ - const auto args = currentArguments(); - const auto bytes = args.first().toByteArray(); - return encrypt(bytes); -} - -QByteArray ItemEncryptedScriptable::decrypt() -{ - const auto args = currentArguments(); - const auto bytes = args.first().toByteArray(); - return decrypt(bytes); -} - -void ItemEncryptedScriptable::encryptItem() -{ - QVariantMap dataMap; - const auto formats = call("dataFormats").toList(); - for (const auto &formatValue : formats) { - const auto format = formatValue.toString(); - if ( !format.startsWith(COPYQ_MIME_PREFIX) ) { - const auto data = call("data", QVariantList() << format).toByteArray(); - dataMap.insert(format, data); - } - } - - const auto bytes = call("pack", QVariantList() << dataMap).toByteArray(); - const auto encryptedBytes = encrypt(bytes); - if (encryptedBytes.isEmpty()) - return; - - call("setData", QVariantList() << mimeEncryptedData << encryptedBytes); - - for ( const auto &format : dataMap.keys() ) - call("removeData", QVariantList() << format); -} - -void ItemEncryptedScriptable::decryptItem() -{ - const auto encryptedBytes = call("data", QVariantList() << mimeEncryptedData).toByteArray(); - const auto itemData = decrypt(encryptedBytes); - if (itemData.isEmpty()) - return; - - const auto dataMap = call("unpack", QVariantList() << itemData).toMap(); - for ( const auto &format : dataMap.keys() ) - call("setData", QVariantList() << format << dataMap[format]); -} - -void ItemEncryptedScriptable::encryptItems() -{ - const auto dataValueList = call("selectedItemsData").toList(); - - QVariantList dataList; - for (const auto &itemDataValue : dataValueList) { - auto itemData = itemDataValue.toMap(); - - QVariantMap itemDataToEncrypt; - for ( const auto &format : itemData.keys() ) { - if ( !format.startsWith(COPYQ_MIME_PREFIX) ) { - itemDataToEncrypt.insert(format, itemData[format]); - itemData.remove(format); - } - } - - const auto bytes = call("pack", QVariantList() << itemDataToEncrypt).toByteArray(); - const auto encryptedBytes = encrypt(bytes); - if (encryptedBytes.isEmpty()) - return; - itemData.insert(mimeEncryptedData, encryptedBytes); - - dataList.append(itemData); - } - - call( "setSelectedItemsData", QVariantList() << QVariant(dataList) ); -} - -void ItemEncryptedScriptable::decryptItems() -{ - const auto dataValueList = call("selectedItemsData").toList(); - - QVariantList dataList; - for (const auto &itemDataValue : dataValueList) { - auto itemData = itemDataValue.toMap(); - - const auto encryptedBytes = itemData.value(mimeEncryptedData).toByteArray(); - if ( !encryptedBytes.isEmpty() ) { - itemData.remove(mimeEncryptedData); - - const auto decryptedBytes = decrypt(encryptedBytes); - if (decryptedBytes.isEmpty()) - return; - - const auto decryptedItemData = call("unpack", QVariantList() << decryptedBytes).toMap(); - for ( const auto &format : decryptedItemData.keys() ) - itemData.insert(format, decryptedItemData[format]); - } - - dataList.append(itemData); - } - - call( "setSelectedItemsData", QVariantList() << QVariant(dataList) ); -} - -void ItemEncryptedScriptable::copyEncryptedItems() -{ - const auto dataValueList = call("selectedItemsData").toList(); - QString text; - for (const auto &dataValue : dataValueList) { - if ( !text.isEmpty() ) - text.append('\n'); - - const auto data = dataValue.toMap(); - const auto itemTextValue = data.value(mimeText); - if ( itemTextValue.isValid() ) { - text.append( getTextData(itemTextValue.toByteArray()) ); - } else { - const auto encryptedBytes = data.value(mimeEncryptedData).toByteArray(); - if ( !encryptedBytes.isEmpty() ) { - const auto itemData = decrypt(encryptedBytes); - if (itemData.isEmpty()) - return; - const auto dataMap = call("unpack", QVariantList() << itemData).toMap(); - text.append( getTextData(dataMap) ); - } - } - } - - call("copy", QVariantList() << text); -} - -QString ItemEncryptedScriptable::generateTestKeys() -{ - const KeyPairPaths keys; - for ( const auto &keyFileName : {keys.sec, keys.pub} ) { - if ( QFile::exists(keyFileName) && !QFile::remove(keyFileName) ) - return QString("Failed to remove \"%1\"").arg(keys.sec); - } - - QProcess process; - startGenerateKeysProcess(&process, true); - - if ( !waitOrTerminate(&process) || !verifyProcess(&process) ) { - return QString("ItemEncrypt ERROR: %1; stderr: %2") - .arg( process.errorString() ) - .arg( QString::fromUtf8(process.readAllStandardError()) ); - } - - const auto error = exportImportGpgKeys(); - if ( !error.isEmpty() ) - return error; - - for ( const auto &keyFileName : {keys.sec, keys.pub} ) { - if ( !QFile::exists(keyFileName) ) - return QString("Failed to create \"%1\"").arg(keys.sec); - } - - return QString(); -} - -bool ItemEncryptedScriptable::isGpgInstalled() -{ - return ::isGpgInstalled(); -} - -QByteArray ItemEncryptedScriptable::encrypt(const QByteArray &bytes) -{ - const auto encryptedBytes = readGpgOutput(QStringList("--encrypt"), bytes); - if ( encryptedBytes.isEmpty() ) - eval("throw 'Failed to execute GPG!'"); - return encryptedBytes; -} - -QByteArray ItemEncryptedScriptable::decrypt(const QByteArray &bytes) -{ - const auto decryptedBytes = readGpgOutput(QStringList("--decrypt"), bytes); - if ( decryptedBytes.isEmpty() ) - eval("throw 'Failed to execute GPG!'"); - return decryptedBytes; -} - -ItemEncryptedLoader::ItemEncryptedLoader() - : ui() - , m_settings() - , m_gpgProcessStatus(GpgNotRunning) - , m_gpgProcess(nullptr) -{ -} - -ItemEncryptedLoader::~ItemEncryptedLoader() -{ - terminateGpgProcess(); -} - -ItemWidget *ItemEncryptedLoader::create(const QModelIndex &index, QWidget *parent, bool) const -{ - if ( index.data(contentType::isHidden).toBool() ) - return nullptr; - - const QVariantMap dataMap = index.data(contentType::data).toMap(); - return dataMap.contains(mimeEncryptedData) ? new ItemEncrypted(parent) : nullptr; -} - -QStringList ItemEncryptedLoader::formatsToSave() const -{ - return QStringList(mimeEncryptedData); -} - -QVariantMap ItemEncryptedLoader::applySettings() -{ - Q_ASSERT(ui != nullptr); - m_settings.insert( "encrypt_tabs", ui->plainTextEditEncryptTabs->toPlainText().split('\n') ); - return m_settings; -} - -QWidget *ItemEncryptedLoader::createSettingsWidget(QWidget *parent) -{ - ui.reset(new Ui::ItemEncryptedSettings); - QWidget *w = new QWidget(parent); - ui->setupUi(w); - - connect( ui->pushButtonAddCommands, SIGNAL(clicked()), - this, SLOT(addCommands()) ); - - ui->plainTextEditEncryptTabs->setPlainText( - m_settings.value("encrypt_tabs").toStringList().join("\n") ); - - // Check if gpg application is available. - if ( !isGpgInstalled() ) { - m_gpgProcessStatus = GpgNotInstalled; - } else { - KeyPairPaths keys; - ui->labelShareInfo->setTextFormat(Qt::RichText); - ui->labelShareInfo->setText( tr("To share encrypted items on other computer or" - " session, you'll need public and secret key files:" - "
    " - "
  • %1
  • " - "
  • %2
    (Keep this secret key in a safe place.)
  • " - "
" - ) - .arg( quoteString(keys.pub) ) - .arg( quoteString(keys.sec) ) - ); - } - - updateUi(); - - connect( ui->pushButtonPassword, SIGNAL(clicked()), - this, SLOT(setPassword()) ); - - return w; -} - -bool ItemEncryptedLoader::canLoadItems(QIODevice *file) const -{ - QDataStream stream(file); - - QString header; - stream >> header; - - return stream.status() == QDataStream::Ok - && (header == dataFileHeader || header == dataFileHeaderV2); -} - -bool ItemEncryptedLoader::canSaveItems(const QString &tabName) const -{ - for ( const auto &encryptTabName : m_settings.value("encrypt_tabs").toStringList() ) { - if ( encryptTabName.isEmpty() ) - continue; - - QString tabName1 = tabName; - - // Ignore ampersands (usually just for underlining mnemonics) if none is specified. - if ( !hasKeyHint(encryptTabName) ) - removeKeyHint(&tabName1); - - // Ignore path in tab tree if none path separator is specified. - if ( !encryptTabName.contains('/') ) { - const int i = tabName1.lastIndexOf('/'); - tabName1.remove(0, i + 1); - } - - if ( tabName1 == encryptTabName ) - return true; - } - - return false; -} - -ItemSaverPtr ItemEncryptedLoader::loadItems(const QString &, QAbstractItemModel *model, QIODevice *file, int maxItems) -{ - // This is needed to skip header. - if ( !canLoadItems(file) ) - return nullptr; - - if (m_gpgProcessStatus == GpgNotInstalled) { - emit error( tr("GnuPG must be installed to view encrypted tabs.") ); - return nullptr; - } - - importGpgKey(); - - QProcess p; - startGpgProcess( &p, QStringList("--decrypt") ); - - char encryptedBytes[4096]; - - QDataStream stream(file); - while ( !stream.atEnd() ) { - const int bytesRead = stream.readRawData(encryptedBytes, 4096); - if (bytesRead == -1) { - emitDecryptFailed(); - COPYQ_LOG("ItemEncrypted ERROR: Failed to read encrypted data"); - return nullptr; - } - p.write(encryptedBytes, bytesRead); - } - - p.closeWriteChannel(); - if ( !waitOrTerminate(&p) || !verifyProcess(&p) ) { - emitDecryptFailed(); - return nullptr; - } - - const QByteArray bytes = p.readAllStandardOutput(); - if ( bytes.isEmpty() ) { - emitDecryptFailed(); - COPYQ_LOG("ItemEncrypt ERROR: Failed to read encrypted data."); - verifyProcess(&p); - return nullptr; - } - - QDataStream stream2(bytes); - - quint64 length; - stream2 >> length; - if ( length <= 0 || stream2.status() != QDataStream::Ok ) { - emitDecryptFailed(); - COPYQ_LOG("ItemEncrypt ERROR: Failed to parse item count!"); - return nullptr; - } - length = qMin(length, static_cast(maxItems)) - static_cast(model->rowCount()); - - const auto count = length < maxItemCount ? static_cast(length) : maxItemCount; - for ( int i = 0; i < count && stream2.status() == QDataStream::Ok; ++i ) { - if ( !model->insertRow(i) ) { - emitDecryptFailed(); - COPYQ_LOG("ItemEncrypt ERROR: Failed to insert item!"); - return nullptr; - } - QVariantMap dataMap; - stream2 >> dataMap; - model->setData( model->index(i, 0), dataMap, contentType::data ); - } - - if ( stream2.status() != QDataStream::Ok ) { - emitDecryptFailed(); - COPYQ_LOG("ItemEncrypt ERROR: Failed to decrypt item!"); - return nullptr; - } - - return createSaver(); -} - -ItemSaverPtr ItemEncryptedLoader::initializeTab(const QString &, QAbstractItemModel *, int) -{ - if (m_gpgProcessStatus == GpgNotInstalled) - return nullptr; - - return createSaver(); -} - -QObject *ItemEncryptedLoader::tests(const TestInterfacePtr &test) const -{ -#ifdef HAS_TESTS - QObject *tests = new ItemEncryptedTests(test); - return tests; -#else - Q_UNUSED(test); - return nullptr; -#endif -} - -ItemScriptable *ItemEncryptedLoader::scriptableObject(QObject *parent) -{ - return new ItemEncryptedScriptable(parent); -} - -QList ItemEncryptedLoader::commands() const -{ - QList commands; - - Command c; - c.name = tr("Encrypt (needs GnuPG)"); - c.icon = QString(QChar(IconLock)); - c.input = "!OUTPUT"; - c.output = mimeEncryptedData; - c.inMenu = true; - c.cmd = "copyq: plugins.itemencrypted.encryptItems()"; - c.shortcuts.append( toPortableShortcutText(tr("Ctrl+L")) ); - commands.append(c); - - c = Command(); - c.name = tr("Decrypt"); - c.icon = QString(QChar(IconUnlock)); - c.input = mimeEncryptedData; - c.output = mimeItems; - c.inMenu = true; - c.cmd = "copyq: plugins.itemencrypted.decryptItems()"; - c.shortcuts.append( toPortableShortcutText(tr("Ctrl+L")) ); - commands.append(c); - - c = Command(); - c.name = tr("Decrypt and Copy"); - c.icon = QString(QChar(IconUnlockAlt)); - c.input = mimeEncryptedData; - c.inMenu = true; - c.cmd = "copyq: plugins.itemencrypted.copyEncryptedItems()"; - c.shortcuts.append( toPortableShortcutText(tr("Ctrl+Shift+L")) ); - commands.append(c); - - return commands; -} - -void ItemEncryptedLoader::setPassword() -{ - if (m_gpgProcessStatus == GpgGeneratingKeys) - return; - - if (m_gpgProcess != nullptr) { - terminateGpgProcess(); - return; - } - - if ( !keysExist() ) { - m_gpgProcessStatus = GpgGeneratingKeys; - m_gpgProcess = new QProcess(this); - startGenerateKeysProcess(m_gpgProcess); - } else { - // Change password. - m_gpgProcessStatus = GpgChangingPassword; - m_gpgProcess = new QProcess(this); - startGpgProcess( m_gpgProcess, QStringList() << "--edit-key" << "copyq" << "passwd" << "save"); - } - - m_gpgProcess->waitForStarted(); - if ( m_gpgProcess->state() == QProcess::NotRunning ) { - onGpgProcessFinished( m_gpgProcess->exitCode(), m_gpgProcess->exitStatus() ); - } else { - connect( m_gpgProcess, SIGNAL(finished(int,QProcess::ExitStatus)), - this, SLOT(onGpgProcessFinished(int,QProcess::ExitStatus)) ); - updateUi(); - } -} - -void ItemEncryptedLoader::terminateGpgProcess() -{ - if (m_gpgProcess == nullptr) - return; - QProcess *p = m_gpgProcess; - m_gpgProcess = nullptr; - p->terminate(); - p->waitForFinished(); - p->deleteLater(); - m_gpgProcessStatus = GpgNotRunning; - updateUi(); -} - -void ItemEncryptedLoader::onGpgProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) -{ - QString error; - - if (m_gpgProcess != nullptr) { - if (ui != nullptr) { - if (exitStatus != QProcess::NormalExit) - error = m_gpgProcess->errorString(); - else if (exitCode != 0) - error = getTextData(m_gpgProcess->readAllStandardError()); - else if ( m_gpgProcess->error() != QProcess::UnknownError ) - error = m_gpgProcess->errorString(); - else if ( !keysExist() ) - error = tr("Failed to generate keys."); - } - - m_gpgProcess->deleteLater(); - m_gpgProcess = nullptr; - } - - // Export and import private key to a file in configuration. - if ( m_gpgProcessStatus == GpgGeneratingKeys && error.isEmpty() ) - error = exportImportGpgKeys(); - - if (!error.isEmpty()) - error = tr("Error: %1").arg(error); - - m_gpgProcessStatus = GpgNotRunning; - - updateUi(); - ui->labelInfo->setText( error.isEmpty() ? tr("Done") : error ); -} - -void ItemEncryptedLoader::addCommands() -{ - emit addCommands(commands()); -} - -void ItemEncryptedLoader::updateUi() -{ - if (ui == nullptr) - return; - - if (m_gpgProcessStatus == GpgNotInstalled) { - ui->labelInfo->setText("To use item encryption, install" - " GnuPG" - " application and restart CopyQ."); - ui->pushButtonPassword->hide(); - ui->pushButtonAddCommands->hide(); - ui->groupBoxEncryptTabs->hide(); - ui->groupBoxShareInfo->hide(); - } else if (m_gpgProcessStatus == GpgGeneratingKeys) { - ui->labelInfo->setText( tr("Creating new keys (this may take a few minutes)...") ); - ui->pushButtonPassword->setText( tr("Cancel") ); - } else if (m_gpgProcessStatus == GpgChangingPassword) { - ui->labelInfo->setText( tr("Setting new password...") ); - ui->pushButtonPassword->setText( tr("Cancel") ); - } else if ( !keysExist() ) { - ui->labelInfo->setText( tr("Encryption keys must be generated" - " before item encryption can be used.") ); - ui->pushButtonPassword->setText( tr("Generate New Keys...") ); - } else { - ui->pushButtonPassword->setText( tr("Change Password...") ); - } -} - -void ItemEncryptedLoader::emitDecryptFailed() -{ - emit error( tr("Decryption failed!") ); -} - -ItemSaverPtr ItemEncryptedLoader::createSaver() -{ - auto saver = std::make_shared(); - connect( saver.get(), SIGNAL(error(QString)), - this, SIGNAL(error(QString)) ); - return saver; -} - -Q_EXPORT_PLUGIN2(itemencrypted, ItemEncryptedLoader) diff --git a/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.h b/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.h deleted file mode 100644 index 5c3dfd0..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (c) 2014, Lukas Holecek - - This file is part of CopyQ. - - CopyQ 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. - - CopyQ 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 CopyQ. If not, see . -*/ - -#ifndef ITEMENCRYPTED_H -#define ITEMENCRYPTED_H - -#include "item/itemwidget.h" -#include "gui/icons.h" - -#include -#include - -#include - -namespace Ui { -class ItemEncryptedSettings; -} - -class QIODevice; - -class ItemEncrypted : public QWidget, public ItemWidget -{ - Q_OBJECT - -public: - explicit ItemEncrypted(QWidget *parent); - - void setEditorData(QWidget *editor, const QModelIndex &index) const override; - - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const override; -}; - -class ItemEncryptedSaver : public QObject, public ItemSaverInterface -{ - Q_OBJECT - -public: - bool saveItems(const QString &tabName, const QAbstractItemModel &model, QIODevice *file) override; - -signals: - void error(const QString &); - -private: - void emitEncryptFailed(); -}; - -class ItemEncryptedScriptable : public ItemScriptable -{ - Q_OBJECT -public: - explicit ItemEncryptedScriptable(QObject *parent) : ItemScriptable(parent) {} - -public slots: - bool isEncrypted(); - QByteArray encrypt(); - QByteArray decrypt(); - - void encryptItem(); - void decryptItem(); - - void encryptItems(); - void decryptItems(); - - void copyEncryptedItems(); - - QString generateTestKeys(); - bool isGpgInstalled(); - -private: - QByteArray encrypt(const QByteArray &bytes); - QByteArray decrypt(const QByteArray &bytes); -}; - -class ItemEncryptedLoader : public QObject, public ItemLoaderInterface -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID COPYQ_PLUGIN_ITEM_LOADER_ID) - Q_INTERFACES(ItemLoaderInterface) - -public: - ItemEncryptedLoader(); - - ~ItemEncryptedLoader(); - - ItemWidget *create(const QModelIndex &index, QWidget *parent, bool) const override; - - QString id() const override { return "itemencrypted"; } - QString name() const override { return tr("Encryption"); } - QString author() const override { return QString(); } - QString description() const override { return tr("Encrypt items and tabs."); } - QVariant icon() const override { return QVariant(IconLock); } - - QStringList formatsToSave() const override; - - QVariantMap applySettings() override; - - void loadSettings(const QVariantMap &settings) override { m_settings = settings; } - - QWidget *createSettingsWidget(QWidget *parent) override; - - bool canLoadItems(QIODevice *file) const override; - - bool canSaveItems(const QString &tabName) const override; - - ItemSaverPtr loadItems(const QString &tabName, QAbstractItemModel *model, QIODevice *file, int maxItems) override; - - ItemSaverPtr initializeTab(const QString &, QAbstractItemModel *model, int maxItems) override; - - QObject *tests(const TestInterfacePtr &test) const override; - - const QObject *signaler() const override { return this; } - - ItemScriptable *scriptableObject(QObject *parent) override; - - QList commands() const override; - -signals: - void error(const QString &); - void addCommands(const QList &commands); - -private slots: - void setPassword(); - void terminateGpgProcess(); - void onGpgProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); - void addCommands(); - -private: - enum GpgProcessStatus { - GpgNotInstalled, - GpgNotRunning, - GpgGeneratingKeys, - GpgChangingPassword - }; - - void updateUi(); - - void emitDecryptFailed(); - - ItemSaverPtr createSaver(); - - std::unique_ptr ui; - QVariantMap m_settings; - - GpgProcessStatus m_gpgProcessStatus; - QProcess *m_gpgProcess; -}; - -#endif // ITEMENCRYPTED_H diff --git a/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.pro b/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.pro deleted file mode 100644 index 0ed1708..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/itemencrypted.pro +++ /dev/null @@ -1,23 +0,0 @@ -include(../plugins_common.pri) - -HEADERS += itemencrypted.h \ - ../../src/gui/iconwidget.h -SOURCES += itemencrypted.cpp -SOURCES += \ - ../../src/common/config.cpp \ - ../../src/common/log.cpp \ - ../../src/common/mimetypes.cpp \ - ../../src/common/shortcuts.cpp \ - ../../src/common/textdata.cpp \ - ../../src/gui/iconfont.cpp \ - ../../src/gui/iconwidget.cpp \ - ../../src/item/serialize.cpp -FORMS += itemencryptedsettings.ui - -CONFIG(debug, debug|release) { - SOURCES += tests/itemencryptedtests.cpp - HEADERS += tests/itemencryptedtests.h -} - -TARGET = $$qtLibraryTarget(itemencrypted) - diff --git a/CopyQ-3.0.2/plugins/itemencrypted/itemencryptedsettings.ui b/CopyQ-3.0.2/plugins/itemencrypted/itemencryptedsettings.ui deleted file mode 100644 index 88a62cb..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/itemencryptedsettings.ui +++ /dev/null @@ -1,160 +0,0 @@ - - - ItemEncryptedSettings - - - - 0 - 0 - 324 - 367 - - - - - 0 - 1 - - - - - - - To encrypt and decrypt items add appropriate commands under Commands tab. - - - true - - - true - - - - - - - - - - true - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - Add Actions to Menu and Toolbar - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Sharing Encrypted Items and Tabs - - - - - - - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - - - - Encrypted Tabs - - - - - - <p>Specify names of tabs (one per line) which will be automatically encrypted and decrypted.</p> -<p>Set unload tab interval in History tab to safely unload decrypted items from memory.</p> - - - true - - - - - - - - 0 - 1 - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/CopyQ-3.0.2/plugins/itemencrypted/tests/itemencryptedtests.cpp b/CopyQ-3.0.2/plugins/itemencrypted/tests/itemencryptedtests.cpp deleted file mode 100644 index 413f0f5..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/tests/itemencryptedtests.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (c) 2014, Lukas Holecek - - This file is part of CopyQ. - - CopyQ 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. - - CopyQ 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 CopyQ. If not, see . -*/ - -#include "itemencryptedtests.h" - -#include "tests/test_utils.h" - -ItemEncryptedTests::ItemEncryptedTests(const TestInterfacePtr &test, QObject *parent) - : QObject(parent) - , m_test(test) -{ -} - -void ItemEncryptedTests::initTestCase() -{ - if ( qgetenv("COPYQ_TESTS_SKIP_ITEMENCRYPT") == "1" ) - SKIP("Unset COPYQ_TESTS_SKIP_ITEMENCRYPT to run the tests"); - - TEST(m_test->initTestCase()); -} - -void ItemEncryptedTests::cleanupTestCase() -{ - TEST(m_test->cleanupTestCase()); -} - -void ItemEncryptedTests::init() -{ - TEST(m_test->init()); -} - -void ItemEncryptedTests::cleanup() -{ - TEST( m_test->cleanup() ); -} - -void ItemEncryptedTests::encryptDecryptData() -{ - if ( !isGpgInstalled() ) - SKIP("gpg2 is required to run the test"); - - RUN("-e" << "plugins.itemencrypted.generateTestKeys()", "\n"); - - // Test gpg errors first. - RUN("-e" << "plugins.itemencrypted.encrypt(input());print('')", ""); - - const QByteArray input("\x00\x01\x02\x03\x04", 5); - QByteArray stdoutActual; - QByteArray stderrActual; - - // Encrypted data differs. - QCOMPARE( m_test->run(Args("-e") << "plugins.itemencrypted.encrypt(input())", &stdoutActual, nullptr, input), 0 ); - QVERIFY(!stdoutActual.isEmpty()); - QVERIFY(stdoutActual != input); - - QCOMPARE( m_test->run(Args("-e") << "plugins.itemencrypted.decrypt(plugins.itemencrypted.encrypt(input()))", &stdoutActual, nullptr, input), 0 ); - QCOMPARE(stdoutActual, input); -} - -bool ItemEncryptedTests::isGpgInstalled() const -{ - QByteArray actualStdout; - const auto exitCode = m_test->run(Args("-e") << "plugins.itemencrypted.isGpgInstalled()", &actualStdout); - Q_ASSERT(exitCode == 0); - Q_ASSERT(actualStdout == "true\n" || actualStdout == "false\n"); - return actualStdout == "true\n"; -} diff --git a/CopyQ-3.0.2/plugins/itemencrypted/tests/itemencryptedtests.h b/CopyQ-3.0.2/plugins/itemencrypted/tests/itemencryptedtests.h deleted file mode 100644 index f6543f9..0000000 --- a/CopyQ-3.0.2/plugins/itemencrypted/tests/itemencryptedtests.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (c) 2014, Lukas Holecek - - This file is part of CopyQ. - - CopyQ 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. - - CopyQ 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 CopyQ. If not, see . -*/ - -#ifndef ITEMENCRYPTEDTESTS_H -#define ITEMENCRYPTEDTESTS_H - -#include "tests/testinterface.h" - -#include - -class ItemEncryptedTests : public QObject -{ - Q_OBJECT -public: - explicit ItemEncryptedTests(const TestInterfacePtr &test, QObject *parent = nullptr); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void init(); - void cleanup(); - - void encryptDecryptData(); - -private: - bool isGpgInstalled() const; - - TestInterfacePtr m_test; -}; - -#endif // ITEMENCRYPTEDTESTS_H diff --git a/CopyQ-3.0.2/plugins/itemfakevim/CMakeLists.txt b/CopyQ-3.0.2/plugins/itemfakevim/CMakeLists.txt deleted file mode 100644 index 2210253..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -file(GLOB copyq_plugin_itemfakevim_SOURCES - ${copyq_plugin_itemfakevim_SOURCES} - fakevim/*.cpp - fakevim/utils/*.cpp - ) - -include_directories(fakevim) - -add_definitions( -DFAKEVIM_STANDALONE -DQTCREATOR_UTILS_STATIC_LIB ) -set(copyq_plugin_itemfakevim_DEFINITIONS - FAKEVIM_STANDALONE - QTCREATOR_UTILS_STATIC_LIB) - -set(copyq_plugin_itemfakevim_RESOURCES itemfakevim.qrc) - -copyq_add_plugin(itemfakevim) - -# Disable warnings for 3rd-party source code. -if (PEDANTIC) - if (CMAKE_COMPILER_IS_GNUCXX) - set(IGNORE_PEDANTIC_FLAGS "-Wno-suggest-override") - else() - set(IGNORE_PEDANTIC_FLAGS "-Wno-unused-macros") - endif() - - set_source_files_properties( - fakevim/fakevimhandler.cpp - fakevim/fakevimactions.cpp - PROPERTIES COMPILE_FLAGS - "\ - -Wno-shorten-64-to-32 \ - -Wno-sign-conversion \ - -Wno-conversion \ - -Wno-unreachable-code \ - -Wno-documentation-unknown-command \ - -Wno-shadow \ - -Wno-missing-declarations \ - -Wno-strict-overflow \ - ${IGNORE_PEDANTIC_FLAGS} \ - ") -endif() - diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/LGPL_EXCEPTION.TXT b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/LGPL_EXCEPTION.TXT deleted file mode 100644 index add80b9..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/LGPL_EXCEPTION.TXT +++ /dev/null @@ -1,22 +0,0 @@ -Digia Qt LGPL Exception version 1.1 - -As an additional permission to the GNU Lesser General Public License version -2.1, the object code form of a "work that uses the Library" may incorporate -material from a header file that is part of the Library. You may distribute -such object code under terms of your choice, provided that: - (i) the header files of the Library have not been modified; and - (ii) the incorporated material is limited to numerical parameters, data - structure layouts, accessors, macros, inline functions and - templates; and - (iii) you comply with the terms of Section 6 of the GNU Lesser General - Public License version 2.1. - -Moreover, you may apply this exception to a modified version of the Library, -provided that such modification does not involve copying material from the -Library into the modified Library's header files unless such material is -limited to (i) numerical parameters; (ii) data structure layouts; -(iii) accessors; and (iv) small macros, templates and inline functions of -five lines or less in length. - -Furthermore, you are not required to apply this additional permission to a -modified version of the Library. diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/LICENSE.LGPL b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/LICENSE.LGPL deleted file mode 100644 index 602bfc9..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/LICENSE.LGPL +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.png b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.png deleted file mode 100644 index 19bc688..0000000 Binary files a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.png and /dev/null differ diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.pri b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.pri deleted file mode 100644 index ecc7127..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.pri +++ /dev/null @@ -1,14 +0,0 @@ -include($$PWD/utils/utils.pri) - -DEFINES += FAKEVIM_STANDALONE - -INCLUDEPATH += $$PWD - -SOURCES += $$PWD/fakevimhandler.cpp \ - $$PWD/fakevimactions.cpp - -HEADERS += $$PWD/fakevimhandler.h \ - $$PWD/fakevimactions.h - -CONFIG += qt -QT += widgets diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.pro b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.pro deleted file mode 100644 index e4d1ebc..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevim.pro +++ /dev/null @@ -1,3 +0,0 @@ -TEMPLATE = lib - -include(fakevim.pri) diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimactions.cpp b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimactions.cpp deleted file mode 100644 index 977ddc0..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimactions.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "fakevimactions.h" -#include "fakevimhandler.h" - -// Please do not add any direct dependencies to other Qt Creator code here. -// Instead emit signals and let the FakeVimPlugin channel the information to -// Qt Creator. The idea is to keep this file here in a "clean" state that -// allows easy reuse with any QTextEdit or QPlainTextEdit derived class. - - -#include - -#include -#include -#include - -#ifdef FAKEVIM_STANDALONE -using namespace FakeVim::Internal::Utils; -#else -using namespace Utils; -#endif - -/////////////////////////////////////////////////////////////////////// -// -// FakeVimSettings -// -/////////////////////////////////////////////////////////////////////// - -namespace FakeVim { -namespace Internal { - -typedef QLatin1String _; - -#ifdef FAKEVIM_STANDALONE -namespace Utils { - -SavedAction::SavedAction(QObject *parent) - : QObject(parent) -{ -} - -void SavedAction::setValue(const QVariant &value) -{ - m_value = value; -} - -QVariant SavedAction::value() const -{ - return m_value; -} - -void SavedAction::setDefaultValue(const QVariant &value) -{ - m_defaultValue = value; -} - -QVariant SavedAction::defaultValue() const -{ - return m_defaultValue; -} - -void SavedAction::setSettingsKey(const QString &key) -{ - m_settingsKey = key; -} - -QString SavedAction::settingsKey() const -{ - return m_settingsKey; -} - -} // namespace Utils -#endif // FAKEVIM_STANDALONE - -FakeVimSettings::FakeVimSettings() -{} - -FakeVimSettings::~FakeVimSettings() -{ - qDeleteAll(m_items); -} - -void FakeVimSettings::insertItem(int code, SavedAction *item, - const QString &longName, const QString &shortName) -{ - QTC_ASSERT(!m_items.contains(code), qDebug() << code; return); - m_items[code] = item; - if (!longName.isEmpty()) { - m_nameToCode[longName] = code; - m_codeToName[code] = longName; - } - if (!shortName.isEmpty()) - m_nameToCode[shortName] = code; -} - -#ifndef FAKEVIM_STANDALONE -void FakeVimSettings::readSettings(QSettings *settings) -{ - foreach (SavedAction *item, m_items) - item->readSettings(settings); -} - -void FakeVimSettings::writeSettings(QSettings *settings) -{ - foreach (SavedAction *item, m_items) - item->writeSettings(settings); -} -#endif // FAKEVIM_STANDALONE - -SavedAction *FakeVimSettings::item(int code) -{ - QTC_ASSERT(m_items.value(code, 0), qDebug() << "CODE: " << code; return 0); - return m_items.value(code, 0); -} - -SavedAction *FakeVimSettings::item(const QString &name) -{ - return m_items.value(m_nameToCode.value(name, -1), 0); -} - -QString FakeVimSettings::trySetValue(const QString &name, const QString &value) -{ - int code = m_nameToCode.value(name, -1); - if (code == -1) - return FakeVimHandler::tr("Unknown option: %1").arg(name); - if (code == ConfigTabStop || code == ConfigShiftWidth) { - if (value.toInt() <= 0) - return FakeVimHandler::tr("Argument must be positive: %1=%2") - .arg(name).arg(value); - } - SavedAction *act = item(code); - if (!act) - return FakeVimHandler::tr("Unknown option: %1").arg(name); - act->setValue(value); - return QString(); -} - -SavedAction *createAction(FakeVimSettings *instance, int code, const QVariant &value, - const QString &settingsKey = QString(), - const QString &shortKey = QString()) -{ - SavedAction *item = new SavedAction(instance); - item->setValue(value); -#ifndef FAKEVIM_STANDALONE - item->setSettingsKey(_("FakeVim"), settingsKey); - item->setDefaultValue(value); - item->setCheckable( value.canConvert() ); -#endif - instance->insertItem(code, item, settingsKey.toLower(), shortKey); - return item; -} - -FakeVimSettings *theFakeVimSettings() -{ - static FakeVimSettings *s = 0; - if (s) - return s; - - s = new FakeVimSettings; - - // Specific FakeVim settings - createAction(s, ConfigReadVimRc, false, _("ReadVimRc")); - createAction(s, ConfigVimRcPath, QString(), _("VimRcPath")); -#ifndef FAKEVIM_STANDALONE - createAction(s, ConfigUseFakeVim, false, _("UseFakeVim")); - s->item(ConfigUseFakeVim)->setText(QCoreApplication::translate("FakeVim::Internal", - "Use Vim-style Editing")); - s->item(ConfigReadVimRc)->setText(QCoreApplication::translate("FakeVim::Internal", - "Read .vimrc")); - s->item(ConfigVimRcPath)->setText(QCoreApplication::translate("FakeVim::Internal", - "Path to .vimrc")); -#endif - createAction(s, ConfigShowMarks, false, _("ShowMarks"), _("sm")); - createAction(s, ConfigPassControlKey, false, _("PassControlKey"), _("pck")); - createAction(s, ConfigPassKeys, true, _("PassKeys"), _("pk")); - - // Emulated Vim setting - createAction(s, ConfigStartOfLine, true, _("StartOfLine"), _("sol")); - createAction(s, ConfigTabStop, 8, _("TabStop"), _("ts")); - createAction(s, ConfigSmartTab, false, _("SmartTab"), _("sta")); - createAction(s, ConfigHlSearch, true, _("HlSearch"), _("hls")); - createAction(s, ConfigShiftWidth, 8, _("ShiftWidth"), _("sw")); - createAction(s, ConfigExpandTab, false, _("ExpandTab"), _("et")); - createAction(s, ConfigAutoIndent, false, _("AutoIndent"), _("ai")); - createAction(s, ConfigSmartIndent, false, _("SmartIndent"), _("si")); - createAction(s, ConfigIncSearch, true, _("IncSearch"), _("is")); - createAction(s, ConfigUseCoreSearch, false, _("UseCoreSearch"), _("ucs")); - createAction(s, ConfigSmartCase, false, _("SmartCase"), _("scs")); - createAction(s, ConfigIgnoreCase, false, _("IgnoreCase"), _("ic")); - createAction(s, ConfigWrapScan, true, _("WrapScan"), _("ws")); - createAction(s, ConfigTildeOp, false, _("TildeOp"), _("top")); - createAction(s, ConfigShowCmd, true, _("ShowCmd"), _("sc")); - createAction(s, ConfigRelativeNumber, false, _("RelativeNumber"),_("rnu")); - createAction(s, ConfigScrollOff, 0, _("ScrollOff"), _("so")); - createAction(s, ConfigBackspace, _("indent,eol,start"), _("ConfigBackspace"), _("bs")); - createAction(s, ConfigIsKeyword, _("@,48-57,_,192-255,a-z,A-Z"), _("IsKeyword"), _("isk")); - createAction(s, ConfigClipboard, QString(), _("Clipboard"), _("cb")); - - return s; -} - -SavedAction *theFakeVimSetting(int code) -{ - return theFakeVimSettings()->item(code); -} - -} // namespace Internal -} // namespace FakeVim diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimactions.h b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimactions.h deleted file mode 100644 index 513af4f..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimactions.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef FAKEVIM_ACTIONS_H -#define FAKEVIM_ACTIONS_H - -#ifndef FAKEVIM_STANDALONE -# include -#endif - -#include -#include -#include -#include - -namespace FakeVim { -namespace Internal { - -#ifdef FAKEVIM_STANDALONE -namespace Utils { - -class SavedAction : public QObject -{ - Q_OBJECT - -public: - SavedAction(QObject *parent); - void setValue(const QVariant &value); - QVariant value() const; - void setDefaultValue(const QVariant &value); - QVariant defaultValue() const; - void setSettingsKey(const QString &key); - QString settingsKey() const; - - QVariant m_value; - QVariant m_defaultValue; - QString m_settingsKey; -}; - -} // namespace Utils -#endif // FAKEVIM_STANDALONE - -enum FakeVimSettingsCode -{ - ConfigUseFakeVim, - ConfigReadVimRc, - ConfigVimRcPath, - - ConfigStartOfLine, - ConfigHlSearch, - ConfigTabStop, - ConfigSmartTab, - ConfigShiftWidth, - ConfigExpandTab, - ConfigAutoIndent, - ConfigSmartIndent, - - ConfigIncSearch, - ConfigUseCoreSearch, - ConfigSmartCase, - ConfigIgnoreCase, - ConfigWrapScan, - - // command ~ behaves as g~ - ConfigTildeOp, - - // indent allow backspacing over autoindent - // eol allow backspacing over line breaks (join lines) - // start allow backspacing over the start of insert; CTRL-W and CTRL-U - // stop once at the start of insert. - ConfigBackspace, - - // @,48-57,_,192-255 - ConfigIsKeyword, - - // other actions - ConfigShowMarks, - ConfigPassControlKey, - ConfigPassKeys, - ConfigClipboard, - ConfigShowCmd, - ConfigScrollOff, - ConfigRelativeNumber -}; - -class FakeVimSettings : public QObject -{ - Q_OBJECT - -public: - FakeVimSettings(); - ~FakeVimSettings(); - void insertItem(int code, Utils::SavedAction *item, - const QString &longname = QString(), - const QString &shortname = QString()); - - Utils::SavedAction *item(int code); - Utils::SavedAction *item(const QString &name); - QString trySetValue(const QString &name, const QString &value); - -#ifndef FAKEVIM_STANDALONE - void readSettings(QSettings *settings); - void writeSettings(QSettings *settings); -#endif - -private: - QHash m_items; - QHash m_nameToCode; - QHash m_codeToName; -}; - -FakeVimSettings *theFakeVimSettings(); -Utils::SavedAction *theFakeVimSetting(int code); - -} // namespace Internal -} // namespace FakeVim - -#endif // FAKEVIM_ACTTIONS_H diff --git a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimhandler.cpp b/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimhandler.cpp deleted file mode 100644 index 73b7e40..0000000 --- a/CopyQ-3.0.2/plugins/itemfakevim/fakevim/fakevimhandler.cpp +++ /dev/null @@ -1,8671 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -// -// ATTENTION: -// -// 1 Please do not add any direct dependencies to other Qt Creator code here. -// Instead emit signals and let the FakeVimPlugin channel the information to -// Qt Creator. The idea is to keep this file here in a "clean" state that -// allows easy reuse with any QTextEdit or QPlainTextEdit derived class. -// -// 2 There are a few auto tests located in ../../../tests/auto/fakevim. -// Commands that are covered there are marked as "// tested" below. -// -// 3 Some conventions: -// -// Use 1 based line numbers and 0 based column numbers. Even though -// the 1 based line are not nice it matches vim's and QTextEdit's 'line' -// concepts. -// -// Do not pass QTextCursor etc around unless really needed. Convert -// early to line/column. -// -// A QTextCursor is always between characters, whereas vi's cursor is always -// over a character. FakeVim interprets the QTextCursor to be over the character -// to the right of the QTextCursor's position(). -// -// A current "region of interest" -// spans between anchor(), (i.e. the character below anchor()), and -// position(). The character below position() is not included -// if the last movement command was exclusive (MoveExclusive). -// - -#include "fakevimhandler.h" - -#include "fakevimactions.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -//#define DEBUG_KEY 1 -#ifdef DEBUG_KEY -# define KEY_DEBUG(s) qDebug() << s -#else -# define KEY_DEBUG(s) -#endif - -//#define DEBUG_UNDO 1 -#ifdef DEBUG_UNDO -# define UNDO_DEBUG(s) qDebug() << "REV" << revision() << s -#else -# define UNDO_DEBUG(s) -#endif - -using namespace Utils; -#ifdef FAKEVIM_STANDALONE -using namespace FakeVim::Internal::Utils; -#endif - -namespace FakeVim { -namespace Internal { - -/////////////////////////////////////////////////////////////////////// -// -// FakeVimHandler -// -/////////////////////////////////////////////////////////////////////// - -#define StartOfLine QTextCursor::StartOfLine -#define EndOfLine QTextCursor::EndOfLine -#define MoveAnchor QTextCursor::MoveAnchor -#define KeepAnchor QTextCursor::KeepAnchor -#define Up QTextCursor::Up -#define Down QTextCursor::Down -#define Right QTextCursor::Right -#define Left QTextCursor::Left -#define EndOfDocument QTextCursor::End -#define StartOfDocument QTextCursor::Start -#define NextBlock QTextCursor::NextBlock - -#define ParagraphSeparator QChar::ParagraphSeparator - -#define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s) - -#define MetaModifier // Use HostOsInfo::controlModifier() instead -#define ControlModifier // Use HostOsInfo::controlModifier() instead - -typedef QLatin1String _; - -/* Clipboard MIME types used by Vim. */ -static const QString vimMimeText = _("_VIM_TEXT"); -static const QString vimMimeTextEncoded = _("_VIMENC_TEXT"); - -using namespace Qt; - -/*! A \e Mode represents one of the basic modes of operation of FakeVim. -*/ - -enum Mode -{ - InsertMode, - ReplaceMode, - CommandMode, - ExMode -}; - -enum BlockInsertMode -{ - NoneBlockInsertMode, - AppendBlockInsertMode, - AppendToEndOfLineBlockInsertMode, - InsertBlockInsertMode, - ChangeBlockInsertMode -}; - -/*! A \e SubMode is used for things that require one more data item - and are 'nested' behind a \l Mode. -*/ -enum SubMode -{ - NoSubMode, - ChangeSubMode, // Used for c - DeleteSubMode, // Used for d - FilterSubMode, // Used for ! - IndentSubMode, // Used for = - RegisterSubMode, // Used for " - ShiftLeftSubMode, // Used for < - ShiftRightSubMode, // Used for > - InvertCaseSubMode, // Used for g~ - DownCaseSubMode, // Used for gu - UpCaseSubMode, // Used for gU - WindowSubMode, // Used for Ctrl-w - YankSubMode, // Used for y - ZSubMode, // Used for z - CapitalZSubMode, // Used for Z - ReplaceSubMode, // Used for r - MacroRecordSubMode, // Used for q - MacroExecuteSubMode, // Used for @ - CtrlVSubMode // Used for Ctrl-v in insert mode -}; - -/*! A \e SubSubMode is used for things that require one more data item - and are 'nested' behind a \l SubMode. -*/ -enum SubSubMode -{ - NoSubSubMode, - FtSubSubMode, // Used for f, F, t, T. - MarkSubSubMode, // Used for m. - BackTickSubSubMode, // Used for `. - TickSubSubMode, // Used for '. - TextObjectSubSubMode, // Used for thing like iw, aW, as etc. - ZSubSubMode, // Used for zj, zk - OpenSquareSubSubMode, // Used for [{, {(, [z - CloseSquareSubSubMode, // Used for ]}, ]), ]z - SearchSubSubMode, - CtrlVUnicodeSubSubMode // Used for Ctrl-v based unicode input -}; - -enum VisualMode -{ - NoVisualMode, - VisualCharMode, - VisualLineMode, - VisualBlockMode -}; - -enum MoveType -{ - MoveExclusive, - MoveInclusive, - MoveLineWise -}; - -/*! - \enum RangeMode - - The \e RangeMode serves as a means to define how the "Range" between - the \l cursor and the \l anchor position is to be interpreted. - - \value RangeCharMode Entered by pressing \key v. The range includes - all characters between cursor and anchor. - \value RangeLineMode Entered by pressing \key V. The range includes - all lines between the line of the cursor and - the line of the anchor. - \value RangeLineModeExclusice Like \l RangeLineMode, but keeps one - newline when deleting. - \value RangeBlockMode Entered by pressing \key Ctrl-v. The range includes - all characters with line and column coordinates - between line and columns coordinates of cursor and - anchor. - \value RangeBlockAndTailMode Like \l RangeBlockMode, but also includes - all characters in the affected lines up to the end - of these lines. -*/ - -enum EventResult -{ - EventHandled, - EventUnhandled, - EventCancelled, // Event is handled but a sub mode was cancelled. - EventPassedToCore -}; - -struct CursorPosition -{ - CursorPosition() : line(-1), column(-1) {} - CursorPosition(int block, int column) : line(block), column(column) {} - explicit CursorPosition(const QTextCursor &tc) - : line(tc.block().blockNumber()), column(tc.positionInBlock()) {} - CursorPosition(const QTextDocument *document, int position) - { - QTextBlock block = document->findBlock(position); - line = block.blockNumber(); - column = position - block.position(); - } - bool isValid() const { return line >= 0 && column >= 0; } - bool operator>(const CursorPosition &other) const - { return line > other.line || column > other.column; } - bool operator==(const CursorPosition &other) const - { return line == other.line && column == other.column; } - bool operator!=(const CursorPosition &other) const { return !operator==(other); } - - int line; // Line in document (from 0, folded lines included). - int column; // Position on line. -}; - -QDebug operator<<(QDebug ts, const CursorPosition &pos) -{ - return ts << "(line: " << pos.line << ", column: " << pos.column << ")"; -} - -class Mark -{ -public: - Mark(const CursorPosition &pos = CursorPosition(), const QString &fileName = QString()) - : m_position(pos), m_fileName(fileName) {} - - bool isValid() const { return m_position.isValid(); } - - bool isLocal(const QString &localFileName) const - { - return m_fileName.isEmpty() || m_fileName == localFileName; - } - - /* Return position of mark within given document. - * If saved line number is too big, mark position is at the end of document. - * If line number is in document but column is too big, mark position is at the end of line. - */ - CursorPosition position(const QTextDocument *document) const - { - QTextBlock block = document->findBlockByNumber(m_position.line); - CursorPosition pos; - if (block.isValid()) { - pos.line = m_position.line; - pos.column = qMax(0, qMin(m_position.column, block.length() - 2)); - } else if (document->isEmpty()) { - pos.line = 0; - pos.column = 0; - } else { - pos.line = document->blockCount() - 1; - pos.column = qMax(0, document->lastBlock().length() - 2); - } - return pos; - } - - const QString &fileName() const { return m_fileName; } - -private: - CursorPosition m_position; - QString m_fileName; -}; -typedef QHash Marks; -typedef QHashIterator MarksIterator; - -struct State -{ - State() : revision(-1), position(), marks(), lastVisualMode(NoVisualMode), - lastVisualModeInverted(false) {} - State(int revision, const CursorPosition &position, const Marks &marks, - VisualMode lastVisualMode, bool lastVisualModeInverted) : revision(revision), - position(position), marks(marks), lastVisualMode(lastVisualMode), - lastVisualModeInverted(lastVisualModeInverted) {} - - bool isValid() const { return position.isValid(); } - - int revision; - CursorPosition position; - Marks marks; - VisualMode lastVisualMode; - bool lastVisualModeInverted; -}; - -struct Column -{ - Column(int p, int l) : physical(p), logical(l) {} - int physical; // Number of characters in the data. - int logical; // Column on screen. -}; - -QDebug operator<<(QDebug ts, const Column &col) -{ - return ts << "(p: " << col.physical << ", l: " << col.logical << ")"; -} - -struct Register -{ - Register() : rangemode(RangeCharMode) {} - Register(const QString &c) : contents(c), rangemode(RangeCharMode) {} - Register(const QString &c, RangeMode m) : contents(c), rangemode(m) {} - QString contents; - RangeMode rangemode; -}; - -QDebug operator<<(QDebug ts, const Register ®) -{ - return ts << reg.contents; -} - -struct SearchData -{ - SearchData() - { - forward = true; - highlightMatches = true; - } - - QString needle; - bool forward; - bool highlightMatches; -}; - -// If string begins with given prefix remove it with trailing spaces and return true. -static bool eatString(const char *prefix, QString *str) -{ - if (!str->startsWith(_(prefix))) - return false; - *str = str->mid(strlen(prefix)).trimmed(); - return true; -} - -static QRegExp vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool smartCaseOption) -{ - /* Transformations (Vim regexp -> QRegExp): - * \a -> [A-Za-z] - * \A -> [^A-Za-z] - * \h -> [A-Za-z_] - * \H -> [^A-Za-z_] - * \l -> [a-z] - * \L -> [^a-z] - * \o -> [0-7] - * \O -> [^0-7] - * \u -> [A-Z] - * \U -> [^A-Z] - * \x -> [0-9A-Fa-f] - * \X -> [^0-9A-Fa-f] - * - * \< -> \b - * \> -> \b - * [] -> \[\] - * \= -> ? - * - * (...) <-> \(...\) - * {...} <-> \{...\} - * | <-> \| - * ? <-> \? - * + <-> \+ - * \{...} -> {...} - * - * \c - set ignorecase for rest - * \C - set noignorecase for rest - */ - // FIXME: Option smartcase should be used only if search was typed by user. - bool ignorecase = ignoreCaseOption - && !(smartCaseOption && needle.contains(QRegExp(_("[A-Z]")))); - QString pattern; - pattern.reserve(2 * needle.size()); - - bool escape = false; - bool brace = false; - bool embraced = false; - bool range = false; - bool curly = false; - foreach (const QChar &c, needle) { - if (brace) { - brace = false; - if (c == QLatin1Char(']')) { - pattern.append(_("\\[\\]")); - continue; - } - pattern.append(QLatin1Char('[')); - escape = true; - embraced = true; - } - if (embraced) { - if (range) { - QChar c2 = pattern[pattern.size() - 2]; - pattern.remove(pattern.size() - 2, 2); - pattern.append(c2.toUpper() + QLatin1Char('-') + c.toUpper()); - pattern.append(c2.toLower() + QLatin1Char('-') + c.toLower()); - range = false; - } else if (escape) { - escape = false; - pattern.append(c); - } else if (c == QLatin1Char('\\')) { - escape = true; - } else if (c == QLatin1Char(']')) { - pattern.append(QLatin1Char(']')); - embraced = false; - } else if (c == QLatin1Char('-')) { - range = ignorecase && pattern[pattern.size() - 1].isLetter(); - pattern.append(QLatin1Char('-')); - } else if (c.isLetter() && ignorecase) { - pattern.append(c.toLower()).append(c.toUpper()); - } else { - pattern.append(c); - } - } else if (QString::fromLatin1("(){}+|?").indexOf(c) != -1) { - if (c == QLatin1Char('{')) { - curly = escape; - } else if (c == QLatin1Char('}') && curly) { - curly = false; - escape = true; - } - - if (escape) - escape = false; - else - pattern.append(QLatin1Char('\\')); - pattern.append(c); - } else if (escape) { - // escape expression - escape = false; - if (c == QLatin1Char('<') || c == QLatin1Char('>')) - pattern.append(_("\\b")); - else if (c == QLatin1Char('a')) - pattern.append(_("[a-zA-Z]")); - else if (c == QLatin1Char('A')) - pattern.append(_("[^a-zA-Z]")); - else if (c == QLatin1Char('h')) - pattern.append(_("[A-Za-z_]")); - else if (c == QLatin1Char('H')) - pattern.append(_("[^A-Za-z_]")); - else if (c == QLatin1Char('c') || c == QLatin1Char('C')) - ignorecase = (c == QLatin1Char('c')); - else if (c == QLatin1Char('l')) - pattern.append(_("[a-z]")); - else if (c == QLatin1Char('L')) - pattern.append(_("[^a-z]")); - else if (c == QLatin1Char('o')) - pattern.append(_("[0-7]")); - else if (c == QLatin1Char('O')) - pattern.append(_("[^0-7]")); - else if (c == QLatin1Char('u')) - pattern.append(_("[A-Z]")); - else if (c == QLatin1Char('U')) - pattern.append(_("[^A-Z]")); - else if (c == QLatin1Char('x')) - pattern.append(_("[0-9A-Fa-f]")); - else if (c == QLatin1Char('X')) - pattern.append(_("[^0-9A-Fa-f]")); - else if (c == QLatin1Char('=')) - pattern.append(_("?")); - else - pattern.append(QLatin1Char('\\') + c); - } else { - // unescaped expression - if (c == QLatin1Char('\\')) - escape = true; - else if (c == QLatin1Char('[')) - brace = true; - else if (c.isLetter() && ignorecase) - pattern.append(QLatin1Char('[') + c.toLower() + c.toUpper() + QLatin1Char(']')); - else - pattern.append(c); - } - } - if (escape) - pattern.append(QLatin1Char('\\')); - else if (brace) - pattern.append(QLatin1Char('[')); - - return QRegExp(pattern); -} - -static bool afterEndOfLine(const QTextDocument *doc, int position) -{ - return doc->characterAt(position) == ParagraphSeparator - && doc->findBlock(position).length() > 1; -} - -static void searchForward(QTextCursor *tc, QRegExp &needleExp, int *repeat) -{ - const QTextDocument *doc = tc->document(); - const int startPos = tc->position(); - - // Search from beginning of line so that matched text is the same. - tc->movePosition(StartOfLine); - - // forward to current position - *tc = doc->find(needleExp, *tc); - while (!tc->isNull() && tc->anchor() < startPos) { - if (!tc->hasSelection()) - tc->movePosition(Right); - if (tc->atBlockEnd()) - tc->movePosition(NextBlock); - *tc = doc->find(needleExp, *tc); - } - - if (tc->isNull()) - return; - - --*repeat; - - while (*repeat > 0) { - if (!tc->hasSelection()) - tc->movePosition(Right); - if (tc->atBlockEnd()) - tc->movePosition(NextBlock); - *tc = doc->find(needleExp, *tc); - if (tc->isNull()) - return; - --*repeat; - } - - if (!tc->isNull() && afterEndOfLine(doc, tc->anchor())) - tc->movePosition(Left); -} - -static void searchBackward(QTextCursor *tc, QRegExp &needleExp, int *repeat) -{ - // Search from beginning of line so that matched text is the same. - QTextBlock block = tc->block(); - QString line = block.text(); - - int i = line.indexOf(needleExp, 0); - while (i != -1 && i < tc->positionInBlock()) { - --*repeat; - i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); - if (i == line.size()) - i = -1; - } - - if (i == tc->positionInBlock()) - --*repeat; - - while (*repeat > 0) { - block = block.previous(); - if (!block.isValid()) - break; - line = block.text(); - i = line.indexOf(needleExp, 0); - while (i != -1) { - --*repeat; - i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); - if (i == line.size()) - i = -1; - } - } - - if (!block.isValid()) { - *tc = QTextCursor(); - return; - } - - i = line.indexOf(needleExp, 0); - while (*repeat < 0) { - i = line.indexOf(needleExp, i + qMax(1, needleExp.matchedLength())); - ++*repeat; - } - tc->setPosition(block.position() + i); - tc->setPosition(tc->position() + needleExp.matchedLength(), KeepAnchor); -} - -// Commands [[, [] -static void bracketSearchBackward(QTextCursor *tc, const QString &needleExp, int repeat) -{ - QRegExp re(needleExp); - QTextCursor tc2 = *tc; - tc2.setPosition(tc2.position() - 1); - searchBackward(&tc2, re, &repeat); - if (repeat <= 1) - tc->setPosition(tc2.isNull() ? 0 : tc2.position(), KeepAnchor); -} - -// Commands ][, ]] -// When ]] is used after an operator, then also stops below a '}' in the first column. -static void bracketSearchForward(QTextCursor *tc, const QString &needleExp, int repeat, - bool searchWithCommand) -{ - QRegExp re(searchWithCommand ? QString(_("^\\}|^\\{")) : needleExp); - QTextCursor tc2 = *tc; - tc2.setPosition(tc2.position() + 1); - searchForward(&tc2, re, &repeat); - if (repeat <= 1) { - if (tc2.isNull()) { - tc->setPosition(tc->document()->characterCount() - 1, KeepAnchor); - } else { - tc->setPosition(tc2.position() - 1, KeepAnchor); - if (searchWithCommand && tc->document()->characterAt(tc->position()).unicode() == '}') { - QTextBlock block = tc->block().next(); - if (block.isValid()) - tc->setPosition(block.position(), KeepAnchor); - } - } - } -} - -static bool substituteText(QString *text, QRegExp &pattern, const QString &replacement, - bool global) -{ - bool substituted = false; - int pos = 0; - int right = -1; - while (true) { - pos = pattern.indexIn(*text, pos, QRegExp::CaretAtZero); - if (pos == -1) - break; - - // ensure that substitution is advancing towards end of line - if (right == text->size() - pos) { - ++pos; - if (pos == text->size()) - break; - continue; - } - - right = text->size() - pos; - - substituted = true; - QString matched = text->mid(pos, pattern.cap(0).size()); - QString repl; - bool escape = false; - // insert captured texts - for (int i = 0; i < replacement.size(); ++i) { - const QChar &c = replacement[i]; - if (escape) { - escape = false; - if (c.isDigit()) { - if (c.digitValue() <= pattern.captureCount()) - repl += pattern.cap(c.digitValue()); - } else { - repl += c; - } - } else { - if (c == QLatin1Char('\\')) - escape = true; - else if (c == QLatin1Char('&')) - repl += pattern.cap(0); - else - repl += c; - } - } - text->replace(pos, matched.size(), repl); - pos += (repl.isEmpty() && matched.isEmpty()) ? 1 : repl.size(); - - if (pos >= text->size() || !global) - break; - } - - return substituted; -} - -static int findUnescaped(QChar c, const QString &line, int from) -{ - for (int i = from; i < line.size(); ++i) { - if (line.at(i) == c && (i == 0 || line.at(i - 1) != QLatin1Char('\\'))) - return i; - } - return -1; -} - -static void setClipboardData(const QString &content, RangeMode mode, - QClipboard::Mode clipboardMode) -{ - QClipboard *clipboard = QApplication::clipboard(); - char vimRangeMode = mode; - - QByteArray bytes1; - bytes1.append(vimRangeMode); - bytes1.append(content.toUtf8()); - - QByteArray bytes2; - bytes2.append(vimRangeMode); - bytes2.append("utf-8"); - bytes2.append('\0'); - bytes2.append(content.toUtf8()); - - QMimeData *data = new QMimeData; - data->setText(content); - data->setData(vimMimeText, bytes1); - data->setData(vimMimeTextEncoded, bytes2); - clipboard->setMimeData(data, clipboardMode); -} - -static QByteArray toLocalEncoding(const QString &text) -{ - return HostOsInfo::isWindowsHost() ? QString(text).replace(_("\n"), _("\r\n")).toLocal8Bit() - : text.toLocal8Bit(); -} - -static QString fromLocalEncoding(const QByteArray &data) -{ - return HostOsInfo::isWindowsHost() ? QString::fromLocal8Bit(data).replace(_("\n"), _("\r\n")) - : QString::fromLocal8Bit(data); -} - -static QString getProcessOutput(const QString &command, const QString &input) -{ - QProcess proc; - proc.start(command); - proc.waitForStarted(); - proc.write(toLocalEncoding(input)); - proc.closeWriteChannel(); - - // FIXME: Process should be interruptable by user. - // Solution is to create a QObject for each process and emit finished state. - proc.waitForFinished(); - - return fromLocalEncoding(proc.readAllStandardOutput()); -} - -static const QMap &vimKeyNames() -{ - static QMap k; - if (!k.isEmpty()) - return k; - - // FIXME: Should be value of mapleader. - k.insert(_("LEADER"), Key_Backslash); - - k.insert(_("SPACE"), Key_Space); - k.insert(_("TAB"), Key_Tab); - k.insert(_("NL"), Key_Return); - k.insert(_("NEWLINE"), Key_Return); - k.insert(_("LINEFEED"), Key_Return); - k.insert(_("LF"), Key_Return); - k.insert(_("CR"), Key_Return); - k.insert(_("RETURN"), Key_Return); - k.insert(_("ENTER"), Key_Return); - k.insert(_("BS"), Key_Backspace); - k.insert(_("BACKSPACE"), Key_Backspace); - k.insert(_("ESC"), Key_Escape); - k.insert(_("BAR"), Key_Bar); - k.insert(_("BSLASH"), Key_Backslash); - k.insert(_("DEL"), Key_Delete); - k.insert(_("DELETE"), Key_Delete); - k.insert(_("KDEL"), Key_Delete); - k.insert(_("UP"), Key_Up); - k.insert(_("DOWN"), Key_Down); - k.insert(_("LEFT"), Key_Left); - k.insert(_("RIGHT"), Key_Right); - - k.insert(_("LT"), Key_Less); - k.insert(_("GT"), Key_Greater); - - k.insert(_("F1"), Key_F1); - k.insert(_("F2"), Key_F2); - k.insert(_("F3"), Key_F3); - k.insert(_("F4"), Key_F4); - k.insert(_("F5"), Key_F5); - k.insert(_("F6"), Key_F6); - k.insert(_("F7"), Key_F7); - k.insert(_("F8"), Key_F8); - k.insert(_("F9"), Key_F9); - k.insert(_("F10"), Key_F10); - - k.insert(_("F11"), Key_F11); - k.insert(_("F12"), Key_F12); - k.insert(_("F13"), Key_F13); - k.insert(_("F14"), Key_F14); - k.insert(_("F15"), Key_F15); - k.insert(_("F16"), Key_F16); - k.insert(_("F17"), Key_F17); - k.insert(_("F18"), Key_F18); - k.insert(_("F19"), Key_F19); - k.insert(_("F20"), Key_F20); - - k.insert(_("F21"), Key_F21); - k.insert(_("F22"), Key_F22); - k.insert(_("F23"), Key_F23); - k.insert(_("F24"), Key_F24); - k.insert(_("F25"), Key_F25); - k.insert(_("F26"), Key_F26); - k.insert(_("F27"), Key_F27); - k.insert(_("F28"), Key_F28); - k.insert(_("F29"), Key_F29); - k.insert(_("F30"), Key_F30); - - k.insert(_("F31"), Key_F31); - k.insert(_("F32"), Key_F32); - k.insert(_("F33"), Key_F33); - k.insert(_("F34"), Key_F34); - k.insert(_("F35"), Key_F35); - - k.insert(_("INSERT"), Key_Insert); - k.insert(_("INS"), Key_Insert); - k.insert(_("KINSERT"), Key_Insert); - k.insert(_("HOME"), Key_Home); - k.insert(_("END"), Key_End); - k.insert(_("PAGEUP"), Key_PageUp); - k.insert(_("PAGEDOWN"), Key_PageDown); - - k.insert(_("KPLUS"), Key_Plus); - k.insert(_("KMINUS"), Key_Minus); - k.insert(_("KDIVIDE"), Key_Slash); - k.insert(_("KMULTIPLY"), Key_Asterisk); - k.insert(_("KENTER"), Key_Enter); - k.insert(_("KPOINT"), Key_Period); - - return k; -} - -static bool isOnlyControlModifier(const Qt::KeyboardModifiers &mods) -{ - return (mods ^ HostOsInfo::controlModifier()) == Qt::NoModifier; -} - - -Range::Range() - : beginPos(-1), endPos(-1), rangemode(RangeCharMode) -{} - -Range::Range(int b, int e, RangeMode m) - : beginPos(qMin(b, e)), endPos(qMax(b, e)), rangemode(m) -{} - -QString Range::toString() const -{ - return QString::fromLatin1("%1-%2 (mode: %3)").arg(beginPos).arg(endPos) - .arg(rangemode); -} - -bool Range::isValid() const -{ - return beginPos >= 0 && endPos >= 0; -} - -QDebug operator<<(QDebug ts, const Range &range) -{ - return ts << '[' << range.beginPos << ',' << range.endPos << ']'; -} - - -ExCommand::ExCommand(const QString &c, const QString &a, const Range &r) - : cmd(c), hasBang(false), args(a), range(r), count(1) -{} - -bool ExCommand::matches(const QString &min, const QString &full) const -{ - return cmd.startsWith(min) && full.startsWith(cmd); -} - -QDebug operator<<(QDebug ts, const ExCommand &cmd) -{ - return ts << cmd.cmd << ' ' << cmd.args << ' ' << cmd.range; -} - -QDebug operator<<(QDebug ts, const QList &sels) -{ - foreach (const QTextEdit::ExtraSelection &sel, sels) - ts << "SEL: " << sel.cursor.anchor() << sel.cursor.position(); - return ts; -} - -QString quoteUnprintable(const QString &ba) -{ - QString res; - for (int i = 0, n = ba.size(); i != n; ++i) { - const QChar c = ba.at(i); - const int cc = c.unicode(); - if (c.isPrint()) - res += c; - else if (cc == QLatin1Char('\n')) - res += _(""); - else - res += QString::fromLatin1("\\x%1").arg(c.unicode(), 2, 16, QLatin1Char('0')); - } - return res; -} - -static bool startsWithWhitespace(const QString &str, int col) -{ - QTC_ASSERT(str.size() >= col, return false); - for (int i = 0; i < col; ++i) { - uint u = str.at(i).unicode(); - if (u != QLatin1Char(' ') && u != QLatin1Char('\t')) - return false; - } - return true; -} - -inline QString msgMarkNotSet(const QString &text) -{ - return FakeVimHandler::tr("Mark \"%1\" not set.").arg(text); -} - -class Input -{ -public: - // Remove some extra "information" on Mac. - static Qt::KeyboardModifiers cleanModifier(Qt::KeyboardModifiers m) - { - return m & ~Qt::KeypadModifier; - } - - Input() - : m_key(0), m_xkey(0), m_modifiers(0) {} - - explicit Input(QChar x) - : m_key(x.unicode()), m_xkey(x.unicode()), m_modifiers(0), m_text(x) - { - if (x.isUpper()) - m_modifiers = Qt::ShiftModifier; - else if (x.isLower()) - m_key = x.toUpper().unicode(); - } - - Input(int k, Qt::KeyboardModifiers m, const QString &t = QString()) - : m_key(k), m_modifiers(cleanModifier(m)), m_text(t) - { - if (m_text.size() == 1) { - QChar x = m_text.at(0); - - // On Mac, QKeyEvent::text() returns non-empty strings for - // cursor keys. This breaks some of the logic later on - // relying on text() being empty for "special" keys. - // FIXME: Check the real conditions. - if (x.unicode() < ' ') - m_text.clear(); - else if (x.isLetter()) - m_key = x.toUpper().unicode(); - } - - // Set text only if input is ascii key without control modifier. - if (m_text.isEmpty() && k >= 0 && k <= 0x7f && (m & HostOsInfo::controlModifier()) == 0) { - QChar c = QChar::fromLatin1(k); - if (c.isLetter()) - m_text = QString(isShift() ? c.toUpper() : c); - else if (!isShift()) - m_text = c; - } - - // Normalize . - if (m_key == Qt::Key_Backtab) { - m_key = Qt::Key_Tab; - m_modifiers |= Qt::ShiftModifier; - } - - // m_xkey is only a cache. - m_xkey = (m_text.size() == 1 ? m_text.at(0).unicode() : m_key); - } - - bool isValid() const - { - return m_key != 0 || !m_text.isNull(); - } - - bool isDigit() const - { - return m_xkey >= '0' && m_xkey <= '9'; - } - - bool isKey(int c) const - { - return !m_modifiers && m_key == c; - } - - bool isBackspace() const - { - return m_key == Key_Backspace || isControl('h'); - } - - bool isReturn() const - { - return m_key == QLatin1Char('\n') || m_key == Key_Return || m_key == Key_Enter; - } - - bool isEscape() const - { - return isKey(Key_Escape) || isKey(27) || isControl('c') - || isControl(Key_BracketLeft); - } - - bool is(int c) const - { - return m_xkey == c && !isControl(); - } - - bool isControl() const - { - return isOnlyControlModifier(m_modifiers); - } - - bool isControl(int c) const - { - return isControl() - && (m_xkey == c || m_xkey + 32 == c || m_xkey + 64 == c || m_xkey + 96 == c); - } - - bool isShift() const - { - return m_modifiers & Qt::ShiftModifier; - } - - bool isShift(int c) const - { - return isShift() && m_xkey == c; - } - - bool operator<(const Input &a) const - { - if (m_key != a.m_key) - return m_key < a.m_key; - // Text for some mapped key cannot be determined (e.g. ) so if text is not set for - // one of compared keys ignore it. - if (!m_text.isEmpty() && !a.m_text.isEmpty() && m_text != _(" ")) - return m_text < a.m_text; - return m_modifiers < a.m_modifiers; - } - - bool operator==(const Input &a) const - { - return !(*this < a || a < *this); - } - - bool operator!=(const Input &a) const { return !operator==(a); } - - QString text() const { return m_text; } - - QChar asChar() const - { - return (m_text.size() == 1 ? m_text.at(0) : QChar()); - } - - int toInt(bool *ok, int base) const - { - const int uc = asChar().unicode(); - int res; - if ('0' <= uc && uc <= '9') - res = uc -'0'; - else if ('a' <= uc && uc <= 'z') - res = 10 + uc - 'a'; - else if ('A' <= uc && uc <= 'Z') - res = 10 + uc - 'A'; - else - res = base; - *ok = res < base; - return *ok ? res : 0; - } - - int key() const { return m_key; } - - Qt::KeyboardModifiers modifiers() const { return m_modifiers; } - - // Return raw character for macro recording or dot command. - QChar raw() const - { - if (m_key == Key_Tab) - return QLatin1Char('\t'); - if (m_key == Key_Return) - return QLatin1Char('\n'); - if (m_key == Key_Escape) - return QChar(27); - return m_xkey; - } - - QString toString() const - { - QString key = vimKeyNames().key(m_key); - bool namedKey = !key.isEmpty(); - - if (!namedKey) { - if (m_xkey == '<') - key = _(""); - else if (m_xkey == '>') - key = _(""); - else - key = QChar(m_xkey); - } - - bool shift = isShift(); - bool ctrl = isControl(); - if (shift) - key.prepend(_("S-")); - if (ctrl) - key.prepend(_("C-")); - - if (namedKey || shift || ctrl) { - key.prepend(QLatin1Char('<')); - key.append(QLatin1Char('>')); - } - - return key; - } - - QDebug dump(QDebug ts) const - { - return ts << m_key << '-' << m_modifiers << '-' - << quoteUnprintable(m_text); - } -private: - int m_key; - int m_xkey; - Qt::KeyboardModifiers m_modifiers; - QString m_text; -}; - -// mapping to (do nothing) -static const Input Nop(-1, Qt::KeyboardModifiers(-1), QString()); - -QDebug operator<<(QDebug ts, const Input &input) { return input.dump(ts); } - -class Inputs : public QVector -{ -public: - Inputs() : m_noremap(true), m_silent(false) {} - - explicit Inputs(const QString &str, bool noremap = true, bool silent = false) - : m_noremap(noremap), m_silent(silent) - { - parseFrom(str); - squeeze(); - } - - bool noremap() const { return m_noremap; } - - bool silent() const { return m_silent; } - -private: - void parseFrom(const QString &str); - - bool m_noremap; - bool m_silent; -}; - -static Input parseVimKeyName(const QString &keyName) -{ - if (keyName.length() == 1) - return Input(keyName.at(0)); - - const QStringList keys = keyName.split(QLatin1Char('-')); - const int len = keys.length(); - - if (len == 1 && keys.at(0).toUpper() == _("NOP")) - return Nop; - - Qt::KeyboardModifiers mods = NoModifier; - for (int i = 0; i < len - 1; ++i) { - const QString &key = keys[i].toUpper(); - if (key == _("S")) - mods |= Qt::ShiftModifier; - else if (key == _("C")) - mods |= HostOsInfo::controlModifier(); - else - return Input(); - } - - if (!keys.isEmpty()) { - const QString key = keys.last(); - if (key.length() == 1) { - // simple character - QChar c = key.at(0).toUpper(); - return Input(c.unicode(), mods); - } - - // find key name - QMap::ConstIterator it = vimKeyNames().constFind(key.toUpper()); - if (it != vimKeyNames().end()) - return Input(*it, mods); - } - - return Input(); -} - -void Inputs::parseFrom(const QString &str) -{ - const int n = str.size(); - for (int i = 0; i < n; ++i) { - ushort c = str.at(i).unicode(); - if (c == '<') { - int j = str.indexOf(QLatin1Char('>'), i); - Input input; - if (j != -1) { - const QString key = str.mid(i+1, j - i - 1); - if (!key.contains(QLatin1Char('<'))) - input = parseVimKeyName(key); - } - if (input.isValid()) { - append(input); - i = j; - } else { - append(Input(c)); - } - } else { - append(Input(c)); - } - } -} - -class History -{ -public: - History() : m_items(QString()), m_index(0) {} - void append(const QString &item); - const QString &move(const QStringRef &prefix, int skip); - const QString ¤t() const { return m_items[m_index]; } - const QStringList &items() const { return m_items; } - void restart() { m_index = m_items.size() - 1; } - -private: - // Last item is always empty or current search prefix. - QStringList m_items; - int m_index; -}; - -void History::append(const QString &item) -{ - if (item.isEmpty()) - return; - m_items.pop_back(); - m_items.removeAll(item); - m_items << item << QString(); - restart(); -} - -const QString &History::move(const QStringRef &prefix, int skip) -{ - if (!current().startsWith(prefix)) - restart(); - - if (m_items.last() != prefix) - m_items[m_items.size() - 1] = prefix.toString(); - - int i = m_index + skip; - if (!prefix.isEmpty()) - for (; i >= 0 && i < m_items.size() && !m_items[i].startsWith(prefix); i += skip) - ; - if (i >= 0 && i < m_items.size()) - m_index = i; - - return current(); -} - -// Command line buffer with prompt (i.e. :, / or ? characters), text contents and cursor position. -class CommandBuffer -{ -public: - CommandBuffer() : m_pos(0), m_anchor(0), m_userPos(0), m_historyAutoSave(true) {} - - void setPrompt(const QChar &prompt) { m_prompt = prompt; } - void setContents(const QString &s) { m_buffer = s; m_anchor = m_pos = s.size(); } - - void setContents(const QString &s, int pos, int anchor = -1) - { - m_buffer = s; m_pos = m_userPos = pos; m_anchor = anchor >= 0 ? anchor : pos; - } - - QStringRef userContents() const { return m_buffer.leftRef(m_userPos); } - const QChar &prompt() const { return m_prompt; } - const QString &contents() const { return m_buffer; } - bool isEmpty() const { return m_buffer.isEmpty(); } - int cursorPos() const { return m_pos; } - int anchorPos() const { return m_anchor; } - bool hasSelection() const { return m_pos != m_anchor; } - - void insertChar(QChar c) { m_buffer.insert(m_pos++, c); m_anchor = m_userPos = m_pos; } - void insertText(const QString &s) - { - m_buffer.insert(m_pos, s); m_anchor = m_userPos = m_pos = m_pos + s.size(); - } - void deleteChar() { if (m_pos) m_buffer.remove(--m_pos, 1); m_anchor = m_userPos = m_pos; } - - void moveLeft() { if (m_pos) m_userPos = --m_pos; } - void moveRight() { if (m_pos < m_buffer.size()) m_userPos = ++m_pos; } - void moveStart() { m_userPos = m_pos = 0; } - void moveEnd() { m_userPos = m_pos = m_buffer.size(); } - - void setHistoryAutoSave(bool autoSave) { m_historyAutoSave = autoSave; } - void historyDown() { setContents(m_history.move(userContents(), 1)); } - void historyUp() { setContents(m_history.move(userContents(), -1)); } - const QStringList &historyItems() const { return m_history.items(); } - void historyPush(const QString &item = QString()) - { - m_history.append(item.isNull() ? contents() : item); - } - - void clear() - { - if (m_historyAutoSave) - historyPush(); - m_buffer.clear(); - m_anchor = m_userPos = m_pos = 0; - } - - QString display() const - { - QString msg(m_prompt); - for (int i = 0; i != m_buffer.size(); ++i) { - const QChar c = m_buffer.at(i); - if (c.unicode() < 32) { - msg += QLatin1Char('^'); - msg += QChar(c.unicode() + 64); - } else { - msg += c; - } - } - return msg; - } - - void deleteSelected() - { - if (m_pos < m_anchor) { - m_buffer.remove(m_pos, m_anchor - m_pos); - m_anchor = m_pos; - } else { - m_buffer.remove(m_anchor, m_pos - m_anchor); - m_pos = m_anchor; - } - } - - bool handleInput(const Input &input) - { - if (input.isShift(Key_Left)) { - moveLeft(); - } else if (input.isShift(Key_Right)) { - moveRight(); - } else if (input.isShift(Key_Home)) { - moveStart(); - } else if (input.isShift(Key_End)) { - moveEnd(); - } else if (input.isKey(Key_Left)) { - moveLeft(); - m_anchor = m_pos; - } else if (input.isKey(Key_Right)) { - moveRight(); - m_anchor = m_pos; - } else if (input.isKey(Key_Home)) { - moveStart(); - m_anchor = m_pos; - } else if (input.isKey(Key_End)) { - moveEnd(); - m_anchor = m_pos; - } else if (input.isKey(Key_Up) || input.isKey(Key_PageUp)) { - historyUp(); - } else if (input.isKey(Key_Down) || input.isKey(Key_PageDown)) { - historyDown(); - } else if (input.isKey(Key_Delete)) { - if (hasSelection()) { - deleteSelected(); - } else { - if (m_pos < m_buffer.size()) - m_buffer.remove(m_pos, 1); - else - deleteChar(); - } - } else if (!input.text().isEmpty()) { - if (hasSelection()) - deleteSelected(); - insertText(input.text()); - } else { - return false; - } - return true; - } - -private: - QString m_buffer; - QChar m_prompt; - History m_history; - int m_pos; - int m_anchor; - int m_userPos; // last position of inserted text (for retrieving history items) - bool m_historyAutoSave; // store items to history on clear()? -}; - -// Mappings for a specific mode (trie structure) -class ModeMapping : public QMap -{ -public: - const Inputs &value() const { return m_value; } - void setValue(const Inputs &value) { m_value = value; } -private: - Inputs m_value; -}; - -// Mappings for all modes -typedef QHash Mappings; - -// Iterator for mappings -class MappingsIterator : public QVector -{ -public: - MappingsIterator(Mappings *mappings, char mode = -1, const Inputs &inputs = Inputs()) - : m_parent(mappings) - , m_lastValid(-1) - , m_mode(0) - { - reset(mode); - walk(inputs); - } - - // Reset iterator state. Keep previous mode if 0. - void reset(char mode = 0) - { - clear(); - m_lastValid = -1; - m_currentInputs.clear(); - if (mode != 0) { - m_mode = mode; - if (mode != -1) - m_modeMapping = m_parent->find(mode); - } - } - - bool isValid() const { return !empty(); } - - // Return true if mapping can be extended. - bool canExtend() const { return isValid() && !last()->empty(); } - - // Return true if this mapping can be used. - bool isComplete() const { return m_lastValid != -1; } - - // Return size of current map. - int mapLength() const { return m_lastValid + 1; } - - bool walk(const Input &input) - { - m_currentInputs.append(input); - - if (m_modeMapping == m_parent->end()) - return false; - - ModeMapping::Iterator it; - if (isValid()) { - it = last()->find(input); - if (it == last()->end()) - return false; - } else { - it = m_modeMapping->find(input); - if (it == m_modeMapping->end()) - return false; - } - - if (!it->value().isEmpty()) - m_lastValid = size(); - append(it); - - return true; - } - - bool walk(const Inputs &inputs) - { - foreach (const Input &input, inputs) { - if (!walk(input)) - return false; - } - return true; - } - - // Return current mapped value. Iterator must be valid. - const Inputs &inputs() const - { - return at(m_lastValid)->value(); - } - - void remove() - { - if (isValid()) { - if (canExtend()) { - last()->setValue(Inputs()); - } else { - if (size() > 1) { - while (last()->empty()) { - at(size() - 2)->erase(last()); - pop_back(); - if (size() == 1 || !last()->value().isEmpty()) - break; - } - if (last()->empty() && last()->value().isEmpty()) - m_modeMapping->erase(last()); - } else if (last()->empty() && !last()->value().isEmpty()) { - m_modeMapping->erase(last()); - } - } - } - } - - void setInputs(const Inputs &key, const Inputs &inputs, bool unique = false) - { - ModeMapping *current = &(*m_parent)[m_mode]; - foreach (const Input &input, key) - current = &(*current)[input]; - if (!unique || current->value().isEmpty()) - current->setValue(inputs); - } - - const Inputs ¤tInputs() const { return m_currentInputs; } - -private: - Mappings *m_parent; - Mappings::Iterator m_modeMapping; - int m_lastValid; - char m_mode; - Inputs m_currentInputs; -}; - -// state of current mapping -struct MappingState { - MappingState() - : noremap(false), silent(false), editBlock(false) {} - MappingState(bool noremap, bool silent, bool editBlock) - : noremap(noremap), silent(silent), editBlock(editBlock) {} - bool noremap; - bool silent; - bool editBlock; -}; - -class FakeVimHandler::Private : public QObject -{ - Q_OBJECT - -public: - Private(FakeVimHandler *parent, QWidget *widget); - - EventResult handleEvent(QKeyEvent *ev); - bool wantsOverride(QKeyEvent *ev); - bool parseExCommmand(QString *line, ExCommand *cmd); - bool parseLineRange(QString *line, ExCommand *cmd); - int parseLineAddress(QString *cmd); - void parseRangeCount(const QString &line, Range *range) const; - void handleCommand(const QString &cmd); // Sets m_tc + handleExCommand - void handleExCommand(const QString &cmd); - - void installEventFilter(); - void removeEventFilter(); - void passShortcuts(bool enable); - void setupWidget(); - void restoreWidget(int tabSize); - - friend class FakeVimHandler; - - void init(); - void focus(); - - // Call before any FakeVim processing (import cursor position from editor) - void enterFakeVim(); - // Call after any FakeVim processing - // (if needUpdate is true, export cursor position to editor and scroll) - void leaveFakeVim(bool needUpdate = true); - - EventResult handleKey(const Input &input); - EventResult handleDefaultKey(const Input &input); - EventResult handleCurrentMapAsDefault(); - void prependInputs(const QVector &inputs); // Handle inputs. - void prependMapping(const Inputs &inputs); // Handle inputs as mapping. - bool expandCompleteMapping(); // Return false if current mapping is not complete. - bool extendMapping(const Input &input); // Return false if no suitable mappig found. - void endMapping(); - bool canHandleMapping(); - void clearPendingInput(); - void waitForMapping(); - EventResult stopWaitForMapping(bool hasInput); - EventResult handleInsertOrReplaceMode(const Input &); - void handleInsertMode(const Input &); - void handleReplaceMode(const Input &); - void finishInsertMode(); - - EventResult handleCommandMode(const Input &); - - // return true only if input in current mode and sub-mode was correctly handled - bool handleEscape(); - bool handleNoSubMode(const Input &); - bool handleChangeDeleteSubModes(const Input &); - bool handleReplaceSubMode(const Input &); - bool handleFilterSubMode(const Input &); - bool handleRegisterSubMode(const Input &); - bool handleShiftSubMode(const Input &); - bool handleChangeCaseSubMode(const Input &); - bool handleWindowSubMode(const Input &); - bool handleYankSubMode(const Input &); - bool handleZSubMode(const Input &); - bool handleCapitalZSubMode(const Input &); - bool handleMacroRecordSubMode(const Input &); - bool handleMacroExecuteSubMode(const Input &); - - bool handleCount(const Input &); // Handle count for commands (return false if input isn't count). - bool handleMovement(const Input &); - - EventResult handleExMode(const Input &); - EventResult handleSearchSubSubMode(const Input &); - bool handleCommandSubSubMode(const Input &); - void fixSelection(); // Fix selection according to current range, move and command modes. - bool finishSearch(); - void finishMovement(const QString &dotCommandMovement = QString()); - void resetCommandMode(); - void clearCommandMode(); - QTextCursor search(const SearchData &sd, int startPos, int count, bool showMessages); - void search(const SearchData &sd, bool showMessages = true); - bool searchNext(bool forward = true); - void searchBalanced(bool forward, QChar needle, QChar other); - void highlightMatches(const QString &needle); - void stopIncrementalFind(); - void updateFind(bool isComplete); - - void resetCount(); - bool isInputCount(const Input &) const; // Return true if input can be used as count for commands. - int mvCount() const { return qMax(1, g.mvcount); } - int opCount() const { return qMax(1, g.opcount); } - int count() const { return mvCount() * opCount(); } - QTextBlock block() const { return m_cursor.block(); } - int leftDist() const { return position() - block().position(); } - int rightDist() const { return block().length() - leftDist() - (isVisualCharMode() ? 0 : 1); } - bool atBlockStart() const { return m_cursor.atBlockStart(); } - bool atBlockEnd() const { return m_cursor.atBlockEnd(); } - bool atEndOfLine() const { return atBlockEnd() && block().length() > 1; } - bool atDocumentEnd() const { return position() >= lastPositionInDocument(true); } - bool atDocumentStart() const { return m_cursor.atStart(); } - - bool atEmptyLine(const QTextCursor &tc = QTextCursor()) const; - bool atBoundary(bool end, bool simple, bool onlyWords = false, - const QTextCursor &tc = QTextCursor()) const; - bool atWordBoundary(bool end, bool simple, const QTextCursor &tc = QTextCursor()) const; - bool atWordStart(bool simple, const QTextCursor &tc = QTextCursor()) const; - bool atWordEnd(bool simple, const QTextCursor &tc = QTextCursor()) const; - bool isFirstNonBlankOnLine(int pos); - - int lastPositionInDocument(bool ignoreMode = false) const; // Returns last valid position in doc. - int firstPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos - int lastPositionInLine(int line, bool onlyVisibleLines = true) const; // 1 based line, 0 based pos - int lineForPosition(int pos) const; // 1 based line, 0 based pos - QString lineContents(int line) const; // 1 based line - QString textAt(int from, int to) const; - void setLineContents(int line, const QString &contents); // 1 based line - int blockBoundary(const QString &left, const QString &right, - bool end, int count) const; // end or start position of current code block - int lineNumber(const QTextBlock &block) const; - - QTextBlock nextLine(const QTextBlock &block) const; // following line (respects wrapped parts) - QTextBlock previousLine(const QTextBlock &block) const; // previous line (respects wrapped parts) - - int linesOnScreen() const; - int linesInDocument() const; - - // The following use all zero-based counting. - int cursorLineOnScreen() const; - int cursorLine() const; - int cursorBlockNumber() const; // "." address - int physicalCursorColumn() const; // as stored in the data - int logicalCursorColumn() const; // as visible on screen - int physicalToLogicalColumn(int physical, const QString &text) const; - int logicalToPhysicalColumn(int logical, const QString &text) const; - int windowScrollOffset() const; // return scrolloffset but max half the current window height - Column cursorColumn() const; // as visible on screen - void updateFirstVisibleLine(); - int firstVisibleLine() const; - int lastVisibleLine() const; - int lineOnTop(int count = 1) const; // [count]-th line from top reachable without scrolling - int lineOnBottom(int count = 1) const; // [count]-th line from bottom reachable without scrolling - void scrollToLine(int line); - void scrollUp(int count); - void scrollDown(int count) { scrollUp(-count); } - void updateScrollOffset(); - void alignViewportToCursor(Qt::AlignmentFlag align, int line = -1, - bool moveToNonBlank = false); - - int lineToBlockNumber(int line) const; - - void setCursorPosition(const CursorPosition &p); - void setCursorPosition(QTextCursor *tc, const CursorPosition &p); - - // Helper functions for indenting/ - bool isElectricCharacter(QChar c) const; - void indentSelectedText(QChar lastTyped = QChar()); - void indentText(const Range &range, QChar lastTyped = QChar()); - void shiftRegionLeft(int repeat = 1); - void shiftRegionRight(int repeat = 1); - - void moveToFirstNonBlankOnLine(); - void moveToFirstNonBlankOnLine(QTextCursor *tc); - void moveToFirstNonBlankOnLineVisually(); - void moveToNonBlankOnLine(QTextCursor *tc); - void moveToTargetColumn(); - void setTargetColumn(); - void moveToMatchingParanthesis(); - void moveToBoundary(bool simple, bool forward = true); - void moveToNextBoundary(bool end, int count, bool simple, bool forward); - void moveToNextBoundaryStart(int count, bool simple, bool forward = true); - void moveToNextBoundaryEnd(int count, bool simple, bool forward = true); - void moveToBoundaryStart(int count, bool simple, bool forward = true); - void moveToBoundaryEnd(int count, bool simple, bool forward = true); - void moveToNextWord(bool end, int count, bool simple, bool forward, bool emptyLines); - void moveToNextWordStart(int count, bool simple, bool forward = true, bool emptyLines = true); - void moveToNextWordEnd(int count, bool simple, bool forward = true, bool emptyLines = true); - void moveToWordStart(int count, bool simple, bool forward = true, bool emptyLines = true); - void moveToWordEnd(int count, bool simple, bool forward = true, bool emptyLines = true); - - // Convenience wrappers to reduce line noise. - void moveToStartOfLine(); - void moveToStartOfLineVisually(); - void moveToEndOfLine(); - void moveToEndOfLineVisually(); - void moveToEndOfLineVisually(QTextCursor *tc); - void moveBehindEndOfLine(); - void moveUp(int n = 1) { moveDown(-n); } - void moveDown(int n = 1); - void moveUpVisually(int n = 1) { moveDownVisually(-n); } - void moveDownVisually(int n = 1); - void movePageDown(int count = 1); - void movePageUp(int count = 1) { movePageDown(-count); } - void dump(const char *msg) const { - qDebug() << msg << "POS: " << anchor() << position() - << "EXT: " << m_oldExternalAnchor << m_oldExternalPosition - << "INT: " << m_oldInternalAnchor << m_oldInternalPosition - << "VISUAL: " << g.visualMode; - } - void moveRight(int n = 1) { - //dump("RIGHT 1"); - if (isVisualCharMode()) { - const QTextBlock currentBlock = block(); - const int max = currentBlock.position() + currentBlock.length() - 1; - const int pos = position() + n; - setPosition(qMin(pos, max)); - } else { - m_cursor.movePosition(Right, KeepAnchor, n); - } - if (atEndOfLine()) - emit q->fold(1, false); - //dump("RIGHT 2"); - } - void moveLeft(int n = 1) { - m_cursor.movePosition(Left, KeepAnchor, n); - } - void setAnchor() { - m_cursor.setPosition(position(), MoveAnchor); - } - void setAnchor(int position) { - m_cursor.setPosition(position, KeepAnchor); - } - void setPosition(int position) { - m_cursor.setPosition(position, KeepAnchor); - } - void setAnchorAndPosition(int anchor, int position) { - m_cursor.setPosition(anchor, MoveAnchor); - m_cursor.setPosition(position, KeepAnchor); - } - // Set cursor in text editor widget. - void commitCursor() { - if (isVisualBlockMode()) { - emit q->requestSetBlockSelection(m_cursor); - } else { - emit q->requestDisableBlockSelection(); - if (editor()) - EDITOR(setTextCursor(m_cursor)); - } - } - // Restore cursor from editor widget. - void pullCursor() { - if (isVisualBlockMode()) - q->requestBlockSelection(&m_cursor); - else if (editor()) - m_cursor = EDITOR(textCursor()); - } - - // Values to save when starting FakeVim processing. - int m_firstVisibleLine; - QTextCursor m_cursor; - - bool moveToPreviousParagraph(int count) { return moveToNextParagraph(-count); } - bool moveToNextParagraph(int count); - - bool handleFfTt(const QString &key, bool repeats = false); - - void enterVisualInsertMode(QChar command); - void enterReplaceMode(); - void enterInsertMode(); - void enterInsertOrReplaceMode(Mode mode); - void enterCommandMode(Mode returnToMode = CommandMode); - void enterExMode(const QString &contents = QString()); - void showMessage(MessageLevel level, const QString &msg); - void clearMessage() { showMessage(MessageInfo, QString()); } - void notImplementedYet(); - void updateMiniBuffer(); - void updateSelection(); - void updateHighlights(); - void updateCursorShape(); - QWidget *editor() const; - QTextDocument *document() const { return EDITOR(document()); } - QChar characterAtCursor() const - { return document()->characterAt(position()); } - - void joinPreviousEditBlock(); - void beginEditBlock(bool largeEditBlock = false); - void beginLargeEditBlock() { beginEditBlock(true); } - void endEditBlock(); - void breakEditBlock() { m_buffer->breakEditBlock = true; } - - Q_SLOT void onContentsChanged(int position, int charsRemoved, int charsAdded); - Q_SLOT void onUndoCommandAdded(); - - bool isInsertMode() const { return g.mode == InsertMode || g.mode == ReplaceMode; } - // Waiting for movement operator. - bool isOperatorPending() const { - return g.submode == ChangeSubMode - || g.submode == DeleteSubMode - || g.submode == FilterSubMode - || g.submode == IndentSubMode - || g.submode == ShiftLeftSubMode - || g.submode == ShiftRightSubMode - || g.submode == InvertCaseSubMode - || g.submode == DownCaseSubMode - || g.submode == UpCaseSubMode - || g.submode == YankSubMode; } - - bool isVisualMode() const { return g.visualMode != NoVisualMode; } - bool isNoVisualMode() const { return g.visualMode == NoVisualMode; } - bool isVisualCharMode() const { return g.visualMode == VisualCharMode; } - bool isVisualLineMode() const { return g.visualMode == VisualLineMode; } - bool isVisualBlockMode() const { return g.visualMode == VisualBlockMode; } - char currentModeCode() const; - void updateEditor(); - - void selectTextObject(bool simple, bool inner); - void selectWordTextObject(bool inner); - void selectWORDTextObject(bool inner); - void selectSentenceTextObject(bool inner); - void selectParagraphTextObject(bool inner); - bool changeNumberTextObject(int count); - // return true only if cursor is in a block delimited with correct characters - bool selectBlockTextObject(bool inner, char left, char right); - bool selectQuotedStringTextObject(bool inner, const QString "e); - - Q_SLOT void importSelection(); - void exportSelection(); - void commitInsertState(); - void invalidateInsertState(); - bool isInsertStateValid() const; - void clearLastInsertion(); - void ensureCursorVisible(); - void insertInInsertMode(const QString &text); - - // Macro recording - bool startRecording(const Input &input); - void record(const Input &input); - void stopRecording(); - bool executeRegister(int register); - -public: - QTextEdit *m_textedit; - QPlainTextEdit *m_plaintextedit; - bool m_wasReadOnly; // saves read-only state of document - - bool m_inFakeVim; // true if currently processing a key press or a command - - FakeVimHandler *q; - int m_oldExternalPosition; // copy from last event to check for external changes - int m_oldExternalAnchor; - int m_oldInternalPosition; // copy from last event to check for external changes - int m_oldInternalAnchor; - int m_register; - BlockInsertMode m_visualBlockInsert; - - bool m_fakeEnd; - bool m_anchorPastEnd; - bool m_positionPastEnd; // '$' & 'l' in visual mode can move past eol - - QString m_currentFileName; - - int m_findStartPosition; - - int anchor() const { return m_cursor.anchor(); } - int position() const { return m_cursor.position(); } - - struct TransformationData - { - TransformationData(const QString &s, const QVariant &d) - : from(s), extraData(d) {} - QString from; - QString to; - QVariant extraData; - }; - typedef void (Private::*Transformation)(TransformationData *td); - void transformText(const Range &range, Transformation transformation, - const QVariant &extraData = QVariant()); - - void insertText(QTextCursor &tc, const QString &text); - void insertText(const Register ®); - void removeText(const Range &range); - void removeTransform(TransformationData *td); - - void invertCase(const Range &range); - void invertCaseTransform(TransformationData *td); - - void upCase(const Range &range); - void upCaseTransform(TransformationData *td); - - void downCase(const Range &range); - void downCaseTransform(TransformationData *td); - - void replaceText(const Range &range, const QString &str); - void replaceByStringTransform(TransformationData *td); - void replaceByCharTransform(TransformationData *td); - - QString selectText(const Range &range) const; - void setCurrentRange(const Range &range); - Range currentRange() const { return Range(position(), anchor(), g.rangemode); } - - void yankText(const Range &range, int toregister); - - void pasteText(bool afterCursor); - - void joinLines(int count, bool preserveSpace = false); - - void insertNewLine(); - - bool handleInsertInEditor(const Input &input); - bool passEventToEditor(QEvent &event); // Pass event to editor widget without filtering. Returns true if event was processed. - - // undo handling - int revision() const { return document()->availableUndoSteps(); } - void undoRedo(bool undo); - void undo(); - void redo(); - void pushUndoState(bool overwrite = true); - - // extra data for '.' - void replay(const QString &text, int repeat = 1); - void setDotCommand(const QString &cmd) { g.dotCommand = cmd; } - void setDotCommand(const QString &cmd, int n) { g.dotCommand = cmd.arg(n); } - QString visualDotCommand() const; - - // visual modes - void toggleVisualMode(VisualMode visualMode); - void leaveVisualMode(); - - // marks - Mark mark(QChar code) const; - void setMark(QChar code, CursorPosition position); - // jump to valid mark return true if mark is valid and local - bool jumpToMark(QChar mark, bool backTickMode); - // update marks on undo/redo - void updateMarks(const Marks &newMarks); - CursorPosition markLessPosition() const { return mark(QLatin1Char('<')).position(document()); } - CursorPosition markGreaterPosition() const { return mark(QLatin1Char('>')).position(document()); } - - // vi style configuration - QVariant config(int code) const { return theFakeVimSetting(code)->value(); } - bool hasConfig(int code) const { return config(code).toBool(); } - bool hasConfig(int code, const char *value) const // FIXME - { return config(code).toString().contains(_(value)); } - - int m_targetColumn; // -1 if past end of line - int m_visualTargetColumn; // 'l' can move past eol in visual mode only - int m_targetColumnWrapped; // column in current part of wrapped line - - // auto-indent - QString tabExpand(int len) const; - Column indentation(const QString &line) const; - void insertAutomaticIndentation(bool goingDown, bool forceAutoIndent = false); - // number of autoindented characters - void handleStartOfLine(); - - // register handling - QString registerContents(int reg) const; - void setRegister(int reg, const QString &contents, RangeMode mode); - RangeMode registerRangeMode(int reg) const; - void getRegisterType(int reg, bool *isClipboard, bool *isSelection) const; - - void recordJump(int position = -1); - void jump(int distance); - - QList m_extraSelections; - QTextCursor m_searchCursor; - int m_searchStartPosition; - int m_searchFromScreenLine; - QString m_highlighted; // currently highlighted text - - bool handleExCommandHelper(ExCommand &cmd); // Returns success. - bool handleExPluginCommand(const ExCommand &cmd); // Handled by plugin? - bool handleExBangCommand(const ExCommand &cmd); - bool handleExYankDeleteCommand(const ExCommand &cmd); - bool handleExChangeCommand(const ExCommand &cmd); - bool handleExMoveCommand(const ExCommand &cmd); - bool handleExJoinCommand(const ExCommand &cmd); - bool handleExGotoCommand(const ExCommand &cmd); - bool handleExHistoryCommand(const ExCommand &cmd); - bool handleExRegisterCommand(const ExCommand &cmd); - bool handleExMapCommand(const ExCommand &cmd); - bool handleExNohlsearchCommand(const ExCommand &cmd); - bool handleExNormalCommand(const ExCommand &cmd); - bool handleExReadCommand(const ExCommand &cmd); - bool handleExUndoRedoCommand(const ExCommand &cmd); - bool handleExSetCommand(const ExCommand &cmd); - bool handleExShiftCommand(const ExCommand &cmd); - bool handleExSourceCommand(const ExCommand &cmd); - bool handleExSubstituteCommand(const ExCommand &cmd); - bool handleExWriteCommand(const ExCommand &cmd); - bool handleExEchoCommand(const ExCommand &cmd); - - void timerEvent(QTimerEvent *ev) override; - - void setupCharClass(); - int charClass(QChar c, bool simple) const; - signed char m_charClass[256]; - - int m_ctrlVAccumulator; - int m_ctrlVLength; - int m_ctrlVBase; - - void miniBufferTextEdited(const QString &text, int cursorPos, int anchorPos); - - // Data shared among editors with same document. - struct BufferData - { - BufferData() - : lastRevision(0) - , editBlockLevel(0) - , breakEditBlock(false) - , lastVisualMode(NoVisualMode) - , lastVisualModeInverted(false) - {} - - QStack undo; - QStack redo; - State undoState; - int lastRevision; - - int editBlockLevel; // current level of edit blocks - bool breakEditBlock; // if true, joinPreviousEditBlock() starts new edit block - - QStack jumpListUndo; - QStack jumpListRedo; - CursorPosition lastChangePosition; - - VisualMode lastVisualMode; - bool lastVisualModeInverted; - - Marks marks; - - // Insert state to get last inserted text. - struct InsertState { - int pos1; - int pos2; - int backspaces; - int deletes; - QSet spaces; - bool insertingSpaces; - QString textBeforeCursor; - bool newLineBefore; - bool newLineAfter; - } insertState; - - QString lastInsertion; - }; - - typedef QSharedPointer BufferDataPtr; - void pullOrCreateBufferData(); - BufferDataPtr m_buffer; - - // Data shared among all editors. - static struct GlobalData - { - GlobalData() - : passing(false) - , mode(CommandMode) - , submode(NoSubMode) - , subsubmode(NoSubSubMode) - , visualMode(NoVisualMode) - , mvcount(0) - , opcount(0) - , movetype(MoveInclusive) - , rangemode(RangeCharMode) - , gflag(false) - , mappings() - , currentMap(&mappings) - , inputTimer(-1) - , mapDepth(0) - , currentMessageLevel(MessageInfo) - , lastSearchForward(false) - , highlightsCleared(false) - , findPending(false) - , returnToMode(CommandMode) - , currentRegister(0) - , lastExecutedRegister(0) - { - commandBuffer.setPrompt(QLatin1Char(':')); - } - - // Current state. - bool passing; // let the core see the next event - Mode mode; - SubMode submode; - SubSubMode subsubmode; - Input subsubdata; - VisualMode visualMode; - - // [count] for current command, 0 if no [count] available - int mvcount; - int opcount; - - MoveType movetype; - RangeMode rangemode; - bool gflag; // whether current command started with 'g' - - // Extra data for ';'. - Input semicolonType; // 'f', 'F', 't', 'T' - QString semicolonKey; - - // Repetition. - QString dotCommand; - - QHash registers; - - // All mappings. - Mappings mappings; - - // Input. - QList pendingInput; - MappingsIterator currentMap; - int inputTimer; - QStack mapStates; - int mapDepth; - - // Command line buffers. - CommandBuffer commandBuffer; - CommandBuffer searchBuffer; - - // Current mini buffer message. - QString currentMessage; - MessageLevel currentMessageLevel; - QString currentCommand; - - // Search state. - QString lastSearch; // last search expression as entered by user - QString lastNeedle; // last search expression translated with vimPatternToQtPattern() - bool lastSearchForward; // last search command was '/' or '*' - bool highlightsCleared; // ':nohlsearch' command is active until next search - bool findPending; // currently searching using external tool (until editor is focused again) - - // Last substitution command. - QString lastSubstituteFlags; - QString lastSubstitutePattern; - QString lastSubstituteReplacement; - - // Global marks. - Marks marks; - - // Return to insert/replace mode after single command (). - Mode returnToMode; - - // Currently recorded macro (not recording if null string). - QString recording; - int currentRegister; - int lastExecutedRegister; - } g; -}; - -FakeVimHandler::Private::GlobalData FakeVimHandler::Private::g; - -FakeVimHandler::Private::Private(FakeVimHandler *parent, QWidget *widget) -{ - q = parent; - m_textedit = qobject_cast(widget); - m_plaintextedit = qobject_cast(widget); - - init(); - - if (editor()) { - connect(EDITOR(document()), SIGNAL(contentsChange(int,int,int)), - SLOT(onContentsChanged(int,int,int))); - connect(EDITOR(document()), SIGNAL(undoCommandAdded()), SLOT(onUndoCommandAdded())); - m_buffer->lastRevision = revision(); - } -} - -void FakeVimHandler::Private::init() -{ - m_inFakeVim = false; - m_findStartPosition = -1; - m_visualBlockInsert = NoneBlockInsertMode; - m_fakeEnd = false; - m_positionPastEnd = false; - m_anchorPastEnd = false; - m_register = '"'; - m_targetColumn = 0; - m_visualTargetColumn = 0; - m_targetColumnWrapped = 0; - m_oldInternalAnchor = -1; - m_oldInternalPosition = -1; - m_oldExternalAnchor = -1; - m_oldExternalPosition = -1; - m_searchStartPosition = 0; - m_searchFromScreenLine = 0; - m_firstVisibleLine = 0; - m_ctrlVAccumulator = 0; - m_ctrlVLength = 0; - m_ctrlVBase = 0; - - pullOrCreateBufferData(); - setupCharClass(); -} - -void FakeVimHandler::Private::focus() -{ - enterFakeVim(); - - stopIncrementalFind(); - if (!isInsertMode()) { - if (g.subsubmode == SearchSubSubMode) { - setPosition(m_searchStartPosition); - scrollToLine(m_searchFromScreenLine); - setTargetColumn(); - setAnchor(); - commitCursor(); - } else if (g.submode != NoSubMode || g.mode == ExMode) { - leaveVisualMode(); - setPosition(qMin(position(), anchor())); - setTargetColumn(); - setAnchor(); - commitCursor(); - } - - bool exitCommandLine = (g.subsubmode == SearchSubSubMode || g.mode == ExMode); - resetCommandMode(); - if (exitCommandLine) - updateMiniBuffer(); - } - updateCursorShape(); - if (g.mode != CommandMode) - updateMiniBuffer(); - updateHighlights(); - - leaveFakeVim(false); -} - -void FakeVimHandler::Private::enterFakeVim() -{ - QTC_ASSERT(!m_inFakeVim, qDebug() << "enterFakeVim() shouldn't be called recursively!"; return); - - pullOrCreateBufferData(); - - pullCursor(); - if (m_cursor.isNull()) - m_cursor = QTextCursor(document()); - - m_inFakeVim = true; - - removeEventFilter(); - - updateFirstVisibleLine(); - importSelection(); - - // Position changed externally, e.g. by code completion. - if (position() != m_oldInternalPosition) { - // record external jump to different line - if (m_oldInternalPosition != -1 && lineForPosition(m_oldInternalPosition) != lineForPosition(position())) - recordJump(m_oldInternalPosition); - setTargetColumn(); - if (atEndOfLine() && !isVisualMode() && !isInsertMode()) - moveLeft(); - } - - if (m_fakeEnd) - moveRight(); -} - -void FakeVimHandler::Private::leaveFakeVim(bool needUpdate) -{ - QTC_ASSERT(m_inFakeVim, qDebug() << "enterFakeVim() not called before leaveFakeVim()!"; return); - - // The command might have destroyed the editor. - if (m_textedit || m_plaintextedit) { - // We fake vi-style end-of-line behaviour - m_fakeEnd = atEndOfLine() && g.mode == CommandMode && !isVisualBlockMode() - && !isVisualCharMode(); - - //QTC_ASSERT(g.mode == InsertMode || g.mode == ReplaceMode - // || !atBlockEnd() || block().length() <= 1, - // qDebug() << "Cursor at EOL after key handler"); - if (m_fakeEnd) - moveLeft(); - - if (hasConfig(ConfigShowMarks)) - updateSelection(); - - exportSelection(); - updateCursorShape(); - - if (needUpdate) { - commitCursor(); - - // Move cursor line to middle of screen if it's not visible. - const int line = cursorLine(); - if (line < firstVisibleLine() || line > firstVisibleLine() + linesOnScreen()) - scrollToLine(qMax(0, line - linesOnScreen() / 2)); - else - scrollToLine(firstVisibleLine()); - updateScrollOffset(); - } - - installEventFilter(); - } - - m_inFakeVim = false; -} - -bool FakeVimHandler::Private::wantsOverride(QKeyEvent *ev) -{ - const int key = ev->key(); - const Qt::KeyboardModifiers mods = ev->modifiers(); - KEY_DEBUG("SHORTCUT OVERRIDE" << key << " PASSING: " << g.passing); - - if (key == Key_Escape) { - if (g.subsubmode == SearchSubSubMode) - return true; - // Not sure this feels good. People often hit Esc several times. - if (isNoVisualMode() - && g.mode == CommandMode - && g.submode == NoSubMode - && g.currentCommand.isEmpty() - && g.returnToMode == CommandMode) - return false; - return true; - } - - // We are interested in overriding most Ctrl key combinations. - if (isOnlyControlModifier(mods) - && !config(ConfigPassControlKey).toBool() - && ((key >= Key_A && key <= Key_Z && key != Key_K) - || key == Key_BracketLeft || key == Key_BracketRight)) { - // Ctrl-K is special as it is the Core's default notion of Locator - if (g.passing) { - KEY_DEBUG(" PASSING CTRL KEY"); - // We get called twice on the same key - //g.passing = false; - return false; - } - KEY_DEBUG(" NOT PASSING CTRL KEY"); - //updateMiniBuffer(); - return true; - } - - // Let other shortcuts trigger. - return false; -} - -EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev) -{ - const int key = ev->key(); - const Qt::KeyboardModifiers mods = ev->modifiers(); - - if (key == Key_Shift || key == Key_Alt || key == Key_Control - || key == Key_AltGr || key == Key_Meta) - { - KEY_DEBUG("PLAIN MODIFIER"); - return EventUnhandled; - } - - if (g.passing) { - passShortcuts(false); - KEY_DEBUG("PASSING PLAIN KEY..." << ev->key() << ev->text()); - //if (input.is(',')) { // use ',,' to leave, too. - // qDebug() << "FINISHED..."; - // return EventHandled; - //} - g.passing = false; - updateMiniBuffer(); - KEY_DEBUG(" PASS TO CORE"); - return EventPassedToCore; - } - -#ifndef FAKEVIM_STANDALONE - bool inSnippetMode = false; - QMetaObject::invokeMethod(editor(), - "inSnippetMode", Q_ARG(bool *, &inSnippetMode)); - - if (inSnippetMode) - return EventPassedToCore; -#endif - - // Fake "End of line" - //m_tc = m_cursor; - - //bool hasBlock = false; - //emit q->requestHasBlockSelection(&hasBlock); - //qDebug() << "IMPORT BLOCK 2:" << hasBlock; - - //if (0 && hasBlock) { - // (pos > anc) ? --pos : --anc; - - //if ((mods & RealControlModifier) != 0) { - // if (key >= Key_A && key <= Key_Z) - // key = shift(key); // make it lower case - // key = control(key); - //} else if (key >= Key_A && key <= Key_Z && (mods & Qt::ShiftModifier) == 0) { - // key = shift(key); - //} - - //QTC_ASSERT(g.mode == InsertMode || g.mode == ReplaceMode - // || !atBlockEnd() || block().length() <= 1, - // qDebug() << "Cursor at EOL before key handler"); - - enterFakeVim(); - EventResult result = handleKey(Input(key, mods, ev->text())); - leaveFakeVim(result == EventHandled); - - return result; -} - -void FakeVimHandler::Private::installEventFilter() -{ - EDITOR(viewport()->installEventFilter(q)); - EDITOR(installEventFilter(q)); -} - -void FakeVimHandler::Private::removeEventFilter() -{ - EDITOR(viewport()->removeEventFilter(q)); - EDITOR(removeEventFilter(q)); -} - -void FakeVimHandler::Private::setupWidget() -{ - enterFakeVim(); - - resetCommandMode(); - m_wasReadOnly = EDITOR(isReadOnly()); - - updateEditor(); - importSelection(); - updateMiniBuffer(); - updateCursorShape(); - - recordJump(); - setTargetColumn(); - if (atEndOfLine() && !isVisualMode() && !isInsertMode()) - moveLeft(); - - leaveFakeVim(); -} - -void FakeVimHandler::Private::exportSelection() -{ - int pos = position(); - int anc = isVisualMode() ? anchor() : position(); - - m_oldInternalPosition = pos; - m_oldInternalAnchor = anc; - - if (isVisualMode()) { - if (g.visualMode == VisualBlockMode) { - const int col1 = anc - document()->findBlock(anc).position(); - const int col2 = pos - document()->findBlock(pos).position(); - if (col1 > col2) - ++anc; - else if (!atBlockEnd()) - ++pos; - // FIXME: After '$' command (i.e. m_visualTargetColumn == -1), end of selected lines - // should be selected. - setAnchorAndPosition(anc, pos); - commitCursor(); - } else if (g.visualMode == VisualLineMode) { - const int posLine = lineForPosition(pos); - const int ancLine = lineForPosition(anc); - if (anc < pos) { - pos = lastPositionInLine(posLine); - anc = firstPositionInLine(ancLine); - } else { - pos = firstPositionInLine(posLine); - anc = lastPositionInLine(ancLine) + 1; - } - // putting cursor on folded line will unfold the line, so move the cursor a bit - if (!document()->findBlock(pos).isVisible()) - ++pos; - setAnchorAndPosition(anc, pos); - } else if (g.visualMode == VisualCharMode) { - if (anc > pos) - ++anc; - } else { - QTC_CHECK(false); - } - - setAnchorAndPosition(anc, pos); - - setMark(QLatin1Char('<'), markLessPosition()); - setMark(QLatin1Char('>'), markGreaterPosition()); - } else { - if (g.subsubmode == SearchSubSubMode && !m_searchCursor.isNull()) - m_cursor = m_searchCursor; - else - setAnchorAndPosition(pos, pos); - } - m_oldExternalPosition = position(); - m_oldExternalAnchor = anchor(); -} - -void FakeVimHandler::Private::commitInsertState() -{ - if (!isInsertStateValid()) - return; - - QString &lastInsertion = m_buffer->lastInsertion; - BufferData::InsertState &insertState = m_buffer->insertState; - - // Get raw inserted text. - lastInsertion = textAt(insertState.pos1, insertState.pos2); - - // Escape special characters and spaces inserted by user (not by auto-indentation). - for (int i = lastInsertion.size() - 1; i >= 0; --i) { - const int pos = insertState.pos1 + i; - const ushort c = document()->characterAt(pos).unicode(); - if (c == '<') - lastInsertion.replace(i, 1, _("")); - else if ((c == ' ' || c == '\t') && insertState.spaces.contains(pos)) - lastInsertion.replace(i, 1, _(c == ' ' ? "" : "")); - } - - // Remove unnecessary backspaces. - while (insertState.backspaces > 0 && !lastInsertion.isEmpty() && lastInsertion[0].isSpace()) - --insertState.backspaces; - - // backspaces in front of inserted text - lastInsertion.prepend(QString(_("")).repeated(insertState.backspaces)); - // deletes after inserted text - lastInsertion.prepend(QString(_("")).repeated(insertState.deletes)); - - // Remove indentation. - lastInsertion.replace(QRegExp(_("(^|\n)[\\t ]+")), _("\\1")); -} - -void FakeVimHandler::Private::invalidateInsertState() -{ - m_oldInternalPosition = position(); - BufferData::InsertState &insertState = m_buffer->insertState; - insertState.pos1 = -1; - insertState.pos2 = m_oldInternalPosition; - insertState.backspaces = 0; - insertState.deletes = 0; - insertState.spaces.clear(); - insertState.insertingSpaces = false; - insertState.textBeforeCursor = textAt(document()->findBlock(m_oldInternalPosition).position(), - m_oldInternalPosition); - insertState.newLineBefore = false; - insertState.newLineAfter = false; -} - -bool FakeVimHandler::Private::isInsertStateValid() const -{ - return m_buffer->insertState.pos1 != -1; -} - -void FakeVimHandler::Private::clearLastInsertion() -{ - invalidateInsertState(); - m_buffer->lastInsertion.clear(); - m_buffer->insertState.pos1 = m_buffer->insertState.pos2; -} - -void FakeVimHandler::Private::ensureCursorVisible() -{ - int pos = position(); - int anc = isVisualMode() ? anchor() : position(); - - // fix selection so it is outside folded block - int start = qMin(pos, anc); - int end = qMax(pos, anc) + 1; - QTextBlock block = document()->findBlock(start); - QTextBlock block2 = document()->findBlock(end); - if (!block.isVisible() || !block2.isVisible()) { - // FIXME: Moving cursor left/right or unfolding block immediately after block is folded - // should restore cursor position inside block. - // Changing cursor position after folding is not Vim behavior so at least record the jump. - if (block.isValid() && !block.isVisible()) - recordJump(); - - pos = start; - while (block.isValid() && !block.isVisible()) - block = block.previous(); - if (block.isValid()) - pos = block.position() + qMin(m_targetColumn, block.length() - 2); - - if (isVisualMode()) { - anc = end; - while (block2.isValid() && !block2.isVisible()) { - anc = block2.position() + block2.length() - 2; - block2 = block2.next(); - } - } - - setAnchorAndPosition(anc, pos); - } -} - -void FakeVimHandler::Private::importSelection() -{ - if (position() == m_oldExternalPosition - && anchor() == m_oldExternalAnchor) { - // Undo drawing correction. - setAnchorAndPosition(m_oldInternalAnchor, m_oldInternalPosition); - } else { - // Import new selection. - Qt::KeyboardModifiers mods = QApplication::keyboardModifiers(); - if (m_cursor.hasSelection()) { - if (mods & HostOsInfo::controlModifier()) - g.visualMode = VisualBlockMode; - else if (mods & Qt::AltModifier) - g.visualMode = VisualBlockMode; - else if (mods & Qt::ShiftModifier) - g.visualMode = VisualLineMode; - else - g.visualMode = VisualCharMode; - m_buffer->lastVisualMode = g.visualMode; - } else { - g.visualMode = NoVisualMode; - } - } -} - -void FakeVimHandler::Private::updateEditor() -{ - const int charWidth = QFontMetrics(EDITOR(font())).width(QLatin1Char(' ')); - EDITOR(setTabStopWidth(charWidth * config(ConfigTabStop).toInt())); - setupCharClass(); -} - -void FakeVimHandler::Private::restoreWidget(int tabSize) -{ - //clearMessage(); - //updateMiniBuffer(); - //EDITOR(removeEventFilter(q)); - //EDITOR(setReadOnly(m_wasReadOnly)); - const int charWidth = QFontMetrics(EDITOR(font())).width(QLatin1Char(' ')); - EDITOR(setTabStopWidth(charWidth * tabSize)); - g.visualMode = NoVisualMode; - // Force "ordinary" cursor. - EDITOR(setOverwriteMode(false)); - updateSelection(); - updateHighlights(); -} - -EventResult FakeVimHandler::Private::handleKey(const Input &input) -{ - KEY_DEBUG("HANDLE INPUT: " << input << " MODE: " << mode); - - bool hasInput = input.isValid(); - - // Waiting on input to complete mapping? - EventResult r = stopWaitForMapping(hasInput); - - if (hasInput) { - record(input); - g.pendingInput.append(input); - } - - // Process pending input. - // Note: Pending input is global state and can be extended by: - // 1. handling a user input (though handleKey() is not called recursively), - // 2. expanding a user mapping or - // 3. executing a register. - while (!g.pendingInput.isEmpty() && r == EventHandled) { - const Input in = g.pendingInput.takeFirst(); - - // invalid input is used to pop mapping state - if (!in.isValid()) { - endMapping(); - } else { - // Handle user mapping. - if (canHandleMapping()) { - if (extendMapping(in)) { - if (!hasInput || !g.currentMap.canExtend()) - expandCompleteMapping(); - } else if (!expandCompleteMapping()) { - r = handleCurrentMapAsDefault(); - } - } else { - r = handleDefaultKey(in); - } - } - } - - if (g.currentMap.canExtend()) { - waitForMapping(); - return EventHandled; - } - - if (r != EventHandled) - clearPendingInput(); - - return r; -} - -EventResult FakeVimHandler::Private::handleDefaultKey(const Input &input) -{ - if (input == Nop) - return EventHandled; - else if (g.subsubmode == SearchSubSubMode) - return handleSearchSubSubMode(input); - else if (g.mode == CommandMode) - return handleCommandMode(input); - else if (g.mode == InsertMode || g.mode == ReplaceMode) - return handleInsertOrReplaceMode(input); - else if (g.mode == ExMode) - return handleExMode(input); - return EventUnhandled; -} - -EventResult FakeVimHandler::Private::handleCurrentMapAsDefault() -{ - // If mapping has failed take the first input from it and try default command. - const Inputs &inputs = g.currentMap.currentInputs(); - - Input in = inputs.front(); - if (inputs.size() > 1) - prependInputs(inputs.mid(1)); - g.currentMap.reset(); - - return handleDefaultKey(in); -} - -void FakeVimHandler::Private::prependInputs(const QVector &inputs) -{ - for (int i = inputs.size() - 1; i >= 0; --i) - g.pendingInput.prepend(inputs[i]); -} - -void FakeVimHandler::Private::prependMapping(const Inputs &inputs) -{ - // FIXME: Implement Vim option maxmapdepth (default value is 1000). - if (g.mapDepth >= 1000) { - const int i = qMax(0, g.pendingInput.lastIndexOf(Input())); - QList inputs = g.pendingInput.mid(i); - clearPendingInput(); - g.pendingInput.append(inputs); - showMessage(MessageError, tr("Recursive mapping")); - updateMiniBuffer(); - return; - } - - ++g.mapDepth; - g.pendingInput.prepend(Input()); - prependInputs(inputs); - g.commandBuffer.setHistoryAutoSave(false); - - // start new edit block (undo/redo) only if necessary - bool editBlock = m_buffer->editBlockLevel == 0 && !(isInsertMode() && isInsertStateValid()); - if (editBlock) - beginLargeEditBlock(); - g.mapStates << MappingState(inputs.noremap(), inputs.silent(), editBlock); -} - -bool FakeVimHandler::Private::expandCompleteMapping() -{ - if (!g.currentMap.isComplete()) - return false; - - const Inputs &inputs = g.currentMap.inputs(); - int usedInputs = g.currentMap.mapLength(); - prependInputs(g.currentMap.currentInputs().mid(usedInputs)); - prependMapping(inputs); - g.currentMap.reset(); - - return true; -} - -bool FakeVimHandler::Private::extendMapping(const Input &input) -{ - if (!g.currentMap.isValid()) - g.currentMap.reset(currentModeCode()); - return g.currentMap.walk(input); -} - -void FakeVimHandler::Private::endMapping() -{ - if (!g.currentMap.canExtend()) - --g.mapDepth; - if (g.mapStates.isEmpty()) - return; - if (g.mapStates.last().editBlock) - endEditBlock(); - g.mapStates.pop_back(); - if (g.mapStates.isEmpty()) - g.commandBuffer.setHistoryAutoSave(true); - updateMiniBuffer(); -} - -bool FakeVimHandler::Private::canHandleMapping() -{ - // Don't handle user mapping in sub-modes that cannot be followed by movement and in "noremap". - return g.subsubmode == NoSubSubMode - && g.submode != RegisterSubMode - && g.submode != WindowSubMode - && g.submode != ZSubMode - && g.submode != CapitalZSubMode - && g.submode != ReplaceSubMode - && g.submode != MacroRecordSubMode - && g.submode != MacroExecuteSubMode - && (g.mapStates.isEmpty() || !g.mapStates.last().noremap); -} - -void FakeVimHandler::Private::clearPendingInput() -{ - // Clear pending input on interrupt or bad mapping. - g.pendingInput.clear(); - g.mapStates.clear(); - g.mapDepth = 0; - - // Clear all started edit blocks. - while (m_buffer->editBlockLevel > 0) - endEditBlock(); -} - -void FakeVimHandler::Private::waitForMapping() -{ - g.currentCommand.clear(); - foreach (const Input &input, g.currentMap.currentInputs()) - g.currentCommand.append(input.toString()); - updateMiniBuffer(); - - // wait for user to press any key or trigger complete mapping after interval - g.inputTimer = startTimer(1000); -} - -EventResult FakeVimHandler::Private::stopWaitForMapping(bool hasInput) -{ - if (g.inputTimer != -1) { - killTimer(g.inputTimer); - g.inputTimer = -1; - g.currentCommand.clear(); - if (!hasInput && !expandCompleteMapping()) { - // Cannot complete mapping so handle the first input from it as default command. - return handleCurrentMapAsDefault(); - } - } - - return EventHandled; -} - -void FakeVimHandler::Private::timerEvent(QTimerEvent *ev) -{ - if (ev->timerId() == g.inputTimer) { - enterFakeVim(); - EventResult result = handleKey(Input()); - leaveFakeVim(result == EventHandled); - } -} - -void FakeVimHandler::Private::stopIncrementalFind() -{ - if (g.findPending) { - g.findPending = false; - setAnchorAndPosition(m_findStartPosition, m_cursor.selectionStart()); - finishMovement(); - setAnchor(); - } -} - -void FakeVimHandler::Private::updateFind(bool isComplete) -{ - if (!isComplete && !hasConfig(ConfigIncSearch)) - return; - - g.currentMessage.clear(); - - const QString &needle = g.searchBuffer.contents(); - if (isComplete) { - setPosition(m_searchStartPosition); - if (!needle.isEmpty()) - recordJump(); - } - - SearchData sd; - sd.needle = needle; - sd.forward = g.lastSearchForward; - sd.highlightMatches = isComplete; - search(sd, isComplete); -} - -void FakeVimHandler::Private::resetCount() -{ - g.mvcount = 0; - g.opcount = 0; -} - -bool FakeVimHandler::Private::isInputCount(const Input &input) const -{ - return input.isDigit() && (!input.is('0') || g.mvcount > 0); -} - -bool FakeVimHandler::Private::atEmptyLine(const QTextCursor &tc) const -{ - if (tc.isNull()) - return atEmptyLine(m_cursor); - return tc.block().length() == 1; -} - -bool FakeVimHandler::Private::atBoundary(bool end, bool simple, bool onlyWords, - const QTextCursor &tc) const -{ - if (tc.isNull()) - return atBoundary(end, simple, onlyWords, m_cursor); - if (atEmptyLine(tc)) - return true; - int pos = tc.position(); - QChar c1 = document()->characterAt(pos); - QChar c2 = document()->characterAt(pos + (end ? 1 : -1)); - int thisClass = charClass(c1, simple); - return (!onlyWords || thisClass != 0) - && (c2.isNull() || c2 == ParagraphSeparator || thisClass != charClass(c2, simple)); -} - -bool FakeVimHandler::Private::atWordBoundary(bool end, bool simple, const QTextCursor &tc) const -{ - return atBoundary(end, simple, true, tc); -} - -bool FakeVimHandler::Private::atWordStart(bool simple, const QTextCursor &tc) const -{ - return atWordBoundary(false, simple, tc); -} - -bool FakeVimHandler::Private::atWordEnd(bool simple, const QTextCursor &tc) const -{ - return atWordBoundary(true, simple, tc); -} - -bool FakeVimHandler::Private::isFirstNonBlankOnLine(int pos) -{ - for (int i = document()->findBlock(pos).position(); i < pos; ++i) { - if (!document()->characterAt(i).isSpace()) - return false; - } - return true; -} - -void FakeVimHandler::Private::pushUndoState(bool overwrite) -{ - if (m_buffer->editBlockLevel != 0 && m_buffer->undoState.isValid()) - return; // No need to save undo state for inner edit blocks. - - if (m_buffer->undoState.isValid() && !overwrite) - return; - - UNDO_DEBUG("PUSH UNDO"); - int pos = position(); - if (!isInsertMode()) { - if (isVisualMode() || g.submode == DeleteSubMode - || (g.submode == ChangeSubMode && g.movetype != MoveLineWise)) { - pos = qMin(pos, anchor()); - if (isVisualLineMode()) - pos = firstPositionInLine(lineForPosition(pos)); - } else if (g.movetype == MoveLineWise && hasConfig(ConfigStartOfLine)) { - QTextCursor tc = m_cursor; - if (g.submode == ShiftLeftSubMode || g.submode == ShiftRightSubMode - || g.submode == IndentSubMode) { - pos = qMin(pos, anchor()); - } - tc.setPosition(pos); - moveToFirstNonBlankOnLine(&tc); - pos = qMin(pos, tc.position()); - } - } - - m_buffer->redo.clear(); - m_buffer->lastChangePosition = CursorPosition(document(), pos); - if (isVisualMode()) { - setMark(QLatin1Char('<'), markLessPosition()); - setMark(QLatin1Char('>'), markGreaterPosition()); - } - m_buffer->undoState = State(revision(), m_buffer->lastChangePosition, m_buffer->marks, - m_buffer->lastVisualMode, m_buffer->lastVisualModeInverted); -} - -void FakeVimHandler::Private::moveDown(int n) -{ - if (n == 0) - return; - - QTextBlock block = m_cursor.block(); - const int col = position() - block.position(); - - int lines = qAbs(n); - int position = 0; - while (block.isValid()) { - position = block.position() + qMax(0, qMin(block.length() - 2, col)); - if (block.isVisible()) { - --lines; - if (lines < 0) - break; - } - block = n > 0 ? nextLine(block) : previousLine(block); - } - - setPosition(position); - moveToTargetColumn(); - updateScrollOffset(); -} - -void FakeVimHandler::Private::moveDownVisually(int n) -{ - const QTextCursor::MoveOperation moveOperation = (n > 0) ? Down : Up; - int count = qAbs(n); - int oldPos = m_cursor.position(); - - while (count > 0) { - m_cursor.movePosition(moveOperation, KeepAnchor, 1); - if (oldPos == m_cursor.position()) - break; - oldPos = m_cursor.position(); - QTextBlock block = m_cursor.block(); - if (block.isVisible()) - --count; - } - - QTextCursor tc = m_cursor; - tc.movePosition(StartOfLine); - const int minPos = tc.position(); - moveToEndOfLineVisually(&tc); - const int maxPos = tc.position(); - - if (m_targetColumn == -1) { - setPosition(maxPos); - } else { - setPosition(qMin(maxPos, minPos + m_targetColumnWrapped)); - const int targetColumn = m_targetColumnWrapped; - setTargetColumn(); - m_targetColumnWrapped = targetColumn; - } - - updateScrollOffset(); -} - -void FakeVimHandler::Private::movePageDown(int count) -{ - const int scrollOffset = windowScrollOffset(); - const int screenLines = linesOnScreen(); - const int offset = count > 0 ? scrollOffset - 2 : screenLines - scrollOffset + 2; - const int value = count * screenLines - cursorLineOnScreen() + offset; - moveDown(value); - - if (count > 0) - scrollToLine(cursorLine()); - else - scrollToLine(qMax(0, cursorLine() - screenLines + 1)); -} - -bool FakeVimHandler::Private::moveToNextParagraph(int count) -{ - const bool forward = count > 0; - int repeat = forward ? count : -count; - int pos = position(); - QTextBlock block = this->block(); - - if (block.isValid() && block.length() == 1) - ++repeat; - - for (; block.isValid(); block = forward ? block.next() : block.previous()) { - if (block.length() == 1) { - if (--repeat == 0) - break; - while (block.isValid() && block.length() == 1) - block = forward ? block.next() : block.previous(); - } - } - - if (repeat == 0) - setPosition(block.position()); - else if (repeat == 1) - setPosition(forward ? lastPositionInDocument() : 0); - else - return false; - - recordJump(pos); - setTargetColumn(); - g.movetype = MoveExclusive; - - return true; -} - -void FakeVimHandler::Private::moveToEndOfLine() -{ - // Additionally select (in visual mode) or apply current command on hidden lines following - // the current line. - bool onlyVisibleLines = isVisualMode() || g.submode != NoSubMode; - const int id = onlyVisibleLines ? lineNumber(block()) : block().blockNumber() + 1; - setPosition(lastPositionInLine(id, onlyVisibleLines)); - setTargetColumn(); -} - -void FakeVimHandler::Private::moveToEndOfLineVisually() -{ - moveToEndOfLineVisually(&m_cursor); - setTargetColumn(); -} - -void FakeVimHandler::Private::moveToEndOfLineVisually(QTextCursor *tc) -{ - // Moving to end of line ends up on following line if the line is wrapped. - tc->movePosition(StartOfLine); - const int minPos = tc->position(); - tc->movePosition(EndOfLine); - int maxPos = tc->position(); - tc->movePosition(StartOfLine); - if (minPos != tc->position()) - --maxPos; - tc->setPosition(maxPos); -} - -void FakeVimHandler::Private::moveBehindEndOfLine() -{ - emit q->fold(1, false); - int pos = qMin(block().position() + block().length() - 1, - lastPositionInDocument() + 1); - setPosition(pos); -} - -void FakeVimHandler::Private::moveToStartOfLine() -{ - setPosition(block().position()); - setTargetColumn(); -} - -void FakeVimHandler::Private::moveToStartOfLineVisually() -{ - m_cursor.movePosition(StartOfLine, KeepAnchor); - setTargetColumn(); -} - -void FakeVimHandler::Private::fixSelection() -{ - if (g.rangemode == RangeBlockMode) - return; - - if (g.movetype == MoveInclusive) { - // If position or anchor is after end of non-empty line, include line break in selection. - if (document()->characterAt(position()) == ParagraphSeparator) { - if (!atEmptyLine()) { - setPosition(position() + 1); - return; - } - } else if (document()->characterAt(anchor()) == ParagraphSeparator) { - QTextCursor tc = m_cursor; - tc.setPosition(anchor()); - if (!atEmptyLine(tc)) { - setAnchorAndPosition(anchor() + 1, position()); - return; - } - } - } - - if (g.movetype == MoveExclusive && g.subsubmode == NoSubSubMode) { - if (anchor() < position() && atBlockStart()) { - // Exclusive motion ending at the beginning of line - // becomes inclusive and end is moved to end of previous line. - g.movetype = MoveInclusive; - moveToStartOfLine(); - moveLeft(); - - // Exclusive motion ending at the beginning of line and - // starting at or before first non-blank on a line becomes linewise. - if (anchor() < block().position() && isFirstNonBlankOnLine(anchor())) - g.movetype = MoveLineWise; - } - } - - if (g.movetype == MoveLineWise) - g.rangemode = (g.submode == ChangeSubMode) - ? RangeLineModeExclusive - : RangeLineMode; - - if (g.movetype == MoveInclusive) { - if (anchor() <= position()) { - if (!atBlockEnd()) - setPosition(position() + 1); // correction - - // Omit first character in selection if it's line break on non-empty line. - int start = anchor(); - int end = position(); - if (afterEndOfLine(document(), start) && start > 0) { - start = qMin(start + 1, end); - if (g.submode == DeleteSubMode && !atDocumentEnd()) - setAnchorAndPosition(start, end + 1); - else - setAnchorAndPosition(start, end); - } - - // If more than one line is selected and all are selected completely - // movement becomes linewise. - if (start < block().position() && isFirstNonBlankOnLine(start) && atBlockEnd()) { - if (g.submode != ChangeSubMode) { - moveRight(); - if (atEmptyLine()) - moveRight(); - } - g.movetype = MoveLineWise; - } - } else if (!m_anchorPastEnd) { - setAnchorAndPosition(anchor() + 1, position()); - } - } - - if (m_positionPastEnd) { - moveBehindEndOfLine(); - moveRight(); - setAnchorAndPosition(anchor(), position()); - } - - if (m_anchorPastEnd) { - const int pos = position(); - setPosition(anchor()); - moveBehindEndOfLine(); - moveRight(); - setAnchorAndPosition(position(), pos); - } -} - -bool FakeVimHandler::Private::finishSearch() -{ - if (g.lastSearch.isEmpty() - || (!g.currentMessage.isEmpty() && g.currentMessageLevel == MessageError)) { - return false; - } - if (g.submode != NoSubMode) - setAnchorAndPosition(m_searchStartPosition, position()); - return true; -} - -void FakeVimHandler::Private::finishMovement(const QString &dotCommandMovement) -{ - //dump("FINISH MOVEMENT"); - if (g.submode == FilterSubMode) { - int beginLine = lineForPosition(anchor()); - int endLine = lineForPosition(position()); - setPosition(qMin(anchor(), position())); - enterExMode(QString::fromLatin1(".,+%1!").arg(qAbs(endLine - beginLine))); - return; - } - - if (g.submode == ChangeSubMode - || g.submode == DeleteSubMode - || g.submode == YankSubMode - || g.submode == InvertCaseSubMode - || g.submode == DownCaseSubMode - || g.submode == UpCaseSubMode) { - fixSelection(); - - if (g.submode != InvertCaseSubMode - && g.submode != DownCaseSubMode - && g.submode != UpCaseSubMode) { - yankText(currentRange(), m_register); - if (g.movetype == MoveLineWise) - setRegister(m_register, registerContents(m_register), RangeLineMode); - } - - m_positionPastEnd = m_anchorPastEnd = false; - } - - QString dotCommand; - if (g.submode == ChangeSubMode) { - pushUndoState(false); - beginEditBlock(); - removeText(currentRange()); - dotCommand = _("c"); - if (g.movetype == MoveLineWise) - insertAutomaticIndentation(true); - endEditBlock(); - setTargetColumn(); - } else if (g.submode == DeleteSubMode) { - pushUndoState(false); - beginEditBlock(); - const int pos = position(); - // Always delete something (e.g. 'dw' on an empty line deletes the line). - if (pos == anchor() && g.movetype == MoveInclusive) - removeText(Range(pos, pos + 1)); - else - removeText(currentRange()); - dotCommand = _("d"); - if (g.movetype == MoveLineWise) - handleStartOfLine(); - if (atEndOfLine()) - moveLeft(); - else - setTargetColumn(); - endEditBlock(); - } else if (g.submode == YankSubMode) { - bool isVisualModeYank = isVisualMode(); - leaveVisualMode(); - const QTextCursor tc = m_cursor; - if (g.rangemode == RangeBlockMode) { - const int pos1 = tc.block().position(); - const int pos2 = document()->findBlock(tc.anchor()).position(); - const int col = qMin(tc.position() - pos1, tc.anchor() - pos2); - setPosition(qMin(pos1, pos2) + col); - } else { - setPosition(qMin(position(), anchor())); - if (g.rangemode == RangeLineMode) { - if (isVisualModeYank) - moveToStartOfLine(); - } - } - setTargetColumn(); - } else if (g.submode == InvertCaseSubMode - || g.submode == UpCaseSubMode - || g.submode == DownCaseSubMode) { - beginEditBlock(); - if (g.submode == InvertCaseSubMode) { - invertCase(currentRange()); - dotCommand = QString::fromLatin1("g~"); - } else if (g.submode == DownCaseSubMode) { - downCase(currentRange()); - dotCommand = QString::fromLatin1("gu"); - } else if (g.submode == UpCaseSubMode) { - upCase(currentRange()); - dotCommand = QString::fromLatin1("gU"); - } - if (g.movetype == MoveLineWise) - handleStartOfLine(); - endEditBlock(); - } else if (g.submode == IndentSubMode - || g.submode == ShiftRightSubMode - || g.submode == ShiftLeftSubMode) { - recordJump(); - pushUndoState(false); - if (g.submode == IndentSubMode) { - indentSelectedText(); - dotCommand = _("="); - } else if (g.submode == ShiftRightSubMode) { - shiftRegionRight(1); - dotCommand = _(">"); - } else if (g.submode == ShiftLeftSubMode) { - shiftRegionLeft(1); - dotCommand = _("<"); - } - } - - if (!dotCommand.isEmpty() && !dotCommandMovement.isEmpty()) - setDotCommand(dotCommand + dotCommandMovement); - - // Change command continues in insert mode. - if (g.submode == ChangeSubMode) { - clearCommandMode(); - enterInsertMode(); - } else { - resetCommandMode(); - } -} - -void FakeVimHandler::Private::resetCommandMode() -{ - if (g.returnToMode == CommandMode) { - enterCommandMode(); - } else { - clearCommandMode(); - const QString lastInsertion = m_buffer->lastInsertion; - if (g.returnToMode == InsertMode) - enterInsertMode(); - else - enterReplaceMode(); - moveToTargetColumn(); - invalidateInsertState(); - m_buffer->lastInsertion = lastInsertion; - } - if (isNoVisualMode()) - setAnchor(); -} - -void FakeVimHandler::Private::clearCommandMode() -{ - g.submode = NoSubMode; - g.subsubmode = NoSubSubMode; - g.movetype = MoveInclusive; - g.gflag = false; - m_register = '"'; - g.rangemode = RangeCharMode; - g.currentCommand.clear(); - resetCount(); -} - -void FakeVimHandler::Private::updateSelection() -{ - QList selections = m_extraSelections; - if (hasConfig(ConfigShowMarks)) { - for (MarksIterator it(m_buffer->marks); it.hasNext(); ) { - it.next(); - QTextEdit::ExtraSelection sel; - sel.cursor = m_cursor; - setCursorPosition(&sel.cursor, it.value().position(document())); - sel.cursor.setPosition(sel.cursor.position(), MoveAnchor); - sel.cursor.movePosition(Right, KeepAnchor); - sel.format = m_cursor.blockCharFormat(); - sel.format.setForeground(Qt::blue); - sel.format.setBackground(Qt::green); - selections.append(sel); - } - } - //qDebug() << "SELECTION: " << selections; - emit q->selectionChanged(selections); -} - -void FakeVimHandler::Private::updateHighlights() -{ - if (hasConfig(ConfigUseCoreSearch) || !hasConfig(ConfigHlSearch) || g.highlightsCleared) { - if (m_highlighted.isEmpty()) - return; - m_highlighted.clear(); - } else if (m_highlighted != g.lastNeedle) { - m_highlighted = g.lastNeedle; - } else { - return; - } - - emit q->highlightMatches(m_highlighted); -} - -void FakeVimHandler::Private::updateMiniBuffer() -{ - if (!m_textedit && !m_plaintextedit) - return; - - QString msg; - int cursorPos = -1; - int anchorPos = -1; - MessageLevel messageLevel = MessageMode; - - if (!g.mapStates.isEmpty() && g.mapStates.last().silent && g.currentMessageLevel < MessageInfo) - g.currentMessage.clear(); - - if (g.passing) { - msg = _("PASSING"); - } else if (g.subsubmode == SearchSubSubMode) { - msg = g.searchBuffer.display(); - if (g.mapStates.isEmpty()) { - cursorPos = g.searchBuffer.cursorPos() + 1; - anchorPos = g.searchBuffer.anchorPos() + 1; - } - } else if (g.mode == ExMode) { - msg = g.commandBuffer.display(); - if (g.mapStates.isEmpty()) { - cursorPos = g.commandBuffer.cursorPos() + 1; - anchorPos = g.commandBuffer.anchorPos() + 1; - } - } else if (!g.currentMessage.isEmpty()) { - msg = g.currentMessage; - g.currentMessage.clear(); - messageLevel = g.currentMessageLevel; - } else if (!g.mapStates.isEmpty() && !g.mapStates.last().silent) { - // Do not reset previous message when after running a mapped command. - return; - } else if (g.mode == CommandMode && !g.currentCommand.isEmpty() && hasConfig(ConfigShowCmd)) { - msg = g.currentCommand; - messageLevel = MessageShowCmd; - } else if (g.mode == CommandMode && isVisualMode()) { - if (isVisualCharMode()) - msg = _("-- VISUAL --"); - else if (isVisualLineMode()) - msg = _("-- VISUAL LINE --"); - else if (isVisualBlockMode()) - msg = _("VISUAL BLOCK"); - } else if (g.mode == InsertMode) { - msg = _("-- INSERT --"); - } else if (g.mode == ReplaceMode) { - msg = _("-- REPLACE --"); - } else { - QTC_CHECK(g.mode == CommandMode && g.subsubmode != SearchSubSubMode); - if (g.returnToMode == CommandMode) - msg = _("-- COMMAND --"); - else if (g.returnToMode == InsertMode) - msg = _("-- (insert) --"); - else - msg = _("-- (replace) --"); - } - - if (!g.recording.isNull() && msg.startsWith(_("--"))) - msg.append(_("recording")); - - emit q->commandBufferChanged(msg, cursorPos, anchorPos, messageLevel, q); - - int linesInDoc = linesInDocument(); - int l = cursorLine(); - QString status; - const QString pos = QString::fromLatin1("%1,%2") - .arg(l + 1).arg(physicalCursorColumn() + 1); - // FIXME: physical "-" logical - if (linesInDoc != 0) - status = FakeVimHandler::tr("%1%2%").arg(pos, -10).arg(l * 100 / linesInDoc, 4); - else - status = FakeVimHandler::tr("%1All").arg(pos, -10); - emit q->statusDataChanged(status); -} - -void FakeVimHandler::Private::showMessage(MessageLevel level, const QString &msg) -{ - //qDebug() << "MSG: " << msg; - g.currentMessage = msg; - g.currentMessageLevel = level; -} - -void FakeVimHandler::Private::notImplementedYet() -{ - qDebug() << "Not implemented in FakeVim"; - showMessage(MessageError, FakeVimHandler::tr("Not implemented in FakeVim.")); -} - -void FakeVimHandler::Private::passShortcuts(bool enable) -{ - g.passing = enable; - updateMiniBuffer(); - if (enable) - QCoreApplication::instance()->installEventFilter(q); - else - QCoreApplication::instance()->removeEventFilter(q); -} - -bool FakeVimHandler::Private::handleCommandSubSubMode(const Input &input) -{ - //const int key = input.key; - bool handled = true; - if (g.subsubmode == FtSubSubMode) { - g.semicolonType = g.subsubdata; - g.semicolonKey = input.text(); - bool valid = handleFfTt(g.semicolonKey); - g.subsubmode = NoSubSubMode; - if (!valid) { - g.submode = NoSubMode; - resetCommandMode(); - handled = false; - } else { - finishMovement(QString::fromLatin1("%1%2%3") - .arg(count()) - .arg(g.semicolonType.text()) - .arg(g.semicolonKey)); - } - } else if (g.subsubmode == TextObjectSubSubMode) { - bool ok = true; - if (input.is('w')) - selectWordTextObject(g.subsubdata.is('i')); - else if (input.is('W')) - selectWORDTextObject(g.subsubdata.is('i')); - else if (input.is('s')) - selectSentenceTextObject(g.subsubdata.is('i')); - else if (input.is('p')) - selectParagraphTextObject(g.subsubdata.is('i')); - else if (input.is('[') || input.is(']')) - ok = selectBlockTextObject(g.subsubdata.is('i'), '[', ']'); - else if (input.is('(') || input.is(')') || input.is('b')) - ok = selectBlockTextObject(g.subsubdata.is('i'), '(', ')'); - else if (input.is('<') || input.is('>')) - ok = selectBlockTextObject(g.subsubdata.is('i'), '<', '>'); - else if (input.is('{') || input.is('}') || input.is('B')) - ok = selectBlockTextObject(g.subsubdata.is('i'), '{', '}'); - else if (input.is('"') || input.is('\'') || input.is('`')) - ok = selectQuotedStringTextObject(g.subsubdata.is('i'), input.asChar()); - else - ok = false; - g.subsubmode = NoSubSubMode; - if (ok) { - finishMovement(QString::fromLatin1("%1%2%3") - .arg(count()) - .arg(g.subsubdata.text()) - .arg(input.text())); - } else { - resetCommandMode(); - handled = false; - } - } else if (g.subsubmode == MarkSubSubMode) { - setMark(input.asChar(), CursorPosition(m_cursor)); - g.subsubmode = NoSubSubMode; - } else if (g.subsubmode == BackTickSubSubMode - || g.subsubmode == TickSubSubMode) { - if (jumpToMark(input.asChar(), g.subsubmode == BackTickSubSubMode)) { - finishMovement(); - } else { - resetCommandMode(); - handled = false; - } - g.subsubmode = NoSubSubMode; - } else if (g.subsubmode == ZSubSubMode) { - handled = false; - if (input.is('j') || input.is('k')) { - int pos = position(); - emit q->foldGoTo(input.is('j') ? count() : -count(), false); - if (pos != position()) { - handled = true; - finishMovement(QString::fromLatin1("%1z%2") - .arg(count()) - .arg(input.text())); - } - } - } else if (g.subsubmode == OpenSquareSubSubMode || g.subsubmode == CloseSquareSubSubMode) { - int pos = position(); - if (input.is('{') && g.subsubmode == OpenSquareSubSubMode) - searchBalanced(false, QLatin1Char('{'), QLatin1Char('}')); - else if (input.is('}') && g.subsubmode == CloseSquareSubSubMode) - searchBalanced(true, QLatin1Char('}'), QLatin1Char('{')); - else if (input.is('(') && g.subsubmode == OpenSquareSubSubMode) - searchBalanced(false, QLatin1Char('('), QLatin1Char(')')); - else if (input.is(')') && g.subsubmode == CloseSquareSubSubMode) - searchBalanced(true, QLatin1Char(')'), QLatin1Char('(')); - else if (input.is('[') && g.subsubmode == OpenSquareSubSubMode) - bracketSearchBackward(&m_cursor, _("^\\{"), count()); - else if (input.is('[') && g.subsubmode == CloseSquareSubSubMode) - bracketSearchForward(&m_cursor, _("^\\}"), count(), false); - else if (input.is(']') && g.subsubmode == OpenSquareSubSubMode) - bracketSearchBackward(&m_cursor, _("^\\}"), count()); - else if (input.is(']') && g.subsubmode == CloseSquareSubSubMode) - bracketSearchForward(&m_cursor, _("^\\{"), count(), g.submode != NoSubMode); - else if (input.is('z')) - emit q->foldGoTo(g.subsubmode == OpenSquareSubSubMode ? -count() : count(), true); - handled = pos != position(); - if (handled) { - if (lineForPosition(pos) != lineForPosition(position())) - recordJump(pos); - finishMovement(QString::fromLatin1("%1%2%3") - .arg(count()) - .arg(g.subsubmode == OpenSquareSubSubMode ? '[' : ']') - .arg(input.text())); - } - } else { - handled = false; - } - return handled; -} - -bool FakeVimHandler::Private::handleCount(const Input &input) -{ - if (!isInputCount(input)) - return false; - g.mvcount = g.mvcount * 10 + input.text().toInt(); - return true; -} - -bool FakeVimHandler::Private::handleMovement(const Input &input) -{ - bool handled = true; - QString movement; - int count = this->count(); - - if (handleCount(input)) { - return true; - } else if (input.is('0')) { - g.movetype = MoveExclusive; - if (g.gflag) - moveToStartOfLineVisually(); - else - moveToStartOfLine(); - count = 1; - } else if (input.is('a') || input.is('i')) { - g.subsubmode = TextObjectSubSubMode; - g.subsubdata = input; - } else if (input.is('^') || input.is('_')) { - if (g.gflag) - moveToFirstNonBlankOnLineVisually(); - else - moveToFirstNonBlankOnLine(); - g.movetype = MoveExclusive; - } else if (0 && input.is(',')) { - // FIXME: fakevim uses ',' by itself, so it is incompatible - g.subsubmode = FtSubSubMode; - // HACK: toggle 'f' <-> 'F', 't' <-> 'T' - //g.subsubdata = g.semicolonType ^ 32; - handleFfTt(g.semicolonKey, true); - g.subsubmode = NoSubSubMode; - } else if (input.is(';')) { - g.subsubmode = FtSubSubMode; - g.subsubdata = g.semicolonType; - handleFfTt(g.semicolonKey, true); - g.subsubmode = NoSubSubMode; - } else if (input.is('/') || input.is('?')) { - g.lastSearchForward = input.is('/'); - if (hasConfig(ConfigUseCoreSearch)) { - // re-use the core dialog. - g.findPending = true; - m_findStartPosition = position(); - g.movetype = MoveExclusive; - setAnchor(); // clear selection: otherwise, search is restricted to selection - emit q->findRequested(!g.lastSearchForward); - } else { - // FIXME: make core find dialog sufficiently flexible to - // produce the "default vi" behaviour too. For now, roll our own. - g.currentMessage.clear(); - g.movetype = MoveExclusive; - g.subsubmode = SearchSubSubMode; - g.searchBuffer.setPrompt(g.lastSearchForward ? QLatin1Char('/') : QLatin1Char('?')); - m_searchStartPosition = position(); - m_searchFromScreenLine = firstVisibleLine(); - m_searchCursor = QTextCursor(); - g.searchBuffer.clear(); - } - } else if (input.is('`')) { - g.subsubmode = BackTickSubSubMode; - } else if (input.is('#') || input.is('*')) { - // FIXME: That's not proper vim behaviour - QString needle; - QTextCursor tc = m_cursor; - tc.select(QTextCursor::WordUnderCursor); - needle = QRegExp::escape(tc.selection().toPlainText()); - if (!g.gflag) - needle = _("\\<") + needle + _("\\>"); - setAnchorAndPosition(tc.position(), tc.anchor()); - g.searchBuffer.historyPush(needle); - g.lastSearch = needle; - g.lastSearchForward = input.is('*'); - handled = searchNext(); - } else if (input.is('\'')) { - g.subsubmode = TickSubSubMode; - if (g.submode != NoSubMode) - g.movetype = MoveLineWise; - } else if (input.is('|')) { - moveToStartOfLine(); - moveRight(qMin(count, rightDist()) - 1); - setTargetColumn(); - } else if (input.is('}')) { - handled = moveToNextParagraph(count); - } else if (input.is('{')) { - handled = moveToPreviousParagraph(count); - } else if (input.isReturn()) { - moveToStartOfLine(); - moveDown(); - moveToFirstNonBlankOnLine(); - g.movetype = MoveLineWise; - } else if (input.is('-')) { - moveToStartOfLine(); - moveUp(count); - moveToFirstNonBlankOnLine(); - g.movetype = MoveLineWise; - } else if (input.is('+')) { - moveToStartOfLine(); - moveDown(count); - moveToFirstNonBlankOnLine(); - g.movetype = MoveLineWise; - } else if (input.isKey(Key_Home)) { - moveToStartOfLine(); - setTargetColumn(); - movement = _(""); - } else if (input.is('$') || input.isKey(Key_End)) { - if (g.gflag) { - if (count > 1) - moveDownVisually(count - 1); - moveToEndOfLineVisually(); - } else { - if (count > 1) - moveDown(count - 1); - moveToEndOfLine(); - } - g.movetype = atEmptyLine() ? MoveExclusive : MoveInclusive; - setTargetColumn(); - if (g.submode == NoSubMode) - m_targetColumn = -1; - if (isVisualMode()) - m_visualTargetColumn = -1; - movement = _("$"); - } else if (input.is('%')) { - recordJump(); - if (g.mvcount == 0) { - moveToMatchingParanthesis(); - g.movetype = MoveInclusive; - } else { - // set cursor position in percentage - formula taken from Vim help - setPosition(firstPositionInLine((count * linesInDocument() + 99) / 100)); - moveToTargetColumn(); - handleStartOfLine(); - g.movetype = MoveLineWise; - } - } else if (input.is('b') || input.isShift(Key_Left)) { - g.movetype = MoveExclusive; - moveToNextWordStart(count, false, false); - setTargetColumn(); - movement = _("b"); - } else if (input.is('B')) { - g.movetype = MoveExclusive; - moveToNextWordStart(count, true, false); - setTargetColumn(); - } else if (input.is('e') && g.gflag) { - g.movetype = MoveInclusive; - moveToNextWordEnd(count, false, false); - setTargetColumn(); - } else if (input.is('e') || input.isShift(Key_Right)) { - g.movetype = MoveInclusive; - moveToNextWordEnd(count, false, true, false); - setTargetColumn(); - movement = _("e"); - } else if (input.is('E') && g.gflag) { - g.movetype = MoveInclusive; - moveToNextWordEnd(count, true, false); - setTargetColumn(); - } else if (input.is('E')) { - g.movetype = MoveInclusive; - moveToNextWordEnd(count, true, true, false); - setTargetColumn(); - } else if (input.isControl('e')) { - // FIXME: this should use the "scroll" option, and "count" - if (cursorLineOnScreen() == 0) - moveDown(1); - scrollDown(1); - movement = _(""); - } else if (input.is('f')) { - g.subsubmode = FtSubSubMode; - g.movetype = MoveInclusive; - g.subsubdata = input; - } else if (input.is('F')) { - g.subsubmode = FtSubSubMode; - g.movetype = MoveExclusive; - g.subsubdata = input; - } else if (!g.gflag && input.is('g')) { - g.gflag = true; - return true; - } else if (input.is('g') || input.is('G')) { - QString dotCommand = QString::fromLatin1("%1G").arg(count); - recordJump(); - if (input.is('G') && g.mvcount == 0) - dotCommand = QString(QLatin1Char('G')); - int n = (input.is('g')) ? 1 : linesInDocument(); - n = g.mvcount == 0 ? n : count; - if (g.submode == NoSubMode || g.submode == ZSubMode - || g.submode == CapitalZSubMode || g.submode == RegisterSubMode) { - setPosition(firstPositionInLine(n, false)); - handleStartOfLine(); - } else { - g.movetype = MoveLineWise; - g.rangemode = RangeLineMode; - setAnchor(); - setPosition(firstPositionInLine(n, false)); - } - setTargetColumn(); - updateScrollOffset(); - } else if (input.is('h') || input.isKey(Key_Left) || input.isBackspace()) { - g.movetype = MoveExclusive; - int n = qMin(count, leftDist()); - if (m_fakeEnd && block().length() > 1) - ++n; - moveLeft(n); - setTargetColumn(); - movement = _("h"); - } else if (input.is('H')) { - const CursorPosition pos(lineToBlockNumber(lineOnTop(count)), 0); - setCursorPosition(&m_cursor, pos); - handleStartOfLine(); - } else if (input.is('j') || input.isKey(Key_Down) - || input.isControl('j') || input.isControl('n')) { - if (g.gflag) { - g.movetype = MoveExclusive; - moveDownVisually(count); - movement = _("gj"); - } else { - g.movetype = MoveLineWise; - moveDown(count); - movement = _("j"); - } - } else if (input.is('k') || input.isKey(Key_Up) || input.isControl('p')) { - if (g.gflag) { - g.movetype = MoveExclusive; - moveUpVisually(count); - movement = _("gk"); - } else { - g.movetype = MoveLineWise; - moveUp(count); - movement = _("k"); - } - } else if (input.is('l') || input.isKey(Key_Right) || input.is(' ')) { - g.movetype = MoveExclusive; - bool pastEnd = count >= rightDist() - 1; - moveRight(qMax(0, qMin(count, rightDist() - (g.submode == NoSubMode)))); - setTargetColumn(); - if (pastEnd && isVisualMode()) - m_visualTargetColumn = -1; - } else if (input.is('L')) { - const CursorPosition pos(lineToBlockNumber(lineOnBottom(count)), 0); - setCursorPosition(&m_cursor, pos); - handleStartOfLine(); - } else if (g.gflag && input.is('m')) { - const QPoint pos(EDITOR(viewport()->width()) / 2, EDITOR(cursorRect(m_cursor)).y()); - QTextCursor tc = EDITOR(cursorForPosition(pos)); - if (!tc.isNull()) { - m_cursor = tc; - setTargetColumn(); - } - } else if (input.is('M')) { - m_cursor = EDITOR(cursorForPosition(QPoint(0, EDITOR(height()) / 2))); - handleStartOfLine(); - } else if (input.is('n') || input.is('N')) { - if (hasConfig(ConfigUseCoreSearch)) { - bool forward = (input.is('n')) ? g.lastSearchForward : !g.lastSearchForward; - int pos = position(); - emit q->findNextRequested(!forward); - if (forward && pos == m_cursor.selectionStart()) { - // if cursor is already positioned at the start of a find result, this is returned - emit q->findNextRequested(false); - } - setPosition(m_cursor.selectionStart()); - } else { - handled = searchNext(input.is('n')); - } - } else if (input.is('t')) { - g.movetype = MoveInclusive; - g.subsubmode = FtSubSubMode; - g.subsubdata = input; - } else if (input.is('T')) { - g.movetype = MoveExclusive; - g.subsubmode = FtSubSubMode; - g.subsubdata = input; - } else if (input.is('w') || input.is('W')) { // tested - // Special case: "cw" and "cW" work the same as "ce" and "cE" if the - // cursor is on a non-blank - except if the cursor is on the last - // character of a word: only the current word will be changed - bool simple = input.is('W'); - if (g.submode == ChangeSubMode && !document()->characterAt(position()).isSpace()) { - moveToWordEnd(count, simple, true); - g.movetype = MoveInclusive; - } else { - moveToNextWordStart(count, simple, true); - // Command 'dw' deletes to the next word on the same line or to end of line. - if (g.submode == DeleteSubMode && count == 1) { - const QTextBlock currentBlock = document()->findBlock(anchor()); - setPosition(qMin(position(), currentBlock.position() + currentBlock.length())); - } - g.movetype = MoveExclusive; - } - setTargetColumn(); - } else if (input.is('z')) { - g.movetype = MoveLineWise; - g.subsubmode = ZSubSubMode; - } else if (input.is('[')) { - g.subsubmode = OpenSquareSubSubMode; - } else if (input.is(']')) { - g.subsubmode = CloseSquareSubSubMode; - } else if (input.isKey(Key_PageDown) || input.isControl('f')) { - movePageDown(count); - handleStartOfLine(); - movement = _("f"); - } else if (input.isKey(Key_PageUp) || input.isControl('b')) { - movePageUp(count); - handleStartOfLine(); - movement = _("b"); - } else { - handled = false; - } - - if (handled && g.subsubmode == NoSubSubMode) { - if (g.submode == NoSubMode) { - resetCommandMode(); - } else { - // finish movement for sub modes - const QString dotMovement = - (count > 1 ? QString::number(count) : QString()) - + _(g.gflag ? "g" : "") - + (movement.isNull() ? QString(input.asChar()) : movement); - finishMovement(dotMovement); - setTargetColumn(); - } - } - - return handled; -} - -EventResult FakeVimHandler::Private::handleCommandMode(const Input &input) -{ - bool handled = false; - - bool clearGflag = g.gflag; - bool clearRegister = g.submode != RegisterSubMode; - bool clearCount = g.submode != RegisterSubMode && !isInputCount(input); - - // Process input for a sub-mode. - if (input.isEscape()) { - handled = handleEscape(); - } else if (g.subsubmode != NoSubSubMode) { - handled = handleCommandSubSubMode(input); - } else if (g.submode == NoSubMode) { - handled = handleNoSubMode(input); - } else if (g.submode == ChangeSubMode || g.submode == DeleteSubMode) { - handled = handleChangeDeleteSubModes(input); - } else if (g.submode == ReplaceSubMode) { - handled = handleReplaceSubMode(input); - } else if (g.submode == FilterSubMode) { - handled = handleFilterSubMode(input); - } else if (g.submode == RegisterSubMode) { - handled = handleRegisterSubMode(input); - } else if (g.submode == WindowSubMode) { - handled = handleWindowSubMode(input); - } else if (g.submode == YankSubMode) { - handled = handleYankSubMode(input); - } else if (g.submode == ZSubMode) { - handled = handleZSubMode(input); - } else if (g.submode == CapitalZSubMode) { - handled = handleCapitalZSubMode(input); - } else if (g.submode == MacroRecordSubMode) { - handled = handleMacroRecordSubMode(input); - } else if (g.submode == MacroExecuteSubMode) { - handled = handleMacroExecuteSubMode(input); - } else if (g.submode == ShiftLeftSubMode - || g.submode == ShiftRightSubMode - || g.submode == IndentSubMode) { - handled = handleShiftSubMode(input); - } else if (g.submode == InvertCaseSubMode - || g.submode == DownCaseSubMode - || g.submode == UpCaseSubMode) { - handled = handleChangeCaseSubMode(input); - } - - if (!handled && isOperatorPending()) - handled = handleMovement(input); - - // Clear state and display incomplete command if necessary. - if (handled) { - bool noMode = - (g.mode == CommandMode && g.submode == NoSubMode && g.subsubmode == NoSubSubMode); - clearCount = clearCount && noMode && !g.gflag; - if (clearCount && clearRegister) { - resetCommandMode(); - } else { - // Use gflag only for next input. - if (clearGflag) - g.gflag = false; - // Clear [count] and [register] if its no longer needed. - if (clearCount) - resetCount(); - // Show or clear current command on minibuffer (showcmd). - if (input.isEscape() || g.mode != CommandMode || clearCount) - g.currentCommand.clear(); - else - g.currentCommand.append(input.toString()); - } - } else { - resetCommandMode(); - //qDebug() << "IGNORED IN COMMAND MODE: " << key << text - // << " VISUAL: " << g.visualMode; - - // if a key which produces text was pressed, don't mark it as unhandled - // - otherwise the text would be inserted while being in command mode - if (input.text().isEmpty()) - handled = false; - } - - updateMiniBuffer(); - - m_positionPastEnd = (m_visualTargetColumn == -1) && isVisualMode() && !atEmptyLine(); - - return handled ? EventHandled : EventCancelled; -} - -bool FakeVimHandler::Private::handleEscape() -{ - if (isVisualMode()) - leaveVisualMode(); - resetCommandMode(); - return true; -} - -bool FakeVimHandler::Private::handleNoSubMode(const Input &input) -{ - bool handled = true; - - if (input.is('&')) { - handleExCommand(g.gflag ? _("%s//~/&") : _("s")); - } else if (input.is(':')) { - enterExMode(); - } else if (input.is('!') && isNoVisualMode()) { - g.submode = FilterSubMode; - } else if (input.is('!') && isVisualMode()) { - enterExMode(QString::fromLatin1("!")); - } else if (input.is('"')) { - g.submode = RegisterSubMode; - } else if (input.is(',')) { - passShortcuts(true); - } else if (input.is('.')) { - //qDebug() << "REPEATING" << quoteUnprintable(g.dotCommand) << count() - // << input; - QString savedCommand = g.dotCommand; - g.dotCommand.clear(); - beginLargeEditBlock(); - replay(savedCommand); - endEditBlock(); - resetCommandMode(); - g.dotCommand = savedCommand; - } else if (input.is('<') || input.is('>') || input.is('=')) { - if (isNoVisualMode()) { - if (input.is('<')) - g.submode = ShiftLeftSubMode; - else if (input.is('>')) - g.submode = ShiftRightSubMode; - else - g.submode = IndentSubMode; - setAnchor(); - } else { - leaveVisualMode(); - const int lines = qAbs(lineForPosition(position()) - lineForPosition(anchor())) + 1; - const int repeat = count(); - if (input.is('<')) - shiftRegionLeft(repeat); - else if (input.is('>')) - shiftRegionRight(repeat); - else - indentSelectedText(); - const QString selectDotCommand = - (lines > 1) ? QString::fromLatin1("V%1j").arg(lines - 1): QString(); - setDotCommand(selectDotCommand + QString::fromLatin1("%1%2%2").arg(repeat).arg(input.raw())); - } - } else if ((!isVisualMode() && input.is('a')) || (isVisualMode() && input.is('A'))) { - if (isVisualMode()) { - enterVisualInsertMode(QLatin1Char('A')); - } else { - setDotCommand(_("%1a"), count()); - moveRight(qMin(rightDist(), 1)); - breakEditBlock(); - enterInsertMode(); - } - } else if (input.is('A')) { - breakEditBlock(); - moveBehindEndOfLine(); - setAnchor(); - enterInsertMode(); - setTargetColumn(); - setDotCommand(_("%1A"), count()); - } else if (input.isControl('a')) { - if (changeNumberTextObject(count())) - setDotCommand(_("%1"), count()); - } else if ((input.is('c') || input.is('d')) && isNoVisualMode()) { - setAnchor(); - g.opcount = g.mvcount; - g.mvcount = 0; - g.rangemode = RangeCharMode; - g.movetype = MoveExclusive; - g.submode = input.is('c') ? ChangeSubMode : DeleteSubMode; - } else if ((input.is('c') || input.is('C') || input.is('s') || input.is('R')) - && (isVisualCharMode() || isVisualLineMode())) { - setDotCommand(visualDotCommand() + input.asChar()); - leaveVisualMode(); - g.submode = ChangeSubMode; - finishMovement(); - } else if ((input.is('c') || input.is('s')) && isVisualBlockMode()) { - resetCount(); - enterVisualInsertMode(input.asChar()); - } else if (input.is('C')) { - setAnchor(); - moveToEndOfLine(); - g.rangemode = RangeCharMode; - g.submode = ChangeSubMode; - setDotCommand(QString(QLatin1Char('C'))); - finishMovement(); - } else if (input.isControl('c')) { - if (isNoVisualMode()) - showMessage(MessageInfo, tr("Type Alt-V, Alt-V to quit FakeVim mode.")); - else - leaveVisualMode(); - } else if ((input.is('d') || input.is('x') || input.isKey(Key_Delete)) - && isVisualMode()) { - pushUndoState(); - setDotCommand(visualDotCommand() + QLatin1Char('x')); - if (isVisualCharMode()) { - leaveVisualMode(); - g.submode = DeleteSubMode; - finishMovement(); - } else if (isVisualLineMode()) { - leaveVisualMode(); - yankText(currentRange(), m_register); - removeText(currentRange()); - handleStartOfLine(); - } else if (isVisualBlockMode()) { - leaveVisualMode(); - yankText(currentRange(), m_register); - removeText(currentRange()); - setPosition(qMin(position(), anchor())); - } - } else if (input.is('D') && isNoVisualMode()) { - pushUndoState(); - if (atEndOfLine()) - moveLeft(); - g.submode = DeleteSubMode; - g.movetype = MoveInclusive; - setAnchorAndPosition(position(), lastPositionInLine(cursorLine() + count())); - setDotCommand(QString(QLatin1Char('D'))); - finishMovement(); - setTargetColumn(); - } else if ((input.is('D') || input.is('X')) && - (isVisualCharMode() || isVisualLineMode())) { - setDotCommand(visualDotCommand() + QLatin1Char('X')); - leaveVisualMode(); - g.rangemode = RangeLineMode; - g.submode = NoSubMode; - yankText(currentRange(), m_register); - removeText(currentRange()); - moveToFirstNonBlankOnLine(); - } else if ((input.is('D') || input.is('X')) && isVisualBlockMode()) { - setDotCommand(visualDotCommand() + QLatin1Char('X')); - leaveVisualMode(); - g.rangemode = RangeBlockAndTailMode; - yankText(currentRange(), m_register); - removeText(currentRange()); - setPosition(qMin(position(), anchor())); - } else if (input.isControl('d')) { - const int scrollOffset = windowScrollOffset(); - int sline = cursorLine() < scrollOffset ? scrollOffset : cursorLineOnScreen(); - // FIXME: this should use the "scroll" option, and "count" - moveDown(linesOnScreen() / 2); - handleStartOfLine(); - scrollToLine(cursorLine() - sline); - } else if (!g.gflag && input.is('g')) { - g.gflag = true; - } else if (!isVisualMode() && (input.is('i') || input.isKey(Key_Insert))) { - setDotCommand(_("%1i"), count()); - breakEditBlock(); - enterInsertMode(); - if (atEndOfLine()) - moveLeft(); - } else if (input.is('I')) { - if (isVisualMode()) { - enterVisualInsertMode(QLatin1Char('I')); - } else { - if (g.gflag) { - setDotCommand(_("%1gI"), count()); - moveToStartOfLine(); - } else { - setDotCommand(_("%1I"), count()); - moveToFirstNonBlankOnLine(); - } - breakEditBlock(); - enterInsertMode(); - } - } else if (input.isControl('i')) { - jump(count()); - } else if (input.is('J')) { - pushUndoState(); - moveBehindEndOfLine(); - beginEditBlock(); - if (g.submode == NoSubMode) - joinLines(count(), g.gflag); - endEditBlock(); - setDotCommand(_("%1J"), count()); - } else if (input.isControl('l')) { - // screen redraw. should not be needed - } else if (!g.gflag && input.is('m')) { - g.subsubmode = MarkSubSubMode; - } else if (isVisualMode() && (input.is('o') || input.is('O'))) { - int pos = position(); - setAnchorAndPosition(pos, anchor()); - std::swap(m_positionPastEnd, m_anchorPastEnd); - setTargetColumn(); - if (m_positionPastEnd) - m_visualTargetColumn = -1; - } else if (input.is('o') || input.is('O')) { - bool insertAfter = input.is('o'); - setDotCommand(_(insertAfter ? "%1o" : "%1O"), count()); - pushUndoState(); - - // Prepend line only if on the first line and command is 'O'. - bool appendLine = true; - if (!insertAfter) { - if (block().blockNumber() == 0) - appendLine = false; - else - moveUp(); - } - const int line = lineNumber(block()); - - beginEditBlock(); - enterInsertMode(); - setPosition(appendLine ? lastPositionInLine(line) : firstPositionInLine(line)); - clearLastInsertion(); - setAnchor(); - insertNewLine(); - if (appendLine) { - m_buffer->insertState.newLineBefore = true; - } else { - moveUp(); - m_oldInternalPosition = position(); - m_buffer->insertState.pos1 = m_oldInternalPosition; - m_buffer->insertState.newLineAfter = true; - } - setTargetColumn(); - endEditBlock(); - - // Close accidentally opened block. - if (block().blockNumber() > 0) { - moveUp(); - if (line != lineNumber(block())) - emit q->fold(1, true); - moveDown(); - } - } else if (input.isControl('o')) { - jump(-count()); - } else if (input.is('p') || input.is('P') || input.isShift(Qt::Key_Insert)) { - pasteText(!input.is('P')); - setTargetColumn(); - setDotCommand(_("%1p"), count()); - finishMovement(); - } else if (input.is('q')) { - if (g.recording.isNull()) { - // Recording shouldn't work in mapping or while executing register. - handled = g.mapStates.empty(); - if (handled) - g.submode = MacroRecordSubMode; - } else { - // Stop recording. - stopRecording(); - } - } else if (input.is('r')) { - g.submode = ReplaceSubMode; - } else if (!isVisualMode() && input.is('R')) { - pushUndoState(); - breakEditBlock(); - enterReplaceMode(); - } else if (input.isControl('r')) { - int repeat = count(); - while (--repeat >= 0) - redo(); - } else if (input.is('s')) { - pushUndoState(); - leaveVisualMode(); - if (atEndOfLine()) - moveLeft(); - setAnchor(); - moveRight(qMin(count(), rightDist())); - setDotCommand(_("%1s"), count()); - g.submode = ChangeSubMode; - g.movetype = MoveExclusive; - finishMovement(); - } else if (input.is('S')) { - g.movetype = MoveLineWise; - pushUndoState(); - if (!isVisualMode()) { - const int line = cursorLine() + 1; - const int anc = firstPositionInLine(line); - const int pos = lastPositionInLine(line + count() - 1); - setAnchorAndPosition(anc, pos); - } - setDotCommand(_("%1S"), count()); - g.submode = ChangeSubMode; - finishMovement(); - } else if (g.gflag && input.is('t')) { - handleExCommand(_("tabnext")); - } else if (g.gflag && input.is('T')) { - handleExCommand(_("tabprev")); - } else if (input.isControl('t')) { - handleExCommand(_("pop")); - } else if (!g.gflag && input.is('u') && !isVisualMode()) { - int repeat = count(); - while (--repeat >= 0) - undo(); - } else if (input.isControl('u')) { - int sline = cursorLineOnScreen(); - // FIXME: this should use the "scroll" option, and "count" - moveUp(linesOnScreen() / 2); - handleStartOfLine(); - scrollToLine(cursorLine() - sline); - } else if (g.gflag && input.is('v')) { - if (m_buffer->lastVisualMode != NoVisualMode) { - CursorPosition from = markLessPosition(); - CursorPosition to = markGreaterPosition(); - toggleVisualMode(m_buffer->lastVisualMode); - setCursorPosition(m_buffer->lastVisualModeInverted ? to : from); - setAnchor(); - setCursorPosition(m_buffer->lastVisualModeInverted ? from : to); - setTargetColumn(); - } - } else if (input.is('v')) { - toggleVisualMode(VisualCharMode); - } else if (input.is('V')) { - toggleVisualMode(VisualLineMode); - } else if (input.isControl('v')) { - toggleVisualMode(VisualBlockMode); - } else if (input.isControl('w')) { - g.submode = WindowSubMode; - } else if (input.is('x') && isNoVisualMode()) { // = _("dl") - g.movetype = MoveExclusive; - g.submode = DeleteSubMode; - const int n = qMin(count(), rightDist()); - setAnchorAndPosition(position(), position() + n); - setDotCommand(_("%1x"), count()); - finishMovement(); - } else if (input.isControl('x')) { - if (changeNumberTextObject(-count())) - setDotCommand(_("%1"), count()); - } else if (input.is('X')) { - if (leftDist() > 0) { - setAnchor(); - moveLeft(qMin(count(), leftDist())); - yankText(currentRange(), m_register); - removeText(currentRange()); - } - } else if (input.is('Y') && isNoVisualMode()) { - handleYankSubMode(Input(QLatin1Char('y'))); - } else if (input.isControl('y')) { - // FIXME: this should use the "scroll" option, and "count" - if (cursorLineOnScreen() == linesOnScreen() - 1) - moveUp(1); - scrollUp(1); - } else if (input.is('y') && isNoVisualMode()) { - setAnchor(); - g.rangemode = RangeCharMode; - g.movetype = MoveExclusive; - g.submode = YankSubMode; - } else if (input.is('y') && isVisualCharMode()) { - g.rangemode = RangeCharMode; - g.movetype = MoveInclusive; - g.submode = YankSubMode; - finishMovement(); - } else if ((input.is('y') && isVisualLineMode()) - || (input.is('Y') && isVisualLineMode()) - || (input.is('Y') && isVisualCharMode())) { - g.rangemode = RangeLineMode; - g.movetype = MoveLineWise; - g.submode = YankSubMode; - finishMovement(); - } else if ((input.is('y') || input.is('Y')) && isVisualBlockMode()) { - g.rangemode = RangeBlockMode; - g.movetype = MoveInclusive; - g.submode = YankSubMode; - finishMovement(); - } else if (input.is('z')) { - g.submode = ZSubMode; - } else if (input.is('Z')) { - g.submode = CapitalZSubMode; - } else if ((input.is('~') || input.is('u') || input.is('U'))) { - g.movetype = MoveExclusive; - pushUndoState(); - if (isVisualMode()) { - setDotCommand(visualDotCommand() + QString::number(count()) + input.raw()); - if (isVisualLineMode()) - g.rangemode = RangeLineMode; - else if (isVisualBlockMode()) - g.rangemode = RangeBlockMode; - leaveVisualMode(); - if (input.is('~')) - g.submode = InvertCaseSubMode; - else if (input.is('u')) - g.submode = DownCaseSubMode; - else if (input.is('U')) - g.submode = UpCaseSubMode; - finishMovement(); - } else if (g.gflag || (input.is('~') && hasConfig(ConfigTildeOp))) { - if (atEndOfLine()) - moveLeft(); - setAnchor(); - if (input.is('~')) - g.submode = InvertCaseSubMode; - else if (input.is('u')) - g.submode = DownCaseSubMode; - else if (input.is('U')) - g.submode = UpCaseSubMode; - } else { - beginEditBlock(); - if (atEndOfLine()) - moveLeft(); - setAnchor(); - moveRight(qMin(count(), rightDist())); - if (input.is('~')) { - const int pos = position(); - invertCase(currentRange()); - setPosition(pos); - } else if (input.is('u')) { - downCase(currentRange()); - } else if (input.is('U')) { - upCase(currentRange()); - } - setDotCommand(QString::fromLatin1("%1%2").arg(count()).arg(input.raw())); - endEditBlock(); - } - } else if (input.is('@')) { - g.submode = MacroExecuteSubMode; - } else if (input.isKey(Key_Delete)) { - setAnchor(); - moveRight(qMin(1, rightDist())); - removeText(currentRange()); - if (atEndOfLine()) - moveLeft(); - } else if (input.isControl(Key_BracketRight)) { - handleExCommand(_("tag")); - } else if (handleMovement(input)) { - // movement handled - } else { - handled = false; - } - - return handled; -} - -bool FakeVimHandler::Private::handleChangeDeleteSubModes(const Input &input) -{ - bool handled = false; - - if ((g.submode == ChangeSubMode && input.is('c')) - || (g.submode == DeleteSubMode && input.is('d'))) { - g.movetype = MoveLineWise; - pushUndoState(); - const int anc = firstPositionInLine(cursorLine() + 1); - moveDown(count() - 1); - const int pos = lastPositionInLine(cursorLine() + 1); - setAnchorAndPosition(anc, pos); - if (g.submode == ChangeSubMode) - setDotCommand(_("%1cc"), count()); - else - setDotCommand(_("%1dd"), count()); - finishMovement(); - g.submode = NoSubMode; - handled = true; - } - - return handled; -} - -bool FakeVimHandler::Private::handleReplaceSubMode(const Input &input) -{ - bool handled = true; - - setDotCommand(visualDotCommand() + QLatin1Char('r') + input.asChar()); - if (isVisualMode()) { - pushUndoState(); - if (isVisualLineMode()) - g.rangemode = RangeLineMode; - else if (isVisualBlockMode()) - g.rangemode = RangeBlockMode; - else - g.rangemode = RangeCharMode; - leaveVisualMode(); - Range range = currentRange(); - if (g.rangemode == RangeCharMode) - ++range.endPos; - Transformation tr = - &FakeVimHandler::Private::replaceByCharTransform; - transformText(range, tr, input.asChar()); - } else if (count() <= rightDist()) { - pushUndoState(); - setAnchor(); - moveRight(count()); - Range range = currentRange(); - if (input.isReturn()) { - beginEditBlock(); - replaceText(range, QString()); - insertText(QString::fromLatin1("\n")); - endEditBlock(); - } else { - replaceText(range, QString(count(), input.asChar())); - moveRight(count() - 1); - } - setTargetColumn(); - setDotCommand(_("%1r") + input.text(), count()); - } else { - handled = false; - } - g.submode = NoSubMode; - finishMovement(); - - return handled; -} - -bool FakeVimHandler::Private::handleFilterSubMode(const Input &) -{ - return false; -} - -bool FakeVimHandler::Private::handleRegisterSubMode(const Input &input) -{ - bool handled = false; - - QChar reg = input.asChar(); - if (QString::fromLatin1("*+.%#:-\"").contains(reg) || reg.isLetterOrNumber()) { - m_register = reg.unicode(); - g.rangemode = RangeLineMode; - handled = true; - } - g.submode = NoSubMode; - - return handled; -} - -bool FakeVimHandler::Private::handleShiftSubMode(const Input &input) -{ - bool handled = false; - if ((g.submode == ShiftLeftSubMode && input.is('<')) - || (g.submode == ShiftRightSubMode && input.is('>')) - || (g.submode == IndentSubMode && input.is('='))) { - g.movetype = MoveLineWise; - pushUndoState(); - moveDown(count() - 1); - setDotCommand(QString::fromLatin1("%2%1%1").arg(input.asChar()), count()); - finishMovement(); - handled = true; - g.submode = NoSubMode; - } - return handled; -} - -bool FakeVimHandler::Private::handleChangeCaseSubMode(const Input &input) -{ - bool handled = false; - if ((g.submode == InvertCaseSubMode && input.is('~')) - || (g.submode == DownCaseSubMode && input.is('u')) - || (g.submode == UpCaseSubMode && input.is('U'))) { - if (!isFirstNonBlankOnLine(position())) { - moveToStartOfLine(); - moveToFirstNonBlankOnLine(); - } - setTargetColumn(); - pushUndoState(); - setAnchor(); - setPosition(lastPositionInLine(cursorLine() + count()) + 1); - finishMovement(QString::fromLatin1("%1%2").arg(count()).arg(input.raw())); - handled = true; - g.submode = NoSubMode; - } - return handled; -} - -bool FakeVimHandler::Private::handleWindowSubMode(const Input &input) -{ - if (handleCount(input)) - return true; - - leaveVisualMode(); - emit q->windowCommandRequested(input.toString(), count()); - - g.submode = NoSubMode; - return true; -} - -bool FakeVimHandler::Private::handleYankSubMode(const Input &input) -{ - bool handled = false; - if (input.is('y')) { - g.movetype = MoveLineWise; - int endPos = firstPositionInLine(lineForPosition(position()) + count() - 1); - Range range(position(), endPos, RangeLineMode); - yankText(range, m_register); - g.submode = NoSubMode; - handled = true; - } - return handled; -} - -bool FakeVimHandler::Private::handleZSubMode(const Input &input) -{ - bool handled = true; - bool foldMaybeClosed = false; - if (input.isReturn() || input.is('t') - || input.is('-') || input.is('b') - || input.is('.') || input.is('z')) { - // Cursor line to top/center/bottom of window. - Qt::AlignmentFlag align; - if (input.isReturn() || input.is('t')) - align = Qt::AlignTop; - else if (input.is('.') || input.is('z')) - align = Qt::AlignVCenter; - else - align = Qt::AlignBottom; - const bool moveToNonBlank = (input.is('.') || input.isReturn() || input.is('-')); - const int line = g.mvcount == 0 ? -1 : firstPositionInLine(count()); - alignViewportToCursor(align, line, moveToNonBlank); - } else if (input.is('o') || input.is('c')) { - // Open/close current fold. - foldMaybeClosed = input.is('c'); - emit q->fold(count(), foldMaybeClosed); - } else if (input.is('O') || input.is('C')) { - // Recursively open/close current fold. - foldMaybeClosed = input.is('C'); - emit q->fold(-1, foldMaybeClosed); - } else if (input.is('a') || input.is('A')) { - // Toggle current fold. - foldMaybeClosed = true; - emit q->foldToggle(input.is('a') ? count() : -1); - } else if (input.is('R') || input.is('M')) { - // Open/close all folds in document. - foldMaybeClosed = input.is('M'); - emit q->foldAll(foldMaybeClosed); - } else if (input.is('j') || input.is('k')) { - emit q->foldGoTo(input.is('j') ? count() : -count(), false); - } else { - handled = false; - } - if (foldMaybeClosed) - ensureCursorVisible(); - g.submode = NoSubMode; - return handled; -} - -bool FakeVimHandler::Private::handleCapitalZSubMode(const Input &input) -{ - // Recognize ZZ and ZQ as aliases for ":x" and ":q!". - bool handled = true; - if (input.is('Z')) - handleExCommand(QString(QLatin1Char('x'))); - else if (input.is('Q')) - handleExCommand(_("q!")); - else - handled = false; - g.submode = NoSubMode; - return handled; -} - -bool FakeVimHandler::Private::handleMacroRecordSubMode(const Input &input) -{ - g.submode = NoSubMode; - return startRecording(input); -} - -bool FakeVimHandler::Private::handleMacroExecuteSubMode(const Input &input) -{ - g.submode = NoSubMode; - - bool result = true; - int repeat = count(); - while (result && --repeat >= 0) - result = executeRegister(input.asChar().unicode()); - - return result; -} - -EventResult FakeVimHandler::Private::handleInsertOrReplaceMode(const Input &input) -{ - if (position() < m_buffer->insertState.pos1 || position() > m_buffer->insertState.pos2) { - commitInsertState(); - invalidateInsertState(); - } - - if (g.mode == InsertMode) - handleInsertMode(input); - else - handleReplaceMode(input); - - if (!m_textedit && !m_plaintextedit) - return EventHandled; - - if (!isInsertMode() || m_buffer->breakEditBlock - || position() < m_buffer->insertState.pos1 || position() > m_buffer->insertState.pos2) { - commitInsertState(); - invalidateInsertState(); - breakEditBlock(); - m_visualBlockInsert = NoneBlockInsertMode; - } else if (m_oldInternalPosition == position()) { - setTargetColumn(); - } - - updateMiniBuffer(); - - // We don't want fancy stuff in insert mode. - return EventHandled; -} - -void FakeVimHandler::Private::handleReplaceMode(const Input &input) -{ - if (input.isEscape()) { - commitInsertState(); - moveLeft(qMin(1, leftDist())); - enterCommandMode(); - g.dotCommand.append(m_buffer->lastInsertion + _("")); - } else if (input.isKey(Key_Left)) { - moveLeft(); - setTargetColumn(); - } else if (input.isKey(Key_Right)) { - moveRight(); - setTargetColumn(); - } else if (input.isKey(Key_Up)) { - moveUp(); - } else if (input.isKey(Key_Down)) { - moveDown(); - } else if (input.isKey(Key_Insert)) { - g.mode = InsertMode; - } else if (input.isControl('o')) { - enterCommandMode(ReplaceMode); - } else { - joinPreviousEditBlock(); - if (!atEndOfLine()) { - setAnchor(); - moveRight(); - removeText(currentRange()); - } - const QString text = input.text(); - setAnchor(); - insertText(text); - endEditBlock(); - } -} - -void FakeVimHandler::Private::finishInsertMode() -{ - bool newLineAfter = m_buffer->insertState.newLineAfter; - bool newLineBefore = m_buffer->insertState.newLineBefore; - - // Repeat insertion [count] times. - // One instance was already physically inserted while typing. - if (!m_buffer->breakEditBlock && isInsertStateValid()) { - commitInsertState(); - - QString text = m_buffer->lastInsertion; - const QString dotCommand = g.dotCommand; - const int repeat = count() - 1; - m_buffer->lastInsertion.clear(); - joinPreviousEditBlock(); - - if (newLineAfter) { - text.chop(1); - text.prepend(_("\n")); - } else if (newLineBefore) { - text.prepend(_("")); - } - - replay(text, repeat); - - if (m_visualBlockInsert != NoneBlockInsertMode && !text.contains(QLatin1Char('\n'))) { - const CursorPosition lastAnchor = markLessPosition(); - const CursorPosition lastPosition = markGreaterPosition(); - bool change = m_visualBlockInsert == ChangeBlockInsertMode; - const int insertColumn = (m_visualBlockInsert == InsertBlockInsertMode || change) - ? qMin(lastPosition.column, lastAnchor.column) - : qMax(lastPosition.column, lastAnchor.column) + 1; - - CursorPosition pos(lastAnchor.line, insertColumn); - - if (change) - pos.column = m_buffer->insertState.pos1 - document()->findBlock(m_buffer->insertState.pos1).position(); - - // Cursor position after block insert is on the first selected line, - // last selected column for 's' command, otherwise first selected column. - const int endColumn = change ? qMax(0, m_cursor.positionInBlock() - 1) - : qMin(lastPosition.column, lastAnchor.column); - - while (pos.line < lastPosition.line) { - ++pos.line; - setCursorPosition(&m_cursor, pos); - if (m_visualBlockInsert == AppendToEndOfLineBlockInsertMode) { - moveToEndOfLine(); - } else if (m_visualBlockInsert == AppendBlockInsertMode) { - // Prepend spaces if necessary. - int spaces = pos.column - m_cursor.positionInBlock(); - if (spaces > 0) { - setAnchor(); - m_cursor.insertText(QString(_(" ")).repeated(spaces)); - } - } else if (m_cursor.positionInBlock() != pos.column) { - continue; - } - replay(text, repeat + 1); - } - - setCursorPosition(CursorPosition(lastAnchor.line, endColumn)); - } else { - moveLeft(qMin(1, leftDist())); - } - - endEditBlock(); - breakEditBlock(); - - m_buffer->lastInsertion = text; - g.dotCommand = dotCommand; - } else { - moveLeft(qMin(1, leftDist())); - } - - if (newLineBefore || newLineAfter) - m_buffer->lastInsertion.remove(0, m_buffer->lastInsertion.indexOf(QLatin1Char('\n')) + 1); - g.dotCommand.append(m_buffer->lastInsertion + _("")); - - enterCommandMode(); - setTargetColumn(); -} - -void FakeVimHandler::Private::handleInsertMode(const Input &input) -{ - if (input.isEscape()) { - finishInsertMode(); - } else if (g.submode == CtrlVSubMode) { - if (g.subsubmode == NoSubSubMode) { - g.subsubmode = CtrlVUnicodeSubSubMode; - m_ctrlVAccumulator = 0; - if (input.is('x') || input.is('X')) { - // ^VXnn or ^Vxnn with 00 <= nn <= FF - // BMP Unicode codepoints ^Vunnnn with 0000 <= nnnn <= FFFF - // any Unicode codepoint ^VUnnnnnnnn with 00000000 <= nnnnnnnn <= 7FFFFFFF - // ^Vnnn with 000 <= nnn <= 255 - // ^VOnnn or ^Vonnn with 000 <= nnn <= 377 - m_ctrlVLength = 2; - m_ctrlVBase = 16; - } else if (input.is('O') || input.is('o')) { - m_ctrlVLength = 3; - m_ctrlVBase = 8; - } else if (input.is('u')) { - m_ctrlVLength = 4; - m_ctrlVBase = 16; - } else if (input.is('U')) { - m_ctrlVLength = 8; - m_ctrlVBase = 16; - } else if (input.isDigit()) { - bool ok; - m_ctrlVAccumulator = input.toInt(&ok, 10); - m_ctrlVLength = 2; - m_ctrlVBase = 10; - } else { - insertInInsertMode(input.raw()); - g.submode = NoSubMode; - g.subsubmode = NoSubSubMode; - } - } else { - bool ok; - int current = input.toInt(&ok, m_ctrlVBase); - if (ok) - m_ctrlVAccumulator = m_ctrlVAccumulator * m_ctrlVBase + current; - --m_ctrlVLength; - if (m_ctrlVLength == 0 || !ok) { - QString s; - if (QChar::requiresSurrogates(m_ctrlVAccumulator)) { - s.append(QChar(QChar::highSurrogate(m_ctrlVAccumulator))); - s.append(QChar(QChar::lowSurrogate(m_ctrlVAccumulator))); - } else { - s.append(QChar(m_ctrlVAccumulator)); - } - insertInInsertMode(s); - g.submode = NoSubMode; - g.subsubmode = NoSubSubMode; - - // Try again without Ctrl-V interpretation. - if (!ok) - handleInsertMode(input); - } - } - } else if (input.isControl('o')) { - enterCommandMode(InsertMode); - } else if (input.isControl('v')) { - g.submode = CtrlVSubMode; - g.subsubmode = NoSubSubMode; - } else if (input.isControl('w')) { - const int blockNumber = m_cursor.blockNumber(); - const int endPos = position(); - moveToNextWordStart(1, false, false); - if (blockNumber != m_cursor.blockNumber()) - moveToEndOfLine(); - const int beginPos = position(); - Range range(beginPos, endPos, RangeCharMode); - removeText(range); - } else if (input.isKey(Key_Insert)) { - g.mode = ReplaceMode; - } else if (input.isKey(Key_Left)) { - moveLeft(); - setTargetColumn(); - } else if (input.isControl(Key_Left)) { - moveToNextWordStart(1, false, false); - setTargetColumn(); - } else if (input.isKey(Key_Down)) { - g.submode = NoSubMode; - moveDown(); - } else if (input.isKey(Key_Up)) { - g.submode = NoSubMode; - moveUp(); - } else if (input.isKey(Key_Right)) { - moveRight(); - setTargetColumn(); - } else if (input.isControl(Key_Right)) { - moveToNextWordStart(1, false, true); - moveRight(); // we need one more move since we are in insert mode - setTargetColumn(); - } else if (input.isKey(Key_Home)) { - moveToStartOfLine(); - setTargetColumn(); - } else if (input.isKey(Key_End)) { - moveBehindEndOfLine(); - setTargetColumn(); - m_targetColumn = -1; - } else if (input.isReturn() || input.isControl('j') || input.isControl('m')) { - if (!input.isReturn() || !handleInsertInEditor(input)) { - joinPreviousEditBlock(); - g.submode = NoSubMode; - insertNewLine(); - endEditBlock(); - } - } else if (input.isBackspace()) { - if (!handleInsertInEditor(input)) { - joinPreviousEditBlock(); - if (!m_buffer->lastInsertion.isEmpty() - || hasConfig(ConfigBackspace, "start") - || hasConfig(ConfigBackspace, "2")) { - const int line = cursorLine() + 1; - const Column col = cursorColumn(); - QString data = lineContents(line); - const Column ind = indentation(data); - if (col.logical <= ind.logical && col.logical - && startsWithWhitespace(data, col.physical)) { - const int ts = config(ConfigTabStop).toInt(); - const int newl = col.logical - 1 - (col.logical - 1) % ts; - const QString prefix = tabExpand(newl); - setLineContents(line, prefix + data.mid(col.physical)); - moveToStartOfLine(); - moveRight(prefix.size()); - } else { - setAnchor(); - m_cursor.deletePreviousChar(); - } - } - endEditBlock(); - } - } else if (input.isKey(Key_Delete)) { - if (!handleInsertInEditor(input)) { - joinPreviousEditBlock(); - m_cursor.deleteChar(); - endEditBlock(); - } - } else if (input.isKey(Key_PageDown) || input.isControl('f')) { - movePageDown(); - } else if (input.isKey(Key_PageUp) || input.isControl('b')) { - movePageUp(); - } else if (input.isKey(Key_Tab)) { - m_buffer->insertState.insertingSpaces = true; - if (hasConfig(ConfigExpandTab)) { - const int ts = config(ConfigTabStop).toInt(); - const int col = logicalCursorColumn(); - QString str = QString(ts - col % ts, QLatin1Char(' ')); - insertText(str); - } else { - insertInInsertMode(input.raw()); - } - m_buffer->insertState.insertingSpaces = false; - } else if (input.isControl('d')) { - // remove one level of indentation from the current line - int shift = config(ConfigShiftWidth).toInt(); - int tab = config(ConfigTabStop).toInt(); - int line = cursorLine() + 1; - int pos = firstPositionInLine(line); - QString text = lineContents(line); - int amount = 0; - int i = 0; - for (; i < text.size() && amount < shift; ++i) { - if (text.at(i) == QLatin1Char(' ')) - ++amount; - else if (text.at(i) == QLatin1Char('\t')) - amount += tab; // FIXME: take position into consideration - else - break; - } - removeText(Range(pos, pos+i)); - } else if (input.isControl('p') || input.isControl('n')) { - QTextCursor tc = m_cursor; - moveToNextWordStart(1, false, false); - QString str = selectText(Range(position(), tc.position())); - m_cursor = tc; - emit q->simpleCompletionRequested(str, input.isControl('n')); - } else if (input.isShift(Qt::Key_Insert)) { - // Insert text from clipboard. - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *data = clipboard->mimeData(); - if (data && data->hasText()) - insertInInsertMode(data->text()); - } else { - m_buffer->insertState.insertingSpaces = input.isKey(Key_Space); - if (!handleInsertInEditor(input)) { - const QString toInsert = input.text(); - if (toInsert.isEmpty()) - return; - insertInInsertMode(toInsert); - } - m_buffer->insertState.insertingSpaces = false; - } -} - -void FakeVimHandler::Private::insertInInsertMode(const QString &text) -{ - joinPreviousEditBlock(); - insertText(text); - if (hasConfig(ConfigSmartIndent) && isElectricCharacter(text.at(0))) { - const QString leftText = block().text() - .left(position() - 1 - block().position()); - if (leftText.simplified().isEmpty()) { - Range range(position(), position(), g.rangemode); - indentText(range, text.at(0)); - } - } - setTargetColumn(); - endEditBlock(); - g.submode = NoSubMode; -} - -bool FakeVimHandler::Private::startRecording(const Input &input) -{ - QChar reg = input.asChar(); - if (reg == QLatin1Char('"') || reg.isLetterOrNumber()) { - g.currentRegister = reg.unicode(); - g.recording = QLatin1String(""); - return true; - } - - return false; -} - -void FakeVimHandler::Private::record(const Input &input) -{ - if ( !g.recording.isNull() ) - g.recording.append(input.toString()); -} - -void FakeVimHandler::Private::stopRecording() -{ - // Remove q from end (stop recording command). - g.recording.remove(g.recording.size() - 1, 1); - setRegister(g.currentRegister, g.recording, g.rangemode); - g.currentRegister = 0; - g.recording = QString(); -} - -bool FakeVimHandler::Private::executeRegister(int reg) -{ - QChar regChar(reg); - - // TODO: Prompt for an expression to execute if register is '='. - if (reg == '@' && g.lastExecutedRegister != 0) - reg = g.lastExecutedRegister; - else if (QString::fromLatin1("\".*+").contains(regChar) || regChar.isLetterOrNumber()) - g.lastExecutedRegister = reg; - else - return false; - - // FIXME: In Vim it's possible to interrupt recursive macro with . - // One solution may be to call QApplication::processEvents() and check if was - // used when a mapping is active. - // According to Vim, register is executed like mapping. - prependMapping(Inputs(registerContents(reg), false, false)); - - return true; -} - -EventResult FakeVimHandler::Private::handleExMode(const Input &input) -{ - if (input.isEscape()) { - g.commandBuffer.clear(); - resetCommandMode(); - g.submode = NoSubMode; - } else if (g.submode == CtrlVSubMode) { - g.commandBuffer.insertChar(input.raw()); - g.submode = NoSubMode; - } else if (input.isControl('v')) { - g.submode = CtrlVSubMode; - g.subsubmode = NoSubSubMode; - return EventHandled; - } else if (input.isBackspace()) { - if (g.commandBuffer.isEmpty()) { - leaveVisualMode(); - resetCommandMode(); - } else if (g.commandBuffer.hasSelection()) { - g.commandBuffer.deleteSelected(); - } else { - g.commandBuffer.deleteChar(); - } - } else if (input.isKey(Key_Tab)) { - // FIXME: Complete actual commands. - g.commandBuffer.historyUp(); - } else if (input.isReturn()) { - showMessage(MessageCommand, g.commandBuffer.display()); - handleExCommand(g.commandBuffer.contents()); - g.commandBuffer.clear(); - if (m_textedit || m_plaintextedit) - leaveVisualMode(); - } else if (!g.commandBuffer.handleInput(input)) { - qDebug() << "IGNORED IN EX-MODE: " << input.key() << input.text(); - return EventUnhandled; - } - updateMiniBuffer(); - return EventHandled; -} - -EventResult FakeVimHandler::Private::handleSearchSubSubMode(const Input &input) -{ - EventResult handled = EventHandled; - - if (input.isEscape()) { - g.currentMessage.clear(); - setPosition(m_searchStartPosition); - scrollToLine(m_searchFromScreenLine); - } else if (input.isBackspace()) { - if (g.searchBuffer.isEmpty()) - resetCommandMode(); - else - g.searchBuffer.deleteChar(); - } else if (input.isReturn()) { - const QString &needle = g.searchBuffer.contents(); - if (!needle.isEmpty()) - g.lastSearch = needle; - else - g.searchBuffer.setContents(g.lastSearch); - - updateFind(true); - - if (finishSearch()) { - if (g.submode != NoSubMode) - finishMovement(g.searchBuffer.prompt() + g.lastSearch + QLatin1Char('\n')); - if (g.currentMessage.isEmpty()) - showMessage(MessageCommand, g.searchBuffer.display()); - } else { - handled = EventCancelled; // Not found so cancel mapping if any. - } - } else if (input.isKey(Key_Tab)) { - g.searchBuffer.insertChar(QChar(9)); - } else if (!g.searchBuffer.handleInput(input)) { - //qDebug() << "IGNORED IN SEARCH MODE: " << input.key() << input.text(); - return EventUnhandled; - } - - if (input.isReturn() || input.isEscape()) { - g.searchBuffer.clear(); - resetCommandMode(); - updateMiniBuffer(); - } else { - updateMiniBuffer(); - updateFind(false); - } - - return handled; -} - -// This uses 0 based line counting (hidden lines included). -int FakeVimHandler::Private::parseLineAddress(QString *cmd) -{ - //qDebug() << "CMD: " << cmd; - if (cmd->isEmpty()) - return -1; - - int result = -1; - QChar c = cmd->at(0); - if (c == QLatin1Char('.')) { // current line - result = cursorBlockNumber(); - cmd->remove(0, 1); - } else if (c == QLatin1Char('$')) { // last line - result = document()->blockCount() - 1; - cmd->remove(0, 1); - } else if (c == QLatin1Char('\'')) { // mark - cmd->remove(0, 1); - if (cmd->isEmpty()) { - showMessage(MessageError, msgMarkNotSet(QString())); - return -1; - } - c = cmd->at(0); - Mark m = mark(c); - if (!m.isValid() || !m.isLocal(m_currentFileName)) { - showMessage(MessageError, msgMarkNotSet(c)); - return -1; - } - cmd->remove(0, 1); - result = m.position(document()).line; - } else if (c.isDigit()) { // line with given number - result = 0; - } else if (c == QLatin1Char('-') || c == QLatin1Char('+')) { // add or subtract from current line number - result = cursorBlockNumber(); - } else if (c == QLatin1Char('/') || c == QLatin1Char('?') - || (c == QLatin1Char('\\') && cmd->size() > 1 && QString::fromLatin1("/?&").contains(cmd->at(1)))) { - // search for expression - SearchData sd; - if (c == QLatin1Char('/') || c == QLatin1Char('?')) { - const int end = findUnescaped(c, *cmd, 1); - if (end == -1) - return -1; - sd.needle = cmd->mid(1, end - 1); - cmd->remove(0, end + 1); - } else { - c = cmd->at(1); - cmd->remove(0, 2); - sd.needle = (c == QLatin1Char('&')) ? g.lastSubstitutePattern : g.lastSearch; - } - sd.forward = (c != QLatin1Char('?')); - const QTextBlock b = block(); - const int pos = b.position() + (sd.forward ? b.length() - 1 : 0); - QTextCursor tc = search(sd, pos, 1, true); - g.lastSearch = sd.needle; - if (tc.isNull()) - return -1; - result = tc.block().blockNumber(); - } else { - return cursorBlockNumber(); - } - - // basic arithmetic ("-3+5" or "++" means "+2" etc.) - int n = 0; - bool add = true; - int i = 0; - for (; i < cmd->size(); ++i) { - c = cmd->at(i); - if (c == QLatin1Char('-') || c == QLatin1Char('+')) { - if (n != 0) - result = result + (add ? n - 1 : -(n - 1)); - add = c == QLatin1Char('+'); - result = result + (add ? 1 : -1); - n = 0; - } else if (c.isDigit()) { - n = n * 10 + c.digitValue(); - } else if (!c.isSpace()) { - break; - } - } - if (n != 0) - result = result + (add ? n - 1 : -(n - 1)); - *cmd = cmd->mid(i).trimmed(); - - return result; -} - -void FakeVimHandler::Private::setCurrentRange(const Range &range) -{ - setAnchorAndPosition(range.beginPos, range.endPos); - g.rangemode = range.rangemode; -} - -bool FakeVimHandler::Private::parseExCommmand(QString *line, ExCommand *cmd) -{ - *cmd = ExCommand(); - if (line->isEmpty()) - return false; - - // parse range first - if (!parseLineRange(line, cmd)) - return false; - - // get first command from command line - QChar close; - bool subst = false; - int i = 0; - for (; i < line->size(); ++i) { - const QChar &c = line->at(i); - if (c == QLatin1Char('\\')) { - ++i; // skip escaped character - } else if (close.isNull()) { - if (c == QLatin1Char('|')) { - // split on | - break; - } else if (c == QLatin1Char('/')) { - subst = i > 0 && (line->at(i - 1) == QLatin1Char('s')); - close = c; - } else if (c == QLatin1Char('"') || c == QLatin1Char('\'')) { - close = c; - } - } else if (c == close) { - if (subst) - subst = false; - else - close = QChar(); - } - } - - cmd->cmd = line->mid(0, i).trimmed(); - - // command arguments starts with first non-letter character - cmd->args = cmd->cmd.section(QRegExp(_("(?=[^a-zA-Z])")), 1); - if (!cmd->args.isEmpty()) { - cmd->cmd.chop(cmd->args.size()); - cmd->args = cmd->args.trimmed(); - - // '!' at the end of command - cmd->hasBang = cmd->args.startsWith(QLatin1Char('!')); - if (cmd->hasBang) - cmd->args = cmd->args.mid(1).trimmed(); - } - - // remove the first command from command line - line->remove(0, i + 1); - - return true; -} - -bool FakeVimHandler::Private::parseLineRange(QString *line, ExCommand *cmd) -{ - // remove leading colons and spaces - line->remove(QRegExp(_("^\\s*(:+\\s*)*"))); - - // special case ':!...' (use invalid range) - if (line->startsWith(QLatin1Char('!'))) { - cmd->range = Range(); - return true; - } - - // FIXME: that seems to be different for %w and %s - if (line->startsWith(QLatin1Char('%'))) - line->replace(0, 1, _("1,$")); - - int beginLine = parseLineAddress(line); - int endLine; - if (line->startsWith(QLatin1Char(','))) { - *line = line->mid(1).trimmed(); - endLine = parseLineAddress(line); - } else { - endLine = beginLine; - } - if (beginLine == -1 || endLine == -1) - return false; - - const int beginPos = firstPositionInLine(qMin(beginLine, endLine) + 1, false); - const int endPos = lastPositionInLine(qMax(beginLine, endLine) + 1, false); - cmd->range = Range(beginPos, endPos, RangeLineMode); - cmd->count = beginLine; - - return true; -} - -void FakeVimHandler::Private::parseRangeCount(const QString &line, Range *range) const -{ - bool ok; - const int count = qAbs(line.trimmed().toInt(&ok)); - if (ok) { - const int beginLine = document()->findBlock(range->endPos).blockNumber() + 1; - const int endLine = qMin(beginLine + count - 1, document()->blockCount()); - range->beginPos = firstPositionInLine(beginLine, false); - range->endPos = lastPositionInLine(endLine, false); - } -} - -// use handleExCommand for invoking commands that might move the cursor -void FakeVimHandler::Private::handleCommand(const QString &cmd) -{ - handleExCommand(cmd); -} - -bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd) -{ - // :substitute - if (!cmd.matches(_("s"), _("substitute")) - && !(cmd.cmd.isEmpty() && !cmd.args.isEmpty() && QString::fromLatin1("&~").contains(cmd.args[0]))) { - return false; - } - - int count = 1; - QString line = cmd.args; - const int countIndex = line.lastIndexOf(QRegExp(_("\\d+$"))); - if (countIndex != -1) { - count = line.mid(countIndex).toInt(); - line = line.mid(0, countIndex).trimmed(); - } - - if (cmd.cmd.isEmpty()) { - // keep previous substitution flags on '&&' and '~&' - if (line.size() > 1 && line[1] == QLatin1Char('&')) - g.lastSubstituteFlags += line.mid(2); - else - g.lastSubstituteFlags = line.mid(1); - if (line[0] == QLatin1Char('~')) - g.lastSubstitutePattern = g.lastSearch; - } else { - if (line.isEmpty()) { - g.lastSubstituteFlags.clear(); - } else { - // we have /{pattern}/{string}/[flags] now - const QChar separator = line.at(0); - int pos1 = findUnescaped(separator, line, 1); - if (pos1 == -1) - return false; - int pos2 = findUnescaped(separator, line, pos1 + 1); - if (pos2 == -1) - pos2 = line.size(); - - g.lastSubstitutePattern = line.mid(1, pos1 - 1); - g.lastSubstituteReplacement = line.mid(pos1 + 1, pos2 - pos1 - 1); - g.lastSubstituteFlags = line.mid(pos2 + 1); - } - } - - count = qMax(1, count); - QString needle = g.lastSubstitutePattern; - - if (g.lastSubstituteFlags.contains(QLatin1Char('i'))) - needle.prepend(_("\\c")); - - QRegExp pattern = vimPatternToQtPattern(needle, hasConfig(ConfigIgnoreCase), - hasConfig(ConfigSmartCase)); - - QTextBlock lastBlock; - QTextBlock firstBlock; - const bool global = g.lastSubstituteFlags.contains(QLatin1Char('g')); - for (int a = 0; a != count; ++a) { - for (QTextBlock block = document()->findBlock(cmd.range.endPos); - block.isValid() && block.position() + block.length() > cmd.range.beginPos; - block = block.previous()) { - QString text = block.text(); - if (substituteText(&text, pattern, g.lastSubstituteReplacement, global)) { - firstBlock = block; - if (!lastBlock.isValid()) { - lastBlock = block; - beginEditBlock(); - } - QTextCursor tc = m_cursor; - const int pos = block.position(); - const int anchor = pos + block.length() - 1; - tc.setPosition(anchor); - tc.setPosition(pos, KeepAnchor); - tc.insertText(text); - } - } - } - - if (lastBlock.isValid()) { - m_buffer->undoState.position = CursorPosition(firstBlock.blockNumber(), 0); - - leaveVisualMode(); - setPosition(lastBlock.position()); - setAnchor(); - moveToFirstNonBlankOnLine(); - setTargetColumn(); - - endEditBlock(); - } - - return true; -} - -bool FakeVimHandler::Private::handleExMapCommand(const ExCommand &cmd0) // :map -{ - QByteArray modes; - enum Type { Map, Noremap, Unmap } type; - - QByteArray cmd = cmd0.cmd.toLatin1(); - - // Strange formatting. But everything else is even uglier. - if (cmd == "map") { modes = "nvo"; type = Map; } else - if (cmd == "nm" || cmd == "nmap") { modes = "n"; type = Map; } else - if (cmd == "vm" || cmd == "vmap") { modes = "v"; type = Map; } else - if (cmd == "xm" || cmd == "xmap") { modes = "x"; type = Map; } else - if (cmd == "smap") { modes = "s"; type = Map; } else - if (cmd == "omap") { modes = "o"; type = Map; } else - if (cmd == "map!") { modes = "ic"; type = Map; } else - if (cmd == "im" || cmd == "imap") { modes = "i"; type = Map; } else - if (cmd == "lm" || cmd == "lmap") { modes = "l"; type = Map; } else - if (cmd == "cm" || cmd == "cmap") { modes = "c"; type = Map; } else - - if (cmd == "no" || cmd == "noremap") { modes = "nvo"; type = Noremap; } else - if (cmd == "nn" || cmd == "nnoremap") { modes = "n"; type = Noremap; } else - if (cmd == "vn" || cmd == "vnoremap") { modes = "v"; type = Noremap; } else - if (cmd == "xn" || cmd == "xnoremap") { modes = "x"; type = Noremap; } else - if (cmd == "snor" || cmd == "snoremap") { modes = "s"; type = Noremap; } else - if (cmd == "ono" || cmd == "onoremap") { modes = "o"; type = Noremap; } else - if (cmd == "no!" || cmd == "noremap!") { modes = "ic"; type = Noremap; } else - if (cmd == "ino" || cmd == "inoremap") { modes = "i"; type = Noremap; } else - if (cmd == "ln" || cmd == "lnoremap") { modes = "l"; type = Noremap; } else - if (cmd == "cno" || cmd == "cnoremap") { modes = "c"; type = Noremap; } else - - if (cmd == "unm" || cmd == "unmap") { modes = "nvo"; type = Unmap; } else - if (cmd == "nun" || cmd == "nunmap") { modes = "n"; type = Unmap; } else - if (cmd == "vu" || cmd == "vunmap") { modes = "v"; type = Unmap; } else - if (cmd == "xu" || cmd == "xunmap") { modes = "x"; type = Unmap; } else - if (cmd == "sunm" || cmd == "sunmap") { modes = "s"; type = Unmap; } else - if (cmd == "ou" || cmd == "ounmap") { modes = "o"; type = Unmap; } else - if (cmd == "unm!" || cmd == "unmap!") { modes = "ic"; type = Unmap; } else - if (cmd == "iu" || cmd == "iunmap") { modes = "i"; type = Unmap; } else - if (cmd == "lu" || cmd == "lunmap") { modes = "l"; type = Unmap; } else - if (cmd == "cu" || cmd == "cunmap") { modes = "c"; type = Unmap; } - - else - return false; - - QString args = cmd0.args; - bool silent = false; - bool unique = false; - forever { - if (eatString("", &args)) { - silent = true; - } else if (eatString("", &args)) { - continue; - } else if (eatString("", &args)) { - continue; - } else if (eatString("", &args)) { - notImplementedYet(); - continue; - } else if (eatString("