pax_global_header00006660000000000000000000000064145726262160014525gustar00rootroot0000000000000052 comment=176e66cffc1c78a39a069ed1bb9558cc36e359ea ksnip-master/000077500000000000000000000000001457262621600135065ustar00rootroot00000000000000ksnip-master/.editorconfig000066400000000000000000000002431457262621600161620ustar00rootroot00000000000000root = true [*] charset = utf-8 end_of_line = lf trim_trailing_whitespace = true [CMakeLists.txt] indent_style = tab indent_size = 1 insert_final_newline = true ksnip-master/.github/000077500000000000000000000000001457262621600150465ustar00rootroot00000000000000ksnip-master/.github/FUNDING.yml000066400000000000000000000003431457262621600166630ustar00rootroot00000000000000# These are supported funding model platforms github: DamirPorobic liberapay: dporobic patreon: dporobic open_collective: ksnip custom: [paypal.me/damirporobic, gofundme.com/f/buy-a-macbook-for-ksnips-cross-platform-support] ksnip-master/.github/ISSUE_TEMPLATE/000077500000000000000000000000001457262621600172315ustar00rootroot00000000000000ksnip-master/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000014401457262621600217220ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: bug assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. Linux] - Distribution in case of Linux: [e.g. Ubuntu] - Window System in case of Linux: [e.g. X11] - ksnip version: [e.g. 1.8.0] - How did you install ksnip: [e.g. AppImage] **Additional context** If applicable, add any other context about the problem here. ksnip-master/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000007271457262621600227640ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for this project title: '' labels: feature_request assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Additional context** Add any other context or screenshots about the feature request here. ksnip-master/.github/scripts/000077500000000000000000000000001457262621600165355ustar00rootroot00000000000000ksnip-master/.github/scripts/build_ksnip.sh000066400000000000000000000003741457262621600214000ustar00rootroot00000000000000#!/bin/bash mkdir build && cd build cmake .. -G"${CMAKE_GENERATOR}" -DBUILD_TESTS=${BUILD_TESTS} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DVERSION_SUFIX=${VERSION_SUFFIX} -DBUILD_NUMBER=${BUILD_NUMBER} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} ${MAKE_BINARY}ksnip-master/.github/scripts/delete_release.sh000066400000000000000000000030521457262621600220330ustar00rootroot00000000000000 GIT_COMMIT="${GITHUB_SHA}" GIT_REPO_SLUG="${GITHUB_REPOSITORY}" release_url="https://api.github.com/repos/${GIT_REPO_SLUG}/releases/tags/${RELEASE_TAG}" echo "Getting the release ID..." echo "release_url: ${release_url}" release_infos=$(curl -XGET --header "Authorization: token ${GITHUB_TOKEN}" "${release_url}") echo "release_infos: ${release_infos}" release_id=$(echo "${release_infos}" | grep "\"id\":" | head -n 1 | tr -s " " | cut -f 3 -d" " | cut -f 1 -d ",") echo "release ID: ${release_id}" git fetch --tags origin target_commit_sha=$(git rev-list -n 1 "${RELEASE_TAG}") echo "target_commit_sha: ${target_commit_sha}" echo "GIT_COMMIT: ${GIT_COMMIT}" if [ "${GIT_COMMIT}" != "${target_commit_sha}" ] ; then echo "GIT_COMMIT != target_commit_sha, hence deleting tag and release for '${RELEASE_TAG}'..." if [ -n "${release_id}" ]; then delete_release_url="https://api.github.com/repos/${GIT_REPO_SLUG}/releases/${release_id}" echo "Delete the release..." echo "delete_url: ${delete_release_url}" curl -XDELETE \ --header "Authorization: token ${GITHUB_TOKEN}" \ "${delete_release_url}" fi if [ "${RELEASE_TAG}" == "continuous" ] ; then # if this is a continuous build tag, then delete the old tag # in preparation for the new release echo "Delete the tag..." delete_tag_url="https://api.github.com/repos/${GIT_REPO_SLUG}/git/refs/tags/${RELEASE_TAG}" echo "delete_url: ${delete_tag_url}" curl -XDELETE \ --header "Authorization: token ${GITHUB_TOKEN}" \ "${delete_tag_url}" fi fiksnip-master/.github/scripts/linux/000077500000000000000000000000001457262621600176745ustar00rootroot00000000000000ksnip-master/.github/scripts/linux/build_appImage.sh000066400000000000000000000017731457262621600231420ustar00rootroot00000000000000#!/bin/bash mkdir build && cd build echo "--> Build" cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=/usr -DVERSION_SUFIX=${VERSION_SUFFIX} -DBUILD_NUMBER=${BUILD_NUMBER} -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} make DESTDIR=appdir -j$(nproc) install ; find appdir/ echo "--> Copy SSL libs to appDir" mkdir -p appdir/usr/lib/ cp /lib/x86_64-linux-gnu/libssl.so.1.0.0 appdir/usr/lib/ echo "--> Copy kImageAnnotator translations to appDir" mkdir -p appdir/usr/share/kImageAnnotator/ cp -r ${INSTALL_PREFIX}/share/kImageAnnotator/translations appdir/usr/share/kImageAnnotator/ echo "--> Package appImage" unset QTDIR; unset QT_PLUGIN_PATH ; unset LD_LIBRARY_PATH ../linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ../linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage -extra-plugins=iconengines,imageformats echo "--> Whats in here" ls echo "--> Move" mv ksnip*.AppImage* ${GITHUB_WORKSPACE}/ echo "--> Done" ksnip-master/.github/scripts/linux/deb/000077500000000000000000000000001457262621600204265ustar00rootroot00000000000000ksnip-master/.github/scripts/linux/deb/build_deb.sh000066400000000000000000000002101457262621600226640ustar00rootroot00000000000000#!/bin/bash cd ksnip-${VERSION_NUMBER} dpkg-buildpackage -us -uc -i -b mv ${WORKSPACE}/ksnip_*.deb ${WORKSPACE}/ksnip-${VERSION}.deb ksnip-master/.github/scripts/linux/deb/debian/000077500000000000000000000000001457262621600216505ustar00rootroot00000000000000ksnip-master/.github/scripts/linux/deb/debian/compat000066400000000000000000000000031457262621600230470ustar00rootroot0000000000000012 ksnip-master/.github/scripts/linux/deb/debian/control000066400000000000000000000006421457262621600232550ustar00rootroot00000000000000Source: ksnip Section: utils Priority: optional Maintainer: Damir Porobic Build-Depends: debhelper (>=9), cmake (>=3.5) Standards-Version: 4.1.1 Homepage: http://ksnip.org Package: ksnip Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Conflicts: libkimageannotator-common Description: Screenshot Tool Screenshot tool that provides many annotation features for your screenshots. ksnip-master/.github/scripts/linux/deb/debian/copyright000066400000000000000000000017741457262621600236140ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: ksnip Source: https://github.com/ksnip/ksnip/blob/master/LICENSE Files: * Copyright: Copyright 2021 ksnip License: GPL-2+ License: GPL-2+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . This 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 General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". ksnip-master/.github/scripts/linux/deb/debian/rules000077500000000000000000000020761457262621600227350ustar00rootroot00000000000000#!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. export DH_VERBOSE = 1 # see FEATURE AREAS in dpkg-buildflags(1) #export DEB_BUILD_MAINT_OPTIONS = hardening=+all # see ENVIRONMENT in dpkg-buildflags(1) # package maintainers to append CFLAGS #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic # package maintainers to append LDFLAGS #export DEB_LDFLAGS_MAINT_APPEND = %: dh $@ #dh_make generated override targets # This is example for Cmake (See https://bugs.debian.org/641051 ) override_dh_auto_configure: dh_auto_configure -- -DVERSION_SUFIX=$(VERSION_SUFFIX) -DBUILD_NUMBER=$(BUILD_NUMBER) -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_PREFIX_PATH="$(Qt5_DIR);$(INSTALL_PREFIX)" -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) override_dh_shlibdeps: dh_shlibdeps -l"$(Qt5_DIR)/lib" --dpkg-shlibdeps-params=--ignore-missing-info # Manually install kimageannotator translation files override_dh_auto_install: dh_auto_install mkdir -p $(CURDIR)/debian/ksnip/usr/ cp -r $(INSTALL_PREFIX)/share $(CURDIR)/debian/ksnip/usr/ ksnip-master/.github/scripts/linux/deb/debian/source/000077500000000000000000000000001457262621600231505ustar00rootroot00000000000000ksnip-master/.github/scripts/linux/deb/debian/source/format000066400000000000000000000000151457262621600243570ustar00rootroot000000000000003.0 (native) ksnip-master/.github/scripts/linux/deb/setup_changelog_file.sh000066400000000000000000000014211457262621600251260ustar00rootroot00000000000000#!/bin/bash cp CHANGELOG.md changelog sed -i '1,2d' changelog #Remove header and empty line ad the beginning sed -i 's/\[\(.*[^]]*\)\].*/\1)/g' changelog # Replace links to issues with only number sed -i "s/^[[:blank:]]*$/\n -- Damir Porobic ${BUILD_TIME}\n/" changelog # After every release add time and author sed -i 's/## Release \([0-9]*\.[0-9]*\.[0-9]*\)/ksnip (\1) stable; urgency=medium\n/' changelog # Rename release headers sed -i 's/^\(\* .*\)/ \1/' changelog # Add two spaces before every entry printf "\n -- Damir Porobic ${BUILD_TIME}\n" >> changelog # Add time and author for the first release cp changelog ksnip-${VERSION_NUMBER}/debian/ echo "Changelog:" echo "---------------" cat changelog echo "---------------" ksnip-master/.github/scripts/linux/deb/setup_deb_directory_structure.sh000066400000000000000000000007051457262621600271420ustar00rootroot00000000000000#!/bin/bash echo "--> Create directory and copy everything we need to deliver" mkdir ksnip-${VERSION_NUMBER} cp -R CMakeLists.txt cmake/ desktop/ icons/ LICENSE.txt README.md src/ translations/ ksnip-${VERSION_NUMBER}/ echo "--> Package source content" tar -cvzf ksnip_${VERSION_NUMBER}.orig.tar.gz ksnip-${VERSION_NUMBER}/ echo "--> Copy source package to debian directory" cp -R ${WORKSPACE}/.github/scripts/linux/deb/debian ksnip-${VERSION_NUMBER}/ ksnip-master/.github/scripts/linux/rpm/000077500000000000000000000000001457262621600204725ustar00rootroot00000000000000ksnip-master/.github/scripts/linux/rpm/build_rpm.sh000066400000000000000000000003061457262621600230020ustar00rootroot00000000000000#!/bin/bash cd ksnip-${VERSION_NUMBER} rpmbuild -ba SPECS/ksnip-*.spec --define '_topdir %(pwd)' mv ${WORKSPACE}/ksnip-${VERSION_NUMBER}/RPMS/x86_64/ksnip-*.rpm ${WORKSPACE}/ksnip-${VERSION}.rpm ksnip-master/.github/scripts/linux/rpm/ksnip.spec000066400000000000000000000022111457262621600224660ustar00rootroot00000000000000%define packager Damir Porobic %define __spec_install_post %{nil} %define debug_package %{nil} %define __os_install_post %{_dbpath}/brp-compress %define _signature gpg %define _gpg_name Ksnip Name: ksnip Summary: Screenshot Tool Version: X.X.X Release: 1 Source0: %{name}-%{version}.tar.gz URL: https://github.com/ksnip/ksnip License: GPLV2+ Group: Application/Utility %description Screenshot tool that provides many annotation features for your screenshots. %prep %setup %build cmake . make %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/share/kImageAnnotator/ cp -a $INSTALL_PREFIX/share/kImageAnnotator/translations/. $RPM_BUILD_ROOT/usr/share/kImageAnnotator/translations %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %{_usr}/bin/%{name} %{_usr}/share/applications/org.%{name}.%{name}.desktop %{_usr}/share/icons/hicolor/scalable/apps/%{name}.svg %{_usr}/share/%{name}/translations/*.qm %{_usr}/share/kImageAnnotator/translations/*.qm %{_usr}/share/metainfo/org.%{name}.%{name}.appdata.xml %changelog ksnip-master/.github/scripts/linux/rpm/setup_rpm_directory_structure.sh000066400000000000000000000011471457262621600272530ustar00rootroot00000000000000#!/bin/bash echo "--> Create directory and everything we need to deliver" mkdir ksnip-${VERSION_NUMBER} cp -R CMakeLists.txt cmake/ desktop/ icons/ LICENSE.txt README.md src/ translations/ ksnip-${VERSION_NUMBER}/ echo "--> Package directory" tar -cvzf ksnip-${VERSION_NUMBER}.tar.gz ksnip-${VERSION_NUMBER}/ echo "--> Move package to SOURCE directory" mkdir ksnip-${VERSION_NUMBER}/SOURCES mv ksnip-${VERSION_NUMBER}.tar.gz ksnip-${VERSION_NUMBER}/SOURCES/ echo "--> Copy spec file to SPEC directory" mkdir ksnip-${VERSION_NUMBER}/SPECS cp ksnip.spec ksnip-${VERSION_NUMBER}/SPECS/ksnip-${VERSION_NUMBER}.spec ksnip-master/.github/scripts/linux/rpm/setup_spec_file.sh000066400000000000000000000015571457262621600242070ustar00rootroot00000000000000#!/bin/bash echo "--> Create copy of spec file" cp ${WORKSPACE}/.github/scripts/linux/rpm/ksnip.spec . echo "--> Update changelog entries" cp CHANGELOG.md changelog sed -i '1,2d' changelog #Remove header and empty line ad the beginning sed -i 's/* /-- /g' changelog # Replace asterisk with double dash sed -i 's/\[\(.*[^]]*\)\].*/\1)/g' changelog # Replace links to issues with only number sed -i "s/## Release \([0-9]*\.[0-9]*\.[0-9]*\)/* ${BUILD_DATE} Damir Porobic \1/" changelog # Format release headers cat changelog >> ksnip.spec echo "--> Update version" sed -i "s/Version: X.X.X/Version: ${VERSION_NUMBER}/" ksnip.spec sed -i "s;cmake .;cmake . -DVERSION_SUFIX=${VERSION_SUFFIX} -DBUILD_NUMBER=${BUILD_NUMBER} -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_PREFIX_PATH=${INSTALL_PREFIX} -DCMAKE_BUILD_TYPE=${BUILD_TYPE};" ksnip.spec # ; is the delimiter ksnip-master/.github/scripts/linux/setup_linux_build_variables.sh000066400000000000000000000001511457262621600260130ustar00rootroot00000000000000#!/bin/bash echo "MAKE_BINARY=make" >> $GITHUB_ENV echo "CMAKE_GENERATOR=Unix Makefiles" >> $GITHUB_ENV ksnip-master/.github/scripts/macos/000077500000000000000000000000001457262621600176375ustar00rootroot00000000000000ksnip-master/.github/scripts/macos/add_osx_cert.sh000077500000000000000000000011651457262621600226370ustar00rootroot00000000000000#!/bin/bash KEY_CHAIN=build.keychain CERTIFICATE_P12=certificate.p12 # Recreate the certificate from the secure environment variable echo ${APPLE_CERT_P12} | base64 --decode > $CERTIFICATE_P12 # Create a keychain security create-keychain -p main $KEY_CHAIN # Make the keychain the default so identities are found security default-keychain -s $KEY_CHAIN # Unlock the keychain security unlock-keychain -p main $KEY_CHAIN security import $CERTIFICATE_P12 -k $KEY_CHAIN -P ${APPLE_CERT_P12_PASS} -T /usr/bin/codesign; security set-key-partition-list -S apple-tool:,apple: -s -k main $KEY_CHAIN # Remove cert file rm -fr *.p12ksnip-master/.github/scripts/macos/notarize_osx_dmg_package.sh000066400000000000000000000021061457262621600252200ustar00rootroot00000000000000#!/bin/bash echo "Starting Notarization process." response=$(xcrun altool -t osx -f ksnip-${VERSION}.dmg --primary-bundle-id org.ksnip.ksnip --notarize-app -u ${APPLE_DEV_USER} -p ${APPLE_DEV_PASS}) requestUUID=$(echo "${response}" | tr ' ' '\n' | tail -1) retryCounter=0 while true; do retryCounter=$((retryCounter + 1)) if [[ "${retryCounter}" -gt 5 ]]; then echo "Notarization timeout!" exit 1 fi echo "Notarization retry ${retryCounter}." echo "Checking notarization status." statusCheckResponse=$(xcrun altool --notarization-info ${requestUUID} -u ${APPLE_DEV_USER} -p ${APPLE_DEV_PASS}) isSuccess=$(echo "${statusCheckResponse}" | grep "success") isFailure=$(echo "${statusCheckResponse}" | grep "invalid") if [[ "${isSuccess}" != "" ]]; then echo "Notarization done!" xcrun stapler staple -v ksnip-${VERSION}.dmg echo "Stapler done!" exit 0 fi if [[ "${isFailure}" != "" ]]; then echo "Notarization failed!" exit 1 fi echo "Notarization not finished yet, sleep 2min then check again..." sleep 120 doneksnip-master/.github/scripts/macos/package_dmg.sh000077500000000000000000000004701457262621600224210ustar00rootroot00000000000000#!/bin/bash mv build/src/ksnip*.app ksnip.app cp build/translations/ksnip_*.qm ./ksnip.app/Contents/Resources/ cp kImageAnnotator/build/translations/kImageAnnotator_*.qm ./ksnip.app/Contents/Resources/ macdeployqt ksnip.app -dmg -sign-for-notarization="${APPLE_DEV_IDENTITY}" mv ksnip.dmg ksnip-${VERSION}.dmgksnip-master/.github/scripts/macos/setup_macos_build_variables.sh000066400000000000000000000001511457262621600257210ustar00rootroot00000000000000#!/bin/bash echo "MAKE_BINARY=make" >> $GITHUB_ENV echo "CMAKE_GENERATOR=Unix Makefiles" >> $GITHUB_ENV ksnip-master/.github/scripts/setup_build_variables.sh000066400000000000000000000037531457262621600234500ustar00rootroot00000000000000#!/bin/bash VERSION_REGEX="([0-9]{1,}\.)+[0-9]{1,}" BUILD_TIME=$(date +"%a, %d %b %Y %T %z") BUILD_DATE=$(date +"%a %b %d %Y") BUILD_NUMBER=$(git rev-list --count HEAD)-$(git rev-parse --short HEAD) VERSION_NUMBER=$(grep "project.*" CMakeLists.txt | egrep -o "${VERSION_REGEX}") WORKSPACE="$GITHUB_WORKSPACE" INSTALL_PREFIX="$WORKSPACE/tmp" echo "BUILD_TYPE=Release" >> $GITHUB_ENV echo "BUILD_TIME=$BUILD_TIME" >> $GITHUB_ENV echo "BUILD_DATE=$BUILD_DATE" >> $GITHUB_ENV echo "BUILD_NUMBER=$BUILD_NUMBER" >> $GITHUB_ENV echo "VERSION_REGEX=$VERSION_REGEX" >> $GITHUB_ENV echo "WORKSPACE=$WORKSPACE" >> $GITHUB_ENV echo "INSTALL_PREFIX=$INSTALL_PREFIX" >> $GITHUB_ENV echo "VERSION_NUMBER=$VERSION_NUMBER" >> $GITHUB_ENV echo "UPLOADTOOL_ISPRERELEASE=true" >> $GITHUB_ENV echo "BUILD_TESTS=OFF" >> $GITHUB_ENV if [[ "$GITHUB_REF" = refs/tags* ]]; then GITHUB_TAG=${GITHUB_REF#refs/tags/} echo "GitHub Tag is: $GITHUB_TAG" echo "GITHUB_TAG=$GITHUB_TAG" >> $GITHUB_ENV else echo "GitHub Ref is: $GITHUB_REF" fi if [[ -z "${GITHUB_TAG}" ]]; then echo "Build is not tagged this is a continuous build" VERSION_SUFFIX="continuous" echo "VERSION_SUFFIX=$VERSION_SUFFIX" >> $GITHUB_ENV echo "VERSION=${VERSION_NUMBER}-${VERSION_SUFFIX}" >> $GITHUB_ENV echo "RELEASE_NAME=Continuous build" >> $GITHUB_ENV echo "IS_PRERELASE=true" >> $GITHUB_ENV echo "RELEASE_TAG=continuous" >> $GITHUB_ENV else echo "Build is tagged this is not a continues build" echo "Building ksnip version ${VERSION_NUMBER}" echo "VERSION=${VERSION_NUMBER}" >> $GITHUB_ENV echo "RELEASE_NAME=${GITHUB_TAG}" >> $GITHUB_ENV echo "IS_PRERELASE=false" >> $GITHUB_ENV echo "RELEASE_TAG=${GITHUB_TAG}" >> $GITHUB_ENV fi # Message show on the release page ACTION_LINK_TEXT="Build logs: https://github.com/ksnip/ksnip/actions" BUILD_TIME_TEXT="Build Time: $(TZ=CET date +"%d.%m.%Y %T %Z")" UPLOADTOOL_BODY="${ACTION_LINK_TEXT} %0A ${BUILD_TIME_TEXT}" echo "UPLOADTOOL_BODY=$UPLOADTOOL_BODY" >> $GITHUB_ENVksnip-master/.github/scripts/setup_googleTest.sh000066400000000000000000000004061457262621600224250ustar00rootroot00000000000000#!/bin/bash git clone --depth 1 https://github.com/google/googletest cd googletest || exit mkdir build && cd build || exit cmake .. -G"${CMAKE_GENERATOR}" -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" -DBUILD_SHARED_LIBS=ON ${MAKE_BINARY} && ${MAKE_BINARY} installksnip-master/.github/scripts/setup_kColorPicker.sh000066400000000000000000000012741457262621600227040ustar00rootroot00000000000000#!/bin/bash if [[ -z "${GITHUB_TAG}" ]]; then echo "Building ksnip with latest version of kColorPicker" git clone --depth 1 https://github.com/ksnip/kColorPicker.git else KCOLORPICKER_VERSION=$(grep "set.*KCOLORPICKER_MIN_VERSION" CMakeLists.txt | egrep -o "${VERSION_REGEX}") echo "Building ksnip with kColorPicker version ${KCOLORPICKER_VERSION}" git clone --depth 1 --branch "v${KCOLORPICKER_VERSION}" https://github.com/ksnip/kColorPicker.git fi cd kColorPicker || exit mkdir build && cd build || exit cmake .. -G"${CMAKE_GENERATOR}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" -DBUILD_EXAMPLE=OFF -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" ${MAKE_BINARY} && ${MAKE_BINARY} installksnip-master/.github/scripts/setup_kImageAnnotator.sh000066400000000000000000000014341457262621600233760ustar00rootroot00000000000000#!/bin/bash if [[ -z "${GITHUB_TAG}" ]]; then echo "Building ksnip with latest version of kImageAnnotator" git clone --depth 1 https://github.com/ksnip/kImageAnnotator.git else KIMAGEANNOTATOR_VERSION=$(grep "set.*KIMAGEANNOTATOR_MIN_VERSION" CMakeLists.txt | egrep -o "${VERSION_REGEX}") echo "Building ksnip with kImageAnnotator version ${KIMAGEANNOTATOR_VERSION}" git clone --depth 1 --branch "v${KIMAGEANNOTATOR_VERSION}" https://github.com/ksnip/kImageAnnotator.git fi cd kImageAnnotator || exit mkdir build && cd build || exit cmake .. -G"${CMAKE_GENERATOR}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" -DBUILD_EXAMPLE=OFF -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" -DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES="${INSTALL_PREFIX}/include" ${MAKE_BINARY} && ${MAKE_BINARY} installksnip-master/.github/scripts/windows/000077500000000000000000000000001457262621600202275ustar00rootroot00000000000000ksnip-master/.github/scripts/windows/msi/000077500000000000000000000000001457262621600210175ustar00rootroot00000000000000ksnip-master/.github/scripts/windows/msi/package_msi.sh000066400000000000000000000001771457262621600236230ustar00rootroot00000000000000#!/bin/bash cd build "C:\Program Files\CMake\bin\cpack.exe" --verbose mv ksnip*.msi ${GITHUB_WORKSPACE}/ksnip-${VERSION}.msi ksnip-master/.github/scripts/windows/msi/sign_msi_package.ps1000066400000000000000000000020251457262621600247260ustar00rootroot00000000000000$CERTIFICATE_PFX_ENCODED = $Env:MICROSOFT_CERT_PFX -replace "\\", "" $MICROSOFT_CERT_PFX_PASS = $Env:MICROSOFT_CERT_PFX_PASS -replace "\\", "" $CERTIFICATE_PFX = "certificate.pfx" $CERTIFICATE_PFX_DECODE = [system.convert]::frombase64string($CERTIFICATE_PFX_ENCODED) set-content -Path $CERTIFICATE_PFX -Value $CERTIFICATE_PFX_DECODE -Encoding Byte $MICROSOFT_CERT_PFX_PASS_SECURED = ConvertTo-SecureString -String $MICROSOFT_CERT_PFX_PASS -AsPlainText -Force Write-Host "Import Certificate" Import-PfxCertificate -FilePath $CERTIFICATE_PFX -CertStoreLocation Cert:\LocalMachine\My -Password $MICROSOFT_CERT_PFX_PASS_SECURED Write-Host "Sign package" $KSNIP_VERSION = $Env:VERSION $KSNIP_MSI = "ksnip-$KSNIP_VERSION.msi" $TIMESTAMP_SERVER = "http://timestamp.comodoca.com/authenticode" $SIGNTOOL = 'C:\Program Files (x86)\Windows Kits\10\bin\x64\signtool.exe' & SIGNTOOL sign /v /debug /sm /fd SHA256 /s My /n 'Damir Porobic' /d 'Ksnip - Screenshot Tool' /t $TIMESTAMP_SERVER $KSNIP_MSI rm $CERTIFICATE_PFX Write-Host "Finished signing"ksnip-master/.github/scripts/windows/package_exe.sh000066400000000000000000000007621457262621600230240ustar00rootroot00000000000000#!/bin/bash mkdir packageDir mv build/src/ksnip*.exe packageDir/ksnip.exe windeployqt.exe --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --release packageDir/ksnip.exe cp build/translations/ksnip_*.qm ./packageDir/translations/ cp kImageAnnotator/build/translations/kImageAnnotator_*.qm ./packageDir/translations/ cp "${OPENSSL_DIR}"/*.dll ./packageDir/ cp "${COMPILE_RUNTIME_DIR}"/*.dll ./packageDir/ mkdir packageDir/plugins 7z a ksnip-${VERSION}-windows.zip ./packageDir/* ksnip-master/.github/scripts/windows/setup_windows_build_variables.sh000066400000000000000000000006221457262621600267040ustar00rootroot00000000000000#!/bin/bash echo "MAKE_BINARY=nmake" >> $GITHUB_ENV echo "CMAKE_GENERATOR=NMake Makefiles" >> $GITHUB_ENV echo "LIB=$LIB;$INSTALL_PREFIX/lib" >> $GITHUB_ENV echo "INCLUDE=$INCLUDE;$INSTALL_PREFIX/include" >> $GITHUB_ENV echo "OPENSSL_DIR=$WORKSPACE/OpenSSL" >> $GITHUB_ENV echo "COMPILE_RUNTIME_DIR=$WORKSPACE/CompileRuntime" >> $GITHUB_ENV echo "KIMAGEANNOTATOR_DIR=${INSTALL_PREFIX}" >> $GITHUB_ENVksnip-master/.github/workflows/000077500000000000000000000000001457262621600171035ustar00rootroot00000000000000ksnip-master/.github/workflows/linux.yml000066400000000000000000000157441457262621600210000ustar00rootroot00000000000000name: linux on: push: branches: [ master ] tags: - "v*" jobs: test-linux: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up linux build variables run: bash ./.github/scripts/linux/setup_linux_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'linux' install-deps: 'true' - name: Install dependencies run: sudo apt-get install extra-cmake-modules libxcb-xfixes0-dev xvfb - name: Set up GoogleTest run: bash ./.github/scripts/setup_googleTest.sh - name: Set up kColorPicker env: BUILD_TYPE: Debug run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator env: BUILD_TYPE: Debug run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Build env: BUILD_TESTS: ON BUILD_TYPE: Debug run: bash ./.github/scripts/build_ksnip.sh - name: Test working-directory: ${{github.workspace}}/build/tests run: xvfb-run --auto-servernum --server-num=1 --server-args="-screen 0 1024x768x24" ctest --extra-verbose package-appImage: runs-on: ubuntu-20.04 needs: test-linux steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/linux/setup_linux_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'linux' install-deps: 'true' - name: Install dependencies run: sudo apt-get install extra-cmake-modules libxcb-xfixes0-dev libssl-dev - name: Set up kColorPicker run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Download deploy tool run: | wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" chmod a+x linuxdeployqt-continuous-x86_64.AppImage - name: Package AppImage working-directory: ${{github.workspace}} run: bash ./.github/scripts/linux/build_appImage.sh - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: ksnip.AppImage path: ksnip*.AppImage* - name: Delete existing release with same name env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bash ./.github/scripts/delete_release.sh - name: Upload Release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ksnip-${{ env.VERSION }}-x86_64.AppImage asset_name: ksnip-${{ env.VERSION }}-x86_64.AppImage tag: ${{ env.RELEASE_TAG }} overwrite: true release_name: ${{ env.RELEASE_NAME }} body: ${{ env.UPLOADTOOL_BODY }} prerelease: ${{ env.IS_PRERELASE }} package-rpm: runs-on: ubuntu-latest needs: test-linux steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/linux/setup_linux_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'linux' install-deps: 'true' - name: Install dependencies run: sudo apt-get install extra-cmake-modules libxcb-xfixes0-dev libssl-dev rpm - name: Set up kColorPicker run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Set up spec file run: bash ./.github/scripts/linux/rpm/setup_spec_file.sh - name: Set up directory structure run: bash ./.github/scripts/linux/rpm/setup_rpm_directory_structure.sh - name: Package rpm run: bash ./.github/scripts/linux/rpm/build_rpm.sh - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: ksnip.rpm path: ksnip-*.rpm - name: Delete existing release with same name env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bash ./.github/scripts/delete_release.sh - name: Upload Release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ksnip-${{ env.VERSION }}.rpm asset_name: ksnip-${{ env.VERSION }}.rpm tag: ${{ env.RELEASE_TAG }} overwrite: true release_name: ${{ env.RELEASE_NAME }} body: ${{ env.UPLOADTOOL_BODY }} prerelease: ${{ env.IS_PRERELASE }} package-deb: runs-on: ubuntu-latest needs: test-linux steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/linux/setup_linux_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'linux' install-deps: 'true' - name: Install dependencies run: sudo apt-get install cmake extra-cmake-modules libxcb-xfixes0-dev libssl-dev devscripts debhelper - name: Set up kColorPicker run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Set up directory structure run: bash ./.github/scripts/linux/deb/setup_deb_directory_structure.sh - name: Set up changelog run: bash ./.github/scripts/linux/deb/setup_changelog_file.sh - name: Package deb run: bash ./.github/scripts/linux/deb/build_deb.sh - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: ksnip.deb path: ksnip-*.deb - name: Delete existing release with same name env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bash ./.github/scripts/delete_release.sh - name: Upload Release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ksnip-${{ env.VERSION }}.deb asset_name: ksnip-${{ env.VERSION }}.deb tag: ${{ env.RELEASE_TAG }} overwrite: true release_name: ${{ env.RELEASE_NAME }} body: ${{ env.UPLOADTOOL_BODY }} prerelease: ${{ env.IS_PRERELASE }} ksnip-master/.github/workflows/macos.yml000066400000000000000000000063431457262621600207360ustar00rootroot00000000000000name: macOS on: push: branches: [ master ] tags: - "v*" jobs: test-macos: runs-on: macos-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/macos/setup_macos_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'mac' install-deps: 'true' - name: Set up GoogleTest run: bash ./.github/scripts/setup_googleTest.sh - name: Set up kColorPicker env: BUILD_TYPE: Debug run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator env: BUILD_TYPE: Debug run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Build env: BUILD_TESTS: ON BUILD_TYPE: Debug run: bash ./.github/scripts/build_ksnip.sh - name: Test working-directory: ${{github.workspace}}/build/tests run: ctest --extra-verbose package-dmg: runs-on: macos-latest needs: test-macos steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/macos/setup_macos_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'mac' install-deps: 'true' - name: Set up kColorPicker run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Build run: bash ./.github/scripts/build_ksnip.sh - name: Add OSX certificate to key chain env: APPLE_CERT_P12: ${{ secrets.APPLE_CERT_P12 }} APPLE_CERT_P12_PASS: ${{ secrets.APPLE_CERT_P12_PASS }} run: bash ./.github/scripts/macos/add_osx_cert.sh - name: Package dmg env: APPLE_DEV_IDENTITY: ${{ secrets.APPLE_DEV_IDENTITY }} run: bash ./.github/scripts/macos/package_dmg.sh - name: Notarize dmg package env: APPLE_DEV_PASS: ${{ secrets.APPLE_DEV_PASS }} APPLE_DEV_USER: ${{ secrets.APPLE_DEV_USER }} run: bash ./.github/scripts/macos/notarize_osx_dmg_package.sh - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: ksnip-macos.dmg path: ksnip-*.dmg - name: Delete existing release with same name env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bash ./.github/scripts/delete_release.sh - name: Upload Release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ksnip-${{ env.VERSION }}.dmg asset_name: ksnip-${{ env.VERSION }}.dmg tag: ${{ env.RELEASE_TAG }} overwrite: true release_name: ${{ env.RELEASE_NAME }} body: ${{ env.UPLOADTOOL_BODY }} prerelease: ${{ env.IS_PRERELASE }} ksnip-master/.github/workflows/windows.yml000066400000000000000000000136441457262621600213300ustar00rootroot00000000000000name: windows on: push: branches: [ master ] tags: - "v*" jobs: test-windows: runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/windows/setup_windows_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'windows' install-deps: 'true' arch: 'win64_msvc2019_64' - name: Set up nmake uses: ilammy/msvc-dev-cmd@v1 - name: Set up kColorPicker env: BUILD_TYPE: Debug run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator env: BUILD_TYPE: Debug run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Set up GoogleTest run: bash ./.github/scripts/setup_googleTest.sh - name: Add GoogleTest bin dir to PATH uses: myci-actions/export-env-var-powershell@1 with: name: PATH value: $env:PATH;$env:INSTALL_PREFIX/bin - name: Build env: BUILD_TESTS: ON BUILD_TYPE: Debug run: bash ./.github/scripts/build_ksnip.sh - name: Test working-directory: ${{github.workspace}}/build/tests run: ctest --extra-verbose package-exe: runs-on: windows-latest needs: test-windows steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/windows/setup_windows_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'windows' install-deps: 'true' arch: 'win64_msvc2019_64' - name: Set up nmake uses: ilammy/msvc-dev-cmd@v1 - name: Set up kColorPicker run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Build run: bash ./.github/scripts/build_ksnip.sh - name: Download OpenSSL run: | curl -L "https://github.com/ksnip/dependencies/raw/master/windows/openSSL.zip" --output openssl.zip 7z x openssl.zip -o"${{ env.OPENSSL_DIR }}" - name: Download CompileRuntime run: | curl -L "https://github.com/ksnip/dependencies/raw/master/windows/compileRuntime.zip" --output compileruntime.zip 7z x compileruntime.zip -o"${{ env.COMPILE_RUNTIME_DIR }}" - name: Package exe run: bash ./.github/scripts/windows/package_exe.sh - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: ksnip-windows.zip path: ksnip-*.zip - name: Delete existing release with same name env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bash ./.github/scripts/delete_release.sh - name: Upload Release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ksnip-${{ env.VERSION }}-windows.zip asset_name: ksnip-${{ env.VERSION }}-windows.zip tag: ${{ env.RELEASE_TAG }} overwrite: true release_name: ${{ env.RELEASE_NAME }} body: ${{ env.UPLOADTOOL_BODY }} prerelease: ${{ env.IS_PRERELASE }} package-msi: runs-on: windows-latest needs: test-windows steps: - name: Checkout uses: actions/checkout@v3 - name: Set up build variables run: bash ./.github/scripts/setup_build_variables.sh - name: Set up windows build variables run: bash ./.github/scripts/windows/setup_windows_build_variables.sh - name: Install Qt uses: jurplel/install-qt-action@v3 with: version: '5.15.2' host: 'windows' install-deps: 'true' arch: 'win64_msvc2019_64' - name: Set up nmake uses: ilammy/msvc-dev-cmd@v1 - name: Set up kColorPicker run: bash ./.github/scripts/setup_kColorPicker.sh - name: Set up kImageAnnotator run: bash ./.github/scripts/setup_kImageAnnotator.sh - name: Download OpenSSL run: | curl -L "https://github.com/ksnip/dependencies/raw/master/windows/openSSL.zip" --output openssl.zip 7z x openssl.zip -o"${{ env.OPENSSL_DIR }}" - name: Download CompileRuntime run: | curl -L "https://github.com/ksnip/dependencies/raw/master/windows/compileRuntime.zip" --output compileruntime.zip 7z x compileruntime.zip -o"${{ env.COMPILE_RUNTIME_DIR }}" - name: Build run: bash ./.github/scripts/build_ksnip.sh - name: Package msi run: bash ./.github/scripts/windows/msi/package_msi.sh - name: Sign msi env: MICROSOFT_CERT_PFX: ${{ secrets.MICROSOFT_CERT_PFX }} MICROSOFT_CERT_PFX_PASS: ${{ secrets.MICROSOFT_CERT_PFX_PASS }} run: powershell ./.github/scripts/windows/msi/sign_msi_package.ps1 - name: Upload Artifact uses: actions/upload-artifact@v3 with: name: ksnip-windows.msi path: ksnip-*.msi - name: Delete existing release with same name env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bash ./.github/scripts/delete_release.sh - name: Upload Release uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ksnip-${{ env.VERSION }}.msi asset_name: ksnip-${{ env.VERSION }}.msi tag: ${{ env.RELEASE_TAG }} overwrite: true release_name: ${{ env.RELEASE_NAME }} body: ${{ env.UPLOADTOOL_BODY }} prerelease: ${{ env.IS_PRERELASE }} ksnip-master/.gitignore000066400000000000000000000017051457262621600155010ustar00rootroot00000000000000# C++ objects and libs *.slo *.lo *.o *.a *.la *.lai *.so *.dll *.dylib # Qt-es /.qmake.cache /.qmake.stash *.pro.user *.pro.user.* *.qbs.user *.qbs.user.* *.moc moc_*.cpp qrc_*.cpp ui_*.h Makefile* *build-* # QtCreator *.autosave # QtCtreator Qml *.qmlproject.user *.qmlproject.user.* # QtCtreator CMake CMakeLists.txt.user # kdevelop apidocs .kdev4 build *~ *.kdev4 *.bak *.orig *.rej doxygen.log Doxyfile *.kdevelop *.kdevelop.filelist *.kdevelop.pcs *.kdevses .*kate-swp build/ mem.log.* massif.* callgrind.* perf.data* # from kdiff3 *.BACKUP.* *.BASE.* *.LOCAL.* *.REMOTE.* # visual studio code *.vscode/ # clion *.idea # macos .DS_Store # other .directory # snap /parts/ /stage/ /prime/ /*.snap # Snapcraft global state tracking data(automatically generated) # https://forum.snapcraft.io/t/location-to-save-global-state/768 /snap/.snapcraft/ # Source archive packed by `snapcraft cleanbuild` before pushing to the LXD container /*_source.tar.bz2 ksnip-master/CHANGELOG.md000066400000000000000000001517741457262621600153360ustar00rootroot00000000000000# Change log ## Release 1.11.0 * Fixed: Cannot compile from source, kImageAnnotatorConfig not found despite being built and installed. ([#1027](https://github.com/ksnip/ksnip/issues/1027)) * New kImageAnnotator: Allow copying items between tabs. ([#318](https://github.com/ksnip/kImageAnnotator/issues/318)) * New kImageAnnotator: CTRL + A does not select all text typed. ([#198](https://github.com/ksnip/kImageAnnotator/issues/198)) * New kImageAnnotator: Open text edit mode when double-click on textbox figure in Text tool. ([#180](https://github.com/ksnip/kImageAnnotator/issues/180)) * New kImageAnnotator: Add reflowing capability to the text tool. ([#129](https://github.com/ksnip/kImageAnnotator/issues/129)) * New kImageAnnotator: Editing text, no mouse cursor edit functions. ([#297](https://github.com/ksnip/kImageAnnotator/issues/297)) * New kImageAnnotator: Mouse click within a text box for setting specific editing position and selecting text. ([#273](https://github.com/ksnip/kImageAnnotator/issues/273)) * Fixed kImageAnnotator: Text isn't reflowed the next line within the box and text overlaps when resizing box. ([#271](https://github.com/ksnip/kImageAnnotator/issues/271)) * Fixed kImageAnnotator: Can't wrap long text line when resizing text box. ([#211](https://github.com/ksnip/kImageAnnotator/issues/211)) * Fixed kImageAnnotator: Key press operations affect items across different tabs. ([#319](https://github.com/ksnip/kImageAnnotator/issues/319)) * Fixed kImageAnnotator: Clipboard cleared when new tab added. ([#321](https://github.com/ksnip/kImageAnnotator/issues/321)) * Fixed kImageAnnotator: Crash after pressing key when no tab exists or closing last tab. ([#334](https://github.com/ksnip/kImageAnnotator/issues/334)) * Fixed kImageAnnotator: KeyInputHelperTest failed with QT_QPA_PLATFORM=offscreen. ([#335](https://github.com/ksnip/kImageAnnotator/issues/335)) ## Release 1.10.1 * Fixed: DragAndDrop not working with snaps. ([#898](https://github.com/ksnip/ksnip/issues/898)) * Fixed: Loading image from stdin single instance client runner side doesn't work. ([#741](https://github.com/ksnip/ksnip/issues/741)) * Fixed kImageAnnotator: Fix for unnecessary scrollbars when a screenshot has a smaller size than the previous one. ([#303](https://github.com/ksnip/kImageAnnotator/issues/303)) * Fixed kImageAnnotator: Add KDE support for scale factor. ([#302](https://github.com/ksnip/kImageAnnotator/issues/302)) * Fixed kImageAnnotator: Show tab tooltips on initial tabs. * Fixed kImageAnnotator: Sticker resizing is broken when bounding rect flipped. ([#306](https://github.com/ksnip/kImageAnnotator/issues/306)) ## Release 1.10.0 * New: Set image save location on command line. ([#666](https://github.com/ksnip/ksnip/issues/666)) * New: Add debug logging. ([#711](https://github.com/ksnip/ksnip/issues/711)) * New: Add FTP upload. ([#104](https://github.com/ksnip/ksnip/issues/104)) * New: Upload image via command line without opening editor. ([#217](https://github.com/ksnip/ksnip/issues/217)) * New: Add multi-language comment option to desktop file. ([#726](https://github.com/ksnip/ksnip/issues/726)) * New: Add MimeType of Images to desktop file. ([#725](https://github.com/ksnip/ksnip/issues/725)) * New: Add .jpeg to open file dialog filter (File > Open). ([#749](https://github.com/ksnip/ksnip/issues/749)) * New: Escape closes window (and exits when not using tray). ([#770](https://github.com/ksnip/ksnip/issues/770)) * New: Double-click mouse to confirm rect selection. ([#771](https://github.com/ksnip/ksnip/issues/771)) * New: Activate tab that is prompting for save. ([#750](https://github.com/ksnip/ksnip/issues/750)) * New: Add Save all options menu. ([#754](https://github.com/ksnip/ksnip/issues/754)) * New: Allow overwriting existing files. ([#661](https://github.com/ksnip/ksnip/issues/661)) * New: Allow setting Imgur upload title/description. ([#679](https://github.com/ksnip/ksnip/issues/679)) * New: Search bar in the settings dialog. ([#619](https://github.com/ksnip/ksnip/issues/619)) * New: Make implicit capture delay configurable. ([#820](https://github.com/ksnip/ksnip/issues/820)) * New: Shortcuts for Actions can be made global and non-global per config. ([#823](https://github.com/ksnip/ksnip/issues/823)) * New: OCR scan of screenshots (via plugin). ([#603](https://github.com/ksnip/ksnip/issues/603)) * New kImageAnnotator: Add optional undo, redo, crop, scale and modify canvas buttons to dock widgets. ([#263](https://github.com/ksnip/kImageAnnotator/issues/263)) * New kImageAnnotator: Cut out vertical or horizontal slice of an image. ([#236](https://github.com/ksnip/kImageAnnotator/issues/236)) * New kImageAnnotator: Middle-click on tab header closes tab. ([#280](https://github.com/ksnip/kImageAnnotator/issues/280)) * New kImageAnnotator: Add button to fit image into current view. ([#281](https://github.com/ksnip/kImageAnnotator/issues/281)) * New kImageAnnotator: Allow changing item opacity. ([#110](https://github.com/ksnip/kImageAnnotator/issues/110)) * New kImageAnnotator: Add support for RGBA colors with transparency. ([#119](https://github.com/ksnip/kImageAnnotator/issues/119)) * New kImageAnnotator: Add mouse cursor sticker. ([#290](https://github.com/ksnip/kImageAnnotator/issues/290)) * New kImageAnnotator: Allow scaling stickers per setting. ([#285](https://github.com/ksnip/kImageAnnotator/issues/285)) * New kImageAnnotator: Respect original aspect ratio of stickers. ([#291](https://github.com/ksnip/kImageAnnotator/issues/291)) * New kImageAnnotator: Respect original size of stickers. ([#295](https://github.com/ksnip/kImageAnnotator/issues/295)) * Fixed: Opens a new window for each capture. ([#728](https://github.com/ksnip/ksnip/issues/728)) * Fixed: First cli invocation won't copy image to clipboard. ([#764](https://github.com/ksnip/ksnip/issues/764)) * Fixed: Snipping area incorrectly positioned with screen scaling. ([#276](https://github.com/ksnip/ksnip/issues/276)) * Fixed: MainWindow position not restored when outside primary screen. ([#789](https://github.com/ksnip/ksnip/issues/789)) * Fixed: Interface window isn't restored to the default after tab is closed in maximized state. ([#757](https://github.com/ksnip/ksnip/issues/757)) * Fixed: Failed Imgur uploads show up titled as 'Upload Successful'. ([#802](https://github.com/ksnip/ksnip/issues/802)) * Fixed: Preview of screenshot is scaled after changing desktop size. ([#844](https://github.com/ksnip/ksnip/issues/844)) * Fixed: After an auto start followed by reboot/turn on the window section is stretched. ([#842](https://github.com/ksnip/ksnip/issues/842)) * Fixed kImageAnnotator: Adding image effect does not send image change notification. ([#283](https://github.com/ksnip/kImageAnnotator/issues/283)) * Fixed kImageAnnotator: Blur / Pixelate break when going past image edge once. ([#267](https://github.com/ksnip/kImageAnnotator/issues/267)) * Fixed kImageAnnotator: Item opacity not applied when item shadow disabled. ([#284](https://github.com/ksnip/kImageAnnotator/issues/284)) * Changed: Improve translation experience by using full sentences. ([#759](https://github.com/ksnip/ksnip/issues/759)) * Changed: Make switch 'to select tool after drawing item' by default disabled. * Changed kImageAnnotator: Max font size changed to 100pt. ## Release 1.9.2 * Fixed: Version `Qt_5.15' not found (required by /usr/bin/ksnip). ([#712](https://github.com/ksnip/ksnip/issues/712)) * Fixed: CI packages show continuous suffix for tagged build. ([#710](https://github.com/ksnip/ksnip/issues/710)) * Fixed: kImageAnnotator not translated with deb package. ([#359](https://github.com/ksnip/ksnip/issues/359)) * Fixed: Windows packages increased in size. ([#713](https://github.com/ksnip/ksnip/issues/713)) * Fixed: The string 'Actions' is not available for translation. ([#729](https://github.com/ksnip/ksnip/issues/729)) * Fixed: HiDPI issue with multiple screen on Windows. ([#668](https://github.com/ksnip/ksnip/issues/668)) * Fixed: Snipping Area not closing when pressing ESC. ([#735](https://github.com/ksnip/ksnip/issues/735)) * Fixed: Sometimes "Snipping Area Rulers" not shown after starting rectangular selection. ([#684](https://github.com/ksnip/ksnip/issues/684)) * Fixed: Cursor not positioned correctly when snipping area opens. ([#736](https://github.com/ksnip/ksnip/issues/736)) * Fixed: Mouse cursor not captured when triggered via global shortcut. ([#737](https://github.com/ksnip/ksnip/issues/737)) * Fixed: Dual 4K screens get scrambled on X11. ([#734](https://github.com/ksnip/ksnip/issues/734)) * Fixed: VCRUNTIME140_1.dll was not found. ([#743](https://github.com/ksnip/ksnip/issues/743)) * Fixed: Screenshot area issue when monitor count changes on Windows. ([#722](https://github.com/ksnip/ksnip/issues/722)) * Fixed: Wayland does not support QWindow::requestActivate(). ([#656](https://github.com/ksnip/ksnip/issues/656)) * Fixed: Wrong area is captured on a Wayland screen scaling. ([#691](https://github.com/ksnip/ksnip/issues/691)) * Changed: Enforce xdg-desktop-portal screenshots for Gnome >= 41. ([#727](https://github.com/ksnip/ksnip/issues/727)) * Fixed kImageAnnotator: Crash while typing text on wayland. ([#256](https://github.com/ksnip/kImageAnnotator/issues/256)) * Changed kImageAnnotator: Show scrollbar when not all tools visible. ([#258](https://github.com/ksnip/kImageAnnotator/issues/258)) ## Release 1.9.1 * Fixed: MacOS package damaged and not starting. ([#653](https://github.com/ksnip/ksnip/issues/653)) * Fixed: Deb CI build is frequently failing due to docker image pull limit. ([#655](https://github.com/ksnip/ksnip/issues/655)) * Fixed: Dropped temporary images appear in the open recent menu. ([#613](https://github.com/ksnip/ksnip/issues/613)) * Fixed: Resizing window to match content doesn't work on opening first image/screenshot. ([#664](https://github.com/ksnip/ksnip/issues/664)) * Fixed: HiDPI issue with multiple screen on Windows. ([#668](https://github.com/ksnip/ksnip/issues/668)) * Fixed: Cursor not captured in rectangle capture. ([#670](https://github.com/ksnip/ksnip/issues/670)) * Changed: Migrate CI from Travic-CI to GitHub Action. ([#676](https://github.com/ksnip/ksnip/issues/676)) * Fixed kImageAnnotator: Crashes on destruction. ([#242](https://github.com/ksnip/kImageAnnotator/issues/242)) * Fixed kImageAnnotator: Memory leaks caught by ASAN. ([#243](https://github.com/ksnip/kImageAnnotator/issues/243)) * Changed kImageAnnotator: Use system font provided by QGuiApplication as default for text tool. ([#247](https://github.com/ksnip/kImageAnnotator/issues/247)) ## Release 1.9.0 * New: Add option to select the default action for tray icon left click. ([#502](https://github.com/ksnip/ksnip/issues/502)) * New: Open/Paste from clipboard via tray icon. ([#520](https://github.com/ksnip/ksnip/issues/520)) * New: Show/hide toolbar and annotation settings with TAB. ([#476](https://github.com/ksnip/ksnip/issues/476)) * New: Add setting for auto hiding toolbar and annotator settings. ([#527](https://github.com/ksnip/ksnip/issues/527)) * New: Allow setting transparency of not selected snipping area region. ([#517](https://github.com/ksnip/ksnip/issues/517)) * New: Resize selected rect area with arrow keys. ([#515](https://github.com/ksnip/ksnip/issues/515)) * New: Copy a screenshot to clipboard as data URI. ([#474](https://github.com/ksnip/ksnip/issues/474)) * New: Allow disabling tray icon notifications. ([#561](https://github.com/ksnip/ksnip/issues/561)) * New: Provide option to open recent files. ([#272](https://github.com/ksnip/ksnip/issues/272)) * New: Allow disabling auto resizing after first capture. ([#551](https://github.com/ksnip/ksnip/issues/551)) * New: Drag and Drop from ksnip to other applications. ([#377](https://github.com/ksnip/ksnip/issues/377)) * New: Add support for KDE Plasma notification service. ([#592](https://github.com/ksnip/ksnip/issues/592)) * New: ksnip as MSI Package for window. ([#546](https://github.com/ksnip/ksnip/issues/546)) * New: User-defined actions for taking screenshot and post-processing. ([#369](https://github.com/ksnip/ksnip/issues/369)) * New: Add 'hide main window' option to actions. ([#636](https://github.com/ksnip/ksnip/issues/636)) * New: Discord Invite in application. ([#638](https://github.com/ksnip/ksnip/issues/638)) * New kImageAnnotator: Add function for loading translations. ([#173](https://github.com/ksnip/kImageAnnotator/issues/173)) * New kImageAnnotator: Add a new tool for creating resizable movable duplicates of regions. ([#131](https://github.com/ksnip/kImageAnnotator/issues/131)) * New kImageAnnotator: Add support for hiding annotation settings panel. ([#182](https://github.com/ksnip/kImageAnnotator/issues/182)) * New kImageAnnotator: Add config option for numbering tool to only set next number. ([#42](https://github.com/ksnip/kImageAnnotator/issues/42)) * New kImageAnnotator: Allow manually changing canvas size. ([#92](https://github.com/ksnip/kImageAnnotator/issues/92)) * New kImageAnnotator: Canvas background color configurable. ([#91](https://github.com/ksnip/kImageAnnotator/issues/91)) * New kImageAnnotator: Zoom in and out with keyboard shortcuts. ([#192](https://github.com/ksnip/kImageAnnotator/issues/192)) * New kImageAnnotator: Zoom in and out via buttons from UI. ([#197](https://github.com/ksnip/kImageAnnotator/issues/197)) * New kImageAnnotator: Add reset zoom keyboard shortcut with tooltip. ([#209](https://github.com/ksnip/kImageAnnotator/issues/209)) * New kImageAnnotator: Add keyboard shortcut support for text tool. ([#183](https://github.com/ksnip/kImageAnnotator/issues/183)) * New kImageAnnotator: Allow rotating background image. ([#199](https://github.com/ksnip/kImageAnnotator/issues/199)) * New kImageAnnotator: Allow flipping background image horizontally and vertically. ([#221](https://github.com/ksnip/kImageAnnotator/issues/221)) * New kImageAnnotator: Configurable UI with dockable settings widgets. ([#102](https://github.com/ksnip/kImageAnnotator/issues/102)) * New kImageAnnotator: Add invert color image effect. ([#228](https://github.com/ksnip/kImageAnnotator/issues/228)) * New kImageAnnotator: Allow disabling item shadow per item from UI. ([#223](https://github.com/ksnip/kImageAnnotator/issues/223)) * New kImageAnnotator: Add a font selection to UI. ([#130](https://github.com/ksnip/kImageAnnotator/issues/130)) * New kImageAnnotator: Add zoom in/out capability to crop view. ([#212](https://github.com/ksnip/kImageAnnotator/issues/212)) * New kImageAnnotator: Allow to zoom in modify canvas view. ([#229](https://github.com/ksnip/kImageAnnotator/issues/229)) * New kImageAnnotator: Select item after drawing it and allow changing settings. ([#230](https://github.com/ksnip/kImageAnnotator/issues/230)) * Changed kImageAnnotator: Change drop shadow to cover all sites. ([#202](https://github.com/ksnip/kImageAnnotator/issues/202)) * Fixed: Not possible to change adorner color. ([#601](https://github.com/ksnip/ksnip/issues/601)) * Fixed: ksnip --version output printed to stderr. ([#617](https://github.com/ksnip/ksnip/issues/617)) * Fixed kImageAnnotator: Deleting item outside image doesn't decrease canvas size. ([#164](https://github.com/ksnip/kImageAnnotator/issues/164)) * Fixed kImageAnnotator: Duplicate region of grayscale image has color. ([#214](https://github.com/ksnip/kImageAnnotator/issues/214)) * Fixed kImageAnnotator: Marker shows fill and width config when modifying existing item. ([#225](https://github.com/ksnip/kImageAnnotator/issues/225)) * Fixed kImageAnnotator: Highlighter/Marker washed out color and overlapping. ([#227](https://github.com/ksnip/kImageAnnotator/issues/227)) * Fixed kImageAnnotator: Popup menus shown outside screen. ([#226](https://github.com/ksnip/kImageAnnotator/issues/226)) * Fixed kImageAnnotator: Not possible to enter value in the width tool. ([#233](https://github.com/ksnip/kImageAnnotator/issues/233)) * Fixed kImageAnnotator: Obfuscation tool shows fonts settings when switching from tool with font. ([#231](https://github.com/ksnip/kImageAnnotator/issues/231)) * Fixed kImageAnnotator: Annotation tools are not displayed if application starts with docks hidden. ([#237](https://github.com/ksnip/kImageAnnotator/issues/237)) * Fixed kImageAnnotator: Vertical scrollbar missing after using Paste embedded and moving the image. ([#232](https://github.com/ksnip/kImageAnnotator/issues/232)) * Fixed kImageAnnotator: Not possible to disable tool automatically deselected after drawn. ([#238](https://github.com/ksnip/kImageAnnotator/issues/238)) * Fixed kImageAnnotator: Annotation tool shortcuts do not work if the panel is hidden. ([#239](https://github.com/ksnip/kImageAnnotator/issues/239)) ## Release 1.8.2 * Fixed: Add missing includes to build on UNIX. ([#581](https://github.com/ksnip/ksnip/issues/581)) * Fixed: Ksnip starts minimized. ([#593](https://github.com/ksnip/ksnip/issues/593)) * Fixed: Main window still show after screenshot when corresponding option disabled. ([#596](https://github.com/ksnip/ksnip/issues/596)) * Fixed: Cancel screenshot shows main window when window was hidden. ([#607](https://github.com/ksnip/ksnip/issues/607)) * Fixed: HiDPI scaling not handled correctly under windows. ([#590](https://github.com/ksnip/ksnip/issues/590)) * Fixed: Close button hidden after taking screenshot under kwin. ([#588](https://github.com/ksnip/ksnip/issues/588)) * Fixed kImageAnnotator: Fetching image from annotator with HiDPI enabled pixelates image. ([#218](https://github.com/ksnip/kImageAnnotator/issues/218)) * Fixed kImageAnnotator: Keep aspect ratio only work when pressing CTRL before moving resize handle. ([#219](https://github.com/ksnip/kImageAnnotator/issues/219)) ## Release 1.8.1 * Changed: Allow changing adorner color for rect area selection. ([#519](https://github.com/ksnip/ksnip/issues/519)) * Changed: Notarize ksnip for macOS. ([#402](https://github.com/ksnip/ksnip/issues/402)) * Changed: Default font for numbering tool change to Arial. ([#200](https://github.com/ksnip/kImageAnnotator/issues/200)) * Changed kImageAnnotator: Horizontally align text inside spin box. ([#203](https://github.com/ksnip/kImageAnnotator/issues/203)) * Changed kImageAnnotator: Change zoom with mouse wheel to CTRL+Wheel. ([#210](https://github.com/ksnip/kImageAnnotator/issues/210)) * Fixed: If file selection is cancelled during ksnip's file open dialog via tray icon, ksnip closes. ([#503](https://github.com/ksnip/ksnip/issues/503)) * Fixed: Cancel on Quit not work when editor is hidden. ([#342](https://github.com/ksnip/ksnip/issues/342)) * Fixed: Canceling rect area selection activates main window. ([#521](https://github.com/ksnip/ksnip/issues/521)) * Fixed: Enter key doesn't finishes resizing. ([#523](https://github.com/ksnip/ksnip/issues/523)) * Fixed: Missing version number in mac binaries. ([#401](https://github.com/ksnip/ksnip/issues/401)) * Fixed: Canceling save dialog show the option save path in the header. ([#545](https://github.com/ksnip/ksnip/issues/545)) * Fixed: Save-as Window does not get focus when using snap. ([#543](https://github.com/ksnip/ksnip/issues/543)) * Fixed: Editor can not be shown again after click close icon. ([#400](https://github.com/ksnip/ksnip/issues/400)) * Fixed: Icons and text boxes not correctly scaled under gnome with hdpi. ([#549](https://github.com/ksnip/ksnip/issues/549)) * Fixed: Window captures include non-transparent border of background on Gnome. ([#460](https://github.com/ksnip/ksnip/issues/460)) * Fixed: Annotating hidpi image downscales the result after being saved. ([#172](https://github.com/ksnip/kImageAnnotator/issues/172)) * Fixed kImageAnnotator: Brazilian Portuguese translation not loaded. ([#176](https://github.com/ksnip/kImageAnnotator/issues/176)) * Fixed kImageAnnotator: error: control reaches end of non-void function. ([#177](https://github.com/ksnip/kImageAnnotator/issues/177)) * Fixed kImageAnnotator: Cursor in Text tool have too bad visibility. ([#184](https://github.com/ksnip/kImageAnnotator/issues/184)) * Fixed kImageAnnotator: bumped SONAME without name change. ([#185](https://github.com/ksnip/kImageAnnotator/issues/185)) * Fixed kImageAnnotator: Entering multiple characters at once moves the text cursor only for one character. ([#186](https://github.com/ksnip/kImageAnnotator/issues/186)) * Fixed kImageAnnotator: Activating context menu while drawing item leaves item in error state. ([#196](https://github.com/ksnip/kImageAnnotator/issues/196)) * Fixed kImageAnnotator: Icons not scaled on gnome with hdpi enabled. ([#201](https://github.com/ksnip/kImageAnnotator/issues/201)) * Fixed kImageAnnotator: Text/Number Pointer and Text/Number Arrow don't inherit Text/Number Font in Settings. ([#208](https://github.com/ksnip/kImageAnnotator/issues/208)) ## Release 1.8.0 * New: Pin screenshots in frameless windows that stay in foreground. ([#365](https://github.com/ksnip/ksnip/issues/365)) * New: Support for unit tests. ([#80](https://github.com/ksnip/ksnip/issues/80)) * New: Add brew cask package for ksnip. ([#394](https://github.com/ksnip/ksnip/issues/394)) * New: Allow setting image quality when saving images. ([#382](https://github.com/ksnip/ksnip/issues/382)) * New: Add support for cross-platform wayland screenshots using xdg-desktop-portal. ([#243](https://github.com/ksnip/ksnip/issues/243)) * New: Add save and save as tab contextMenu items. ([#332](https://github.com/ksnip/ksnip/issues/332)) * New: Add open directory context menu item on capture tabs. ([#339](https://github.com/ksnip/ksnip/issues/339)) * New: Add copy path to clipboard context menu item on capture tabs. ([#331](https://github.com/ksnip/ksnip/issues/331)) * New: Add option to delete saved images. ([#378](https://github.com/ksnip/ksnip/issues/378)) * New: Add support for loading image from stdin. ([#414](https://github.com/ksnip/ksnip/issues/414)) * New: Add screenshot options as application actions to desktop file. ([#450](https://github.com/ksnip/ksnip/issues/450)) * New: Allow renaming existing images. ([#438](https://github.com/ksnip/ksnip/issues/438)) * New: Make hiding main window during screenshot optional. ([#386](https://github.com/ksnip/ksnip/issues/386)) * New: Open several files at once in tabs. ([#355](https://github.com/ksnip/ksnip/issues/355)) * New: Allow modifying selected rectangle before making screenshot. ([#197](https://github.com/ksnip/ksnip/issues/197)) * New: Option to keep main window hidden after a taking screenshot. ([#409](https://github.com/ksnip/ksnip/issues/409)) * New kImageAnnotator: Add Pixelate image area tool. ([#140](https://github.com/ksnip/kImageAnnotator/issues/140)) * New kImageAnnotator: Zoom in and out. ([#123](https://github.com/ksnip/kImageAnnotator/issues/123)) * New kImageAnnotator: Add interface for adding custom tab context menu actions. ([#96](https://github.com/ksnip/kImageAnnotator/issues/96)) * New kImageAnnotator: Add drop shadow to captured images. ([#133](https://github.com/ksnip/kImageAnnotator/issues/133)) * New kImageAnnotator: Add grayscale image effect. ([#151](https://github.com/ksnip/kImageAnnotator/issues/151)) * New kImageAnnotator: Add numeric pointer with arrow annotation item. ([#152](https://github.com/ksnip/kImageAnnotator/issues/152)) * New kImageAnnotator: Add text pointer annotation item. ([#154](https://github.com/ksnip/kImageAnnotator/issues/154)) * New kImageAnnotator: Add text pointer with arrow annotation item. ([#153](https://github.com/ksnip/kImageAnnotator/issues/153)) * New kImageAnnotator: Add option to automatically switching to select tool after drawing item. ([#161](https://github.com/ksnip/kImageAnnotator/issues/161)) * New kImageAnnotator: Edit Text box with double click. ([#60](https://github.com/ksnip/kImageAnnotator/issues/60)) * New kImageAnnotator: Resize elements while keeping aspect ratio. ([#170](https://github.com/ksnip/kImageAnnotator/issues/170)) * Changed: Show all Screenshot options in System Tray. ([#404](https://github.com/ksnip/ksnip/issues/404)) * Changed: Upload multiple stickers at once. ([#427](https://github.com/ksnip/ksnip/issues/427)) * Changed: Follow pattern for monochromatic systray icon. ([#352](https://github.com/ksnip/ksnip/issues/352)) * Changed: Pin window shows default cursor when mouse over it. ([#465](https://github.com/ksnip/ksnip/issues/465)) * Changed: Cancel snipping area if no selection made after 60 sec. ([#475](https://github.com/ksnip/ksnip/issues/475)) * Changed: Allow removing imgur account. ([#366](https://github.com/ksnip/ksnip/issues/366)) * Changed kImageAnnotator: Draw point when clicking and releasing without moving cursor. ([#136](https://github.com/ksnip/kImageAnnotator/issues/136)) * Changed kImageAnnotator: Zoom out less than 100%. ([#150](https://github.com/ksnip/kImageAnnotator/issues/150)) * Changed kImageAnnotator: Change to select tool after adding new annotation item. ([#155](https://github.com/ksnip/kImageAnnotator/issues/155)) * Changed kImageAnnotator: Move current zoom text to left side config panel. ([#157](https://github.com/ksnip/kImageAnnotator/issues/157)) * Fixed: Snap crashing when trying to take screenshot under Wayland. ([#389](https://github.com/ksnip/ksnip/issues/389)) * Fixed: zh_Hans translation won't load. ([#429](https://github.com/ksnip/ksnip/issues/429)) * Fixed: Ksnip only saves the upper right part of the screenshot with HiDPI. ([#439](https://github.com/ksnip/ksnip/issues/439)) * Fixed: Main window not resized with new captures. ([#446](https://github.com/ksnip/ksnip/issues/446)) * Fixed: Brazilian Portuguese translation not loaded. ([#493](https://github.com/ksnip/ksnip/issues/493)) * Fixed kImageAnnotator: Blur radius not updated when changing current items settings. ([#142](https://github.com/ksnip/kImageAnnotator/issues/142)) * Fixed kImageAnnotator: Text tool opens many unix sockets. ([#144](https://github.com/ksnip/kImageAnnotator/issues/144)) * Fixed kImageAnnotator: Text No Border and No Fill shows shadow beneath text. ([#148](https://github.com/ksnip/kImageAnnotator/issues/148)) * Fixed kImageAnnotator: Item properties remain displayed after item is removed or deselected. ([#168](https://github.com/ksnip/kImageAnnotator/issues/168)) * Fixed kImageAnnotator: Changing text box through editing text doesn't update resize handles. ([#171](https://github.com/ksnip/kImageAnnotator/issues/171)) * Fixed kColorPicker: Border around colors is not centered. ([#6](https://github.com/ksnip/kColorPicker/issues/6)) ## Release 1.7.3 * New: Provide ksnip flatpak. ([#127](https://github.com/ksnip/ksnip/issues/127)) * Changed: Install svg icon file in hicolor theme dir instead of usr/share/pixmaps/. ([#297](https://github.com/ksnip/ksnip/issues/297)) ## Release 1.7.2 * Changed: Stop upload script when process writes to stderr. ([#383](https://github.com/ksnip/ksnip/issues/383)) * Changed: Upload script uses regex to select output for clipboard. ([#384](https://github.com/ksnip/ksnip/issues/384)) * Fixed: Ksnip becomes unresponsive when file dropped into it. ([#373](https://github.com/ksnip/ksnip/issues/373)) * Fixed: Ksnip window always visible on screenshots on Gnome Wayland. ([#375](https://github.com/ksnip/ksnip/issues/375)) * Fixed: Selecting path in Snap via file-chooser sets home directory to /run/user/1000. ([#388](https://github.com/ksnip/ksnip/issues/388)) * Fixed: Snap not able to run custom upload script. ([#380](https://github.com/ksnip/ksnip/issues/380)) * Fixed: kImageAnnotator: Tests fail to build with shared library. ([#128](https://github.com/ksnip/kImageAnnotator/issues/128)) ## Release 1.7.1 * Fixed: User not prompted to save when taking new screenshot without tabs. ([#357](https://github.com/ksnip/ksnip/issues/357)) * Fixed: kImageAnnotator not translated with AppImage. ([#358](https://github.com/ksnip/ksnip/issues/358)) * Fixed kImageAnnotator: Crashes after undoing a number annotation. ([#106](https://github.com/ksnip/kImageAnnotator/issues/114)) * Fixed kImageAnnotator: Text overlapping when resizing text box. ([#53](https://github.com/ksnip/kImageAnnotator/issues/53)) * Fixed kImageAnnotator: Snap lines to degrees not working when CTRL pressed before clicking annotation area. ([#113](https://github.com/ksnip/kImageAnnotator/issues/113)) * Fixed kImageAnnotator: "Border and Fill" submenu cutting off text under windows.. ([#117](https://github.com/ksnip/kImageAnnotator/issues/117)) * Fixed kImageAnnotator: Undo removes several or all items. ([#121](https://github.com/ksnip/kImageAnnotator/issues/121)) * Fixed kImageAnnotator: Marker Rect and Ellipse draw only border but no fill. ([#126](https://github.com/ksnip/kImageAnnotator/issues/126)) ## Release 1.7.0 * New: Provide ksnip snap. ([#147](https://github.com/ksnip/ksnip/issues/147)) * New: Pasting image or path to image from clipboard. ([#275](https://github.com/ksnip/ksnip/issues/275)) * New: Save to same file when editing existing image. ([#271](https://github.com/ksnip/ksnip/issues/271)) * New: Support for PrtScrn hotkey. ([#239](https://github.com/ksnip/ksnip/issues/239)) * New: Auto save new screenshot. ([#291](https://github.com/ksnip/ksnip/issues/291)) * New: Remember file for already saved images. ([#292](https://github.com/ksnip/ksnip/issues/292)) * New: Add support for drag and drop images into ksnip. ([#282](https://github.com/ksnip/ksnip/issues/282)) * New: Insert embedded image into an existing screenshot. ([#293](https://github.com/ksnip/ksnip/issues/293)) * New: Show screenshots in tabs. ([#298](https://github.com/ksnip/ksnip/issues/298)) * New: Add Maximize Window Button in Print Preview. ([#190](https://github.com/ksnip/ksnip/issues/190)) * New: Click on toast message opens content. ([#303](https://github.com/ksnip/ksnip/issues/303)) * New: Remember last used folder in the save file dialog. ([#264](https://github.com/ksnip/ksnip/issues/264)) * New: Custom script for upload images. ([#268](https://github.com/ksnip/ksnip/issues/268)) * New: Disable single global hotkey by clearing the shortcut. ([#316](https://github.com/ksnip/ksnip/issues/316)) * New: Run ksnip as single instance. ([#238](https://github.com/ksnip/ksnip/issues/238)) * New: Add option for disabling tabs. ([#329](https://github.com/ksnip/ksnip/issues/329)) * New: Add count wildcard format for filename. ([#318](https://github.com/ksnip/ksnip/issues/318)) * New: Allow to change upload imgur URI. ([#159](https://github.com/ksnip/ksnip/issues/159)) * New: Support for adding custom stickers. ([#246](https://github.com/ksnip/ksnip/issues/246)) * New kImageAnnotator: Add option to translate UI. ([#54](https://github.com/ksnip/kImageAnnotator/issues/54)) * New kImageAnnotator: Saved image expand to include annotations out of border. ([#90](https://github.com/ksnip/kImageAnnotator/issues/90)) * New kImageAnnotator: Add support for stickers. ([#74](https://github.com/ksnip/kImageAnnotator/issues/74)) * New kImageAnnotator: Add tab context menu for close all tabs and close other tabs. ([#93](https://github.com/ksnip/kImageAnnotator/issues/93)) * New kImageAnnotator: Add Number with Arrow/pointer tool. ([#79](https://github.com/ksnip/kImageAnnotator/issues/79)) * Changed: Save As option was added and useInstantSave config was removed. ([#285](https://github.com/ksnip/ksnip/issues/285)) * Changed: Disable scroll down with zero value in timeout widget. ([#294](https://github.com/ksnip/ksnip/issues/294)) * Changed: Disable unsupported capture modes in settings. ([#322](https://github.com/ksnip/ksnip/issues/322)) * Changed kImageAnnotator: Make dropdown buttons show popup on click. ([#89](https://github.com/ksnip/kImageAnnotator/issues/89)) * Changed kImageAnnotator: Hide unavailable setting widgets. ([#101](https://github.com/ksnip/kImageAnnotator/issues/101)) * Changed kImageAnnotator: Make arrow size decrease with stroke size. ([#84](https://github.com/ksnip/kImageAnnotator/issues/84)) * Fixed: Compilation error with Qt 5.15. ([#279](https://github.com/ksnip/ksnip/issues/279)) * Fixed: Undo and redo translation reverts back to English. ([#209](https://github.com/ksnip/ksnip/issues/209)) * Fixed: When 'Capture Save Location' is not set, ksnip fails to save. ([#263](https://github.com/ksnip/ksnip/issues/263)) * Fixed: Connections that required ssl not working on AppImages. ([#320](https://github.com/ksnip/ksnip/issues/320)) * Fixed: Main window hangs when pressing `Esc` on selecting screenshot area state. ([#330](https://github.com/ksnip/ksnip/issues/330)) * Fixed: Unable to resize ksnip window. ([#335](https://github.com/ksnip/ksnip/issues/335)) * Fixed: Rectangle picker is not closed with -r -s switches when mouse button is released. ([#338](https://github.com/ksnip/ksnip/issues/338)) * Fixed: Not able to use ksnip if multiple screens are connected under windows. ([#261](https://github.com/ksnip/ksnip/issues/261)) * Fixed kImageAnnotator: Using select tool marks image as changed. ([#97](https://github.com/ksnip/kImageAnnotator/issues/97)) * Fixed kImageAnnotator: Emoticon selector shows a half of current emoticon. ([#104](https://github.com/ksnip/kImageAnnotator/issues/104)) * Fixed kImageAnnotator: FillPicker text or icon sometimes not visible. ([#105](https://github.com/ksnip/kImageAnnotator/issues/105)) * Fixed kImageAnnotator: Wrong image scaling on hdpi screen. ([#81](https://github.com/ksnip/kImageAnnotator/issues/81)) * Fixed kImageAnnotator: Copy area size differs from last capture. ([#107](https://github.com/ksnip/kImageAnnotator/issues/107)) * Fixed kImageAnnotator: Number Tool not reset when switching between tabs. ([#106](https://github.com/ksnip/kImageAnnotator/issues/106)) ## Release 1.6.2 * Changed: Add missing plugs to silence snap socket warnings. ([#313](https://github.com/ksnip/ksnip/issues/313)) * Fixed: Window decoration and alt+tab menu show Wayland generic icon on KDE Plasma. ([#269](https://github.com/ksnip/kImageAnnotator/issues/269)) * Fixed: Logout canceled by 'ksnip' under KDE. ([#281](https://github.com/ksnip/kImageAnnotator/issues/281)) * Fixed: Ksnip not displayed on the monitor (off screen). ([#307](https://github.com/ksnip/kImageAnnotator/issues/307)) * Fixed: CTRL+Q to quit Ksnip not working. ([#308](https://github.com/ksnip/kImageAnnotator/issues/308)) * Fixed: Global Hotkeys not working with activatedDefaultAction Num and Caps Lock under X11. ([#310](https://github.com/ksnip/kImageAnnotator/issues/310)) * Fixed: Meta Global Hotkey under X11 not working. ([#311](https://github.com/ksnip/kImageAnnotator/issues/311)) ## Release 1.6.1 * Changed: Allow opening link directly to image without opening in browser. ([#248](https://github.com/ksnip/kImageAnnotator/issues/248)) * Changed: Always use transparent snipping area background for Wayland. ([#176](https://github.com/ksnip/kImageAnnotator/issues/176)) * Changed: Disable unavailable config options. ([#254](https://github.com/ksnip/kImageAnnotator/issues/254)) * Fixed kImageAnnotator: Edit border around text box doesn't disappear when done with editing. ([#71](https://github.com/ksnip/kImageAnnotator/issues/71)) * Fixed kImageAnnotator: Edit border not shown under Windows when NoFillNoBorder selected for Text Tool. ([#72](https://github.com/ksnip/kImageAnnotator/issues/72)) * Fixed kImageAnnotator: When adding text with background under Windows a filled rect is show in top left corner. ([#73](https://github.com/ksnip/kImageAnnotator/issues/73)) * Fixed kImageAnnotator: Drawing text tool rect from right to left and bottom top create no rect. ([#76](https://github.com/ksnip/kImageAnnotator/issues/76)) * Fixed kImageAnnotator: Text Tool FillType selection not saved. ([#75](https://github.com/ksnip/kImageAnnotator/issues/75)) * Fixed kImageAnnotator: Icons not scaled with HiDPI. ([#77](https://github.com/ksnip/kImageAnnotator/issues/77)) * Fixed kImageAnnotator: Text Cursor not show on Linux. ([#70](https://github.com/ksnip/kImageAnnotator/issues/70)) ## Release 1.6.0 * New: Make captured cursor an item which can be moved and deleted. ([#86](https://github.com/ksnip/ksnip/issues/86)) * New: Add watermarks to annotated image. ([#199](https://github.com/ksnip/ksnip/issues/199)) * New: Add crop button to toolbar. ([#90](https://github.com/ksnip/ksnip/issues/90)) * New: Add undo and redo button on toolbar. ([#124](https://github.com/ksnip/ksnip/issues/124)) * New: Make if watermark is rotated a config option. ([#206](https://github.com/ksnip/ksnip/issues/206)) * New: Do not open image uploaded to imgur in browser. ([#211](https://github.com/ksnip/ksnip/issues/211)) * New: Add shortcuts for taking screenshots. ([#161](https://github.com/ksnip/ksnip/issues/161)) * New: Add Global HotKeys for Windows. ([#161](https://github.com/ksnip/ksnip/issues/161)) * New: Add Global HotKeys for X11. ([#221](https://github.com/ksnip/ksnip/issues/221)) * New: Provide option to use previous capture area. ([#150](https://github.com/ksnip/ksnip/issues/150)) * New: Add System Tray Icon. ([#163](https://github.com/ksnip/ksnip/issues/163)) * New: Show tray icon notification after image was uploaded to imgur or saved. ([#220](https://github.com/ksnip/ksnip/issues/220)) * New: Add support for Open-with. ([#195](https://github.com/ksnip/ksnip/issues/195)) * New: Open ksnip minimized to tray. ([#240](https://github.com/ksnip/ksnip/issues/240)) * New kImageAnnotator: Edit text box content. ([#51](https://github.com/ksnip/kImageAnnotator/issues/51)) * New kImageAnnotator: Panning image by holding space or mouse middle button and dragging. ([#9](https://github.com/ksnip/kImageAnnotator/issues/9)) * New kImageAnnotator: Change annotation element config after drawing. ([#44](https://github.com/ksnip/kImageAnnotator/issues/44)) * Changed: Change copy icon. ([#157](https://github.com/ksnip/ksnip/issues/157)) * Changed: Before discarding ask if user want save or not or cancel. ([#215](https://github.com/ksnip/ksnip/issues/215)) * Changed: Shortcut for imgur upload was changed to Shift + i. ([#161](https://github.com/ksnip/ksnip/issues/161)) * Changed kImageAnnotator: Increase blur level so that large text is not visible. ([#62](https://github.com/ksnip/kImageAnnotator/issues/62)) * Changed kImageAnnotator: Crop widget updates shows via cursor if something is movable. ([#64](https://github.com/ksnip/kImageAnnotator/issues/64)) * Changed kImageAnnotator: Multi-tool buttons select current (last) tool on single click. ([#66](https://github.com/ksnip/kImageAnnotator/issues/66)) * Fixed: Translations not working for Windows and MacOS. ([#164](https://github.com/ksnip/ksnip/issues/164)) * Fixed: AppImage update fails with "None of the artifacts matched the pattern in the update information". ([#166](https://github.com/ksnip/ksnip/issues/166)) * Fixed: Wildcards in path are not resolved. ([#168](https://github.com/ksnip/ksnip/issues/168)) * Fixed: CLI arg --rectarea doesn't work. ([#170](https://github.com/ksnip/ksnip/issues/170)) * Fixed: Imgur Uploader on windows issue. ([#173](https://github.com/ksnip/ksnip/issues/173)) * Fixed: Add shortcut for File Menu in Main Menu. ([#192](https://github.com/ksnip/ksnip/issues/192)) * Fixed: Prompt to save before exit enabled now by default. ([#193](https://github.com/ksnip/ksnip/issues/193)) * Fixed: Configuration Window not translated. ([#186](https://github.com/ksnip/ksnip/issues/186)) * Fixed: ksnip opens anyway with -s option specified. ([#213](https://github.com/ksnip/ksnip/issues/213)) * Fixed: Open Image with full size window doesn't resize main window. ([#194](https://github.com/ksnip/ksnip/issues/194)) * Fixed: Can't work correctly when using scaled display. ([#174](https://github.com/ksnip/ksnip/issues/174)) * Fixed: Not able to restore window from tray under Windows 10. ([#227](https://github.com/ksnip/ksnip/issues/227)) * Fixed: ksnip opens outside desktop if last saved position was on no longer available monitor. ([#236](https://github.com/ksnip/ksnip/issues/236)) * Fixed: Window demaximize when taking a new screenshot. ([#223](https://github.com/ksnip/ksnip/issues/223)) * Fixed: Add support for Chinese Text Input. ([#208](https://github.com/ksnip/ksnip/issues/208)) * Fixed kImageAnnotator: Unable to select number annotation when clicking on the number without background. ([#46](https://github.com/ksnip/kImageAnnotator/issues/46)) * Fixed kImageAnnotator: Ctrl Modifier stuck on second or third screenshot with Ctrl-N. ([#58](https://github.com/ksnip/kImageAnnotator/issues/58)) * Fixed kImageAnnotator: Undo/Redo is now disabled during crop and scale operation. ([#56](https://github.com/ksnip/kImageAnnotator/issues/56)) * Fixed kImageAnnotator: Mess with russian letters in text tool when typing in Russian. ([#59](https://github.com/ksnip/kImageAnnotator/issues/59)) * Fixed kImageAnnotator: Text tool does not allow me to type accents. ([#57](https://github.com/ksnip/ksnip/issues/57)) * Fixed kImageAnnotator: Highlighter rect and ellipse have only border but no fill. ([#65](https://github.com/ksnip/kImageAnnotator/issues/65)) * Fixed kImageAnnotator: Saved tool selection not loaded on startup. ([#67](https://github.com/ksnip/ksnip/issues/67)) * Fixed kImageAnnotator: On startup does not highlight tool, when this tool not the first item in the list. ([#63](https://github.com/ksnip/kImageAnnotator/issues/63)) * Fixed kImageAnnotator: Cursor image cannot be grabbed for moving. ([#69](https://github.com/ksnip/kImageAnnotator/issues/69)) * Fixed kImageAnnotator: Accents still not work in text tool on Linux. ([#61](https://github.com/ksnip/kImageAnnotator/issues/61)) ## Release 1.5.0 * New: Added Continues Build with Travis-CI that creates AppImages for every commit. ([#63](https://github.com/ksnip/ksnip/issues/63)) * New: Added option to open image from file via GUI. ([#60](https://github.com/ksnip/ksnip/issues/60)) * New: Added option to set next number for Numbering Paint Items via popup settings. ([#59](https://github.com/ksnip/ksnip/issues/59)) * New: Added experimental Wayland support for KDE and Gnome DEs. ([#56](https://github.com/ksnip/ksnip/issues/56)) * New: Metadata info for ksnip is now installed in the /usr/share/metainfo directory. ([#66](https://github.com/ksnip/ksnip/issues/66)) * New: Added option to open image from file via CLI. ([#71](https://github.com/ksnip/ksnip/issues/71)) * New: Instant saving captures without prompting for save location. ([#61](https://github.com/ksnip/ksnip/issues/61)) * New: Scaling/resizing screenshots and items. ([#79](https://github.com/ksnip/ksnip/issues/79)) * New: Added translation support. ([#94](https://github.com/ksnip/ksnip/issues/94)) * New: Added Spanish, German, Dutch Norwegian and Polish translation. ([#94](https://github.com/ksnip/ksnip/issues/94)) * New: Option to switch between dynamic and default painter cursor size. ([#77](https://github.com/ksnip/ksnip/issues/77)) * New: Added RPM and DEB binaries to continues build. * New: Added blur annotation tool. ([#109](https://github.com/ksnip/ksnip/issues/109)) * New: Added Windows support. ([#113](https://github.com/ksnip/ksnip/issues/113)) * New: Added Continues build for Windows binaries. ([#114](https://github.com/ksnip/ksnip/issues/114)) * New: Place time delay settings on Toolbar. ([#91](https://github.com/ksnip/ksnip/issues/91)) * New: Add qt style switcher to configuration. ([#137](https://github.com/ksnip/ksnip/issues/137)) * New: Add icons for dark theme. ([#142](https://github.com/ksnip/ksnip/issues/142)) * New: Store imgur delete links. ([#74](https://github.com/ksnip/ksnip/issues/74)) * New: Freeze image while selecting rectangular area. ([#136](https://github.com/ksnip/ksnip/issues/136)) * New: Magnifying glass for snipping area. ([#62](https://github.com/ksnip/ksnip/issues/62)) * New: Add MacOS support. ([#125](https://github.com/ksnip/ksnip/issues/125)) * New: CI support for MacOS. ([#126](https://github.com/ksnip/ksnip/issues/126)) * New kImageAnnotator: Keep number tool sequence consecutive after deleting item. ([#7](https://github.com/ksnip/kImageAnnotator/issues/7)) * New kImageAnnotator: Added control for setting first number for numbering tool. ([#7](https://github.com/ksnip/kImageAnnotator/issues/7)) * New kImageAnnotator: Text and Number tool have now noBorderAndNoFill type. ([#22](https://github.com/ksnip/kImageAnnotator/issues/22)) * New kImageAnnotator: Double Arrow annotation tool. ([#23](https://github.com/ksnip/kImageAnnotator/issues/23)) * New kImageAnnotator: Marker Rectangle and Ellipse annotation tool. ([#26](https://github.com/ksnip/kImageAnnotator/issues/26)) * New kImageAnnotator: Add config option to setup blur radius. ([#25](https://github.com/ksnip/kImageAnnotator/issues/25)) * Changed: Move and select operation are now combined under single tool. ([#72](https://github.com/ksnip/ksnip/issues/72)) * Changed: Item selection is now based on item shape and not on item bounding rect. ([#83](https://github.com/ksnip/ksnip/issues/83)) * Changed: Imgur upload now asks for confirmation before uploading. This can be disabled in setting. ([#73](https://github.com/ksnip/ksnip/issues/73)) * Changed: CLI screenshots open now in editor when triggered without -s flag. ([#103](https://github.com/ksnip/ksnip/issues/103)) * Changed: Default filename features now a more fine-grained time placeholder. ([#110](https://github.com/ksnip/ksnip/issues/110)) * Changed: Console version output doesn't show build. ([#121](https://github.com/ksnip/ksnip/issues/121)) * Changed kImageAnnotator: Blur tool is now preciser and fits the rect. ([#28](https://github.com/ksnip/kImageAnnotator/issues/28)) * Changed kImageAnnotator: Enter finishes text input and shift-enter adds new line in Text Tool. ([#30](https://github.com/ksnip/kImageAnnotator/issues/30)) * Changed kImageAnnotator: Text item draws border around the text when in text edit mode. ([#34](https://github.com/ksnip/kImageAnnotator/issues/34)) * Fixed: Crash on Ubuntu 17.10 caused by null painterPath pointer in smoothOut method. ([#67](https://github.com/ksnip/ksnip/issues/67)) * Fixed: Default filename for screenshot had one $ sign too many. ([#68](https://github.com/ksnip/ksnip/issues/68)) * Fixed: Cancel on browse to save directory in settings dialog clears save path. ([#69](https://github.com/ksnip/ksnip/issues/69)) * Fixed: About dialog not closing when close button is clicked. ([#76](https://github.com/ksnip/ksnip/issues/76)) * Fixed: Undo move operation returns item to wrong location. ([#84](https://github.com/ksnip/ksnip/issues/84)) * Fixed: Crash when adding an item after another item was moved and undone ([#85](https://github.com/ksnip/ksnip/issues/85)) * Fixed: Crop tool not marking screenshot as unsaved after cropping ([#99](https://github.com/ksnip/ksnip/issues/99)) * Fixed: Scale tool not marking screenshot as unsaved after scaling ([#100](https://github.com/ksnip/ksnip/issues/100)) * Fixed: Running ksnip with -e flag and enabled capture screenshot on startup starts new screenshot. ([#105](https://github.com/ksnip/ksnip/issues/105)) * Fixed: Triggering new capture discards unsaved changes. ([#89](https://github.com/ksnip/ksnip/issues/89)) * Fixed: Text tool cannot be resized. ([#111](https://github.com/ksnip/ksnip/issues/111)) * Fixed: Exe file not showing icon on windows. ([#122](https://github.com/ksnip/ksnip/issues/122)) * Fixed: Buttons for text bold, italic and underlined are not correctly shown under windows. ([#118](https://github.com/ksnip/ksnip/issues/118)) * Fixed: ksnip not running on windows when qt not installed. ([#145](https://github.com/ksnip/ksnip/issues/145)) * Fixed: Imgur upload not working under windows. ([#144](https://github.com/ksnip/ksnip/issues/144)) * Fixed: Snipping area with freezed background image not working. ([#149](https://github.com/ksnip/ksnip/issues/149)) * Fixed: Snipping area cursor included in screenshot. ([#148](https://github.com/ksnip/ksnip/issues/148)) * Fixed kImageAnnotator: Double-click on annotation area causes SIGSEGV crash. ([#29](https://github.com/ksnip/kImageAnnotator/issues/29)) * Fixed kImageAnnotator: CAPS LOCK doesnt work on image editor. ([#27](https://github.com/ksnip/kImageAnnotator/issues/27)) * Fixed kImageAnnotator: Unable to select text item when clicking on text. ([#32](https://github.com/ksnip/kImageAnnotator/issues/32)) * Fixed kImageAnnotator: Some blurs get removed when losing focus. ([#35](https://github.com/ksnip/kImageAnnotator/issues/35)) * Fixed kImageAnnotator: Right click on annotation items selects item but doesn't switch tool. ([#40](https://github.com/ksnip/kImageAnnotator/issues/40)) * Fixed kImageAnnotator: Copy number annotation item doesn't increment number. ([#41](https://github.com/ksnip/kImageAnnotator/issues/41)) * Fixed kImageAnnotator: Crash on startup after adding Blur Radius Picker. ([#43](https://github.com/ksnip/kImageAnnotator/issues/43)) ## Release 1.4.0 * New: Info text (cursor position and selection area size) for snipping area cursor, can be enabled and disabled via settings.([#49](https://github.com/ksnip/ksnip/issues/49)) * New: Horizontal vertical guiding lines for snipping area cursor, can be enabled and disabled via settings. ([#48](https://github.com/ksnip/ksnip/issues/48)) * New: Drop shadow for paint items, can be enabled and disabled via settings ([#47](https://github.com/ksnip/ksnip/issues/47)) * New: Copy/past paint items. ([#46](https://github.com/ksnip/ksnip/issues/46)) * New: Numbering paint item. ([#45](https://github.com/ksnip/ksnip/issues/45)) * New: Arrow paint item. ([#44](https://github.com/ksnip/ksnip/issues/44)) * New: Select multiple paint items and perform operation on all selected at once. ([#42](https://github.com/ksnip/ksnip/issues/42)) * New: Run last or default capture on startup. ([#40](https://github.com/ksnip/ksnip/issues/40)) * New: Run rect capture from command line. ([#39](https://github.com/ksnip/ksnip/issues/39)) * New: Select between default and custom filename for saving screenshots. ([#36](https://github.com/ksnip/ksnip/issues/36)) * New: Keyboard shortcuts for paint tools. ([#43](https://github.com/ksnip/ksnip/issues/43)) * New: Bring to front and send to back paint items. ([#31](https://github.com/ksnip/ksnip/issues/31)) * New: Configurable snipping cursor thickness and color. ([#54](https://github.com/ksnip/ksnip/issues/54)) * Changed: Moving Ksnip from Qt4 to Qt5. ([#22](https://github.com/ksnip/ksnip/issues/22)) * Fixed: Settings window left hand side menu is not correctly selected when opening first time. ([#37](https://github.com/ksnip/ksnip/issues/37)) * Fixed: Snipping area not correctly shown when started on non-primary screen. ([#52](https://github.com/ksnip/ksnip/issues/52)) * Fixed: Active window screenshot ignores delay. ([#53](https://github.com/ksnip/ksnip/issues/53)) * Fixed: Rectangular area screenshot is shifted to the right of actual selected area. ([#51](https://github.com/ksnip/ksnip/issues/51)) * Fixed: Snipping area not closing when pressing Esc on Ubuntu 16.04. ([#57](https://github.com/ksnip/ksnip/issues/57)) ## Release 1.3.2 * Fixed: When compositor is disabled, rect are capture shows only black screen. Fix for Qt4 Ksnip version ([#35](https://github.com/ksnip/ksnip/issues/35)) ## Release 1.3.1 * Fixed: Ksnip 1.3.0 fails to build - due to missing cmath library ([#29](https://github.com/ksnip/ksnip/issues/29)) ## Release 1.3.0 * New: Drawing two shapes, ellipse and rectangle, with and without fill. ([#21](https://github.com/ksnip/ksnip/issues/21)) * New: Customizable color and size (thickness) for drawing tools via button on main tool bar. ([#25](https://github.com/ksnip/ksnip/issues/25)) * New: Writing text on screenshots, with customizable font, size, color etc. ([#8](https://github.com/ksnip/ksnip/issues/8)) * New: Undo/Redo for paint and crop operations. ([#5](https://github.com/ksnip/ksnip/issues/5)) * New: Smooth out free hand pen and marker lines (can be disabled in settings). ([#16](https://github.com/ksnip/ksnip/issues/16)) * New: Print screenshot or save is to prf/ps. ([#23](https://github.com/ksnip/ksnip/issues/23)) * Fixed: Second and subsequent crops don't move painter items correctly ([#27](https://github.com/ksnip/ksnip/issues/27)) * Fixed: Confirming crop via keyboard doesn't close crop panel ([28](https://github.com/ksnip/ksnip/issues/28)) ## Release 1.2.1 * Fixed: Ksnip 1.2.0 binary segfaults when compiled in x86_64 with -fPIC in gcc-5.4.0 ([#20](https://github.com/ksnip/ksnip/issues/20)) * Fixed: Incorrect version number in "About" dialog. ## Release 1.2.0 * New: Added functionality to upload screenshots to Imgur.com in anonymous or account mode. ([#14](https://github.com/ksnip/ksnip/issues/14)) * New: Capture mouse cursor on screenshot (feature can be enabled or disabled in settings). ([#18](https://github.com/ksnip/ksnip/issues/18)) * New: In crop window the crop position, width and height can be entered in numeric values, to provide a more precise crop. ([#17](https://github.com/ksnip/ksnip/issues/17)) * Changed: Settings Window Layout was changed and reorganized. * Fixed: Paint cursor was visible when capturing new screenshot. * Fixed: Crop could leave scene area. ## Release 1.1.0 * New: Cropping captured image to desired size. ([#4](https://github.com/ksnip/ksnip/issues/4)) * New: Command line support, screenshotsa can be taken now from command line too. ([#11](https://github.com/ksnip/ksnip/issues/11)) * New: Moving drawn lines to desired position by dragging. ([#2](https://github.com/ksnip/ksnip/issues/2)) * New: Setting default save location, filename and format from settings window. ([#9](https://github.com/ksnip/ksnip/issues/9)) * Changed: Capturing current screen captures now the screen where the mouse cursor is located. ## Release 1.0.0 * New: Screenshots from a custom drawn rectangular area. * New: Screenshots from the screen where ksnip is currently located (for multi monitor environments). * New: Screenshots from the whole screen, including all monitors. * New: Screenshot of currently active (on top) window. * New: Delayed captures. * New: Drawing on the captured screenshot with Pen or Marker with changeable color and size. * New: Saving ksnip location and selected tool and loading on startup. ksnip-master/CMakeLists.txt000066400000000000000000000045331457262621600162530ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.5) project(ksnip LANGUAGES CXX VERSION 1.11.0) if (DEFINED VERSION_SUFIX AND NOT "${VERSION_SUFIX}" STREQUAL "") set(KSNIP_VERSION_SUFIX "-${VERSION_SUFIX}") endif() set(KSNIP_VERSION "${PROJECT_VERSION}${KSNIP_VERSION_SUFIX}") include(GNUInstallDirs) if (WIN32) set(KSNIP_LANG_INSTALL_DIR "translations") set(KIMAGEANNOTATOR_LANG_INSTALL_DIR "translations") elseif (APPLE) set(KSNIP_LANG_INSTALL_DIR "../Resources") set(KIMAGEANNOTATOR_LANG_INSTALL_DIR "../Resources") elseif (UNIX) set(KSNIP_LANG_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/ksnip/translations") set(KIMAGEANNOTATOR_LANG_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/kImageAnnotator/translations") endif () configure_file(src/BuildConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/BuildConfig.h) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) option(BUILD_TESTS "Build Unit Tests" OFF) if (UNIX AND NOT APPLE) # Without ECM we're unable to load XCB find_package(ECM REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) find_package(X11 REQUIRED) find_package(XCB COMPONENTS XFIXES) endif () set(QT_COMPONENTS Core Widgets Network Xml PrintSupport DBus Svg) set(QT_MIN_VERSION 5.15.2) option(BUILD_WITH_QT6 "Build against Qt6" OFF) if (BUILD_WITH_QT6) set(QT_MAJOR_VERSION 6) else() set(QT_MAJOR_VERSION 5) endif() if (UNIX AND NOT APPLE) list(APPEND QT_COMPONENTS Concurrent) endif() if (X11_FOUND) list(APPEND QT_COMPONENTS X11Extras) elseif (WIN32) list(APPEND QT_COMPONENTS WinExtras) endif() if (BUILD_TESTS) list(APPEND QT_COMPONENTS Test) endif() find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} REQUIRED ${QT_COMPONENTS}) set(KIMAGEANNOTATOR_MIN_VERSION 0.7.1) find_package(kImageAnnotator-Qt${QT_MAJOR_VERSION} ${KIMAGEANNOTATOR_MIN_VERSION} REQUIRED) set(KCOLORPICKER_MIN_VERSION 0.3.0) find_package(kColorPicker-Qt${QT_MAJOR_VERSION} ${KCOLORPICKER_MIN_VERSION} REQUIRED) set(BASEPATH "${CMAKE_SOURCE_DIR}") include_directories("${BASEPATH}") add_subdirectory(src) add_subdirectory(translations) add_subdirectory(desktop) if (BUILD_TESTS) configure_file(src/BuildConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/tests/BuildConfig.h) add_subdirectory(tests) endif (BUILD_TESTS) ksnip-master/CODINGSTYLE.md000066400000000000000000000030221457262621600156110ustar00rootroot00000000000000Ksnip follows the KDELibs (see https://community.kde.org/Policies/Kdelibs_Coding_Style) coding style, with a few exceptions: 1. The access modifier ordering is: public, public slots, signals, protected, protected slots, private, private slots. Member variables come at beginning, before all member functions. This is not strictly enforced, but is a good rule to follow. 2. Headers are cumulative, i.e., all headers that a particular class requires, are #include-ed in the class's header file, not the .cpp code file. The .cpp code file includes only one header, which is its own .h file. E.g., a class Foo, defined in Foo.h, will have its code in Foo.cpp, and Foo.cpp will #include only a single header Foo.h 3. Member variables follow the format mCamelCase, and not m_camelCase which is more common throughout the rest of the KDE Applications 4. Source files are mixed case, named the same as the class they contain. i.e., SomeClass will be defined in SomeClass.cpp, not someclass.cpp 5. Function parameters, if classes, should be past as const references, if basic types like bool, int, float, enum, can be passed by value. Functions that do not change anything on the class (like getters), should be const. 6. Use single TAB instead of four spaces to indent. 7. UnitTest should have the following naming convention: `_Should__When_` Example: `StoreImagesPath_Should_NotSavePath_When_PathAlreadyStored` 8. Tabs should be used for indentation. ksnip-master/CONTACT.md000066400000000000000000000003731457262621600151260ustar00rootroot00000000000000Welcome to the ksnip community. Give and grant anyone constrictive criticism and their desired privacy. Settle conflicts within these bounds. Finding yourselves unable to do so, e-mail [Damir Porobić](email@damirporobic.me), the project maintainer. ksnip-master/LICENSE.txt000066400000000000000000001045151457262621600153370ustar00rootroot00000000000000 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 . ksnip-master/README.md000066400000000000000000000530051457262621600147700ustar00rootroot00000000000000# [ksnip](http://ksnip.org/) [![Linux build status][github-linux-badge]][github-linux-url] [![Windows build status][github-windows-badge]][github-windows-url] [![MacOS build status][github-macos-badge]][github-macos-url] [![GitHub commits (since latest release)][gh-comm-since-badge]][gh-comm-since-url] [![Translation status][weblate-badge]][weblate-url] [![GitHub total downloads][gh-dl-badge]][gh-dl-url] [![SourceForge total downloads][sf-dt-badge]][sf-dt-badge-url] [![Discord][discord-badge]][discord-badge-url] [![IRC: #ksnip on libera.chat][libera-badge]][libera-badge-url] [![GitHub license](https://img.shields.io/github/license/ksnip/ksnip?color=lightgrey)](https://github.com/ksnip/ksnip/blob/master/LICENSE.txt) Version v1.11.0 Ksnip is a Qt-based cross-platform screenshot tool that provides many annotation features for your screenshots. ![ksnip](https://i.imgur.com/0oP6i1H.png "Ksnip with annotations") # Features Latest ksnip version contains following features: * Supports Linux (X11, Plasma Wayland, GNOME Wayland and xdg-desktop-portal Wayland), Windows and macOS. * Screenshot of a custom rectangular area that can be drawn with mouse cursor. * Screenshot of last selected rectangular area without selecting again. * Screenshot of the screen/monitor where the mouse cursor is currently located. * Screenshot of full-screen, including all screens/monitors. * Screenshot of window that currently has focus. * Screenshot of window under mouse cursor. * Screenshot with or without mouse cursor. * Capture mouse cursor as annotation item that can be moved and deleted. * Customizable capture delay for all capture options. * Upload screenshots directly to imgur.com in anonymous or user mode. * Upload screenshots via FTP in anonymous or user mode. * Upload screenshots via custom user defined scripts. * Command-line support, for capturing screenshots and saving to default location, filename and format. * Filename wildcards for Year ($Y), Month ($M), Day ($D), Time ($T) and Counter (multiple # characters for number with zero-leading padding). * Print screenshot or save it to PDF/PS. * Annotate screenshots with pen, marker, rectangles, ellipses, texts and other tools. * Annotate screenshots with stickers and add custom stickers. * Crop and cut out vertical/horizontal slices of images. * Obfuscate image regions with blur and pixelate. * Add effects to image (Drop Shadow, Grayscale, invert color or Border). * Add watermarks to captured images. * Global hotkeys for capturing screenshots (currently only for Windows and X11). * Tabs for screenshots and images. * Open existing images via dialog, drag-and-drop or paste from clipboard. * Run as single instance application (secondary instances send cli parameter to primary instance). * Pin screenshots in frameless windows that stay atop other windows. * User-defined actions for taking screenshot and post-processing. * OCR support through plugin (Window and Linux/Unix). * Many configuration options. # Supported Screenshot Types | | Rect Area | Last Rect Area | Full Screen | Current Screen | Active Window | Window Under Cursor | Without Mouse Cursor | Screenshot Portal | | --------------------|:---------:|:--------------:|:-----------:|:--------------:|:-------------:|:-------------------:|:--------------------:|:-----------------:| | X11 | X | X | X | X | X | | X | | | Plasma Wayland | | | X | X | | X | | | | Gnome Wayland `< 41`| X | X | X | X | X | | X | | | xdg-desktop-portal* | | | | | | | | X | | Windows | X | X | X | X | X | | X | | | macOS | X | X | X | X | | | | | * xdg-desktop-portal screenshots are screenshots taken by the compositor and passed to ksnip, you will see a popup dialog that required additional confirmation, the implementation can vary depending on the compositor. Currently, Snaps and Gnome Wayland `>= 41` only support xdg-desktop-portal screenshots, this is a limitation coming from the Gnome and Snaps, non-native screenshot tools are not allowed to take screenshots in any other way except through the xdg-desktop-portal. # Installing Binaries Binaries can be downloaded from the [Releases page](https://github.com/ksnip/ksnip/releases). Currently, RPM, DEB, APT, Snap, Flatpak and AppImage for Linux, zipped EXE for Windows and APP for macOS in a DMG package are available. ### Continuous build All supported binaries are built for every pushed commit, to be found at the top of the release page. Continuous build artifacts are not fully tested and in most cases they are work in progress, so use them with caution. ## Linux *Click on the item, to expand information.*
AppImage To use AppImages, make them executable and run them, no installation required. ``` $ chmod a+x ksnip*.AppImage $ ./ksnip*.AppImage ``` More info about setting to executable can be found [here](https://discourse.appimage.org/t/how-to-make-an-appimage-executable/80).
RPM Just install them via RPM and use. ``` $ rpm -Uvh ksnip*.rpm $ ksnip ```
DEB Just install them via apt and start using. ``` $ sudo apt install ./ksnip*.deb $ ksnip ```
APT Starting with Ubuntu 21.04 Hirsute Hippo, you can install from the [official package](https://launchpad.net/ubuntu/+source/ksnip): ``` $ sudo apt install ksnip ``` For older Ubuntu versions, you can use [@nemonein](https://github.com/nemonein)'s unofficial [PPA](url): ``` sudo add-apt-repository ppa:nemonein/ksnip sudo apt update sudo apt install ksnip ``` For Debian 11 and later releases, you can install from the [official package](https://tracker.debian.org/pkg/ksnip): ``` $ sudo apt install ksnip ``` For Debian 10 and Debian 9, ksnip is available via [Debian Backports](https://backports.debian.org/). Please enable `bullseye-backports` and `buster-backports` repo for Debian 10 and Debian 9 respectively before installing using `sudo apt install ksnip`.
ArchLinux Ksnip is in the [Extra repository](https://archlinux.org/packages/extra/x86_64/ksnip/), so you can install it directly via pacman. ``` $ sudo pacman -S ksnip ``` If you want to build from the GIT repository, you can use the [AUR package](https://aur.archlinux.org/packages/ksnip-git/) (make sure you build the necessary dependencies too). ``` $ yay -S ksnip-git kimageannotator-git kcolorpicker-git ```
Snap The usual method for Snaps, will install the latest version: ``` $ sudo snap install ksnip ``` The continuous build version is also available as edge, in order to install it you need to provide the edge flag: ``` $ sudo snap install ksnip --edge ``` Snap startup time can be sped up and console output cleaned up from following error `Could not create AF_NETLINK socket (Permission denied)` by running the following commands: ``` $ snap connect ksnip:network-observe $ snap connect ksnip:network-manager-observe ``` If you need to save screenshots to a removable media, the following additional connection is required: ``` $ snap connect ksnip:removable-media ``` This only needs to be done once and connects some Snap plugs which are currently not auto-connected. [![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/ksnip)
Flatpak The usual method for Flatpaks will install the latest version: ``` $ flatpak install flathub org.ksnip.ksnip ``` Then just start it: ``` $ flatpak run org.ksnip.ksnip ``` Download on Flathub
## Windows
MSI The MSI installer installs ksnip on your system and is the preferred way for installing ksnip under Windows.
EXE The EXE file with all required dependencies comes in a zipped package, which just need to be unzipped with your favorite unpacking tool. Ksnip can then be started by just double-clicking ksnip.exe.
## macOS
APP The app file comes in a DMG package which needs to be opened, and the ksnip.app file needs to be dragged and dropped into the "Application" folder. After that the application can be started by double clicking ksnip.app
Homebrew Cask Just install via Homebrew and start using from your "Applications" folder. ``` $ brew install --cask ksnip ```
# Plugins ksnip functionality can be extended by using plugins that need to be downloaded separately and installed or unpacked, depending on the environment. Currently, under `Options > Settings > Plugins` a plugin detection can be triggered either in the default location(s) or by providing a search path where to look for plugins. After clicking on "Detect", ksnip searches for known plugins and when found will list the name and version. ### Default search locations Windows: `plugins` directory, next to `ksnip.exe` Linux/Unix: `/usr/local/lib`, `/usr/local/lib64`, `/usr/lib`, `/usr/lib64` ### Version selection The plugin must match the Qt version and build type of ksnip. If you have a ksnip version that uses Qt 15.5.X and was build in `DEBUG` then the plugin must match the same criteria. In most cases the latest ksnip and plugin version will be using the same Qt version, the only think that you need to watch out for is to not mix `DEBUG` and `RELEASE` build. ## OCR (Window and Linux/Unix) ksnip supports OCR by using the [ksnip-plugin-ocr](https://github.com/ksnip/ksnip-plugin-ocr) which utilizes Tesseract to convert Image to text. When the OCR plugin was loaded, the OCR option becomes available under `Options > OCR`. The latest plugin version can be found [here](https://github.com/ksnip/ksnip-plugin-ocr/releases). # Dependencies ksnip depends on [kImageAnnotator](https://github.com/ksnip/kImageAnnotator) and [kColorPicker](https://github.com/DamirPorobic/kColorPicker) which needs to be installed before building ksnip from source. Installation instructions can be found on the Github pages. # Building from source 1. Get the latest release from GitHub by cloning the repo: `$ git clone https://github.com/ksnip/ksnip` 2. Change to repo directory: `$ cd ksnip` 3. Make new build directory and enter it: `$ mkdir build && cd build` 4. Create the makefile and build the project: `$ cmake .. && make` 5. Now install the application, eventually you need to run it with sudo: `$ sudo make install` 6. Run the application: `$ ksnip` If you are using Archlinux, you may prefer to [build ksnip through AUR](https://github.com/ksnip/ksnip#archlinux). # Known Issues
Expand ### X11 1. Snipping area with transparent background doesn't work when compositor is turned off, freeze background is used in that case. ### macOS 1. Snipping area with transparent background doesn't work, freeze background is always used. Issue [#151](https://github.com/ksnip/ksnip/issues/151) 2. Second activation of snipping area doesn't get focus, you need to switch to the right side in order to see the snipping area. Issue [#152](https://github.com/ksnip/ksnip/issues/152) 3. Mouse cursor is always captured. Issue [#153](https://github.com/ksnip/ksnip/issues/153) ### Wayland 1. Portal and Native Screenshots not working under KDE Plasma `>= 5.80`. The issue is coming from a recent change in KDE Plasma that prevents access to DBUS Interfaces responsible for taking screenshots. This issue is going to be fixed in future Plasma releases for the Portal Screenshots. Workaround for making the Portal Screenshots work is adding the string `X-KDE-DBUS-Restricted-Interfaces=org.kde.kwin.Screenshot` to the `/usr/share/applications/org.freedesktop.impl.portal.desktop.kde.desktop` file and then restarting. Don't forget to enforce Portal screenshots in settings. Issue [#424](https://github.com/ksnip/ksnip/issues/424) 2. Under Gnome Wayland copying images to clipboard and then pasting them somewhere might not work. This happens currently with native Wayland. A workaround is using XWayland by starting ksnip like this `QT_QPA_PLATFORM=xcb /usr/bin/ksnip` or switch to XWayland completely by exporting that variable `export QT_QPA_PLATFORM=xcb`. Issue [#416](https://github.com/ksnip/ksnip/issues/416) 3. Native Wayland screenshots are no longer possible with Gnome `>= 41`. The Gnome developers have forbidden access to the DBus interface that provides Screenshots under Wayland and leave non Gnome application only the possibility to use xdg-desktop-portal screenshots. Security comes before usability for the Gnome developers. There is an open feature request to only grant screenshot permission once instead of for every screenshot, help us raise awareness for such feature [here](https://github.com/flatpak/xdg-desktop-portal/issues/649). 4. Global Hotkeys don't work under Wayland, this is due to the secure nature of Wayland. As long as compositor developers don't provide an interface for us to work with Global Hotkeys, does won't be supported. ### Screen Scaling (HiDPI) 1. Qt is having issues with screen scaling, it can occur that the Snipping area is incorrectly positioned. As a workaround the Snipping Area position or offset can be configured so that it's placed correctly. Issue [#276]
### Snap 1. Drag and Drop might not be working when ksnip or the application that you drag and drop from/to is installed as snap. the reason being that the image is shared via the temp directory which in case of snaps are restricted and every application can only see their own files or files of the user. The workaround for this is to change the temp directory location to a user owned directory like home, document or download directory via `Options > Settings > Application > Temp Directory`. # Discussion & Community If you have general questions, ideas or just want to talk about ksnip, please join our [Discord][discord-badge-url] or [IRC][libera-badge-url] server. # Contribution Any contribution is welcome, be it code, translations or other things. Currently, we need: * Developers for writing code and fixing bugs for linux, windows and macOS. We have **only one developer** and the feature requests and bugs are pilling up. * Testers for testing releases on different OS and Distros. * Docu writers, there are a lot of features that the casual users don't know about. * Bug reporting, Please report any bugs or feature requests related to the annotation editor on the [kImageAnnotator](https://github.com/ksnip/kImageAnnotator/issues) GitHub page under the "Issue" section. All other bugs or feature requests can be reported on the [ksnip](https://github.com/ksnip/ksnip/issues) GitHub page under the "Issue" section. * Translations - [Weblate](https://hosted.weblate.org/projects/ksnip/translations/) is used for translations. For translating annotator-related texts, please refer to [kImageAnnotator](https://github.com/ksnip/kImageAnnotator)
Translation status [![Translation status](https://hosted.weblate.org/widgets/ksnip/-/translations/multi-green.svg)](https://hosted.weblate.org/engage/ksnip/?utm_source=widget)
# Donation ksnip is a non-profitable copylefted libre software project, and still has some costs that need to be covered, like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done by treating developers to a beer or coffee, you can do that [here](https://www.paypal.me/damirporobic), donations are always welcome :) In order to improve our MacOS support, we are trying to collect some money to buy a MacBook, you can donate [here](https://www.gofundme.com/f/buy-a-macbook-for-ksnips-cross-platform-support). Also in crypto: BTC: `bc1q6cke457fk8qhxxacl4nu5q2keudtdukrqe2gx0` ETH: `0xbde87a83427D61072055596e7a746CeC5316253C` BNB: `bnb1fmy0vupsv23s36sejp07jetj6exj3hqeewkj6d` [github-linux-badge]: https://github.com/ksnip/ksnip/actions/workflows/linux.yml/badge.svg [github-linux-url]: https://github.com/ksnip/ksnip/actions/workflows/linux.yml [github-windows-badge]:https://github.com/ksnip/ksnip/actions/workflows/windows.yml/badge.svg [github-windows-url]: https://github.com/ksnip/ksnip/actions/workflows/windows.yml [github-macos-badge]: https://github.com/ksnip/ksnip/actions/workflows/macos.yml/badge.svg [github-macos-url]: https://github.com/ksnip/ksnip/actions/workflows/macos.yml [weblate-badge]: https://hosted.weblate.org/widgets/ksnip/-/translations/svg-badge.svg [weblate-url]: https://hosted.weblate.org/engage/ksnip/?utm_source=widget [gh-dl-badge]: https://img.shields.io/github/downloads/damirporobic/ksnip/total.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMTIgMTIgNDAgNDAiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0zMiwxMy40Yy0xMC41LDAtMTksOC41LTE5LDE5YzAsOC40LDUuNSwxNS41LDEzLDE4YzEsMC4yLDEuMy0wLjQsMS4zLTAuOWMwLTAuNSwwLTEuNywwLTMuMiBjLTUuMywxLjEtNi40LTIuNi02LjQtMi42QzIwLDQxLjYsMTguOCw0MSwxOC44LDQxYy0xLjctMS4yLDAuMS0xLjEsMC4xLTEuMWMxLjksMC4xLDIuOSwyLDIuOSwyYzEuNywyLjksNC41LDIuMSw1LjUsMS42IGMwLjItMS4yLDAuNy0yLjEsMS4yLTIuNmMtNC4yLTAuNS04LjctMi4xLTguNy05LjRjMC0yLjEsMC43LTMuNywyLTUuMWMtMC4yLTAuNS0wLjgtMi40LDAuMi01YzAsMCwxLjYtMC41LDUuMiwyIGMxLjUtMC40LDMuMS0wLjcsNC44LTAuN2MxLjYsMCwzLjMsMC4yLDQuNywwLjdjMy42LTIuNCw1LjItMiw1LjItMmMxLDIuNiwwLjQsNC42LDAuMiw1YzEuMiwxLjMsMiwzLDIsNS4xYzAsNy4zLTQuNSw4LjktOC43LDkuNCBjMC43LDAuNiwxLjMsMS43LDEuMywzLjVjMCwyLjYsMCw0LjYsMCw1LjJjMCwwLjUsMC40LDEuMSwxLjMsMC45YzcuNS0yLjYsMTMtOS43LDEzLTE4LjFDNTEsMjEuOSw0Mi41LDEzLjQsMzIsMTMuNHoiLz48L3N2Zz4= [gh-dl-url]: https://github.com/ksnip/ksnip/releases [sf-dt-badge]: https://img.shields.io/sourceforge/dt/ksnip.svg?logo=data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAyMDAxMDkwNC8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAxL1JFQy1TVkctMjAwMTA5MDQvRFREL3N2ZzEwLmR0ZCI+PHN2ZyB2ZXJzaW9uPSIxLjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjMzMHB4IiBoZWlnaHQ9IjMzMHB4IiB2aWV3Qm94PSIwIDAgMzMwMCAzMzAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0Ij48ZyBpZD0ibGF5ZXIxMDEiIGZpbGw9IiNmZmYiIHN0cm9rZT0ibm9uZSI+IDxwYXRoIGQ9Ik0xNTI4IDMwMTkgYy0xMCAtNSAtMTggLTIwIC0xOCAtMzIgMCAtMTYgMTczIC0xOTUgNjA3IC02MjkgNTYyIC01NjIgNjA2IC02MDkgNjA1IC02MzkgLTEgLTI5IC00OSAtODEgLTQ4MSAtNTEzIC0zMjMgLTMyMyAtNDgxIC00ODggLTQ4MSAtNTAyIDAgLTIzIDE5OCAtMjI0IDIyMSAtMjI0IDE5IDAgMTIzOSAxMjIxIDEyMzkgMTI0MCAwIDggLTI5MSAzMDYgLTY0NyA2NjIgbC02NDggNjQ4IC0xOTAgMCBjLTExMCAwIC0xOTcgLTUgLTIwNyAtMTF6Ii8+IDxwYXRoIGQ9Ik02ODIgMjIwNiBjLTQwMSAtNDAwIC02MTMgLTYxOSAtNjExIC02MjkgNCAtMTggMTI2MiAtMTI4MiAxMjkxIC0xMjk4IDIzIC0xMyAzNzUgLTEyIDM5OSAxIDEwIDYgMTkgMjEgMTkgMzMgMCAxNSAtMTcyIDE5NCAtNjA0IDYyNyAtMzMzIDMzMyAtNjA1IDYxMiAtNjA2IDYyMCAtMiA4IC0yIDI0IC0xIDM1IDEgMTIgMTkzIDIxMiA0ODEgNTAwIDMwOCAzMDggNDgwIDQ4NyA0ODAgNTAwIDAgMjMgLTE5NyAyMjUgLTIyMCAyMjUgLTggMCAtMjkxIC0yNzYgLTYyOCAtNjE0eiIvPiA8cGF0aCBkPSJNMTU5MiAyMjM5IGMtMTM5IC0yMyAtMjY5IC0xMjMgLTMzNiAtMjYwIC00NiAtOTUgLTYwIC0xNjkgLTUyIC0yODkgMTAgLTE2MiA1MSAtMjU4IDE4NiAtNDMxIDEwOCAtMTM4IDEzOCAtMTk2IDE1MyAtMjg4IDEyIC04MyAyNiAtOTAgNzMgLTM4IDgxIDg2IDEzNyAxODYgMTc5IDMxNyA0MCAxMjYgNTUgMjE2IDY2IDQwMCA2IDkxIDE2IDE3NiAyMiAxOTAgMTggMzcgNTEgMzcgNzYgMSA0OCAtNjYgNTUgLTEwNiA1NSAtMjg0IDAgLTEwOSA0IC0xNjYgMTEgLTE2NCAxNiA1IDUzIDkxIDgwIDE4NCA5MSAzMTIgLTg3IDYyMCAtMzgxIDY2MyAtMzggNSAtNzEgOSAtNzQgOSAtMyAtMSAtMjkgLTUgLTU4IC0xMHoiLz4gPC9nPjwvc3ZnPg== [sf-dt-badge-url]: https://sourceforge.net/projects/ksnip [gh-comm-since-badge]: https://img.shields.io/github/commits-since/damirporobic/ksnip/latest.svg?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgdmlld0JveD0iMTIgMTIgNDAgNDAiPjxwYXRoIGZpbGw9IiNmZmYiIGQ9Ik0zMiwxMy40Yy0xMC41LDAtMTksOC41LTE5LDE5YzAsOC40LDUuNSwxNS41LDEzLDE4YzEsMC4yLDEuMy0wLjQsMS4zLTAuOWMwLTAuNSwwLTEuNywwLTMuMiBjLTUuMywxLjEtNi40LTIuNi02LjQtMi42QzIwLDQxLjYsMTguOCw0MSwxOC44LDQxYy0xLjctMS4yLDAuMS0xLjEsMC4xLTEuMWMxLjksMC4xLDIuOSwyLDIuOSwyYzEuNywyLjksNC41LDIuMSw1LjUsMS42IGMwLjItMS4yLDAuNy0yLjEsMS4yLTIuNmMtNC4yLTAuNS04LjctMi4xLTguNy05LjRjMC0yLjEsMC43LTMuNywyLTUuMWMtMC4yLTAuNS0wLjgtMi40LDAuMi01YzAsMCwxLjYtMC41LDUuMiwyIGMxLjUtMC40LDMuMS0wLjcsNC44LTAuN2MxLjYsMCwzLjMsMC4yLDQuNywwLjdjMy42LTIuNCw1LjItMiw1LjItMmMxLDIuNiwwLjQsNC42LDAuMiw1YzEuMiwxLjMsMiwzLDIsNS4xYzAsNy4zLTQuNSw4LjktOC43LDkuNCBjMC43LDAuNiwxLjMsMS43LDEuMywzLjVjMCwyLjYsMCw0LjYsMCw1LjJjMCwwLjUsMC40LDEuMSwxLjMsMC45YzcuNS0yLjYsMTMtOS43LDEzLTE4LjFDNTEsMjEuOSw0Mi41LDEzLjQsMzIsMTMuNHoiLz48L3N2Zz4= [gh-comm-since-url]: https://github.com/ksnip/ksnip/releases/tag/continuous [discord-badge]: https://img.shields.io/discord/812295724837371955.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2 [discord-badge-url]: http://discord.ksnip.org [libera-badge]: https://img.shields.io/badge/libera.chat-%23ksnip-brightgreen.svg [libera-badge-url]: https://web.libera.chat/?channels=#ksnip ksnip-master/cmake/000077500000000000000000000000001457262621600145665ustar00rootroot00000000000000ksnip-master/cmake/cmake_uninstall.cmake.in000066400000000000000000000017551457262621600213560ustar00rootroot00000000000000if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach(file) ksnip-master/desktop/000077500000000000000000000000001457262621600151575ustar00rootroot00000000000000ksnip-master/desktop/CMakeLists.txt000066400000000000000000000006101457262621600177140ustar00rootroot00000000000000# Add desktop file and desktop icon to target machine # Add metadata file if(UNIX AND NOT APPLE) install(PROGRAMS org.ksnip.ksnip.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) install(FILES ksnip.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps) install(FILES org.ksnip.ksnip.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo) endif() ksnip-master/desktop/ksnip.svg000066400000000000000000000124261457262621600170310ustar00rootroot00000000000000 image/svg+xml ksnip-master/desktop/org.ksnip.ksnip.appdata.xml000066400000000000000000000660001457262621600223510ustar00rootroot00000000000000 org.ksnip.ksnip FSFAP GPL-2.0+ Damir Porobic ksnip Cross-Platform Screenshot tool with annotation features

Ksnip is a Qt based cross-platform screenshot tool that provides many annotation features for your screenshots.

Features:

  • Supports Linux (X11, Plasma Wayland, GNOME Wayland and xdg-desktop-portal Wayland), Windows and macOS.
  • Taking screenshot of a custom rectangular area that can be drawn with mouse cursor.
  • Taking screenshot of last selected rectangular area without selecting again.
  • Taking screenshot of the screen/monitor where the mouse cursor is currently located.
  • Taking screenshot of full screen, including all screens/monitors.
  • Taking screenshot of window that currently has focus.
  • Taking screenshot of window under mouse cursor.
  • Take screenshot with or without mouse cursor.
  • Capture mouse cursor as annotation item that can be moved and deleted.
  • Customizable capture delay for all capture options.
  • Upload screenshots directly to imgur.com in anonymous or user mode.
  • Upload screenshots via custom user defined scripts.
  • Command line support, for taking screenshot and saving it to default location, filename and format.
  • Filename wildcards for Year ($Y), Month ($M), Day ($D), Time ($T) and Counter (multiple # characters for number with zero leading padding).
  • Print screenshot or save is to pdf/ps.
  • Annotate screenshots with pen, marker, rectangles, ellipses, texts and other tools.
  • Annotate screenshots with stickers and add custom stickers.
  • Obfuscate image regions with blur and pixelate.
  • Add effects to image (Drop Shadow, Grayscale, invert color or Border).
  • Add watermarks to captured images.
  • Global HotKeys for taking Screenshots (Currently only for Windows and X11).
  • Tabs for Screenshots and images.
  • Open existing images via dialog, drag-and-drop or paste from clipboard.
  • Run as single instance application (secondary instances send cli parameter to primary instance).
  • Pin Screenshots in Frameless windows that stay on top of other windows.
  • User-defined actions for taking screenshot and post-processing.
  • OCR support through plugin (Window and Linux/Unix).
  • Many configuration options.
org.ksnip.ksnip.desktop http://ksnip.org Main Window https://i.imgur.com/4nMcbnF.png Crop Window https://i.imgur.com/1aQZID6.png Snipping Window 1 https://i.imgur.com/gXolSAI.png Snipping Window 2 https://i.imgur.com/ATGeYvI.png Snipping Window 3 https://i.imgur.com/dMrqJpq.png Settings Dialog https://i.imgur.com/5YaVTV4.png Sticker Settings https://i.imgur.com/PCLxIUo.png Imgur History Links https://i.imgur.com/AQuHhDR.png ksnip org.ksnip.ksnip.desktop damir.porobic@gmx.com
  • Fixed: Cannot compile from source, kImageAnnotatorConfig not found despite being built and installed.
  • New kImageAnnotator: Allow copying items between tabs.
  • New kImageAnnotator: CTRL + A does not select all text typed.
  • New kImageAnnotator: Open text edit mode when double-click on textbox figure in Text tool.
  • New kImageAnnotator: Add reflowing capability to the text tool.
  • New kImageAnnotator: Editing text, no mouse cursor edit functions.
  • New kImageAnnotator: Mouse click within a text box for setting specific editing position and selecting text.
  • Fixed kImageAnnotator: Text isn't reflowed the next line within the box and text overlaps when resizing box.
  • Fixed kImageAnnotator: Can't wrap long text line when I resize Text box area.
  • Fixed kImageAnnotator: Key press operations affect items across different tabs.
  • Fixed kImageAnnotator: Clipboard cleared when new tab added.
  • Fixed kImageAnnotator: Crash after pressing key when no tab exists or closing last tab.
  • Fixed kImageAnnotator: KeyInputHelperTest failed with QT_QPA_PLATFORM=offscreen.
  • Fixed: DragAndDrop not working with snaps.
  • Fixed: Loading image from stdin single instance client runner side doesn't work.
  • Fixed kImageAnnotator: Fix for unnecessary scrollbars when a screenshot has a smaller size than the previous one.
  • Fixed kImageAnnotator: Add KDE support for scale factor.
  • Fixed kImageAnnotator: Show tab tooltips on initial tabs.
  • Fixed kImageAnnotator: Sticker resizing is broken when bounding rect flipped.
  • New: Set image save location on command line.
  • New: Add debug logging.
  • New: Add FTP upload.
  • New: Upload image via command line without opening editor.
  • New: Add multi-language comment option to desktop file.
  • New: Add MimeType of Images to desktop file.
  • New: Add .jpeg to open file dialog filter (File > Open).
  • New: Escape closes window (and exits when not using tray).
  • New: Double-click mouse to confirm rect selection.
  • New: Activate tab that is prompting for save.
  • New: Add Save all options menu.
  • New: Allow overwriting existing files.
  • New: Allow setting Imgur upload title/description.
  • New: Search bar in the settings dialog.
  • New: Make implicit capture delay configurable.
  • New: Shortcuts for Actions can be made global and non-global per config.
  • New: OCR scan of screenshots (via plugin).
  • New kImageAnnotator: Add optional undo, redo, crop, scale and modify canvas buttons to dock widgets.
  • New kImageAnnotator: Cut out vertical or horizontal slice of an image.
  • New kImageAnnotator: Middle-click on tab header closes tab.
  • New kImageAnnotator: Add button to fit image into current view.
  • New kImageAnnotator: Allow changing item opacity.
  • New kImageAnnotator: Add support for RGBA colors with transparency.
  • New kImageAnnotator: Add mouse cursor sticker.
  • New kImageAnnotator: Allow scaling stickers per setting.
  • New kImageAnnotator: Respect original aspect ratio of stickers.
  • New kImageAnnotator: Respect original size of stickers.
  • Fixed: Opens a new window for each capture.
  • Fixed: First cli invocation won't copy image to clipboard.
  • Fixed: Snipping area incorrectly positioned with screen scaling.
  • Fixed: MainWindow position not restored when outside primary screen.
  • Fixed: Interface window isn't restored to the default after tab is closed in maximized state.
  • Fixed: Failed Imgur uploads show up titled as 'Upload Successful'.
  • Fixed: Preview of screenshot is scaled after changing desktop size.
  • Fixed: After an auto start followed by reboot/turn on the window section is stretched.
  • Fixed kImageAnnotator: Adding image effect does not send image change notification.
  • Fixed kImageAnnotator: Blur / Pixelate break when going past image edge once.
  • Fixed kImageAnnotator: Item opacity not applied when item shadow disabled.
  • Changed: Improve translation experience by using full sentences.
  • Changed: Make switch 'to select tool after drawing item' by default disabled.
  • Changed kImageAnnotator: Max font size changed to 100pt.
  • Fixed: Version `Qt_5.15' not found (required by /usr/bin/ksnip).
  • Fixed: CI packages show continuous suffix for tagged build.
  • Fixed: kImageAnnotator not translated with deb package.
  • Fixed: Windows packages increased in size.
  • Fixed: The string 'Actions' is not available for translation.
  • Fixed: HiDPI issue with multiple screen on Windows.
  • Fixed: Snipping Area not closing when pressing ESC.
  • Fixed: Sometimes "Snipping Area Rulers" not shown after starting rectangular selection.
  • Fixed: Cursor not positioned correctly when snipping area opens.
  • Fixed: Mouse cursor not captured when triggered via global shortcut.
  • Fixed: Dual 4K screens get scrambled on X11.
  • Fixed: VCRUNTIME140_1.dll was not found.
  • Fixed: Screenshot area issues when monitor count changes on Windows.
  • Fixed: Wayland does not support QWindow::requestActivate().
  • Fixed: Wrong area is captured on a Wayland screen scaling.
  • Changed: Enforce xdg-desktop-portal screenshots for Gnome >= 41.
  • Fixed kImageAnnotator: Crash while typing text on wayland.
  • Changed kImageAnnotator: Show scrollbar when not all tools visible.
  • Fixed: MacOS package damaged and not starting.
  • Fixed: Deb CI build is frequently failing due to docker image pull limit.
  • Fixed: Dropped temporary images appear in the open recent menu.
  • Fixed: Resizing window to match content doesn't work on opening first image/screenshot.
  • Fixed: HiDPI issue with multiple screen on Windows.
  • Fixed: Cursor not captured in rectangle capture.
  • Changed: Migrate CI from Travic-CI to GitHub Action.
  • Fixed kImageAnnotator: Crashes on destruction.
  • Fixed kImageAnnotator: Memory leaks caught by ASAN.
  • Changed kImageAnnotator: Use system font provided by QGuiApplication as default for text tool.
  • New: Add option to select the default action for tray icon left click.
  • New: Open/Paste from clipboard via tray icon.
  • New: Show/hide toolbar and annotation settings with TAB.
  • New: Add setting for auto hiding toolbar and annotator settings.
  • New: Allow setting transparency of not selected snipping area region.
  • New: Resize selected rect area with arrow keys.
  • New: Copy a screenshot to clipboard as data URI.
  • New: Provide option to open recent files.
  • New: Allow disabling auto resizing after first capture .
  • New: Drag and Drop from ksnip to other applications.
  • New: Add support for KDE Plasma notification service.
  • New: ksnip as MSI Package for window.
  • New: User-defined actions for taking screenshot and post-processing.
  • New: Add 'hide main window' option to actions.
  • New: Discord Invite in application.
  • New kImageAnnotator: Add function for loading translations.
  • New kImageAnnotator: Add a new tool for creating resizable movable duplicates of regions.
  • New kImageAnnotator: Add support for hiding annotation settings panel.
  • New kImageAnnotator: Add config option for numbering tool to only set next number.
  • New kImageAnnotator: Allow manually changing canvas size.
  • New kImageAnnotator: Canvas background color configurable.
  • New kImageAnnotator: Zoom in and out with keyboard shortcuts.
  • New kImageAnnotator: Zoom in and out via buttons from UI.
  • New kImageAnnotator: Add reset zoom keyboard shortcut with tooltip.
  • New kImageAnnotator: Add keyboard shortcut support for text tool.
  • New kImageAnnotator: Allow rotating background image.
  • New kImageAnnotator: Allow flipping background image horizontally and vertically.
  • New kImageAnnotator: Configurable UI with dockable settings widgets.
  • New kImageAnnotator: Add invert color image effect.
  • New kImageAnnotator: Allow disabling item shadow per item from UI.
  • New kImageAnnotator: Add a font selection to UI.
  • New kImageAnnotator: Add zoom in/out capability to crop view.
  • New kImageAnnotator: Allow to zoom in modify canvas view.
  • New kImageAnnotator: Select item after drawing it and allow changing settings.
  • Changed kImageAnnotator: Change drop shadow to cover all sites.
  • Fixed: Not possible to change adorner color.
  • Fixed: ksnip --version output printed to stderr.
  • Fixed kImageAnnotator: Deleting item outside image doesn't decrease canvas size.
  • Fixed kImageAnnotator: Duplicate region of grayscale image has color.
  • Fixed kImageAnnotator: Marker shows fill and width config when modifying existing item.
  • Fixed kImageAnnotator: Highlighter/Marker washed out color and overlapping.
  • Fixed kImageAnnotator: Popup menus shown outside screen.
  • Fixed kImageAnnotator: Not possible to enter value in the width tool.
  • Fixed kImageAnnotator: Obfuscation tool shows fonts settings when switching from tool with font.
  • Fixed kImageAnnotator: Annotation tools are not displayed if application starts with docks hidden.
  • Fixed kImageAnnotator: Vertical scrollbar missing after using Paste embedded and moving the image.
  • Fixed kImageAnnotator: Not possible to disable tool automatically deselected after drawn.
  • Fixed kImageAnnotator: Annotation tool shortcuts do not work if the panel is hidden.
  • Fixed: Add missing includes to build on UNIX.
  • Fixed: Ksnip starts minimized.
  • Fixed: Main window still show after screenshot when corresponding option disabled.
  • Fixed: Cancel screenshot shows main window when window was hidden.
  • Fixed: HiDPI scaling not handled correctly under windows.
  • Fixed: Close button hidden after taking screenshot under kwin.
  • Fixed kImageAnnotator: Fetching image from annotator with HiDPI enabled pixelates image.
  • Fixed kImageAnnotator: Keep aspect ratio only work when pressing CTRL before moving resize handle.
  • Changed: Allow changing adorner color for rect area selection.
  • Changed: Notarize ksnip for macOS.
  • Changed: Default font for numbering tool change to Arial.
  • Changed kImageAnnotator: Horizontally align text inside spin box.
  • Changed kImageAnnotator: Change zoom with mouse wheel to CTRL+Wheel.
  • Fixed: If file selection is cancelled during ksnip's file open dialog via tray icon, ksnip closes.
  • Fixed: Cancel on Quit not work when editor is hidden.
  • Fixed: Canceling rect area selection activates main window.
  • Fixed: Enter key doesn't finishes resizing.
  • Fixed: Missing version number in mac binaries.
  • Fixed: Canceling save dialog show the option save path in the header.
  • Fixed: Save-as Window does not get focus when using snap.
  • Fixed: Editor can not be shown again after click close icon.
  • Fixed: Icons and text boxes not correctly scaled under gnome with hdpi.
  • Fixed: Window captures include non-transparent border of background on Gnome.
  • Fixed: Annotating hidpi image downscales the result after being saved.
  • Fixed kImageAnnotator: Brazilian Portuguese translation not loaded.
  • Fixed kImageAnnotator: error: control reaches end of non-void function.
  • Fixed kImageAnnotator: Cursor in Text tool have too bad visibility.
  • Fixed kImageAnnotator: bumped SONAME without name change.
  • Fixed kImageAnnotator: Entering multiple characters at once moves the text cursor only for one character.
  • Fixed kImageAnnotator: Activating context menu while drawing item leaves item in error state.
  • Fixed kImageAnnotator: Icons not scaled on gnome with hdpi enabled.
  • Fixed kImageAnnotator: Text/Number Pointer and Text/Number Arrow don't inherit Text/Number Font in Settings.
  • New: Pin screenshots in frameless windows that stay in foreground.
  • New: Support for unit tests.
  • New: Add brew cask package for ksnip.
  • New: Allow setting image quality when saving images.
  • New: Add support for cross-platform wayland screenshots using xdg-desktop-portal.
  • New: Add save and save as tab contextMenu items.
  • New: Add open directory context menu item on capture tabs.
  • New: Add copy path to clipboard context menu item on capture tabs.
  • New: Add option to delete saved images.
  • New: Add support for loading image from stdin.
  • New: Add screenshot options as application actions to desktop file.
  • New: Allow renaming existing images.
  • New: Make hiding main window during screenshot optional.
  • New: Open several files at once in tabs.
  • New: Allow modifying selected rectangle before making screenshot.
  • New: Option to keep main window hidden after a taking screenshot.
  • New kImageAnnotator: Add Pixelate image area tool.
  • New kImageAnnotator: Zoom in and out.
  • New kImageAnnotator: Add interface for adding custom tab context menu actions.
  • New kImageAnnotator: Add drop shadow to captured images.
  • New kImageAnnotator: Add grayscale image effect.
  • New kImageAnnotator: Add numeric pointer with arrow annotation item.
  • New kImageAnnotator: Add text pointer annotation item.
  • New kImageAnnotator: Add text pointer with arrow annotation item.
  • New kImageAnnotator: Add option to automatically switching to select tool after drawing item.
  • New kImageAnnotator: Edit Text box with double click.
  • New kImageAnnotator: Resize elements while keeping aspect ratio.
  • Changed: Show all Screenshot options in System Tray.
  • Changed: Upload multiple stickers at once.
  • Changed: Follow pattern for monochromatic systray icon.
  • Changed: Pin window shows default cursor when mouse over it.
  • Changed: Cancel snipping area if no selection made after 60 sec.
  • Changed: Allow removing imgur account.
  • Changed kImageAnnotator: Draw point when clicking and releasing without moving cursor.
  • Changed kImageAnnotator: Zoom out less than 100%.
  • Changed kImageAnnotator: Change to select tool after adding new annotation item.
  • Changed kImageAnnotator: Move current zoom text to left side config panel.
  • Fixed: Snap crashing when trying to take screenshot under Wayland.
  • Fixed: zh_Hans translation won't load.
  • Fixed: Ksnip only saves the upper right part of the screenshot with HiDPI.
  • Fixed: Main window not resized with new captures.
  • Fixed: Brazilian Portuguese translation not loaded.
  • Fixed kImageAnnotator: Blur radius not updated when changing current items settings.
  • Fixed kImageAnnotator: Text tool opens many unix sockets.
  • Fixed kImageAnnotator: Text No Border and No Fill shows shadow beneath text.
  • Fixed kImageAnnotator: Item properties remain displayed after item is removed or deselected.
  • Fixed kImageAnnotator: Changing text box through editing text doesn't update resize handles.
  • Fixed kColorPicker: Border around colors is not centered.
  • Provide ksnip flatpak.
  • Changed: Install svg icon file in hicolor theme dir instead of usr/share/pixmaps/.
  • Changed: Stop upload script when process writes to stderr.
  • Changed: Upload script uses regex to select output for clipboard.
  • Fixed: Ksnip becomes unresponsive when file dropped into it.
  • Fixed: Ksnip window always visible on screenshots on Gnome Wayland.
  • Fixed: Selecting path in Snap via file-chooser sets home directory to /run/user/1000.
  • Fixed: Snap not able to run custom upload script.
  • Fixed: kImageAnnotator: Tests fail to build with shared library.
ksnip-master/desktop/org.ksnip.ksnip.desktop000066400000000000000000000026441457262621600216150ustar00rootroot00000000000000[Desktop Entry] Type=Application Exec=/usr/bin/ksnip %F Icon=ksnip Terminal=false StartupNotify=false Name=ksnip GenericName=ksnip Screenshot Tool GenericName[ru]=Создание Ñнимков Ñкрана Categories=Utility; Actions=Area;LastArea;FullScreen;Window; MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/png; Comment=Cross-platform screenshot tool that provides many annotation features for your screenshots. Comment[pt_BR]=Ferramenta de captura de tela de Cross-plataforma que fornece muitos recursos de anotação para suas capturas de tela. Comment[ru]=КроÑÑ-платформенный инÑтрумент Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñнимков Ñкрана, который предоÑтавлÑет множеÑтво функций их аннотированиÑ. X-KDE-DBUS-Restricted-Interfaces=org.kde.kwin.Screenshot,org.kde.KWin.ScreenShot2 [Desktop Action Area] Exec=ksnip -r -c Icon=ksnip Name=Capture a rectangular area Name[ru]=Снимок выделенной облаÑти [Desktop Action LastArea] Exec=ksnip -l -c Icon=ksnip Name=Capture last selected rectangular area Name[ru]=Снимок поÑледней облаÑти [Desktop Action FullScreen] Exec=ksnip -m -c Icon=ksnip Name=Capture a fullscreen Name[ru]=Снимок вÑего Ñкрана [Desktop Action Window] Exec=ksnip -a -c Icon=ksnip Name=Capture the focused window Name[ru]=Снимок активного Ñкрана ksnip-master/icons/000077500000000000000000000000001457262621600146215ustar00rootroot00000000000000ksnip-master/icons/dark/000077500000000000000000000000001457262621600155425ustar00rootroot00000000000000ksnip-master/icons/dark/action.svg000066400000000000000000000044041457262621600175420ustar00rootroot00000000000000 image/svg+xmlksnip-master/icons/dark/activeWindow.svg000066400000000000000000000055301457262621600207310ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/clock.svg000066400000000000000000000053461457262621600173660ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/copy.svg000066400000000000000000000112361457262621600172400ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/crop.svg000066400000000000000000000123171457262621600172320ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/currentScreen.svg000066400000000000000000000125561457262621600211160ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/delete.svg000066400000000000000000000057001457262621600175270ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/drawRect.svg000066400000000000000000000132361457262621600200430ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/fullScreen.svg000066400000000000000000000146461457262621600204000ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/ksnip.svg000066400000000000000000000127341457262621600174160ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/lastRect.svg000066400000000000000000000135321457262621600200500ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/paste.svg000066400000000000000000000076401457262621600174060ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/pasteEmbedded.svg000066400000000000000000000053161457262621600210160ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/pin.svg000066400000000000000000000046731457262621600170630ustar00rootroot00000000000000 image/svg+xmlksnip-master/icons/dark/redo.svg000066400000000000000000000075561457262621600172310ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/save.svg000066400000000000000000000066151457262621600172310ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/saveAs.svg000066400000000000000000000204351457262621600175110ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/undo.svg000066400000000000000000000076221457262621600172370ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/wayland.svg000066400000000000000000000201001457262621600177130ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/dark/windowUnderCursor.svg000066400000000000000000000106641457262621600217750ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/ksnip.icns000066400000000000000000002532061457262621600166330ustar00rootroot00000000000000icnsV†is32ûHGIT€U THGHHGEHGGHF:€;†?@GHGHGHGGHGƒHFLtmm‚nmnkJGHGHGGIFHGƒHC©ÿýþÿþÿòTD€HGHGGM"6KGHGHH:£ÿûý€þýÿòTDHHGHGGM$9KG‚HGHI:¤ÿû€þýÿòTDHGHGGM#8KGƒHGHI:¤ÿýþÿþÿòTDHHGGM#8KG„HGHI:¤ÿýþþÿòTDHGGM#8KG…HGHI<ÎÿýþÿòTDHGM$@IG†HGJA¿þüþÿòTDHM#;KGˆHI@Ã÷òþÿòTCN#;LFHG‡HI@ÂùìóÿòTJ%;LFHGˆH I@Âùîí÷òX;LFHG‰HI@Âùíïñê5 =KFHGŠHI@ÂùíïòèM@DBF.8LFHGŠHI@Âùîí÷óVFJHN*>†?GHGHGI‚KHGƒHGHˆIHGHGH„G¡H 767ˆ876„76776‚767600„101676‚7677676‚76:VQQ‚RQRP86‚7677586„73|껼»¾³@476771]H3‚7677-xÁ¶¸·º¯@4€76771[‡F3ƒ7678-x·¸»°@4776771[„F3„7678-x·¸¹¸»°@476771[„~€F3…7 678-x·¸¸»°@4€72^ˆ…G3†7678-u··»°@4773Rieegd=5‡7678&röº°@480cwNSTQ9476‡7672#r¹¯@51_’rRXU<576‡76670/#qů@.`‹rSU<576ˆ76670-/#t»;^ˆuQ<576‰76670-./'ch…ƒ‚‡l7676Š76670-./)PH:<=:KB386Š76670-/&\‹:3561Mm?386‰76670.'Z‚<5783Kqh@386‰7671&[‰ƒ<5773Lomj@486‡7678)Z‡Šƒ<5773Kkfie;376…76771]ˆˆŠƒ<5782R‰ƒƒ†A4…76771_€ˆŠƒ<5782T¯­¬²Q18ƒ76771_Žˆˆ‰ˆŠƒ<5782T€’«¨«O18‚76770_Ž‚ˆŠƒ<5781T…{“¬¬O1876770_އ‚ˆŠƒ<5781T„|“¯O18ƒ74b‘ŠŠ‹ŠŒ…<5781U†€‚}˜Q18‚768K†H G867755„76766:‚ 37675?j‚~‚H3ƒ76766:ƒ 37675BPhƒF3‚76766;„ 37675ATNh‚F3ƒ766;ƒ 37675ASRNh…F3‚7668† 37675BTRSNkH3‚7675)…+*+676769<;96ƒ767ˆ976767656676767Š67676„76 7l8mk'kbddddddddddddddddddddddddbk'dÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿdbÿ÷ûûûûûûûûûûûûûûûûûûûûûûûû÷ÿbdÿûþþþþþþþþþþþþþþþþþþþþþþþþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿddÿûþþþþþþþþþþþþþþþþþþþþþþþþûÿdbÿ÷ûûûûûûûûûûûûûûûûûûûûûûûû÷ÿbdÿûþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþûÿd'kbddddddddddddddddddddddddbk'ih32LGGH§GHGG­­HGGH§GHGHGHHGHG‹HG€HGHGHGHHGGHŒIHGˆHGHGG€HGHGHGHGHJAŒBGHG†H GHGGJGHHGHGHGHI@€âÓ‰ÕØÌRE†H GHGGJ1FHGGHGHG€HC®ÿýþ†ÿþÿóTD…HGHGGM J€GHG HGHGHH9£ÿúü…ýüÿñTD„HGHGGM$J€GHG HGHHGHI;¥ÿüþÿþ‚ÿþÿóTDƒH GHGGM#I€GHGHG€H GHI;¤ÿüþÿþÿþÿóTD‚H GHGGM#I€GHGHGH GHI;¤ÿüþÿþ€ÿþÿóTDH GHGGM#I€GHGHG‚HGHI;¤ÿýþÿþÿÿþÿóTD€HGHGGM#€I€GHGHGƒHGHI;¤ÿýþÿþÿþÿóTDHHGHGGL#I€GHGHG„HGHJ9ÀÿüþÿþþÿóTDHGHGGM%€J€GHGHG…HGK=¨þüþþÿþÿóTDHHGGM$€ CIGHGHGHG†HJ<®ùðþ ÿóTDHGGM#€  DJGHHGHGHG†HJ<­üëò€þÿóTDHGM# DJFHGHGHGHG†H J<­ûíîòþþÿóUDHM# DJFHGHHGHGHG†HJ<­ûíðîòþÿòTCM# DJFHG€HGHGHG†HJ<­ûíïðîòÿòTJ%€ DJFHGHGHGHG†H J<­ûíðïðíõòX„ DJFHG‚HGHGHG†HJ<­ûíððïïñé5EIGHGƒHGHGHG†H J<­ûíððïïñæM@D€CBE)AJGHGƒHGHGHG†H J<­ûíðïðíöòVFJ€IHNEJFHG‚HGHGHG†H J<­ûíïðîòÿòTDH€G FLDJFHGHGHGHG†H J<­ûíðîóþÿòTD€H GFL DJFHG€HGHGHG†H J<­ûíîóþþÿóTD€HGFL DJFHGHHGHGHG†HJ<­üëó€þÿóTD€HGFL DJFHGHGHGHG†HJ<®ùðþÿóTD€HGFL DJGHHGHGHG…H GK=©ÿüþþÿþÿóTD€HGFL BIGHGHGHG„HGHJ9¿ÿüþÿþþÿóTD€HGFL€J€GHGHGƒHGHJ:¢ÿýþÿþÿþÿóTD€HGFL‚I€GHGHG‚HGHJ:¢ÿýþÿþÿóTD€HGFL‚I€GHGHGH GHJ:¢ÿüþÿþ€ÿþÿóTD€HGFLI€GHGHG€H GHJ:¢ÿüþÿþÿþÿóTD€HGFL€I€GHG HGHHGHJ:¢ÿüþÿþ‚ÿþÿóTD€H GFLI€GHG HGHGHH8¡ÿúü…ýüÿñTD€HGFL€I€GHGHG€HB«ÿýþ†ÿþÿóTD€HGFL‚I€GHGHGHI@€ãÕÖ‡×ÖÚÎRE€HGGK& €I€GHGHGHGHKBB‹CGHGHGI„JIGHHGHGHG€HGŽHGHGH†G€HGHGHGHHGHGƒH†G€HGHGH§GHGG­H­GGH§GHGG776§7677­66©766³7676™766Ž76‰76776ˆ7679223‡2323676‡76774776†781_¤š‰›•>5‡76774M86‰73Ƚ¾†¿¾Á¶@4†76771_u4ˆ7677,xÁ¶‡·¹¯@4…76771Zˆo4‰7 678-y·¸¹¸‚¹¸»°@4„76771[„‚o5Š7 678-y·¸¹¸¹¸»°@4ƒ7 6771[…~ƒp5‹7 678-y·¸¹¸€¹¸»°@4‚7 6771[…~ƒp5Œ7678-y·¸¹¸¹¹¸»°@47 6771[„~~‚o57678-x·¸¹¸¹¸»°@4€7 6773_ˆ‚‚ƒ‚†s5Ž7678.v·¸¹¸¸»°@4776772Qrmmnnmq`57679'q·¸¹¸»°@476770clN€SRTM6676Ž7 683#r·¸¸»°@4€7 1_’hSWVVXQ96767672.$r··»°@4771`Ž‹hRVUWP85767671-/#r·º°@481`އ‹hRVWP8576‘7671-./#q¹¯@51`Žˆ‡ŒhRXP8676’7671-../#qį@.`އˆ‡‹gTQ8676“7671-.-./#t»;_‰ŠŠ‰kM9676”7 671-..-./'ch…ƒ‚‡_4776•7 671-..-./)PH:‚<;N<476•7 671-.-./&\‹:36€561Yg8576”7 671-../'Z‚<5783Urb9576“7 671-./'Z‰ƒ<5‚73Vnnc9576’7 671-/'Z‡Šƒ<5‚7 3Vojoc9576‘7 671.'ZˆˆŠƒ<5‚7 3Vokjoc95767672&[€ˆŠƒ<5‚7 3Wplmkpd:576Ž7 678+Zˆˆ‰ˆŠƒ<5‚7 3Ujfggfj^7676Œ76771^Žˆˆ‰ˆˆŠƒ<5781d–€Ž–y376771_ˆˆ‰ˆ‰ˆŠƒ<57 82b°­®®­³•4Œ76771_Žˆˆ‰ˆ‰‰ˆŠƒ<57 82b€‘«¨¨§®3‹7 6771_Žˆˆ‰ˆ€‰ˆŠƒ<57 82c…{“¬©¨¯‘3Š7 6771_Žˆˆ‰ˆ‰ˆŠƒ<57 82b…|“¬¨¯‘3‰7 6771_Žˆˆ‰ˆ‚‰ˆŠƒ<57 82b…~€|“«®4ˆ76770^‡‡…ˆ‡‰‚<57 82b„~|‘±3Š74c’‹ˆŒއ=57 81eˆ‚ƒƒ„œ–3‰73P|v‰wxs;5‚73Xsn€onpn6ˆ76784676€7675„43766ˆ76Ž76‚76†76‰76•76½766©766­776§7677776§7677­66©766´76œ7Ž6Š76776‰7669Œ876ˆ76774776…7669%Š  376†76774M86‡7668‹386…76771_u4‰767;ˆ376„76771Zˆo4ˆ76766:‰386ƒ76771[„‚o5‰76766:ˆ386‚7 6771[…~ƒp5Š76766:‡3867 6771[…~ƒp5‹76766:†386776€71[…€ƒo5Œ76766:…386767673[…€‚q576766;„ 38667683Q„}€~|„i3Ž7676:‚386766<Nˆ}~„s;576766:‚37€6 :Nˆ~€~„s:476Ž766:3866:Nˆ~~„s:486766:€€376:Nˆ|„s:486766:27:N‡‚s:486‘766:‚2<Mq:486’766:„6S|8486“766:„€@A376”766:„-4‚30R>486”766:„49792hy9486“766:‚27671a‰r:486’766:386€7 82cƒƒs:486‘766:€€386€7 82b…}„s:486766:386€7 82b…~~„s:486766:‚386€7 82b„~€~„s:4767676:‚386€7 81d„~~„s;576‹76766;„38672Yƒ}€~|„j3Œ76766:…3867 5Dj‚€‚q5‹76766:†38675GPgƒ€ƒo5Š76766:‡3867 5GTNhƒƒp5‰76766:ˆ3867 5GTRNhƒ~ƒp5ˆ76766:‰3867 5GSQRNh‚‚p5‰766;ˆ3767 5GSQQRNg†o4ˆ7668‹38675HUR€SOmt4‡7669& ‡  37675CMƒKT76ˆ765876767…64776‰7Ž6ƒ76†76Š76Ä766©766­776§7677h8mk \¤—™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™—¤\šÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿš—ÿ÷ûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûû÷ÿ—™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™™ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ™—ÿ÷ûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûû÷ÿ—šÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿš\¤—™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™™—¤\it327CÿÿüFIIHIHëIHIHIIFƒIGGHïGHGGIÿ÷HƒIGGHïGHGGIƒHGGHGíHGHGGHƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHG‡HG«HG§HGˆHGHGGIƒIGGHG‡HGG©IHG¤HGHGGˆHGHGGIƒIGGHG†HGHI?@¥A@AGHG¢HGHGGJG‡HGHGGIƒIGGHG†HI@€ÞÐÑ£ÒÑÔÊRE¢HGHGHI2FHG…HGHGGIƒIGGHGˆHE²ÿýþ¢ÿþÿôUD¡H GHGGM JGG…HGHGGIƒIGGHG†HGHG:§ÿú£üÿòUD H GHGGL$IGG…HGHGGIƒIGGHG‡H GHI<©ÿüþÿþžÿþÿôUDŸH GHGGL#IGG…HGHGGIƒIGGHGˆH GHI<¨ÿüþÿþÿþÿôUDžH GHGGL#IGG…HGHGGIƒIGGHG‰H GHI<¨ÿüþÿþœÿþÿôUDH GHGGL#IGG…HGHGGIƒIGGHGŠH GHI<¨ÿüþÿþ›ÿþÿôUDœHGHGGL#€IGG…HGHGGIƒIGGHG‹H GHI<¨ÿüþÿþšÿþÿôUD›HGHGGL#IGG…HGHGGIƒIGGHGŒH GHI<§ÿüþÿþ™ÿþÿôUDšHGHGGL#‚IGG…HGHGGIƒIGGHGH GHI<§ÿüþÿþ˜ÿþÿôUD™HGHGGL#ƒIGG…HGHGGIƒIGGHGŽH GHI<§ÿüþÿþ—ÿþÿôUD˜HGHGGL#„IGG…HGHGGIƒIGGHGH GHI<§ÿüþÿþ–ÿþÿôUD—HGHGGL#…IGG…HGHGGIƒIGGHGH GHI<§ÿüþÿþ•ÿþÿôUD–HGHGGL#†IGG…HGHGGIƒIGGHG‘H GHI<§ÿüþÿþ”ÿþÿôUD•HGHGGL#‡IGG…HGHGGIƒIGGHG’H GHI<§ÿüþÿþ“ÿþÿôUD”HGHGGL#ˆIGG…HGHGGIƒIGGHG“H GHI<§ÿüþÿþ’ÿþÿôUD“HGHGGL#‰IGG…HGHGGIƒIGGHG”H GHI<§ÿüþÿþ‘ÿþÿôUD’HGHGGL#ŠIGG…HGHGGIƒIGGHG•H GHI<§ÿüþÿþÿþÿôUD‘HGHGGL#‹IGG…HGHGGIƒIGGHG–H GHI<§ÿüþÿþÿþÿôUDHGHGGL"ŒIGG…HGHGGIƒIGGHG—H GHI<§ÿüþÿþŽÿþÿôUDHGHGGL"IGG…HGHGGIƒIGGHG˜H GHI<§ÿýþÿþÿþÿôUDŽHGHGGL"ŽIGG…HGHGGIƒIGGHG™H GHI<¦ÿýþÿþŒÿþÿôUDHGHGGL"‘IGG…HGHGGIƒIGGHGšH GIFHÜÿþþÿþ‹ÿþÿôUDŒHGHGGL'ŽJGG…HGHGGIƒIGGHGœHFPÚïüÿþÿþŠÿþÿôUD‹HGHGGL$ŽCIG†HGHGGIƒIGGHGœH FNßñêýÿþÿþ‰ÿþÿôUDŠHGHGGL# CJG‡HGHGGIƒIGGHGœH FNÝõìëýÿþÿþˆÿþÿôUD‰HGHGGL# DJFHG†HGHGGIƒIGGHGœH FNÞóðíëýÿþÿþ‡ÿþÿôUDˆHGHGGL#€Œ DJFHG‡HGHGGIƒIGGHGœH FNÞôîñíëýÿþÿþ†ÿþÿôUD‡H GHGGL#‹ DJFHGˆHGHGGIƒIGGHGœH FNÞôïïñíëýÿþÿþ…ÿþÿôUD†HGHGGL#€Š DJFHG‰HGHGGIƒIGGHGœHFNÞôîðïñíëýÿþÿþ„ÿþÿôUD…HGHGGL#‰DJFHGŠHGHGGIƒIGGHGœHFNÞôîïðïñíëýÿþÿþƒÿþÿôUD„HGHGGL#‚ˆDJFHG‹HGHGGIƒIGGHGœHFNÞôîðïðïñíëýÿþÿþ‚ÿþÿôUDƒHGHGGL#ƒ‡DJFHGŒHGHGGIƒIGGHGœHFNÞôîððïðïñíëýÿþÿþÿþÿôUD‚HGHGGL#„†DJFHGHGHGGIƒIGGHGœHFNÞôî€ð ïðïñíëýÿþÿþ€ÿþÿôUDHGHGGL#……DJFHGŽHGHGGIƒIGGHGœHFNÞôîðïðïñíëýÿþÿþÿÿþÿôUD€HGHGGL#†„DJFHGHGHGGIƒIGGHGœHFNÞôî‚ðïðïñíëýÿþÿþÿþÿôUDHHGHGGL#‡ƒDJFHGHGHGGIƒIGGHGœHFNÞôîƒðïðïñíëýÿþÿþþÿôUDHGHGGL#ˆ‚DJFHG‘HGHGGIƒIGGHGœHFNÞôî„ðïðïñíëýÿþÿþÿôUDHHGGL#‰DJFHG’HGHGGIƒIGGHGœHFNÞôî…ðïðïñíëýÿþþÿôUDHGGL#Š€DJFHG“HGHGGIƒIGGHGœHFNÞôî†ðïðïñíëýÿýÿôUDHGL#‹ DJFHG”HGHGGIƒIGGHGœHFNÞôî‡ðïðïñíëýþÿôUDHL#Œ DJFHG•HGHGGIƒIGGHGœHFNÞôîˆðïðïñíëüÿóUCM#DJFHG–HGHGGIƒIGGHGœHFNÞôî‰ð ïðïñíêÿóUI$ŽDJFHG—HGHGGIƒIGGHGœHFNÞôîŠðïðïñìîòYDJFHG˜HGHGGIƒIGGHGœHFNÞôî‹ðïðïððâ4ŽEIGHG™HGHGGIƒIGGHGœHFNÞôî‹ðïðïïñáM@DCE*@JGHG™HGHGGIƒIGGHGœHFNÞôîŠð ïðïðíïòWEJŽIHNEJFHG˜HGHGGIƒIGGHGœHFNÞôî‰ð ïðïðíìÿôUDHŽG FLCJFHG—HGHGGIƒIGGHGœHFNÞôîˆð ïðïðííüÿóUDŽH GGL CJFHG–HGHGGIƒIGGHGœHFNÞôî‡ð ïðïðíìýþÿôUDŽH GGL CJFHG•HGHGGIƒIGGHGœHFNÞôî†ð ïðïðííýÿþÿôUDŽH GGL CJFHG”HGHGGIƒIGGHGœHFNÞôî…ð ïðïðííýÿþþÿôUDŽHGGL CJFHG“HGHGGIƒIGGHGœHFNÞôî„ðïðïðíìýÿþÿþÿôUDŽHGGL CJFHG’HGHGGIƒIGGHGœHFNÞôîƒðïðïðíìýÿþÿþþÿôUDŽHGGL€ CJFHG‘HGHGGIƒIGGHGœHFNÞôî‚ðïðïðíìýÿþÿþÿþÿôUDŽHGGL CJFHGHGHGGIƒIGGHGœHFNÞôîðïðïðíìýÿþÿþÿÿþÿôUDŽHGGL‚ CJFHGHGHGGIƒIGGHGœHFNÞôî€ð ïðïðíìýÿþÿþ€ÿþÿôUDŽHGGLƒ CJFHGŽHGHGGIƒIGGHGœHFNÞôîððïðïðíìýÿþÿþÿþÿôUDŽHGGL„ CJFHGHGHGGIƒIGGHGœHFNÞôîðïðïðíìýÿþÿþ‚ÿþÿôUDŽHGGL… CJFHGŒHGHGGIƒIGGHGœHFNÞôîïðïðíìýÿþÿþƒÿþÿôUDŽHGGL† CJFHG‹HGHGGIƒIGGHGœHFNÞôîðïðíìýÿþÿþ„ÿþÿôUDŽHGGL‡ CJFHGŠHGHGGIƒIGGHGœH FNÞôïïðíìýÿþÿþ…ÿþÿôUDŽHGGLˆ CJFHG‰HGHGGIƒIGGHGœH FNÞôîðíìýÿþÿþ†ÿþÿôUDŽHGGL‰ CJFHGˆHGHGGIƒIGGHGœH FNÞóïíìýÿþÿþ‡ÿþÿôUDŽHGGLŠ CJFHG‡HGHGGIƒIGGHGœH FNÞõììýÿþÿþˆÿþÿôUDŽHGGL‹ CJFHG†HGHGGIƒIGGHGœH FNßòìýÿþÿþ‰ÿþÿôUDŽHGGLŽ CJG‡HGHGGIƒIGGHGœHFPÛñüÿþÿþŠÿþÿôUDŽHGGL BIG†HGHGGIƒIGGHGšH GIFGÝÿþþÿþ‹ÿþÿôUDŽHGGK ŽJGG…HGHGGIƒIGGHG™H GHI; ÿýþÿþŒÿþÿôUDŽHGGLIGG…HGHGGIƒIGGHG˜H GHI;¡ÿýþÿþÿþÿôUDŽHGGLIGG…HGHGGIƒIGGHG—H GHI;¡ÿüþÿþŽÿþÿôUDŽHGGLIGG…HGHGGIƒIGGHG–H GHI;¡ÿüþÿþÿþÿôUDŽHGGL€ŽIGG…HGHGGIƒIGGHG•H GHI;¡ÿüþÿþÿþÿôUDŽHGGLIGG…HGHGGIƒIGGHG”H GHI;¡ÿüþÿþ‘ÿþÿôUDŽHGGL€ŒIGG…HGHGGIƒIGGHG“H GHI;¡ÿüþÿþ’ÿþÿôUDŽHGGL‹IGG…HGHGGIƒIGGHG’H GHI;¡ÿüþÿþ“ÿþÿôUDŽHGGL‚ŠIGG…HGHGGIƒIGGHG‘H GHI;¡ÿüþÿþ”ÿþÿôUDŽHGGLƒ‰IGG…HGHGGIƒIGGHGH GHI;¡ÿüþÿþ•ÿþÿôUDŽHGGL„ˆIGG…HGHGGIƒIGGHGH GHI;¡ÿüþÿþ–ÿþÿôUDŽHGGL…‡IGG…HGHGGIƒIGGHGŽH GHI;¡ÿüþÿþ—ÿþÿôUDŽHGGL††IGG…HGHGGIƒIGGHGH GHI;¡ÿüþÿþ˜ÿþÿôUDŽHGGL‡…IGG…HGHGGIƒIGGHGŒH GHI;¢ÿüþÿþ™ÿþÿôUDŽHGGLˆ„IGG…HGHGGIƒIGGHG‹H GHI;¢ÿüþÿþšÿþÿôUDŽHGGL‰ƒIGG…HGHGGIƒIGGHGŠH GHI;¢ÿüþÿþ›ÿþÿôUDŽHGGLŠ‚IGG…HGHGGIƒIGGHG‰H GHI;¢ÿüþÿþœÿþÿôUDŽHGGL‹IGG…HGHGGIƒIGGHGˆH GHI;¢ÿüþÿþÿþÿôUDŽHGGLŒ€IGG…HGHGGIƒIGGHG‡H GHI;¢ÿüþÿþžÿþÿôUDŽHGGLIGG…HGHGGIƒIGGHG†HGHH9 ÿúü¡ýüÿòUDŽHGGLIGG…HGHGGIƒIGGHG…HGHHCªÿýþ¢ÿþÿôUDŽHGGLIGG…HGHGGIƒIGGHG†HI@âÕÖ£×ÖÙÎREŽHGGK' IGG…HGHGGIƒIGGHG†HGHK¨CDGHGHGI’KJG‡HGHGGIƒIGGHGˆHFªHGHGH”GˆHGHGGIƒIGGHG‡HG«HG‘H”GˆHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒIGGHGíHGHGGIƒHGGHGíHGHGGHƒIGGHïGHGGIƒ÷HÿIGGHïGHGGIƒFIIHIHëIHIHIIFÿÿüÿÿü96676í767669ƒ6776ï76776ÿ76676í767667ƒ6776ï76776ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒŒ76ç7ƒŒ7667§8776¥76776Œ7ƒ‹767811¥212676£76774776Š7ƒ‹781_¡—˜£™˜š“>5£76775M86‹7ƒ74‚Ⱦ¤¿Á·A4¢76771_t4Œ7ƒ‹7676-zÀµ¢·¶¹¯@4¡76772Zˆo5Œ7ƒŒ7 677.{·¸¹¸ž¹¸»±@4 76772[„‚o5Œ7ƒ7 677.{·¸¹¸¹¸»±@4Ÿ7 6772[„~ƒp5Œ7ƒŽ7 677.{·¸¹¸œ¹¸»±@4ž7 6772[„~ƒo5Œ7ƒ7 677.{·¸¹¸›¹¸»±@476772[„€ƒo5Œ7ƒ7 677.{·¸¹¸š¹¸»±@4œ7 6772[„€ƒo5Œ7ƒ‘7 677.z·¸¹¸™¹¸»±@4›7 6772[„€ƒo5Œ7ƒ’7 678.z·¸¹¸˜¹¸»±@4š76772[„€€ƒo5Œ7ƒ“7 678.z·¸¹¸—¹¸»±@4™76772[„€€€ƒo5Œ7ƒ”7 678.z·¸¹¸–¹¸»±@4˜7 6772[„€€€ƒo5Œ7ƒ•7 678.z·¸¹¸•¹¸»±@4—7 6772[„€€ƒo5Œ7ƒ–7 678.z·¸¹¸”¹¸»±@4–7 6772[„€‚€ƒo5Œ7ƒ—7 678.z·¸¹¸“¹¸»±@4•7 6772\…€ƒ€ƒo5Œ7ƒ˜7 678.z·¸¹¸’¹¸»±@4”7 6772\…€„€ƒo5Œ7ƒ™7 678.z·¸¹¸‘¹¸»±@4“7 6772\…€…€ƒo5Œ7ƒš7 678.z·¸¹¸¹¸»±@4’7 6772\„€†€ƒo5Œ7ƒ›7 678.z·¸¹¸¹¸»±@4‘7 6772\…€‡€ƒo5Œ7ƒœ7 678.z·¸¹¸Ž¹¸»±@47 6772\…€ˆ€ƒo5Œ7ƒ7 678.z·¸¹¸¹¸»±@476771\„~Œ~‚o5Œ7ƒž7 678.z·¸¹¸Œ¹¸»±@4Ž76774_ˆ‚‚Œƒ‚†r5Œ7ƒŸ7 678-rÁ·¸¹¸‹¹¸»±@476772OpkŽlkp^5Œ7ƒ 7 677%p·¸¹¸Š¹¸»±@4Œ76770bhOŽSRTM6676Š7ƒ 7 6770$p·¸¹¸‰¹¸»±@4‹76771_‘dSWVXQ9676‹7ƒ 7 676//$p·¸¹¸ˆ¹¸»±@4Š76771_ŽŠdSŒVUWP8676Œ7ƒ 7 676../$p·¸¹¸‡¹¸»±@4‰7 6771`އ‹eS‰VUVUWP86767ƒ 7 676.-./$p·¸¹¸†¹¸»±@4ˆ7 6771`Žˆˆ‹eSˆVUVUWP8676Ž7ƒ 7676.--./$p·¸¹¸…¹¸»±@4‡76771`Ž€ˆ‹eS‡VUVUWP86767ƒ 7676.-.-./$p·¸¹¸„¹¸»±@4†7 6771`Žˆˆ‰ˆ‹eS†VUVUWP86767ƒ 7676.-..-./$p·¸¹¸ƒ¹¸»±@4…7 6771`Žˆˆ‰ˆˆ‹eS…VUVUWP8676‘7ƒ 7676.-€. -./$pÁ·¸¹¸‚¹¸»±@4„76771`Žˆˆ‰€ˆ‹eS„VUVUWP8676’7ƒ 7676.-. -./$oÁ·¸¹¸¹¸»±@4ƒ76771`Žˆˆ‰ˆ‰ˆˆ‹eSƒVUVUWP8676“7ƒ 7676.-‚. -./$oÁ·¸¹¸€¹¸»±@4‚76771`Žˆˆ‰ˆ‰‰ˆˆ‹eS‚VUVUWP8676”7ƒ 7676.-ƒ.-./$oÁ·¸¹¸¹¹¸»±@47 6771`Žˆˆ‰ˆ€‰ˆˆ‹eSVUVUWP8676•7ƒ 7676.-„.-./$oÁ·¸¹¸¹¸»±@4€7 6771`Žˆˆ‰ˆ‰ˆˆ‹eS€VUVUWP8676–7ƒ 7676.-….-./$oÁ·¸¹¸¸»±@4776771`Žˆˆ‰ˆ‚‰ˆˆ‹eSVVUVUWP8676—7ƒ 7676.-†.-./$oÁ·¸¹¸»±@476771`Žˆˆ‰ˆƒ‰ˆˆ‹eSVUVUWP8676˜7ƒ 7676.-‡.-./$nÁ€¸»±@4€71`Žˆˆ‰ˆ„‰ ˆˆ‹eSVVUWP8676™7ƒ 7676.-ˆ.-./$nÁ¸·»±@4771`Žˆˆ‰ˆ…‰ ˆˆ‹eSVUWP8676š7ƒ 7676.-‰.-./$nÁ·º±@481`Žˆˆ‰ˆ†‰ ˆˆ‹eSVWP8676›7ƒ 7676.-Š.-./$nÁº°@52`Žˆˆ‰ˆ‡‰ ˆˆ‹eRXP8676œ7ƒ 7676.-‹. -./$nð@.`އˆ‹dTP86767ƒ 7676.-Œ. -./#qº<_‰Š‰ŒgM8676ž7ƒ 7676.-.-./'ai…ƒ‚‡\4776Ÿ7ƒ 7676.-.-./)OG:<;N<476Ÿ7ƒ 7676.-Œ.-./'[‹;36Ž561Yf8576ž7ƒ 7676.-‹.-./'Yƒ=5784Urb95767ƒ 7676.-Š. -./'Yމƒ=573Vnnc:576œ7ƒ 7676.-‰. -./'Yއ‰„=57 3Vojoc:576›7ƒ 7676.-ˆ. -./'YŽˆˆŠ„=57 3Vokjoc:576š7ƒ 7676.-‡.-./'YŽ€ˆŠ„=57 3Vokljoc:576™7ƒ 7676.-†. -./'YŽˆˆ‰ˆŠ„=57 3Vokkljoc:576˜7ƒ 7676.-….-./'YŽˆˆ‰ˆˆŠ„=57 3Voklkljoc9576—7ƒ 7676.-„.-./'YŽˆˆ‰ˆ‰ˆŠ„=573Vokllkljoc9576–7ƒ 7676.-ƒ.-./'YŽˆˆ‰ˆ‰‰ˆŠ„=573Vok€lkljoc9576•7ƒ 7676.-‚. -./'YŽˆˆ‰ˆ€‰ˆŠ„=573Voklkljoc9576”7ƒ 7676.-. -./'YŽˆˆ‰ˆ‰ˆŠ„=573Vok‚lkljoc9576“7ƒ 7676.-€. -./'YŽˆˆ‰ˆ‚‰ˆŠ„=573Vokƒlkljoc9576’7ƒ 7676.-..-..'YŽˆˆ‰ˆƒ‰ˆŠ„=573Vok„lkljoc9576‘7ƒ 7676.-.-./'YŽˆˆ‰ˆ„‰ˆŠ„=573Vok…lkljoc95767ƒ 7676.-../'YŽˆˆ‰ˆ…‰ˆŠ„=573Vok†lkljoc:5767ƒ 7 676.-./'YŽˆˆ‰ˆ†‰ˆŠ„=573Vok‡lkljoc:576Ž7ƒ 7 676../'YŽˆˆ‰ˆ‡‰ˆŠ„=573Vokˆlkljoc:5767ƒ 7 676/.'YŽˆˆ‰ˆˆ‰ˆŠ„=573Vok‹ljoc:576Œ7ƒ 7 676/'ZŽˆˆ‰ˆ‰‰ˆŠ„=573WpŒlmkod;576‹7ƒ 7 677(Zˆˆ‰ˆŠ‰ˆŠ„=573Ukfgfj^7676Š7ƒŸ7 6780[Žˆˆ‰ˆ‹‰ˆŠ„=5782b”Ž”x4Œ7ƒž7 6771^Žˆˆ‰ˆŒ‰ˆŠ„=5782bš¯Ž®­³”4Œ7ƒ7 6771^Žˆˆ‰ˆ‰ˆŠ„=572c€«¨¨‹©§®4Œ7ƒœ7 6771_Žˆˆ‰ˆŽ‰ˆŠ„=57 82c…{‘¬©©ª©ˆª¨¯4Œ7ƒ›7 6771_Žˆˆ‰ˆ‰ˆŠ„=57 82c„|‘¬©©ª©‡ª¨¯4Œ7ƒš7 6771^Žˆˆ‰ˆ‰ˆŠ„=57 82c„~€|‘¬©©ª©†ª¨¯4Œ7ƒ™7 6771^Žˆˆ‰ˆ‘‰ˆŠ„=57 82c„~€€|‘¬©©ª©…ª¨¯4Œ7ƒ˜7 6771^Žˆˆ‰ˆ’‰ˆŠ„=5782c„~€€|‘¬©©ª©„ª¨¯4Œ7ƒ—7 6771_Žˆˆ‰ˆ“‰ˆŠ„=5782c„~€€€|‘¬©©ª©ƒª¨¯4Œ7ƒ–7 6771_Žˆˆ‰ˆ”‰ˆŠ„=5782c„~€€€€|‘¬©©ª©‚ª¨¯4Œ7ƒ•7 6771_Žˆˆ‰ˆ•‰ˆŠ„=5782c„~€€ €€|‘¬©©ª©ª¨¯4Œ7ƒ”7 6771_Žˆˆ‰ˆ–‰ˆŠ„=5782c„~€ €€|‘¬©©ª©€ª¨¯4Œ7ƒ“7 6771_Žˆˆ‰ˆ—‰ˆŠ„=5782c„~‚€€€|‘¬©©ª©ªª¨¯4Œ7ƒ’7 6771_Žˆˆ‰ˆ˜‰ˆŠ„=5782c„~ƒ€€€|‘¬©©ª©ª¨¯4Œ7ƒ‘7 6771_Žˆˆ‰ˆ™‰ˆŠ„=5782c„~„€ €€|‘¬©©ª©¨¯4Œ7ƒ7 6771_Žˆˆ‰ˆš‰ˆŠ„=5782c„~…€ €€|‘¬©©ª¨¯4Œ7ƒ7 6771_Žˆˆ‰ˆ›‰ˆŠ„=5782c„~†€ €€|‘¬©©¨¯4Œ7ƒŽ7 6771_Žˆˆ‰ˆœ‰ˆŠ„=5782c„~‡€ €€|‘¬©¨¯4Œ7ƒ7 6771_Žˆˆ‰ˆ‰ˆŠ„=5782c„~ˆ€ €€|‘¬¨¯4Œ7ƒŒ7 6771_Žˆˆ‰ˆž‰ˆŠ„=5782c„~‰€€€|‘«¯4Œ7ƒ‹76770^‡‡¡ˆ‡‰ƒ=5782bƒ~{ް4Œ7ƒ74c’¥Œއ=5782e‰‚ƒ„š•4Œ7ƒŒ73O|vv£wvxs;573Wplmnj66‹7ƒ‹767844§5676Ž7675’32776Š7ƒ76ª7676”76Œ7ƒŒ76¿76¤7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ6776ï76776ƒ76676í767667ÿ6776ï76776ƒ96676í767669ÿÿüÿÿü96676í767669ƒ6776ï76776ÿ76676í767667ƒ6776ï76776ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ7«6¹7ƒ‹7677ª676¤76776Œ7ƒŒ766¨9876¤76774776Š7ƒŠ7669% ¦  376¢76775M86‹7ƒ‹7667§286¡76771_t4Œ7ƒŒ767;¤286 76772Zˆo5Œ7ƒ‹76766:¥286Ÿ76772[„‚o5Œ7ƒŒ76766:¤286ž7 6772[„~ƒp5Œ7ƒ76766:£2867 6772[„~ƒo5Œ7ƒŽ76766:¢286œ76772[„€ƒo5Œ7ƒ76766:¡286›7 6772[„€ƒo5Œ7ƒ76766: 286š7 6772[„€ƒo5Œ7ƒ‘76766:Ÿ286™76772[„€€ƒo5Œ7ƒ’76766:ž286˜76772[„€€€ƒo5Œ7ƒ“76766:286—7 6772[„€€€ƒo5Œ7ƒ”76766:œ286–7 6772[„€€ƒo5Œ7ƒ•76766:›286•7 6772[„€‚€ƒo5Œ7ƒ–76766:š286”7 6772\…€ƒ€ƒo5Œ7ƒ—76766:™286“7 6772\…€„€ƒo5Œ7ƒ˜76766:˜286’7 6772\…€…€ƒo5Œ7ƒ™76766:—286‘7 6772\„€†€ƒo5Œ7ƒš76766:–2867 6772\…€‡€ƒo5Œ7ƒ›76766:•2867 6772\…€ˆ€ƒo5Œ7ƒœ76766:”28676€72\„Žƒo5Œ7ƒ76766:“286Œ767674\…€ƒq5Œ7ƒž767676’286‹767674PzŽ{yg4Œ7ƒŸ76674‘286Š76766<Q‡}}ƒr;576Š7ƒ 7674286‰7 6766:Qˆ~Œ€~„s:476‹7ƒ 7674286ˆ7 6766:Qˆ~Š€~„r:486Œ7ƒ 7674€Ž286‡7 6766:Qˆ~ˆ€€~„r:4867ƒ 7674286†7 6766:Qˆ~‡€€~„r:486Ž7ƒ 7674‚Œ286…76766:€Qˆ~†€€~„r:4867ƒ 7674ƒ‹286„76766:Qˆ~…€€~„r:4867ƒ 7674„Š286ƒ76766:‚Qˆ~„€€~„r:486‘7ƒ 7674…‰286‚76766:ƒQˆ~ƒ€€~„r:486’7ƒ 7674†ˆ28676766:„Qˆ~‚€€~„r:486“7ƒ 7674‡‡286€76766:…Qˆ~€€~„r:486”7ƒ 7674ˆ† 286776766:†Qˆ~€€€~„r:486•7ƒ 7674‰… 28676766:‡Qˆ~€€€~„r:486–7ƒ 7674Š„ 2866766:ˆQˆ~€€~„r:486—7ƒ 7674‹ƒ286766:‰ Qˆ~€~„r:486˜7ƒ 7674Œ‚28€6:Š Qˆ~€~„r:486™7ƒ 76742866:‹ Qˆ~~„r:486š7ƒ 7674Ž€276:Œ Qˆ|„r:486›7ƒ 767427: Q†‚r:486œ7ƒ 76742;ŒOŒp:4867ƒ 76745Uz8486ž7ƒ 7674’ A@376Ÿ7ƒ 7674’-431R>476Ÿ7ƒ 7674‘49792hx9486ž7ƒ 767427672a‰r:4867ƒ 7674286Ž7 82cƒƒs;486œ7ƒ 7674Ž€286Ž7 82c„}„s;486›7ƒ 7674286Ž7 82c„~„s;486š7ƒ 7674Œ‚286Ž7 82c„~€~„s;486™7ƒ 7674‹ƒ286Ž7 82c„~€~„s;486˜7ƒ 7674Š„286Ž782c„~€€~„s;486—7ƒ 7674‰…286Ž782c„~€€€~„s;486–7ƒ 7674ˆ†286Ž782c„~€€€~„s;486•7ƒ 7674‡‡286Ž782c„~€€~„s;486”7ƒ 7674†ˆ286Ž782c„~‚€€~„s;486“7ƒ 7674…‰286Ž782c„~ƒ€€~„s;486’7ƒ 7674„Š286Ž782c„~„€€~„s;486‘7ƒ 7674ƒ‹286Ž782c„~…€€~„s;4867ƒ 7674‚Œ286Ž782c„~†€€~„s;4867ƒ 7674286Ž782c„~‡€€~„s;486Ž7ƒ 7674€Ž286Ž782c„~ˆ€€~„s;4867ƒ 7674286Ž782c„~Š€~„s;486Œ7ƒ 7674286Ž782b„Œ€~„t;476‹7ƒŸ76674‘286Ž782d„~~ƒs<576Š7ƒž767676’28673W€zŽ{yh4Œ7ƒ76766:“28675Di‚Ž€ƒq5Œ7ƒœ76766:”28675GPf‚Žƒo5Œ7ƒ›76766:•2867 5GTNg‚€ˆ€ƒo5Œ7ƒš76766:–2867 5GSRNg‚€‡€ƒo5Œ7ƒ™76766:—2867 5GSQRNg‚€†€ƒo5Œ7ƒ˜76766:˜2867 5GSQRRNg‚€…€ƒo5Œ7ƒ—76766:™2867 5GSQQRRNg‚€„€ƒo5Œ7ƒ–76766:š28675GSQRQRRNg‚€ƒ€ƒo5Œ7ƒ•76766:›28675GSQRRQRRNg‚€‚€ƒo5Œ7ƒ”76766:œ28675GSQ€R QRRNg‚€€ƒo5Œ7ƒ“76766:28675GSQR QRRNg‚€€€ƒo5Œ7ƒ’76766:ž28675GSQ‚RQRRNg‚€€€ƒo5Œ7ƒ‘76766:Ÿ28675GSQƒRQRRNg‚€€ƒo5Œ7ƒ76766: 28675GSQ„R QRRNg‚€ƒo5Œ7ƒ76766:¡28675GSQ…R QRRNg‚€ƒo5Œ7ƒŽ76766:¢28675GSQ†RQRRNg‚€ƒo5Œ7ƒ76766:£28675GSQ‡R QRRNg‚ƒo5Œ7ƒŒ76766:¤28675GSQˆR QRRNg‚~ƒp5Œ7ƒ‹76766:¥28675GSQ‰RQRRNf‚ƒo5Œ7ƒŒ766;¤28675FSQRNe…o5Œ7ƒ‹7668§28675HUŽSTOks5Œ7ƒŠ7669& £  37675CLJKJR76‹7ƒŒ765©8767676’54776Š7ƒŒ767ª6‘76”76Œ7ƒ7«6¹7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ÷7ƒ6776ï76776ƒ76676í767667ÿ6776ï76776ƒ96676í767669ÿÿüt8mk@Z¢–˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜–¢Zšÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿš–ÿ÷ûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûû÷ÿ–˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜˜ÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿ˜–ÿ÷ûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûûû÷ÿ–šÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿšZ¢–˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜–¢Zic08E’ jP ‡ ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cÿOÿQ2ÿd#Creator: JasPer Version 1.900.1ÿR ÿ\@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ DQÿ“ß‚(#[5h¤¿^q6‚êˆVeÝ*Oû㕪éªx™–]ò žµ³òË%‡è;ÇV’({¿o(õ‡äéÅõŸKþ¢»ó¾_ϵU"¹ovAÊæ‡¡å(?e¾ÈYÇkúgä*š ¬HÒØ”é º÷‰¬ø“ÂØ¥9Å—Ôºý=ö½„À:þ„±iß‚"µ5®a;ÝýÞqô¸6ê ÔâëÈÛWô3Mœâ¡:y.ôá*ÉÝ êààÝBYËnXP™¼¢ãÇߨ ÉŒðU ïc¼"…ZM"¬ Ò_<(ÃJ¢gžuàT›Oõst©õ‡íCfY"ýçúoª7²€O5ŒÇÚy?˜}¦àe÷ö‘<„|˜ŽÓ…i>Iý6eàꮟ«?‘.'¹+¹Ðc)×ÚR¼6:#Èù»X®áÍaÜüÏf;‰/ËR¾Œ8 Ú§o„VcdžlͲs’kg zUånêB$9´€.Òž,üÖýRZD¬´Ó­®§ n?j1Å4%ÓEß¿DôC &VçV*ÛbiÅŸÎVÎrU>o*+»éhÉ9„YLó¬\Fdx…ÇÚu?ˆ>£P#ÞYB¿PŠÊ»†¸R[×!5%tNÙ.Äæ4®ÉœmžÒe"gT@&Ýð”›yXÇ0P‘Ñ ÊÕÏ®Ô8þýÀ|í$N€5µö¢ÄÓÛnJ PVÈ|Úèœ^xüdj¹_-gsiX¢i‚â—?ª\ßkN{2WkÏd ~â!ó?– Ê—ésÚx˼2ÍVø%gisX#ÕQøï]‹êÏñÇÚm¨ºip2ÿO6P¥”žª¼¤‚¢-,_d*#5*+DdœéM |u$fÓÀù§kh.Z*ä¬ï# Ø6d{“—ÃhH%Ÿ¬LE¯þf'ErÆd®jÞÝFsPÄ.jë«_@&Õw=[°>øâ uI#ü…$Ò'Zvwnvm[ÄäAãT’‘Àn™ÈÏÀR~°ûBÀÇè6VA²ÑÒ¡j9¿f¹²µ!Tiñÿpk"åÔ»Æè>Gþä¯/zhj3Š!˜Œ?ÇÛSOœ‡Úê8–Ì’£áï~wŸëg9- ýÅ+¦¬LD>ÕxÚ^Ö—‚­(üêÖ½4“Í:±Ÿ¬zÁbëk µxÚ\Èd4ÕÔ„0|Ì«”½ä“ÌæÒñ, ʰ(;\˜")ÏH±Óf=zf*¦0B·ìsÒ 3?²Wß± @,™íV×ù˜'sÜöe+»·9rYÍ•jbÅ¡š¹É_ÛŠÈ0•‚€©Ò ß#£u>妿wõ!io€£ôSSò þ_:}‚[’¾Ö½æQaù5ð¢4w0ÊÁëôí.´ß‡Iœj‡gôñ×ÊeZ HßÐ÷Âð’ÛHÈäΈpof­†ÜÅØFòs˜¸]æÄ‡fâOáp:!Žv~']º‡C5!…–¹™@ »}6˜8]µìÇÿEGžRÍM箹Rè²w‡_1nŽ“¯Ï”ƒÅRà3¦V!ZŸÀãà´Ÿ"»Ý–ax·.ºÏùäå¸Y)JªL±ëâ’&Ùvtª“y†臦 ‘`Ä ˜SUSìˆ0yZiSzF3i¹MP+ñ¯]‘.ú绵1ÂXÃ5/º¥ÇÛRÇÛMCíz8§o ~–ØzEÑÐôÁã˜Ü|0­KA«k¤rŒ5m²eW´M?ö¡Ø J D_gK´ll)ÜóÒéWö¢÷müZ‚Ü/»%z[;ãæh«¥j†ÊSEɲ&þRÏ] ŽƒA£§Ìª‘ wm„ïÓŒÀÊÅ-Š»÷¢HˆÝ…T4 ¡¾…ÎŽ¿&´j#fmæ Õ Ïd»Ôºz'³vH6Ä $™0Tž3#—ËÚ^8Q»àU=›ô’aÛz Ié»Ð¤¦ÖÓYFÆ Æ¾ú»…Ê¿éÞ~výv‹`ŒoEnÛÆ`SýÅM=‘ÖšÏ0Í sBmº™WI÷i:#.Lí4 ´àªo #}H|É pj¹=ƒ[ׄcýì`H;í̬!r²Luù©&v †à½65ß,'nWÌÇ5¯Ã«üd‡TÌá~­°UœŠ§د¼-hx_’šbîòKkµ'kÐ7O1šo ß8û üpÃ$Ó¹›„={½šªÄ“Ü^ÿ†A 1éHÁ+ų́túqŠa13ê=ùÂ)½ŠB+# e7ŽXïT0vÜiŠef?n~¡Û™ÇÛMCê¡áö¸€†WÞ/Hš÷ã«WX„ø•ÖÅ¾îš C>é3J} ×Ò€Vë¥t¶“mh;ÿ9øØ€Èïsî B N†ª²kžvzk9À{)ÞM‘CA¹éþKŽ.´Á‡ê ×5ë¸|oÞ ÄBŸá?1Ð¹Š±Äü!€U¸þÕÚÍꃄR㠌ӊô†Ø>2ÒÇ– ûžw—©äPcëc"ô/8€¥ho(?‡ƒÑ‘$3¬è¦•3„Àƒ" VßVàY>:‰òï¿?ëû.Æ$K»®Ÿ™0 š.™ÞgJôì§±ÂÉä-;Å€úcÉ aë‰úí‰rÏï¸ø„–œì4Áþ1\–¸%8ØïÞæ†Û8aö € %$•50ÙÚäýŒ‡—ëû^6‡I¶Ç𘶖±D¥•Ozѱÿ##›Ó`Ý“Ñ ×YÔ"ô = ƒ å²XwwŸ{W…ÀP¬$Ö"¤”tÀÔÛ1S×aàZQŽlÉ–ø¾« |ÇÉCWg_P‘ùi“æòFÄšó°¨6zß™Mù“OÌP`Uü¦Ûq$mN¸am™XøQZ¢f$tßÙ'ÍR¼•¨(ì¦Ž¿É_äù¤¡Ÿ4pè» Äž"hºµ„kGnÁ@}" Ja&­°ç ¦²²Üü¾^uÐ…å/1_ÇÛ©ÑöèÔ>Û,œl~tòÒwa˜óÞ36º‘Ù+·ZrP¯œñ-o}¬®c{ Zõp?Ÿ‰ÖêÉÝÈpjÖ"¸Ì•¬à€lîk­]Lë% /¼¥xO¢í:ò‚Ô/Gäý™Wi³Cè<ø™ÓœQÎòŠHÍ“å(cToSòxÔ¯c%õLræ‘(khb¢|ÙáÜr²X¹›Ñ§m'k= ¦ôÑ…†VŠ"z[œ`ÓÂ娸‡$ÁV(ÆšXR­Yš}ÒUª2 ÈÑâ0Þ»—ÝkSûcÆžŸõ aÇÉÉG”'Rš º·ìR•xê~7rì#‡”à=O§\-:"ãWù›,`^’;:öMOžMè ‡-ØÕŸmµ"9mG–äØÇý÷åQÓ§ˆc¶Ú`®5ÌH'“èÍ ´q³P„fÔmütZ~c‘V éÈTcß™ÇÑŒI=’³ZŸOA™7Ä2&›áÑ¥¸ ÞVØmȆ²¡G#¼í#jG=J‰í°|¹‰–&¥Ç"§Ð."Ð8 ™&wü‚„'@äò»ÊðÞÞÀ„ó]IõÁ*ó°‰)EœH¹m¦«.LJÀ³ªê·ò{¸[1 ¸F;jèë> SÀT©¡÷#(¯(©*†ý°à]žÊ*úÞì·’ãôz9:{Ý -×Ü×óFfÎ)Á“µAg”“ ühBj QàsÃŽaõÀÀƒ:‹¸Ìcù¿ÅÑú×/öwo£×éÔl# }=J/åð]»±o¼(·¥´,VâOLf ,@üh%¿Ò“~Œ†üsIWÊó–S9áÇ0™e<üÅ¢`¸_ã“&’[|јeÿR·þ›¬ºÆc©ø‡ÇÛª±öé$>ÛHœà’?lÑK¯÷  7$‚†ò•eûcBþäN÷ø"¥Ù–¼aС߷£¦0GZtü-‚Zµ:üWF¿ ¯Y%Røš)”)Ìsò7øÕÅõ Þ“\õt~V½úéK›éû~HDEÔ_ÆÊ6ë°W¬Nù$,Æïä.oȺ º¨29Ȫò,’C›-H9*Bù¿y›8GjæhF$_]ãç½/ª&8816‡r–eÊTðØ•Yæ¹[ꩌĆml¯¶1 Í^½˜†¶\­Xó,|•pb3_wz¤l~†ˆˆ:ë^eË‹Í3ɺ! É~¦g=ÓÐÎVtéÕÀ!0° |.Ô›úDy9óðPÛ6Ý]ed·B÷¹ÞïPH8Lj”ˆŠï†¢ðt|&±Ö`*N²ì(#.'!%üý7¹®’!Q™†êz$@ù¨’»ÜZŒ*vÑ#1*òˆ:Þî@nZr*ð LàS•,ݳà›@a^Ìè¼u¦>|CŠôsµ;úøòå@¬ª]¹ý>g1ÄÍøÐ‚…Äg„Y¥G-ó´I ˜[Läî¼nèí§­9rîÎ#Òóîg”Œ¬WEÐ9¢¬Sqxà JåÏ@7Q®O¼¯œê-ˆbêÖa¶U©ãëèL¹Ñ ¶óêélÞ¨w#ç—Ö’­{–ž¡²EgÝDˆ‰t¥‘Èî9÷ûtM¥ñt˜¶¬OˆmndP-ûå‘P6ÿ÷º–3ïF ÔÁKd=sƒ|£½ÝžCœN=‹ ¥«àzü²ñÔñYPŒÝÂ1PÊèæ°£„ª¹`wbob›<±údz¶x;Ž–Ïô²lQ5œGNŒû‡L%ç”}´E­Tñ—²¡ ®Ï*Ë.M˜LõN²MÓ›¸žµ=ýÊÖ%Ý|EdbPC€À1( +yæ âhå/Å«´cG+BÙSiŸÚ1°¶Á›ü†ÿF”üB¾Ÿ’þT&cn< W£†b©À{éwãN¾$¥Œ•ºûµðþãd ˜ÓTq´‚¾¤Œ„d'Uoû­šæ]7cÝÞBf_Áð0’¡Iþæ~«Q3yï>u1öñóklèŒÏÃêÓ(}WÌ>Úô òá¶"Gô¡êÊ’¶”wš”Õ~ö‡X”"¢*:B Qq+ ÉÂWAåDAëè…}ñÂbb4ÐæùÚ ‰ËmÇÅ„ÙnéütºbIãðƒßx¨b³C÷ WÏ|ÜÀ$Y"ËÛÒ×祬/í!eÓ‚¨¶«X5ÞdB*ˆ ”¾Q¾ Älœ¾ÂªÚ‡XtˆYµ éoç¦1+,XƒÊžüõ¹ {ãëqà¸w¸é¦7'œzá|“mf?N7j#†Ò*ØùÅa°êŠü*dצLö>*NÎQfBº×7ñù¾§P¡M²5<…·/|o^4ÉÖˆª£0gä¡>¾ÜˆBZ27»pq€5±°C5í_ßŧAì_kÀz–oQXç(À£ß’æÜ~>~‚=È'iÛÿ{ôïÜÿdÛ˜bøøÿlÂ®à –ét¢õÙKo @$ä<,7pÀl) è;´%R÷Þ’S„ú¯.Î|‰ÿN|Nn?×ÐùØà€J±2˜¨D™ª¾æUØ®Ÿöƒ¬qâÀã'Yê᤯Dn}Žô’û;bÅ]ÀNìT‹ašh°ìûjœÉQõ? õëþ%Î;^Á“ÀæÄë ìf>ßÿxÆå³ûÐlsðcÍð5‚–B»w¬’6¥.°[­ûL©³4%ȹSpªÎ·/;I(§îà ÈP&U[ÿNãÒCÕxqbÉ1,Ò‡H¹ ŽU6Ó™št®à.X'ðáG~€Løüo¤}Ï$;L”ÄÌ1@׿tíý];Cæá¨ƒ¥’½!iã«‹e¡¼«C~mþÖêÜ: ±SÄþŠóóBB=¿$w½Sù™$e5(Ce ¬¼µ#‹ó:š‡¡>½r‚2Šô€j9 =v‘SyVd€Ã ž61y Å4¶ARmÐÔ`ÛŒ)žßuñhOïRÖ¤¦Ó,­Æh1–Hx\p']"jËoJÛÏÁ^~ °ûF@Š¢mãA¢Û¥Q/óìv€(9^mòìC_÷•fnÆj¥@f öL&|è3S Œ.PLPMäçë£kj-v=Hê!µUlºP#HqJaГ‡ ò«á°’&Áƒ¥±î¨&"ë黡}sæ Ý!sB€0/Lã@*l„‰Kë]n#ÈË2Íú\XÆ-§ôDu+̵Lb¤3`°åU×ãƒÉÒٮĈ±ÈßBÍ·~®=cùR®Ë ê‚ÇÛÔ$}½Çá§ÀÕ>‘7,Ïb±­éf,Ë,¸&°·äå co’J}ÝÒ½b ×ë‹V(!6ßm‚f’öA{»‚ 9˜ßäÁ9¯…™L™ ›2rÁ%õ²ÄñÒÔå0Ì)¥ëþHµ)]`…°¡üèí&“IÁIèˬ ‡8'ù&E´x˜Éµ/×Ép¾‹fG(ˆ¤”B÷ÔF{èÁ5÷ùMB7ÏÎTˆÂnŸŒÍa¶ºh¦š4úƒýÍ]#v{ž‡O~/ ô’•G<‡|Gâ¨Æ=±W å ±(˽螚`õîF]ïÜS­’Åä ê^Ü×h¹Ô–Óµ¤J¾ æÓ\š[“ÅdnÚ»«Â„ÀmÉ·¬ðf•ÒA,NI™˜¯‰.q¸‚=Ô£Ûö—jz‰ƒV·[`g-æ¥ò[ÃÉÊަ¹^ÝÊáÌÏè)5î O`åí*Ä…W(Ϫ§…îk¿ç\/½£XÑ»íoûpD°gú>ÒÛKeFs¾Jµ8{"ÿ r–£ÍBÛêÌ®3 ´ó‡]dÕ”ëšYÃQÅ}£qý¸’ã묔²øÑ (á2”“¨ÛP‹ÚžžìQa¡{'YÚŽ—ÅJ~ІV$^lVE'¾&sêbdC*(TüÌ5²žq@ ïÄT‚PP £FªsA„Û *·½YíÔeJÃI‡ÝÊ­r1Hþ5 ›|DqkªN¯”qŵ¯›.ÂûÅÊ¢4Æ{7ðê)’Z#Dب€…öIm2@q3[Ó‹0w70Yé‰Ö ;‰ä#ÿ3ÆØrÖàSgþÚÔØÌ)Bs§¥tŽ)°-&6š´¸ÎW÷ O¡pÔŒëàJÛ™âOpÚ†wQɵ”³ÙJç8*%† ’?¢ÿ~iP¬x“.x",òÊÄSÉò'~ÐçûZ­?h™…P:Í7ïßÿ}'XØ6o?®ûOö쯡^=žkfòë ÉÒNCx)ó7ŸÿÞZ\lqœí>´‹òÊsxHn¼(Mñ'–«w@7îù>¬Òîñ"FÔÇ¢hŠ’º‰©±ÖÛB¡,ü´;A@Û í-a=ÇÜëí‚Ä,¬V–¾y…ó­`ñ4Ç7®æcÔ®IkhÛ¿^sJîÊR§Nk¤Wþ’…¯µðÓy£Lš¹þú±4þé7É·5°Ût|ß'ëÖy9´˜ Œ3Fºl„Ò$ù Þ8k”;+ßçêŠ{ÖRœ>D÷­¥Å"`¸¡„ù]_X€Æ…èYØývDè˜ãd—@‹k: †1ŒcÆ1ŒcÆ/hëã©K7ö8³5V˜0¨%_±„â¿ó§…|%¦;$<¾z©q¤‡ÿ®ÛÊü VMu@0ã CÙc•Z;ÿ1P¹>‰O8­Š:SÒ‰%î8ŒŸÔÆ $%óÕû*QB|T“È›>€Ò`8jø[E»‰ ô!…q‡ *Ì|³–«ù£ ëáÁû¸[¿4 +‘ Hõôé7"p˜·5±Ø(5œÔ•‚+ÔOQÿL}åèC^¿jPä øÎpÎŒ6+øÏAÜݤLyIO‘¥sö2·–Þ‘\þDB=°÷ŽÛõå­w¢«|¼‚¹!­Â ¹óî+}ŸÁÀ†Mƒ5 ÑÌȺ]Wkfò§¢îª[êÍ«»À!GÊ„s­Áíßߢd[çK ¾¯Yÿ¼»͉¡4¦e˜ ùjñÛ'èÍcæa×Af£ó½}¬Æ'ó2ÕȧdevŽ+çñ½©É?Þ¬xl륤ÄH {UµD3ìHÇÅ~¿õÏTh#_Q›—Äj¥DÖ“™ž³Åá€iªODZxcŸq6§>@ADhÿUÌ©OAiNÜ»½@b×uaÉõüà“ëýgý‘…W?ÇÛÒT>®‚áöé°Õ>ŒÖý§íŠÉ&/Ûà÷õ¬Äxƒæ»MF¯ÒàÎð%¸·z ^¦èGU¿¤0h"”[‰à¬If:ÐÍxdŒ üHÖjΙpgï½€?ÌyöI« FPÜí ÇŒ)b­4s¥lG±CÌ$b‡„“Ob€ýŒn‡=%7+½®!n¤QDa] pq#ݹ܆*½Á…ôÇâÒó£Ö¶zÝdÏñ¦dþˆEB5‹Z/ÜÀ¡äçLÅ€âgÆŸ‘AØ6Õ;þ}}›b ?C¯E/AÛáéOœoñªµ•K.¨ 3®5ð³ú%b5”¤J¶|vµk[žs<Ÿx¿´=¬x!©y‡ƒRv˜†VE„ÈvåøM¾áTkII}2ÅlUV*ÏŒƒýb/I›§¹ï6Cà‹‡žA'ôIæ;séý[0—LWK Ê_Ò§Üßž÷¶6ºÉFP­_? ™en‹h!ñ^,3ê2X$N°Çî9¶€õQ7Óÿ!ªOO­Üö«¾ÏâÓý,•ïg@Z2Ÿö¾2s|#å‹1Û¡C=‘íª™”e‚¸/ÏBMxiѫԋ¢v: ×ÄIQnC®Zë‡#=ü»¾ø,ý,+°œKQÒg$Rs<â&D}¥—@ŸI|ÕÄéŠ@±¹‘¥žCò€²BkC:‚<Ò‚¨¬S_ûzù%«Æ^´‹ð@ÆöP)Ë—`î3ó:¿ø¶#Q™eß6šlÊn5‘#‹„/pPÈ­U$èŽ Â)J-3 º/BPˆ£ÐîØó ¿ÿ}1è8—@G]þ5ëÂw‰Ø“>\úÿ[]b¬Ü°-K›Ú] Ÿ¿™\(pRäþ˜ qç-QåÃé0Œb° `Žú]¡v)­Z¸eaÝM)C{ƒƒ‡Ô2¸Ä&ÉAìúd%òxÜkâøÀ$âóÌ¿žOKr+Π|ñ”Ÿo®I+IgÙ<ʯ¢¨ArŠ?—Œ!ñ<”’I$’I$’I$’I$ŒO"ÙñêÊtJ ¢ÿy7«ÛµÇ¹4ô1zün-°9®0 aïÉÑ¡$=ïâÉ [mþzÝ8Àuz¡ mb¸Ì/ ò8÷å&Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶Ù½mD% ØÚÐGvñÀ¶.¥A<ÍמÜ|ÕÀ~AÉVîCžËIN“%å¨KUí¦g ævzèðþh$±XʆÚž=Œ¯W@È¥“CtWT4Î@¸ ÈH&( àDS¶O~vQïØ7™Ä¥ìJXé¥p”@Ž ÿ"›ƒN/÷ñ6ØF½íXß™ãÇŽÚJ³ƒlsp‘×ñX4àbZ—ÖqÞb]R_0q¿jn7>Ú›^B«x5¿4wÞ*¬Vw"Ú&[’+9kþøøî;(äà³Â"`\ÎH?W¸/”8 zÝH¼Ûý¥Ç„„ò7RãÓúʯÀJ„{<u8p–¤ 3kwždËxzßø3럀õ7¥`6mY(vFîú܈tÒ/(Òmµ|áCÏîKƒùó]€r}å£ý»µ’ôç; ?.| oŠ~¶$ü¿'»ž9>Ê¿އ€æ ŒBf”BQ¢‹¨nÇÛÐ|>­Ý‡Û¤@ðÔE“sOd™ªq›2’ýÄcYC*Y|þnc$™Ýò)_„ »õ›½R¸²Ï“V^ Pý¸CT;e.{Ü0tFù`ˆðD6mÀdtRØôí=/L†ºóZúŠ×ÿ~šÏ2ó½–¨k¯˜ÿ5R#u»N\A6ΩW¦!÷ˇ:£Ï!®d‚$ìÞ²)¿FæˆMCè` î"~GÛ®–FE‚·9•Sº9ckUɶHu²c•˜m† 8{®*8‚¢?¤óŸ„gjÎý>†iáÿpláMTù$7”_Ño!œÀ˜†sS%ì×µIÁÚý@“»hjP© ‹nÖ ºËd(ýa ›Ü¶—d±‚뺓J¯?ÝŠÊrÉGbtHpdsü"Ž‚f$‰yý1ûï:ùÅMš2¢‰Wnê-™|šµIËa6¿äýq¹JTûñé²½ ÐPB:SÏÊ)Õˆ8›¿Ë7nÜØT’E\íj¯s²Ræ %o“ckZm*û«¼5?X!¯HÜ_]?lƒJ ù‹šÏÑ ç4jY;£„z|/âV1Å hd ˆ6ޏ²N ™“z8mÊÝèñاºFJ‚Ä©”'–_·(á/~}&Kº.&åë}9þbà.ؾÿ`"º_7ÌæOW¹M øœdÂê&d4ŽÂsòBð¦NéyW™Qcûö(,“êj忨ÿè9£>šK¥åÙ*ìqm Š óRÈÞòCOœ\ß êMkm”=Àÿ4¦—WLM¯gà´/Û ÿ~¹0Ä”‰¤`?ëÈ <Ÿ©Á·f.Dx¤íë)u3ô·v»oJ”rvÍ>È4¢”ûÀ‘oU³äâoñEoûZÙÑ/¦Ù¾?ÿãèNÑçXeÿoOϦ–»ë¤ùà ®Ièï.¾Ò«’ãÑÖÿ"š_”ž7ß{*/|Ðóÿ{pœl¯/ÄXýàîÃóþ%Lfâ‡ëR³F‹¹éóbû>ÔKj&sxé|"Åë„ lÉþPžWÅéQˆ ]àTÊ™›jïŸ[Û=ë[«i4©eŽæn0‡ÄòRI$’I$’I$’I$’,ÔÙõUiÚëN/Luò;Ð ¡#è‡5øÝN6íÔ‚€½F–tWýúp¿ºæãm’Q3ƒm‹W¯ôù.ƒ¾Ÿ°×ä²zZmn&ˆú!*ÓjÄŒÌÕ@gR‹WX÷å&Ûm¶Ûm¶Ûm¶Ûm¶Ûm¶ÛQp')ù°{Ø.LJÉÇ”Š¿ý a1aËÐ`XVtÉï0'ˆ–ƒr+éà±Ú—Èø/Ä¿“WÚž=Œ¯WPOkEht€ç ɈÐêUÝž—âòÞ@ÕðÝX]ü%j•Û¼•ºOY.À`§ö·sÍ9`â—±7žÙR+°.0¾`ýñ¨wjQsª›õõôä•ç0ߟØ[§\ÁÐf¥:¢O–FG#[—·7°ëlöI%¿ïø]ÙºÌ7ܽyŠ Ë3Ê™\ ×bbº‘Ó»oÞŽHk$€wÄ?ä{1“%¼ÔÿN”HÈViAÁnb˜Å—î¿L£Úüëü1,"¦MPM¥8Fˆ !ðxÙYRw¸Ï{õ˜4Û5ÞLTðÇþß2Âq]q¬ÁÎ Ø5ÂŽGü·»¤Þ4øpHÁ[¢ ˆãcŽÛ¤xŸ7m ÓŽ§/ûæ[ú$ÿÏŸŸ…Ô0Ë£ÑW–*“—Ã@ÿ;Ûÿ<úWýOèY~ØM8¡ìÌEÉ ƒŒæ­˜°¿ ð¿ ð¿ ð¿ 6¢‰%2»‹0NòHeÆ\e&bf&bf&bf%â7–ž•+«„ë}m.­¥Õ´º¶—VÒêÚ][K«ium.­¥Õ· 0Û{#aâu¾¶—VÒêÚ][K«ium.­¥Õ´º¶—VÒêÚJªw‡æôšpü:Vl±eÿD0XÈ÷‘Øóó,5¥ÀØøí^¼‡˜ggÐÏ ©éÓÉd¨T$)ë±pÿVnF* Y•gù¿é*àŒ2Tø’¼·¨ð.¯®ãÂB\Í$)¿›Òâ§^Ý,á§ÑÀj >4+‚{oãöè õ_ÿ[z_U¿Û£·Gÿ7@mk…õSwÕd~Ú¶ú@ëݘÐS W®GVsbktÄ ;ëɸˆváÎ “.€,;_{6˜ÿe¸ÿ ÷!?‰tè–žS¼”C„kE(N0ZL[º:å/#½öÕ[e8‡÷YY¬Ök&ZÓË ”sí–—œ:mÓõÉpÅE:TéS¥Ný®mupo­¥Õ´½!V5—s“TJ_U*;;ݼå Y›©6+bƒÚ/´ ºCÚ!üs–êpÝN<þï Uô[æO2x†òŠ Q}å§&V§!‡Ð`t;'hCÓ]ηL~™(w¬.œLí6j‡"ÿƒç¦óáÉìK~º¼#´œêÁl¼¼+ñ_ÿË&"§ÿ\¨È“¦É±é»¾&dÀÎ mˆ•$¾Êê^ð˜Ò,в Ø¢VºXþŒÙ9­Y¢B„„Þ€‘E¯Gû7„úWt[ Ú6HUS!o^ix‘a 8µ–ŒÈÞ:xë¼ÅTõÙ«Cû·ƒ9ujŽïC@p¶ éÔ5Ã:ØŠ›îà-(€Ù¸Q v’/‡3yL÷›‡O´h€qTá²Óón¾Œ1qðk²:Ûß<²6GÚ»Ëo[kcXp>3˜ G’` %VÃX¼º+¯ fr3*}ÃÂQ%Y%Kˆ­×C½¶s<½Ê_éŽÜ²È£’†¿ssâ6÷1\ŽÛ¿”Ê<6€çš DWÃõó¤'hË3Ÿü¯›k…â@ÍK F·÷å ;;¯›æù¾Ä¦…fÒ Ÿš¬oŠzŸ£Ba‹_•‚Ç„1x‡ÉëþS™)i®Ë£ÆK;e`mäSaŃ &bv×”%fìF .˜}Å‹®¤(ž<¯ïŠAçŽ!øÐÄ@u³ÚákyÜÛGi0=¬ †Çœ8iKÿ~¡tŸù•ŽJPªŒk"_·–Q³  æ$„!$`’µÉ¸7²Õ~Ié@‹ÜA©‚bªíÚ»ÐÈÖ oÝVY:DWoØÀò8­½ôÛmvÈõÜ Àœ)’Ê’é b÷€¬3ÐQîÛ³fÛÓã3ʘÄ1Þ›¦o`Z5Ö¸áÊ,—oÊ-#X9†sÌ3ž`íí«°½ç9œv;¤ÞB8|<å”z_ÌÆ~ :Åxmz±·ô®<åqç+??c9f WKÂÏà¢xq[¸G¸jÀ5¤-¯j„¿´j„oíÏ€ VUoJ¨å³:“ È£àðHMÒôÌÜüls~¸UrüŒ»y^„θ 'téÏda’ /ÖÃ%JÞ[låÈt~ör#y^‘†J€c¡ìàN“„§ËUÆl7Ù§›$µ>¶Á¥q_ôàÙd¨+’YŽ«Ì>Ó™Ý×)uã–þéù‹Ü†É¶\¢)~µóBN"·pÓÀÂBUÁ¦¤/LvÑEßdÝ]ƒŽ™Gÿè?Ì€z›+Wæ3òØðÔ³z¡ ›ÿ±öuÈö×›«–â*Ô½¡.Ç| ‘†J€yú¨–.;(űH™sGÄ#®„o+¡Küº#À0*qHÍ,¨'°\‚}á{7ý ¤RÑ`ôdë2€8œ7xÀ\Û ŽÈÃ%@:À‚‰ŽJ}©7‚íjÒApFðÍÞœBÎ&ŒÐ.„‹‡JR$úbZm÷lSW´}”}Ó]xm‹3ò×d£_Ér4ö³3í+ÿð] ìßš9´‹´=®2S]‹ÂH>ºÜ R@¦<@¦¥­ÈGà 껵b…ñçþq‡gær7k3ÏܪsÅ»JÿW2uûpΚ9ØÓ)óJ&‚QFLüUŒŸÚò„»4܇PÔ¸¤Æc<6xîö`¼{±³´.!áïBø Z†ïE¦\ºð«|>1!ÿÓÞ“,!›ˆ”Ë„+Ćþ=ÏrOÏ$ …³ÀÙd¨4Y0À–|!Ó& a‘aŸÕ€kDœí“o!)ë›­$×?z®s.:Ÿ'¥Ûw¬Ä+ÝHË?Ïô?öW±oŽZwä¨:†ñ?s¥Àþ¡$ÿnÌÅÿL˜Wyƒ‘–J%²Ðͳ¶ª$s!/2‹5&Í’ªÐˆõq`žó‚à¡‹%éÐó^zwÕØ¶ƒ¨3wÍè–u:”¡pG’틇×r|Ýíâè¥ëÖߥ<ç)øj†ï'²apHcü,aàlŒ2T3„̉6º‰œó¸¸ Ö1—µå>.^Z† 2%˜E=³ê’±›É~f¨¥.¢Ígnv ÝøK]<Ì­j 8iWKšƒbD,‚K8!€ wpœF>ÂB½ Œ 4H ¢´uµ¼€ófð÷ÉÂÀ9ûkñÙºEô»RÓlÔ~œ–tçe";¾’*57²y‹æ-Ì׺²8³L—“xÜÌÅoDä’ûHѧK·ÝÝT„Fü2)¨Ùxã=~½SrmçxŸï¹½KJ¼V¸¯¹»FJ‘ʵ!ac¢Éœïm«Ï 4Íåz³ s’:ÑÉœå!c¼ÒÉ$’>$€ w&Ïp'Í*L3=Ûì ÑGÁ43ÒìÇ>­ç› ÞüexÌ›/*‡¸6TÊúñáV:õýl•EÄYìµÄxÞ @[A}Õ‡÷ΗîŸÇ!Æ(18Oµ8ª«ÏŠR‘ qù^g†*ý×ÙuV̈¾dãBnÙ®7бóàÓº@ËO ÿàŠ¡Îó_5òÀ$ˆîN»Q_’95C!S¸ïUÓdrRô ÿý"BO›W#9¢ËP3Y82)m®Ý12eÔq—°å“˜"ª†Øc${1"0€Øâ° xÖj-‹ œôMoÝàÿäg-.3'd×óÒnÌs pæ"H'v)ç·°ª\¥ÝË‚ÕlýlºPHGÙ¹Þ, ®a=6tïXxÏ}]†SR¾šÿu?X¥5êµÖ"¨ú~GhW¨Ü…ƒúŠTËè.VgÏ›ÒG.Ì©‡ˆ»Â­A. ³f,ñþ0Ïü v>‚ó±ÎÏžñÕ´GÅÉwS¸ UzÄñ‘U·î$enxèénϯT±žnŒ„HF¢ªçÂf«5Uœ 4s'Àõ^6Ì(žMÆZ´?BÿWœ)Îcb:y°0û«s^}vjÜ‘\d#éw,ÂÄI-ÔAäËà/ƒ ¼‡$îçªñ£ ;%ø? Û¯›ïöÙÉ ê-p[Ã)ó¹ëѦ\kcÓÓª”ÄYK1ÍÝÆàBu˜¤þwasÇ›ç©HÇ}’6“CX¶F w"ØÅ齃¥;*Ë–j”j Jëû¤×Üv}0w"³PæG© ÷ìÔ Ö]$\}¦"Ä44u‡^Ž#"ÿ}s Äõ¸zÖ'w 3iqÏûé7®«ÞH% ¨¢R… [Ž„@'Ïäï(;×_Œ?×g5ä!ol¶béʈ0› àKáõÙó¢6jÆå¯N¥“í5jo†ipØÇƒ×è¨+ií°é1¯ €ECŽWƒŽWƒ’ËA&Îgiµˆw¤§­¼Õ„–«ã‡)Cr–åKØDÚÖÅ‚ó"Éç&ÓV¬åªãöh¤©ZêXf¡Ã·×¿õïÒ ‘Úö,"´`ûR«õT·²Ïk¤„°öø"&ž$x®*˜DÄ%¡)‹°Eè¼]xq(]¶Œ é8D΋¨Ìz‰ÙÎ-Þ¦Úòï9›tÖ2Bué’GJªrøcjÄüßÝãD›¯îS'›úm®)o§õ£äî$ÑnމëG7/pr§Z ¾” ¤W›œ¬èHéÉ‘ß4¸æ—â0"ÿ7ã}ñFµó¿ÿÆšN eo`q+‡p€ÂBU¬â¶®XIý9Ž $%H`„„¸jEsð…Bâjɤ¶hÿÿ>Zx6F*hˆ€È'ä0Ž¡-G‚\=iNUÙË£7 üÑ™Á¬¯¨|•—6O0!íXC§FAv®Â\1 é@'Û3¬@²Qœy<·%bá¼ãiè¬&²Bíw|e·r>èJžsG“Q>ÂU‹›q—ÆìÝ5+I®„o+ /¨²0ŒªŒ71©d·<‰Ì9ñª ªŠ:¹Ph€åùòZ}þÒnîazû¦’^†\y©1ŠÑ]7?#+Ï¡²0ÉPÆG† ‰|uÁF‡½Q°OUë1÷/N­vDØšrß)‚ AU' H«>:££ïò`ënvL‰ÄÌû[; ŸQ—»HnEýHK·”.&a¶3'¼^Jƒ'›NmZ””­0 …eU4›Þñ°B¥pnû¨¥åÐË|ˆ? MÑ×hHƒt´á¨•™È(,q>ü׋W ª}Ge–~ë³wJeqþ/;¾ï½ŒF Ÿ˜¥€­bË»iõi2W˜ÜtY¦Ö?ø 2†ïFÊû6"*Ê#$"ÛXç†â p@a!.…#åo.•wN¼CÑü* gi“~t)&ÖÝfô¼ÔÉù‰[ÚkØ)Pa° õúÔ©#º+_jjîTeíõC¥##üî6éf×I¼E‰î˜0R ·ÈÃ%@E+>¨ØÂé½b_P[¯pc‡¹œÍ,²éCV…*gtàïÞï9 «À£¯°£4»hšzç,„ÃÏûÑ0}ÔyêÖ‡6UiaH(n**q}éKcXÙ.1äzÚ~'7ZյݛÔ:¿Ïž Þƒ\\G¾ä.ÔL𜿮c*¸Pß)1°ÌµÓ—‡åN}:ý¨Lèz{ªÆòZ5 À.êîdXf¦1$­Sè6·y:¸ªô¦Î¶”CoáùFzɰÄÿ9:>SÇûöõ˜‡9™øc–` ú–²ê¤”Ò’ÂAÝãêêÔm}ú`n¤vJ«æOØI.ô-KÈ÷×ç’%òá&“èT¨~)“Q1>LÞ‚°Vž¥'Zü•eë¨HÒ6°w|7ÆA«ø™Õ΄‡:µ®uw`_Új”Õ}!jÃøFl£§d@¬ˆ‘rä86´# œ³^¥©»†`Pÿý¸î 5Qð{°ÒSú¢œÊ Ǚܽ«yåÕß±êÔ3þðšÃÑW,»_ZJаï"(М!ã~—Ys‡—ÆïAD§ §aå‹–X‹>»ˆ©c¾{çÊú“j^yà&q EÂç@(1áé« = CI~G!âÍÊ›É)„¿ÿ'(5`gjѧö“‰ÿdGìšIܨ«<6;:²Xˆì¬Žú×8C›´‡!78%S`|£^ßÌ3ú‡¤=1ßeÚ2RXLÃJá•¶-3kÐæƒ?†7Ê®nIdËÃ’Ž\´©ªÓÕ¤ÁùžðÖ}Ck aèȿֱ»ÏÂúý܇þåbÄ©t þîL wðv©œ<¥ÖM¹Ýé·GT¨ÇÓ½}îq»"×È¥ÊQ%ªÕœ¿zЇH€ëR|1´SÆ—ÀeDŠé¸y4\Þö,"F“¤Ç’tyÔTwÿÿ4ÐY®+n3Uîˆf»òꪛ¦‚ÅéPQ™¹d¶ ÕëpûGÛGÛM‹›óMn®µ–{K°­92"£Ñš´oï•Q¾‘Î+Lmë–ød!T°¼Æ˜œ¡¿†ü/BðØ%P¥蛘È2ÎàËDÓ¢•p·¨!¹o‘Æô¡+Z-°Z(Ÿ™§Ú³2—³]E„•Ü5ÖWš<i…ùTÆR&{—LKA>WÓ»®ÒÖÇ‹¦µRÎç~7-5(Þ¢B ZÉøÝã'Á„÷2+~m›{DÓúŠo™Šoðº}…úÇÖ—ãÒëè'áÍâ|ú[öè|ùõõ_X~ª‹õhïê¨ÿ*öÀüö_ϸÿéùô˜²C€:oUÖGÓrjû¿…­×Í󇽢Ö°¿ 8Îþ[ 0Án^ö[VaýI­"ò½­Y.F}EHƒ )ÌÉÄTžvÏAfsVÌ Øb9…d±ü€µÇÓà“!à×W ÖûˆÃ†¥þ5KüΔÀØ;˜D•`H‹VîÐî\}ÇR\[VBØÜiÐ{¤ë}m.­¦Fÿ7øiµc7l6 ¶^x¹dÅ÷nRéV¼ñk>åd(-ì²Â½ñ3`éO¡*ÈRšc(Ìî€u­Þ¨¢Øõã?ç Ô3ëŠ_teaÈèbȇ“ì>k3k¬·S!ý™OÇŒCUþ''Fß‹×`Ñv›9[&à”)ÊpÞÀb&ýÇâ2§nâP„¨qÑ øÇw\{gMw·©±ÓR–ñ…)da‘àœ7&›pGBü­îmÀÝÇY}’Ó Ýªâ G@ „QTõÃ7çò'#@FrήÄå> [i̜ڳ%Ê<ߡ˨?WÉÁ·+‚ù48¸+?A¬äb‹ î–^×ürâ#ÍQ(&eŸTíì`!ˆ3NøèNÑk Ø\ˆQ[uó|Ü·.Ýaî?˜–Î-a{ ð¹¢¶ëæù¹aD&蜖5GÙëù,ºõBÅ>åNÛvéÅ Ã<9ì=˜æ¨ã¸PLá³2Ô7¹ûpú@¹ÉR®¥â­n¸ŽÜHHX¥4<Þ7åÕu˜~]ôC‘žªÖ 2Œùë›çÄô Ÿz?Ʀ#TÝ‚âžp¾ÇíÌð.)* •ßõÄp† F¡F˜^Lwÿ „Û‡_°ó¤úJyýfûê«Ì¸zéeÊÃ#:G=㢎m5 ¬b…Áï!_A ;›—>3È"ØO`½ßžöÀe›Úd2§ÿÓŸõY¥qxŠo;ÛÆÛºÚj~‰i- ‘´ÑtƒàðÁrŸ˜ ÆûˆN»6µ)jCöß½ 0À«oBM錄­_C©Ëÿp0£Oë’§4еº—}\ñÑf²9ŽÇO-˜ÆÀRà)+µ^ïgpø¢c„:f¢8C¡½7»s‚5‰ËºóWcß“(³Zoþ¢}Óp_‹À½³6–QˆRžI™®wðe‚6³kyö8u jµ}Z@ÂA§l^-ž`^zçbŽÈÃ%@¶SîgIXŽÊ$/¬er@ßœäˆ2ì/¶®HÃ%@m5ª€eýÞ Ýi6½ÿuïü h£õ•“q}|# • ¥AY4\gOo+¡KO:¡m‚8W0õÇ$ÌôÙú¥œ/MJzM‹…PšÒ¿(“‰v1øÍsp´aÒ BÒáPU€ÂŽ1¢Iؽk½ˆ->$üVËlë|½'Ï4ÕGƒKAzVì#ù§dÉ[?³×cï?aó@áÐ:¢ÏÁ²0ÉQ  t®WI¢Q~ŽÚJõZºxîáÐ ´Â˜ÕˆŠZà‘P`0HÈ?uYñ°WïVõG¢°d¥=Gh!8’ÄÝZ {šeÒ^óÛÆ–hPœÍ+GTà½\<¸tã–­ ®~ð’ç0°·î…ÙKgäØóiIN-R§^²yÛ!è#`áíªc7ÙÃóGO@¥`HÈq>|Œ£ vµiQÕ<@?(‹âm€PbÒž†™¥¹~¡©¼ÕxœùSÕw°§V†c>΢‚;Ö†…«íÃxêùÌtïÊú“j^yà&q EÂç@(1áܹOS Ù–›Ü5«_gT ±„þÉM]†DV裹䳰`À£“0bë¬#Il …ApϦç(5`a@¾P¢UÑ6ÓmôÚÉOúx¡TUˆ%Õ† —Çæž«NàÓcN!ckß\V7MKÝËïðšZð¢!˵<»ocGª`4ÍÙåH†I«I™$_ÆSŠöï5Í{X‡¥Ðÿq6ŽñüCK·W”Ö0Ä'Ôéo»x¬ÄÕ«1ð£±TÏÔö?qÑ9@ó]²ÒæÍ|ØÞ„¢—êQßH ¥Û©!–n ¨Ú´€v…yÞäNËeò>Õð´§¼Sþå£d‹,)Ô=ž¥¢«Y\Täð¾·&wÛÿ{;­™Ëpl4¼ÚÑ9ŒÂ•œÇ\JÈ5heÕZKKš¬]¢ÿaršˆ/Ø%P¥蛘È2ÎàËDÓ¢•zR3Mýò¯FÒR&šèô…q«‰| óɨ _Æ#¨N,$ÿKlßÐ-¬ãüÜ>)ÖG­üþêÒ¥‹ûpœ_±ì‰“Š“bW7(Ó01ç,ìÓ£ŽSp¢Xÿ"öX ú€A©ïP½ÁµÒ óùJªñéžæïyasrd5x*-{Ew ãö™þÒÚkûIqûLÿ4ÇöþÒ<¨"ùÄ_8›ç µêÄüQúÆÆs_’ ‘„„ºO¦ã1Oùí+1Çù/` $‹dÝ63 Êi< £wI¶RïþŸx™²Ñf¹ŸMZ•l6F*&¡|±.É@œæ!x$@Fÿ®Þ†ï "·÷#¦Wéêš̳ÀÙd¨=›opÕŠù„tw0©Ì ’…MøÒ Ä5pX+ LªØµEšò©½6¬R4›ã•Çâ¨$¯ò úHq­„æ³o7ñ·…Jf“k,<9`®šÂxUÒpß|¤±"Ó==BÚ“"î…ÃíÔDS¥íÛš³ ›€ÌŸoÇÞZ‡e›'Èý‰Ô)ß%sƒ” ‡¿ á«7íCþ&'%Ä÷Pê?ñ»ËÇ.ûé>Ùƒ³7œµ¢æ€ÓÄâ>ýêß…Â ÖŸvÑ,]‰Ì$¶Šf¼7“f±X“> Pª×¬FhÂ`èøëÓuE-Õ ­WT]8ÒɃ±Qú0úÎu‡ø3Õ ×æÑæW7™ý\h‰¶ ¾pÕ?E¯7Ñ×~á3»Ñ‘=ö îݰWî#°¯,J¹Ûçaw$A9……1ÿ:W¥ñÓM4\uUKvÎy•5Ùº ]ŠÛ§q34JæÔ·£¨ÐêlÌc!Á‡ž+ØŽaö´¶t@ckGŸ;á§QU Ù7ÀzÈ9/d=\ÄÖvÑÁq*owš »Ž(õe.šêÖß…´ Ö÷«1„š ó~ƒZͪ`J:]1\s’›ô5’ºfm“’ÂÒSFT€+Gý!RwÔŠE›XˆÞVg$[pΈ*>büÕ.;Ö€®±¦˜»ÞU‚?'o¿kN&Þ¼Ç#R_“×gdÞk¶nõ`k+~aó ºdv’ä‚wNš¼"²Ð€ k°ýáûi†æÔGš?©î Hq0·ß…ý@³[²3¯šÀôáÎ Bºl¶-‚póe~[–VZˆË@£]9vå°®•ðÝ„¥N³ß… ÖŸvÑ,]ƒJŠJ@°àClH@ZÌlÍ…?¸¦w­JNs•ØDÜP¡û8 5ä/üÿÿ=msúº¯áŸª>’! ÚïÿùWûõYþ¹¿‹ÖÕo™™™š%Ôù(¨ÛlŸRùrqô`yS ”ÈDvkK¦SÔ³7þäìÿxAMbRsœç:3ÇÛSÏœ‡Úî8–Ì’£áïW]ɽöG«øÎÐ÷Æ,€;©j˜„‘¨r§ïQ/eí7ÚÇ“ýt\*®êd½]‚#‡LgÃ^çëý3š¼Ó6oüÞ—f|Ó˜“(üny2úG\Þñoèà7†P™äžÃL†8>,ÙþÈ*ÒR{«Š¦ßG½e4Hi”¼­Êà2T'¾<‰™¸ÓÛ€paä'Ó9ÁB¶—)$qÄÙY™Aª#¢±âÛþcaÇÏølÊp&0ŽRÁâ–ÔþÓ´»3ñ×8[êǰâ*Ê/®åöš‡hB OÓ[G_[5ʬÊ)¦âßÖ¦‡æºæ\Ò ÙâÒt‹×´KI“`z¢CÔ•Âóî‡åô# *_Dß71ñ×mÓ;l¢æù7 +ÜÈrIÑ+ª4/Ðs;já„åQ»·^‹[æeŸQV‡_1r­S«š¹·Y#Ë÷3ðE¯3âkdzVD´ƒ< —ž—¯e½Ékø©Ýb‰XQ€èSà|Gìƒy–%Ïõ€sûN˜æk (Ò¼Ûk2Øò8€ÿñø±BQCâœ^8Ž;‹j’c_Ëm[¯”ü ¨öÇÛSÇÛNCíyƒ ˆå9xŠ.gqŒÕ‰bö†Ì¸u&íà™Ÿ!3JŽÇ„éâ"޶ýa<È=¯ÛÈh˜ÑUš¸ têÚ¼¾¾,KtP³D+®yÔV‚#‘Êð<êö”Kˆ¡¬›µì ÍúfoCdÚšb‚sHŽø~BOo0'(VÀÈ`[Ž)µ´ F´]Y×xVS@‹rÇŒ‘½™ ‘ ä`A £#—ËÚ^8Q»ßîŒ ô”•VñÚa÷ëV+J“Ij|µ+¨ 2€û•þ·éÔ|†±_&˜¶]ž" ]™×.ý±¼ª«Œ Õópˆ–@ìÝgem¦½é2x¼à>«ùb ‡8ü}—GÙÂ2Ño¹T™o½ÐÀùÒ;êÍwÍ–¨ ÉB ô(ú@ °Zn¤G¨fz‚W‰\$8€S­°U ùÑdž^ý„àb̃ ö¿ÙBx2/;·º»ÙˆëÞ427yXcškðÁÞõEhšqÓ|@Âìvè ¾Ç]‹U½ruwc¨Ø7oY–œç$ÍÈ™;bù@kuýäM|3¾ÛeSFÎvÎ*0´s5ÇÛLÃê¢!ö·†WÞ.Ü ÑÒ]‡ û·ã°dœî‹…ø9™~‘SìXÉ·ÓEÍN Í ±ø`6¯8–°‡ž<‹:O±é™9ZüÿcX‚Ï:3·ç…âujTÎwyçáHµW½éT}ÔЛëŸj=óÈÊ·'|âncÝëÚÕ?¹Ç çÄÑ[J!óéáÏ"†ÁwÅGtåñ¤öç‡éïï}OÈý¶ˆðP¦ÚM|Vãçdp$ˆ=aæ©-„¾ÌЈñc)V£Õ®c ·ÿ"بtS#tuk-ŸˆšFñâè p8XÞea‚9;‡¾,!õÕ£IüX#( D]fó_Mž>G2…Fê½@#çTÍÇà0Rý‘ ŽÌ¨Ä. ‡I¶Å0GÕÍe)Ä  Â…6Öº o‘Qm¹ÿwìHˆŠ*àUñΙ͖•hÿjT0¿O èì…B“ä„Ëâmˆ˜9Ýó<+ßT¥ÒjmaÅÓÅdübG¹-oiÚÎ`„òŠŸ&ÏLHrß™]ù•OÌP`Uü¦Ûq$lЀ€ #a€+é„—_² ò¶$\“–ü¾¿…^¿Ÿ·¦Ž¿É_äù¤¡žó\@aFrHÁ=aGéG€Ë¥Á¶2®*ºU©'û­°ç ¦²²;5P‡RÏÉ wwÇÛªÑöé\>Û8œl~tòÒwacî…sJÚÊì, q×!¿‡áäN¦’íó55,rjÃ[¾zž¨æåúïÎÝTIþj#Ût  E?õsf¨Žë½—÷ Úª*½8#§•Õ,kaº'χ!a’ï ¾ö­¢ëÄËÉu<Ù+¥7?ë|Å­“úÑTu’QyVo~ï$iÄàP9rí;™€L÷8ë͸ŸDd0Mëû[(Aw$Nh#ÙÝêIzRøòÆ»€J+UËÉÜ æ½Ë;ÉÅI_RÄÆÙ®:1RÙ­ÿ.Óô'k‘Q#t½æÐÁ¢%‡zÙ©Ù6¥ÄsÎiMÑ9Û‚¶Í¸n¿…ãÈé%·ˆþÿ~„ì%€ŒÕé°©LÙuL0V¼®?4ø 3=š%²,ŠŠ±ÀÝÓ­ÈŽRz‹Â’³‘'mÑ®íu1þõÒæ.sƒI¾e¿‘V áD+­B(füsäû£kÖ”ª“¡,í¡s¦Õéx§¸Hâ;÷1ïïþ~oKЬ`µÎ=ˆ2Ãpq+®G¶@Ú¸~Òœý4®}DÐEö„ϬüeIQýýs2}pPâù—Ý]jI9ùù)[UîmÆQ7,g} ÏðO¨_zmøY5˜Tþ„„²¨)O3ŸˆDŒé“Ÿ—íY²¹ÅÚR¼àÇr1IÏÒ’¢_ŒÀ{ÒuvÓN”äÌ õÇh$&fû$|W±Mû¢e£j¯ëÁf©Ã/x1­D“(–’³ùÉQ%’*ÑmótA*fÚÕµª.Ib‡ ÇBËÉÄUnp[}3DíÈ™ºŽÁÊø<å‰|'˜0·ÂÆç~Ã9îi V7µìGÑ¢Üe³D³_.Ý;–‚åŽÑ÷p;#OëÖL†û§lÉŠÔ}tò—ßõ³Ôk†‰°uðµs ì”ÿI€¸{k¸ŒPüÛ÷’,n3M³(° ˪ŸÇÛ«‘öé$UœÈ7 C_ýǽhUÕ‡…,ªª•cÅ›=âáŽJ5¶Ù¶›în‰3/SMÔK”¥eLŒe»GÅÝç—ÿìèhMàj½œVJS½Þ)Q¸ÞGwÿº+MÈ-ÜÄí°…‡õñ£žÌÐd¢S;9‰2Cº»Â¦?‡$¥ðÒ{MuÐR¤U¸å*gÛ,òêÜ•]±°y¸ŒQpG…AÊœx´öUÅ’¥(Õém¶qÃŽWà $§éO=ÒtòŸŽêæÁª£a%ÍÙÚè2ÑÅÜ#PP†eJƒ ì.€ŠÅFˆmKù ¶ Bœso‡*wÈÜl¦µQaÑU«,ïЀ*ÑQævúaʋ۩x0%‚‡ž¹ò‘AO(ìó ­Ñ5x-ŽŽµ&Í}Þ‰¢tü}‡š“sJšòFÐP.nóT@W$ä}Í3/U[ŠÞavˆ®nŤ¢^ûûð&)RÔz]ªf&W穚8ëŽi 9­-e;šÈUèoØ}Ôé°Ú–óS*=<>/g1_ïò~1!¯£"í;é (Ÿ0âÈè@MýqÙ«¼ ülfe¬êýÛÞ‹„mø dKý 7¶v4PtÔV|w©!E‘QƒïºnjϤÓ#ù^êxyÙ(‹ïB†îE‹Î…7ÌM:ºÜbì†ö§Z^ÞíÂûç]%\#ÞØßLÖÜd®„Kþÿc~ö)u[䊨ßDåEÄvÐFÐ1Ž~”Æí}ûó’æÜ~>~‚=Ì*´×1dOžÎ$Ÿ‡dü2T_g}ôÝ)«ØÈëôŠ_øÎRÞˆ?[ÃÊ÷­ãê»E61¯kbfÀT|Ó'F6eи?–™ŸxP)ù#j‚ÿDwü=²cˆÕ€\ÓT2pän) 5ëIñH¢G?iñQßàlà€†‰:uµùš0'ò/±Pk¼Î.& Àºò²µ½8%E‰êâs¢[xô:~~¹Q×AuŠœöjÿhwlA(èa›àÝŒ¤Í°™fäd&¿Ì“¤*6(ðI\ů«EÕ Ž‘#ræ+I±>cï`A@l_Ò‡H¸5\ÛÑ.¦¢š,õ 2óÖsJìáŸÉö«½tš`#–úIÌ›AÆInÂ'Ë+œ5NmIm¼½Êäì`Oh¥W)òãc[ÍU™¡ï¤gâEˆ]†l2}•1Žg¼}ž4€y3GešÙ–Ð$Ux"×ÎoŸ;'Ôëß$[穜µÒMIR.¥o9×|1í¨'?˜L°Xxî—kùõATêd‡stà¹mN Ü|­Î¸Í ûw%]Ó”2³'ö¿ÏÁ¦>ÕÈ>¡ Š¢mãA¢¡5þ%G¤áåååðÑÈÙû ¤\&ºx¶^F´jÜ·´L˜æ”&¨ÕTÌ“¥èÃå/)yLH#UsÒÆÐe`Yäë^(º^Œ>Rò˜ƒÅÖtð3¸±óÙéh,¦7óv´‚íiR¿ŠfXéÓê$–€a ¨šÄ¾¶Ç w B G#"V*žû 'á Œ§FKñàˆ³=ù¯þ}»Ã%@¯Ls$8sn ö½óh"ÊHs~VU¤’I$³ŠƒZz–á…竤>I¼sMU"ê…<æÇÇÛÔ|}½CíÕ Õ>°,±Æ›t\眯´óMy_&&0¡_­ò3º­I)¹†–átŒÏ¦ú+gÍÓÚ.4Süóïø¿‡Fýz¡ÆM-Cû¾ªäB*tÜ¿ƒZ&"­¼5Mí|àY³NwKÁkÂSš×w²¢¿ ziœÃ=gêKý=m.*3Ýa~_gý¢ªú‰ùˆÿJE“ß8 2YLh˜É×A³#ÐfO=ˆöƒðføý|FU—JiÖÌ€¥#½ÇßÕ4DEŸ³Â)ZH»ºðg”úÖa/²‹¶Ú%Nõ±EO©|EríꤤXÀ¦ÓŠ¥mãfeÎÙð~OX·Qd÷ÄujÀŽž$z5P„U¿°¬é?!¾Çï̓k®ãDXXÔbª®JIDÍU–5ª]ÏL E*PwÎ5ø9 ­±¸>aØÞÏ-=döÛ!‘ۊĘa½fÞ{-b"º<ˆD*¦øP]i<>§™Û¿s'):f‘pD[õa2®ÛŠÖŒg¿=] ñEp ¿7âÃK.¥÷GSpMŒ7ZÛN5B‹,xÏàiB‘”ÚÊwŒ¦.©¶ò û ADõ M‡I;5ÏPœr©({ ûSb±z1û!usçT³&/ûn"wÃ_S¶"ƒ1+,Ø#j¾eƒ Ïi˜(åâ^¿û‚%~“¦,iÅ2^ÞI ½ópÔv䟡üF§4ÐVM¾ÛæjeÉ_óUãy81"€2.Qûæibß*3´§@3+˜UÆú¡©$9+D¨´ÔÃ_ÄEƒU›}ö×yÿE{eéÇ®Z•ผ˜–c¤EZ(ÒÇHEÄÄWjš<¸wRŸÏp•:(o½¹—Ìà±,`v 'Ô\ñ÷ñÕË‹Š ¥>BDÝ òYåwK?ÿ|ú£é¯~$üñ3 ­°$ N›S^á]ZÖCòAÍ3ÁÉÕzd¬Y‹‰‚ D¾#Dàÿy¹/øàZÉÙО ÕÍò7]xÎN %ød$öc˜múç}Žd>QÌ­†úÑY ¯cÒ¸v §Ù4Õ)_†èv¹j/—í©&šQ“¦×ýÈE˜U+ÊŒn­ž†S¸‚•„59-Rè•›Õöóö¢]Qáp/ñá"ÆÖ“ù:C ¬ IÚt÷÷KaËÆCón4—ýƒ"íÐOvSò¾Ã»ÅD8!‹ßÌ ÐkU»›êh÷Í@cÙÕfßD¾†(Qág»  ±é(‰˜Ž:<1^‚içOîöT™Rößëíú¦apŠqêç$ƒ •DuRÑP»b[ƒkÄÞªÐë&B,L ¬¡ô>ºêA<¿KAr5ÁØ¡DFrÁ©úê a¡`óQòN¦”#>ŸûžÐÿ4W„ o‹©&$œÖ-ÍÀW55=‰ô®Ÿ U¡ˆ>´°@vß9‘†J€^3t™éœ™‹Î‚pu28qîüÐ÷ Eºa¦Å ›o*!2ÇuéWÞF¦“RË|ÉÖR3ˆ=À¨"`S¿ñö苲k²¡Àžë4ÿi¢¹…RÙ¥~†ZœyÄFÎÎ3VîgÁŽl%¶Y#•Örh«šÃŽ' l$'FCMUáJWT¼òbÉ”ç'Y•§À º‘Ëç𵕪…Œ?ä€êÉœ3”þ Äéw²ªJ+é5T…ñ®mKåô 5t®eda¤y覅ˆø8s*sÈ;©îrZÙÞ HŠsëµø9 r;¸0˜þYgðè1e 4‹)âÝÇŸYëŒÓ#µ`¿…ôSZN™ÎÇ⺱3éjCï’jèƒAÐ îÿw·“—g:eÀ#ÊÞ {÷TöKôH³/ñUi•Š]‡cت¥†EâàÇï)†Ý: LÎgõâ+¡VHhê Xå’üsíkèçCg ¢kø'’0ÚRNÀâŠ9ñ· ÁvH^.Ûú²Û[ô•êÞÆ—¿Ñœª(bÔC²ÇÛÓ<>®!öêÐÕ>ŒÖý¨ˆW0ž4k@O@¥idÜ$rŨ<»qîqQºÍ˜P2¼ß#}_Axè"¥ÐòýìÂEK˜W#Ûñp¡RÁiJÐsñaÐã=5V°Þmÿ€+µÂ ¤ÅÕõXu$Í žæÍf³N\:#n±5'Ö!Ó$ðG0å‚•¥ûx`,Ý öµ8%<üuùÙS‘«wáÀ©W© ‹©¢%O"®;Vm¼5Bƒ',d(ƒÿN oJ)æØâ=¥.rB-ÒFÆy6p°¢C¼© å r23kÝÒ¨Ùÿ2 ú€ÆDÈÅ]ÒVÑß™.æ©íÏ š0#è÷Ïw®É‚~–C(Y=®é\–/ã} êªC)]ŽÍ0õÆÃ +¢çt‡Œ£­(káŠ0{û êêP°‹cd<˜Ú‹[+´ÁáÅk„'Lý+œYÚªÍ9p;6€„ŒÆÈL‰åÕ Å®„gVO*'(µš¦°•nɺgT¨P+mñ׎-ön=Ðp™Üß6´ô¡]ºÔJÁgÖDI†1¹* êLœ¢8˜^ü…=ôSLnkcZÜH•ñÒðZ.˜[Ç{ÈxޏÂ}ÃÆ–üò‚/h¿ †¡SÌO|*ÎmÀyXR†{‡#ODbL0„²©”Ö›½qÉ;ö ñ?!€z¬./F^ä¡  {nÁŒz Á% ]%«êG”g˜æLnÉ&à¸6± ÕŠY4EßZ´ðhmГ‚Âòç—]†ö jïú!  4ò&TY=À îfPÑ#ÁK`Ü„æâ䯄Ãv?)J«%{Kà X¶²q Ù„î2XÊîÌ[ê1©œN÷?<‡×é$ÇÏÉþEvÅa¨ èúÿ„§§NxCC“árPOC†ƒXÉéooJ*$´cU÷Â\•}€ëS)”}]ÌcåY§b „¦ÕÅé=­´³¶Êy’ÉÛ÷Å€MJÿÕÓ$Ú„þyÙ×l~ÐÀ¿¾$œî­SI59\GÕ ¹cœzûeô ºæåÉCu€ÂB=À EvÏñÎ ˜Ž "Æ™ƒïÎþÛ]y˜' r\fôa,ëÉei&,Piz~X9nZGà\þ·•!'×9Eè|Ý[ä&'ú“Ör/!­Ù‡Û¦`ê‹Çþ¼ÁmÕñêSöá-Z÷·£=~Åq ÖüJÖ嘉9ÚœZńף̘vM¤™Ëïõ¡Y°²LÏÑ?:Ù­¥F\}3Èê« ÷›É&§ J |¼ öIEí9µø 3TÝàè­Û&hÊá£àq&$u/uscŠ~óÝ M™Þ­<™ünÖ¶[1„.s…†}é–¤éÆ~ÓéŸ  íÙ_K¤øâü|3üpÆjâv4ºþ!µÏÐuc‡ÙÎ@Ãu:hÕöºq…k».¶6ãPXÕKnkò¨åOÿ¶êá3oÛ*<¥užЇÒ+UfwK6iÅâBf¦¹Õ ¿‚ú1ž„Ȥ¥?Ø{ˆT†`q:%A@²Aa€Ùª`^ €ÇÌV¢mÝsâjÙÊ¥B<+Þ4òÜd4cÉÓrŸ­Ä,Ú¢W ¸ ú©$ÈbÕçx@7wÊ0ã<ÐR?©]* g?<¥äzFÛ×äºì9¬Nƒb^ˆÉÒб¾ãs+“±XùUc“¡›Œ{>ŸH;*_P”|Æ  «ˆå~X¸b–„1ÌêiªSöH¤àð0,"m" é` C̓ç²`Ex9˜Wø·=› ŠòŒÂ \V,QãSwü¹ÖH±ì3ÜŒÏ/OjÄSa ´Æá ”"˃$ »he]Þ ÔÕö{À²ÛÄ›j"*áñt3é,"azOÜF¨o)Z¸øøùe¾6Wnª`ò‹ƒ’^7iN^b±Tâ)J«ÁõVa?ŠÕ›ÊñèÍT‹¨Ð0A‰pòðkî6Œû#ßv×÷¥¨ßƒ†“üñûeÍÖ ~VKõ6…Ž7'@¼\^ÓØÚ9ZÚCÕ=é Ýßp¥ŠÆ>ª•™¸kûYš: âóÉUkípÖ­¦q–¦[{u`ê»®aN&ÈÒåùè--ÔH"Ó¥^ÅÄa!a 64°/Éùäå,]Yuê„Xdh„æÁ‚*i‚Ñ+áïÎI$9Öè"å®ãËâKÉy$øÆ -:Ôóæ+é|o¡Ä@`ÙH¨Fö-Yüã5ÙŽŸœ{LXÀú¹èÝ] ªR`!£Sü€rç;á¸Iß-O)*LJMQuK†5·¼T^d‚/<Ð@ª*r ÷¹©÷°+ÓŠY%á,sùO”«ÖKt¬Þ\àÞJ+Õ-ÞmYè=-l¸w°¯æpµÖ À¡Æ_U™X×óð™+*Œug»(räf‘} î0¡û Ý(‹[§<>ÔŒÿ|åÄ=‘†J€²—š4ü³È=ä~½7S ˆÎ%b ‚ñØ#©W4d ]!T‰ÛìÎî߈K_·vä|ÚðM*Ä÷-4»•K Æ(ö`‡ßÛ“Ö-¸¤7ÁÌ‘¡Ù²{FDÉvmyãTBYÊ„½$±àMÃ,¼ÇLC¦Î=4}RåÒ¤`ÝT·²½WW¡äu]T*º°˜.Â5§è|Ö-õb"õÿC¶÷¹zuù]˜å½-«„&SÕáE>“IšTð8½)÷¾2ÂP!ÈÞ‚ï ª- ÖL‚*m LŸNþåV©f0{¼ÓS­Y ÈO^ Ã/nŒÙ^¨Â^0Ñèóg+_ðò¶ÙqÎlîŸgÿRŒÏ–Ÿƒä>ѱ²ùg€ÿw£ŠÔd¶8BuÄÕUÉ d%Ì×qZÉÐT™Ä%%ÒoM°mI 2<ÕYô@‡©lw›æù¾o›æù¾o›æù¾o›æù¾o›æNi){ºw/no›æù¾o›æù¾o›æù¾o›æù¾o›æù¾o›æù¾oãÇC®A‘h„mÉ©|¥å/)yKÊ^Rò—”¼¥å/))"N7!~jr %‹W ®Úý0¨ $ ªõF-hL2²Æ ²“:±1_––©6½êeÀÄP2§éÿyìpÞ# •ȇJNgBŸ¹|ãæK©àÄK$a’ $)¿›Òâ§’ X’éžÇ!QZów¡{ËŽ—ãöèõi'íÑkê°óø]êлí´gÕZâûhyõT_ÂŽŸShëݘÐ9ö»àåç…€ü+nºÙ[mïRôî^ˆ<;ž!•=!¿mk*Ñ÷ÀÚ×éÓÁÈ¥5®@¤ï¦`xBJ¹ÜFƒ…y£š`Œâ©c‹ÏMïj=E¨Îi_Ü` Ð=k•ÔI ̈¾‰¢y¶[{óµ|¼\R¶6G¡óæ–ØŠ9Õå`óõ@F*ç­nóȧHgÛÜǨáFXc;Þ·õsDÂòüT% ©P*”ût„4Ô¨pðKþì —›ÿ.8«VÝí·*…†OÁ¾ D±‹ñ±Âêôn/>C¼êe%Ôd<À (Š*ÖÑE]±?5¾¾ÃºR˜› ãÖ7ÍÌ’5&4®×ÜâWblT>¯Êáâ›Þ/ÅI| õñò×Yf'x ¯)A¦Pa¼9šL–æÅ—Ö8¦âžI•®ÃW(¢ŠI:‹Ù€ ®¦ x%å)OVÍl•Í4¶Kï$¡ÁrHzŸ€šɹ-‘1Á€Œt`£&âºo)ºutôö¢e¡ä&tÑB1?0)"Ú#Óë _Þêî䢴k­9„¥š·&™Æ¥nV߈¨“瀅«â2@ƒ“é*Â’(O<,>ÅN¶âk/ä )+*œœœéd{ªZ»É˜€­c*Ó˜ã.4ÊŸO¬ñ2"ûƒ·•¿›(\Õ¶`uP^Сê©`ú}Ï µj$H —¯A˜×%'Jø×±K ’šeoCºŽ¿L"+6Ë”Ê<â‚æQƒ®¹F¢@ç°l6áôC'NùÁûù)ÂEè¡B„©†„?…Y{œžÞ =ÖÒoÙð0I+?Û÷ÿ*[–Vøi %h9J)k3_ãPU„U\†ØçHÅ»£®Rò—“Ó9AK˜ Ï0‹ÁÄìq±ºAIµÞM}§gðºÅÀ.OÁU2X/QmeéšãÄÑÉá³7—£ä|L¯ÝNeæC†7‚ ަïCRCOövÑ·Wé7,ÿvŸz‚HמåÐÿNƒÿ‰[ /≌Ìx1†nÖ,E¢0h×W™~“ó†R;šÆHØm0µH¹êÖ¦Ìd7ì±åk³þz®’ô—‰ ¯¸÷ÇL9ttíÀÜ”â:5ÿ#½³C€\„Óó~¾Ò#ÿ+V Þ«Ò$´ NZ…{hî äù¨AÕ3’®·sÃo+ ~çê1ë"↚Ãò¼ŸàÙƒÔMÑW]ô‘lh&¹§kÅŸØ;ñ¤a§ªUA*iø÷èîŒJ s™¶4îm©ÚàÌh'J¶¼?Wò2eq´h|Úâ;ĩҗºör+ì<>Y-Þå+·ËÙa±=g sg>]úbFÙP4æÒĽ՞ÊJœvĉe«¨w*ª21ø«=1Õ„6±ÝÕÑ{À%ÊÌZ´œ^,X_…æ{§D ¥Û©!–n ¥¥Çïa|‹…¶ºó¤»’TÅÖÒP5Œ» `ã3~ߢ@[wFm­jwaŽf’C°%@D˜bÖîÞÎÊ¿ÝÊ C¦€ßJ_¤~îÃÆ»t†)œD`Dý5fwøÕk‰„áD³Xþtab5’”žî?ú½ä>ô¬Þp•HE6sÁÆ™Üð~.;“*[’ÕÉE2Ø1ä‰>¦J†ÛuÐk-Ì)Ðÿw÷ƒ– ½1LÏÅgz1¨¨ Í“I#QîëÎŽ¤kf,®#Ú§âè„nU}ëR]¿¦«±¸ÙÚ3L§à¼Gw‚é·7>k¯Ü¨ÐÈ€l°:þ¹ ­$Ð¥蛘ӽbhX°bf˜ù•kô9zôi®àù‰@Ê.%ó€0x£,gÞ~Ü=8¿há—ƒÉ,Vƒ¸‹¢zâëhC'Z‰Ö«†ÇÛª­ãF~ËÙÁ«]þlÙ" +LI ãöèõi·í»?mñÛi_VßUo}V¦Õ@~Ú¯ö¸_SˆëÝ™ ²â¨`&ŽÒë0q ã:R³ðµ¤ªG‡VJT éÜx­i9Q“H«xðq–Dïò£çÿÿÈ0Ý¥ùfï›ì€£Óa°«å¦¼l·Úx¤NìCmÚÇJV<_?â¥/'•R˜ð8õ«ƒõ`åýïí>OùA=–§Á*æ‹´òbÇ9¥‘Ò§³Çij7 ÉU¼/x«zº¾2ñyw—v5{N"Âi{r ‚f¤§ã×7„K…Uò’N6 O-Ç3Û½ÿgõ¼·&,OãOMÁU’<`ÇáÞ‰ öŽ)Ù¿%·~±ü)'—e_°²° Ÿðsà6Xiuy:`?ê¡·ÂÁKó5Ëa8¤Lzˆñ¸ý€ÁؽQRmãr9‰B@âð•@¸ºŒþÀCY¿ÒË„ÒxÏ„VŸ“t×`ó ¡WzàõŠIx¿‘]®=›}m.­¥Õ´ÅZ÷«ˆ°p›@FÝLNǺû­gI£8øƒ¥G}á(Q¹e“;ÍÌ?RL2Ï¢wV>‰ÝŽqŠÊp£æ»Cþñš¢º§¨œ+!R’4Ðøˆ¿ÀÖ'hÂó6pV»BF;™i$î$!Ï–üV¥p©(u0Õwîݶ°]Ùä3åÒì,‡K±t4:NKÇÉ:æLŸ/ú ì  Ùò¥Üâo×¾¶­bVÔ«Q¥›'HìXý\s™•ñ—Ô]ìÜÍÊJAµ;‰=BÁ8°¦÷:` ›¦mß­1jÉ(è"ë«v‚ƒÒÕ çøVâïÖr ­© ²ôædLt·-”å‚¿L…†’3ú ¯÷*ÃÛýüÓJÑôÓIZË^?_[íYPSõh&Ö)‡÷'f2Ê —"’<¼´ÞP „æÖ„L¯¦µ`ü„®WýºÚq[3Õ>#<£#i¢4trÈkwâðÍø^­-ŽòûP­”¹Rò¤:bÀí¶t°v]€yÌ”µ6²ô!ÎK—-“ãgmÏçÂpT‚¦Ÿ" z/¸zË¡º}ëo$÷7R\è)^KD9àY ×Úœðn<üògàGë᜖ô™×% yQIB=I1{㟎ä¿ê"éþNà ƒJ:¾¤ä:ÜõoêÏkDÍ@q®è c/u,ójÈYˆ‰ÁÔ‘h"úYöÔ• äíã=Kÿ|šS¶&IÔ¸D2]¾”]<¯¨~Âm´ÚvuâFP‰ËSáÍ͆f…™§²àS'ÿvḂ\Žh v=¿_¹yƒüîùìÌ™Ž1` 0€ïÍØlŒ;úáŽó7ŒáÒ†/F³ýˆ–Z›¸U~O\*w 냮IqÊâÅõCݘkk ²” ö­!Lb,$%gid:¹¶íãÀ¹´,Òr®…¿ó¤3ç×µÙd¨–H®xY:$”ÀX®®ÄýmL.+Êìoz©.™‰0@ñ7ñm'Ú ÿwÊÊ¥ÿ*eƶ˽Ê!ˆƒšƒßÑÉJ_š”¢}°n¸5ÂB‚µÝ)žË¶y±¨¼ùºTŽš‚bb~ $#œ0‘±1¬œVµ .©Y$GÅ¡µ6šÛRj|00O9* ¥bEBˆˆˆ€ÍJŵp6Z@¼ÇßÐ*…l8ã¨É µgB“ ¤ˆåm‹” ÏŸî±‹8Mc°‡mÇT–Ê <àEŠ[¸HF B­tDÊD kÅ_8$BP ö¸3 ‰C‰Ÿù.UpÕ&¯rêô ú¸è|Ú$úrH›sZ‰ÕmµÝÞ2i#ôú¿¨kÀƒèì¤ k¥³jï"è£çìÝý¼ q@ºñ™ÈNî]L(£‰QÄÑ û|¶JPÿÕèä·ÔV½œ”äV˜0–n)ųÔDJ¤lë:γ¬çN’2ýùZ)¶ÿ2Ïÿk Ž0jo¿¹&ªª®¾%xXHJH¶ùÀá|àq„ƒ“ßVt–‰Wy,&šý d9ÿ~wA A¿½öãݺw&hÇc³Øüb›õîW›«G¢ÈéK4¦Pã¥ÖW}JÁ 9âÅè)Eô#*jˆ•`§ôOú2 BޱZ`ãñÎg˜y…óõ¤/ll÷×Mú_wÉ@ÿbÒ@˜6µäa’ áA+ŽàN‰ l/‚³ø‘“¸>‚ _,¡¡­U²"HN9 ÔͲ‚[—F! %³Q¤^Ÿ•Î\ rÏðÒ@ÕþFèHˆÒ§ú.î ½%×¼ÒzmHà†erƒ½àN€Áæ¹%ðç#"ã8­+ª³ ö&N.; 8Œ»ÿäÝ[0ô”Ðxè.ùµÃ Høš [¥¤›2!¤ ûcÍÿsíÖ40ñ Ð —ÂJ·¦ñçç<¿Vdp&ƒ6ÔÍ.;¿UsŠÊ³b¼ÒÆâ?é€m¹Xyœ¿!Äå€!F®Â>áÖ#©O±›áâO‹¾”C qoÐÓ ‹lËôé/ÅØ§«QþØãŠÃÿg^ñöÅò$=^[ -É%wŸÂÆÿ"Ò^™¼j5(Íp—>ìòV‹‹aœRÙ´wƒþ=kÊÞúLBZh55¾£cHºf8 `õ½st]UvÙ—f̛ጕà'² ²:jo„'vüÇ¢ŽÓs †ÀÀÏ4ËÃÐlg«]*Rrkª•é-HhÓ.«ÜLªÑ([äÚÒIGzKXªÕœ¿zÎÕVaku_MÅÝ8çÙ˜§/*‹ó¡³'zïqvüI¨LÞ5‘ª§Æ0 `Í!‚úìÊ^ Õ£fx§Vm•2*.ÂTàâBêCCœ{4Aâ6Peâº9#ã¢}ùe·OØ%P¥蛘¦ä´Ý„R;ÉÆvöÙ0‹áq¢O›ÅA6…ö¿ó:Vö,ÊV ŽËR ä(pDûþs大@ÓCÌA>G@1- Õ²Êt>oÌz×9ú§bóxm/¢¢¹‚ƒÑ €‰™ ©âú­oÛ¦×Õ`_U݇ê§V~ªŽùõÆ ç¯þª›õ6þ¦`µ~¹òIa=8û±†d<ÏáÆ1ò?O#^wƒîŽg¶bŠ’¡´|•VT Hrû´ð•2Rðo­¥Õ´ºµ¦ûIù\F­_{ì6=1+ѹÆÀ—ÖÒêÚ][K«ep«IJ¼+ Šž£Ê€ƒ«:³«<Œƒ„XºÔôjz5=žþ~]\'[ëium.­¨Çãóg’uOoÒí¢õÖÍ/ü@qÃÑ¿>Øÿ\•A£—¿ÎÒd ‹5N›džeœýÛˆÑÓ'*ƒC“ä…ÈíóàÝÒŒc=Ì—‰*Ÿ)q?ü˜PJéVße çþá¦÷Ÿ¼¶VLWÖóB¶ëÎ!ðWcУ€Í8õuAP¥SÏZ¥¶`')×lQà€¯ãñø«¡¤Xò到Gƒ\DFJüíi8LYÖAJn!®lÇTù#ÚK80ñÆ›0°üÓŽ@­ð‹ád@‰£„@‰£„@ˆÍRÙ@|ÈžÃ?é «ªBç¹§ ¯t€ ù¼ÔG­ ¨ÿVV)|©0¿ÿ=¡ùý3ŒŒþÒ¢Ê_)ÆÅ‘&LõNMGš#Ô¸S'hâ$_Ú“Qæˆ÷ó‚¡š‚ƒ†ÂŒT­KÕñ:@tÍÛå&®‡W~€Dt!wžFµÈÃ›Š™ÎÓˆi>NµA •j¤ ,eâÒp¹žYj¿õ¾!w–o÷E‚ͨ ÿ7¢¼×Ì –IOíhC# dÔâqE[ç”-ôk%¿/Úc~¬ ÒI–Þ„`r6*ú;Ú>†Ùìš^îŸÈž“G©0®–÷úäK Òæ¦Âß@a_xm ›4é:ß[K–´¯NW®/@JH­Ç"sÖùŠ—i5ÝfâÈÅ-^õ>”p`8ú36ä0¥ð\‡/á@ú+xUkƒUkˆ¿f´OÉ©ñ_yj»^ ›¾O̱˶fZ/OÓâÐx‹±üm¥è$(ÄkvÓ‰ÇOÑÿ$¢ê/a¼öœ ¨»tP²è¼³ñE.RýŒ[8¦QtÚÝY‘ ,K»pˆ|8ó ªFœU6ƒx¬àƒ«dÙƒ&+âÇÀ<é £™ç¿…&B_áÊ_ð÷Ö™­%Ô%‹Ç¿‡0G£êiõj×eº„‰íÛîׂ&p¾]Ü,=+Œ½‘Í«ÿ‚ˆkl©²«ó¦Ê¯Î˜£I5¤‘¨žëöAl´óS_aØ;¯ygIè<8Øôh d1î„Ù% °šÂ†iÀ†PôF/¶W5Y/ßíÞ§€¶C­Š™ø÷øÀÁ_›=¶"ùJFM ý˜éS¢@#°0;±a~)åhj¾Àµ~*:f2H¯ëާ«­´>PÇÕO=|á! À ]¥ãËŠ‰ú|ɬQò0‡IÞXÜèk¡f"4 ι®/^ Ë,“™Qô"Áâ¤ä!„„«"Ÿy0ói¼¿Êìo~ý<ÛÉ€Á0¤êÿèJÅŠñêiµc¼‰Ã‚è"µè§HÞ“^ÖHB2¢Qï\B…CT2v¹€Õ‡ë|¹¨—lò3ƒcà* žÖ#§Þp܃üÆÔÕœ˜+'L›OÉo¼ü¾hn@%Éó²•1®ˆ„õŸdªÄ¤ÝÊQÓå‘åÖnO)Lj*œ²1ù=ü>¶ò„cn¼Â%žAÔãE{â.; a5‘‚à¸. ‚ੇuMЦaEÿ3À ÂߣÈÎ$<é¥C$Ä2nyzºd5òlÙ‰ö$Nÿ “º¼´•=ZÎø{á­hš-&ŽK 0§¥oÊ’ºD`côùø`n˜¥l.Uë8‘|‡"«œØ êaƒï ZMÙ-hÖX}BSaàñË[$ÿÿkŽzý@…»_Yz­¦¦#Qs6^‰=(5#ði€4ü  #×PèH?•çß„È b'3 ­lã‡Ýb ·7×ôM{=øÒœ£µúJâhý¹o< ‡ô´¡§Ô„µ¯|÷æ¶QHKÿø¾„ïƃsÖ&ûXyÈ‚(C2!,PRŠ1Þ=– ¡èFѲž#­Aƒ2ü½¿õh(îb+L‚|d–‚ÝëºTG"|§ÿ}MXÂ=¶(¨Kw  „éÆi.:ˆIç +ÿS@:Eb¯tgɫ༧jr€Áý)Œ.cUº# ¾!»dÿ¯ùñUìd/ËRKÝVÊ­V´£¤œAµ‰½ýN ôÎ(Ôßëä;èµF‹e=ÍÔ(QŒPÈ;}+–k<€ÊØUmšØ%P¥蛘ӽbcŠ—Ðl›º¥„/Ï>ýó¬'Þa™p1(`ìzPò_n“¡×@ªWû÷(ÿGð˜Ê^Fi\£1¼ì¢ÿPS[ ž2 ¨ÑÁç4Íë$b{Žu·ËÝÜ´­?çð/ð&6àK:HùÓàý@óä>@ðJµ‰šÆ¤¬º›™ÌÅ(¦Ö°öÂBPk ãKÊÜ‚—þ%ŸOy GÁOÒ[(@Àl¼è¸¾ûp€ùø ²í]oóOçÃ$ò$ o³ƒÜ­¥±€ÛWÀ„„ƒ-†9½#l·¦ã1Oùé=oæiÊà;°¼ÂçJCO_q8  ÞŠÃ |¯¶WfW¯ÿFÚ%_ä€~@’^OȰÂBFÜGÔS7Êìsmõ¯U¿ÿhïâzã–öØ ÀæS™HBÿ¹ê)›eø «„o0Éød1¬4阎$ÁÙÖÆ†HDa!/ø“„o0ýð\½C€H„&öOuËŸªu3`ÂB_-µFåq¬¿ÊèXyñùø ‡ÿEøFÄ­ñ¾§?Ú-£á/õ)ßQíÐ çØß©«¾¡ÏÛwkç½~¦ÛêYý¢Ñð©ú”øþÚö ïÔCú’að‰}T'ê²/ž½§ÈõQZùë7ÏNýL?¨›õþ¤>êH¾ |á¯dùÂ~Ú'õRŸ¨ß~ _ÕGgç¦~vߨêùÂO„ÎÄà8h ƒd"<¼&önÅvö@l±²1»®@19¸õ!Y0éËü~bb9­~…¶ÀÆWæ¦Ú`-3SÙu¡ÅbV-¶¶%ƒW°øJ˜Þ3sŸ’jºÐïC™™‡ É·†®§Øk%†La=ów««–(2õ[™„0 2÷¡ÛEòW¶Gá¤-åÑâ¾ù/+&# °I¯í Kxˆò6ÑLJ¹ç‰a‰ éßjù†h«H¸ü `ôÔëm7e~êƒOª|)“cTôd) FB¬ü¿PC‘-ÁÿuÆüuj"g¸`HIºƒa!+m"°b!/­rgÓÎ’cŠ' á¤×Š7n±;¡¸NICeO¾:ãÑÎ#ã¡jƒøÇ¶ ®°E­×Íó|ß7Íó{µòÀí9­˜¢Hj\Lá$´+X˜š¤<ãó‘JVÕÀ‹Ÿ†có6Œ®Ë0k°¡ Œw-ý —©Klògý)ö“UÆ]é0%`/)ym€ xýx…P׿®ïrÀÈ 4öħ9ˆû™WQ8º–“šmõÏ®õ¿;Ö@kÃÞ ¯®3õõú×86³›D¹“rˆ0ĤÕ\1„Nˆ)ëºiÂIôBôBóª>®ù*š¾q Á­*D$¦R“7Ž6ƒ@HK»ÝÆ:‹òF*ynÖÒ„„³7Fé< ¢Œ$$/ÝÆ:‚Ï: Gn4;a  ¹Šædý¥bÉ»qžÏv ÕÇéñFRŸ ’ ƒ‹á ÷ÎU¿†îÕ²ý¨þèH>ê"èÁ7I­‡k•ïÌP¹ÙÒ_{øUƒiå:“&“*K±ÓÓëŸû£â‰aú?ÆÞ·‚AU9žÚ˜ úR5Ü„“þ_D"„B!„J˜Cn÷ø=£€û»J6›Ñ›Â–[#ä•0à4ï?ìÿD„ùkP@ŸY€¿Îé%õâL&îC|‚æÓUj QÁÿøP*ªo)âBXÌÑÿE/Þ>KzñÏîëæ˜Fýq^cla!/à v/Ê0—Éc%ÀÂBJîÕhMíüÖÕ#tBjÀ jƒ¯€ÂBZ,N©ëéHMo¾ÓØ»‹~Pxl%ÈÂBZ#‹½ÂBQ¶eöœÝWAX*Mº­Ã0QÞ^o˜º.° ê—¾ˆwžÌ£%Ê’ÿó¥ kß^Áøàù³>4 QB!²»7KåôÍjÊ'Ð?#âIz’S™ìcs޾!Ã%À—”`é¶ðˆPm™MR.÷6@ÐôÚóxUm;ëYø™&ô`âĹH†ÌŸqÏàoªrÀî ¦“utshSÿ~X~¥ñÃ#Y Ϋ”87­‡y+äÎcqF€¼à/x À^ð€Ð¸ÏøŸ‡nýÁ<¢ù­‹¦Ÿ&ÿu¥'ÄÕ,W#ÿÝsPöc8ÑWíìÂB$"@¡ñf€•p@rI;ÈŒ‘T·î8(›Ê60A±‡àã º“7y¥/Fr¶.Њ#P½ ÊÈSŸ?Ø›2¯ÝòˆŠ¾eaõ±¡/b\/Ä/h¸žßÖÛê’ï¸olÓ^×c»AÆ]#)ƒbè&wŸ[yÓuÁ\ì:W¾xyõ@ÒÒ™ÆßLÛ€hý„çj æÞ§ÿB¶­š@ ‚—ãòW€™.'èöQ…ÅŸ"ñÙ_J »PëÙÈ”§·vñ¿0óŽ-zT!‚ü  P=D;R?­ƒ;ÞR?å/'D ¥Û©!–n ¥¥Î'ÿýÔË(Âa³½\‹3{x+ÿST”™W Žµâ»“ KLûñ¦?ø™Oß©lMqÊ88¤³F­n]’*)D¬i5¨é!ªE:äéÿIÐׇÑ Dg1X©æzXÆ5J:ÿ—q=&4ÕÕ-!úÁµ €À`0 á²§|˜Ÿ¼ŸîЉD¤B¬ÂA¥Œøâªªªª¹†ÈseVc:]ƒZáàa¸·ÆœS{šS¥P¥è›/ƒ¾¹ÉG ǘººÅ̺¹8óÂ/H³Á¬U¨›’Àd& ©Ó]­g›»Ñ°/¥2AíÜKHè A'vB¹¶L]ùG㡚+E£¿HôIΔNfŽ€¡Î‚ë{ÅÎäâ ³†Ä‰Dßoêk´2oÚôJHÐmÉ(@©UuIø8¤³F­n]’*)T4gÿ}ärÓ$î^Ú™ƒ÷à„ƒSn–c7´»N{…R»ïþïû­‡|‹‰q'Ò…TqÍ}ùâ:©"Z”Z4KxQmLþµ£±Oj¥\r¼ø)¹·:L0yæpñ¾¦Ú)“á+óÕ§Îgöè?çÖŸž¹¯œê©4ù+ÿT«|ô¿Ô'>B©“íqý§ºùËß=—ÕPþªºùéÙ>/’½¯žÁ|ô¯ÏMüæQ_êmàþ£‹ç¿8oÎÎùÂ~ªóéÛäa¿8OÏsßž“ùÛ~v7È:?çtà9«Gõࢸ*"ÖDÜ–Ý$€úMš¨j¡ïÚX»KH0v ÿ|,¯ ˜àÚzäPkP¸Ø¦„z-¶¶%šq$´mFËÈgûˆ:J/59{õÖèDï„ÝF xÀÂýu¥¢ldÚLƒówœPcµ˜y¶÷á›mç0€aø™v3Â_?â¾ÿ;b¦HŠëZÝ|ßôÖb\$÷_7×®¼º0$Êä¨ÄÅÓ 1VdGžÓ6E5ÆF?ºþ²oÿKlÒâ]ò§ â«Óž9KÊ^Rò•SPC‘-Áÿu'NmÀhÁ¿ú‡g×ø™„îÉ#±Þo2ão"ëCí7عò ߆ À®ÙŽŠŸ²硸BÝIþÑ Û¢Ó KCðtå(üYN¦úç«n¾zer´ªJ¯|Sc—qû&üÍÎÁ]QÞuÿ{—žkNõ’™ÃG›)VC縿€Àz›óî;Š÷ywªâ:¶g|*"Ÿ'ùûé•ËÀwk¾-G›-‰k,Mqœz%€€´k§šSù0¹ÅAøâëÔò€Ê£ØÊ7”Bµƒû¹4¿WI÷l ð´(‹ã4vGdvGdvGdv>à‚¶«žƒ:˜ hîVÀÂ|Dà27l ÿ â¬[Í“­úŸˆ>—ÞÃꙸï¢þŠÇ”^˜çý€ÖrPàç{‡·5þ:껣5£Ÿ3¹§hýÀŠÓ‰U.¾ÎÕ([\ŒE<.þxéGhþ5Hë¶Xú»õrÆkÕ/§§âohÍü¥t97Ÿ-:“˜‘xßç}ìÇTѶàD¿ÿp þ ¹cöLÇœ*ÞÚqu˜ú˜ÀWͪRwŒ#q˜K¼‘sH¼ÏŸ#þŽàsY~A\ÄR„Òøy ËüÍ›û5s“%5Ç›Eç ÌÌKVÙÇ´›޹¹ D_ Gª±ù2ùÌnÿsÃV@Â=Îc‰ö#Úr·;tWÔO«J¾¤ÚeÖµ»!Ðô9TPCµ·ÿ/oM„„{«Cû­¿ùË“0A¿¾Ñ1­W‡9s̈;&ÏÍ„Bؤž‹‡· Úý!â#s2ЫQæÍÏA‘ j뼿'£›Õ“ã–¡ä](‚XÝPî%+ æ\¿ÃØÓÅ}Á¦W]mGµÐ4㜿„©Á¬Š¿d££eA‰2Ê 1áž^Uå^[3Ö(b.fEês&Î;y ä7ƒ×9c„ãè‡‰ãÆ†™Læ†*Æ’½µ¯åâk¢'c0†šÔ¡ÓXë¤ÂgH£ qb Ö|P¼=ÇÄ~Zò£jšß:ì]FBaÀUÕÕ P' êdÕGsŽáõ×Þ½”Ô–°øÙ½˜A¹;ª] SõFÄnª`P $³™Ë³R¼<áç:ë å{CÜ®k6)ù•Î ÍÚ‚Å\b1õrùÖP2yn X–%‰bŽŽa¿ìQAOrd¥{ì®GPCµ·û@H¸ÇTödš‹úCBO»çtìlðINóÛJ]4•£@Ë›ŒŒ À%%у{Rœíº¤“#D¾v³µ¬†¬Ÿ­r°[Mµp„]Ë3 µ­\kÔ~h­;“¯¬ùØ.ó#„Ó1N«{¢þ~øD›#ì«x—'Z|Iû¸ÔBä›õ#µ0O Ex/½+ßÿHDÌ\Y˜†û½÷ÔÂÍëÆdá¶¼ 0?äÝ*<‘äŸ)¼×W˜Dî®§¥E­ÛƒÞp{Í«îÿó ®ÄÓ0OÖñ)$ÝK4ç:Á¾ºÚ27#%ó»¥îxF&I"xCÞ×h<Š©Á=vl·»XѬÐ-a»ÝìÖ-„ä˃®Ä"©:DÿJ˜ÈhÂAå>p"ÙÙÈÚ"kë…¢Ïi¥TEù*û­þ—uæ½´¹àŸóxWS/ÿÿk‡¼ÖRþ“6½‰¢ $#¬¶’½¯µðù_9ÛžÈÃ%@¿ÝÆ:‹ÿm½öpÏ´€HG ÀóÝÆ:ƒy…p²Û9°Â'™ySF9ëöÐV-7dõÇ/g)VÔleü©ÀŠ© „ƒ¢z $%Ê­´Öb&hÂÌB•«`XAèjï­‡p?äÃB¾ÞE( ¨«-¾Çc±ÔîÅaù„K¼?¼w„Z¿Ç%³ÕèU¶-6­ô`Šƒn§ÿ&IH œá3†Ô*#Ò@t¯–[Ò!Ó$§˜0ˆÐÀ #Ú—P›j¢ úLœX]‹“õÙ Ҍ²”þT< õzϹL¤3hW~ºâGÑR„‚¢²¢µ-æ‚*ýLìóKøP@*|l}ùâSŒþއ8ed\¬0ÛùÃ1lÀnž0’0›aA²÷0±›Å`5͹Ÿìì“…>Ÿ&Ñ$„⊾ßìXئ£Óº~8˾&€@:lˆ(d¼cQˆCJe¾>3Ò¾”‡ Ô!™ŠZ*{õ 81f[$ǪeAuÙ×1îÇO±¾{:3jv—edËlûu¼&À "ò™1ÄÔC¼VP̘[.7=¦z–ø§înøF¦w<ê}6¬Y`ÛrQ÷i½u;Õ~$€llñ*T*NCÂ%à‘÷{[ÉÇa¯>öÐ;¦Ýý ½‹¤p-e¿#fîüÉT>Ô°¡‹å0H ¥Û©!–n ¥¥ÎÇC€gÆ‘a=‚Ø-SâwÖÊ+Zȴ‘¸^H òø™WªÕœ¿zÎÕVaŽìǯN"ƒ¼ bFG•I¶ ¶á™½*L¶É7RR‚ܵ&<8ø[l^# &Žâgéò%MÍ;Iâªïr¿ÿ@3Vî´Ã£&ÒVƒQ(”JL}1%ºYNÔÚoa¦Ñ¨<#ÆÄæ\š(¤Ð¥è›/ƒ¾¹ÉG!Çú—åå)Væ~ËÁÔÕ3ïqðÝi¹õhYÀÔZŸÜ8QAUŽ’რ(€ÚÝóUúˆ:âdCã B'E£¿HôIcg˜_ÅIÁcë­ Þ{bÀ…v0`„Š“ 茑܅~ìàOcôÖR?Oã©UuIø8¤³F­n]’*)T4gÿ}ärÓÑGà¦XË•×s©{²k¥ª®ïþð­‡ÚvcÓ"}TqÍ}ùâ:óNgT‚%P ŠmJ'”Oä/f¸\€Jh¶AMæ$4[9uΓ€B÷P6pgoðþ¥‹ç)§ÂWç«_9{çÔÉ«?=Ÿ~r?ŸZoÏaüö¯ÎÿyÉß!ÏláýL—η~rßž‡>JŸçÖÿO^ÑÑ/’Á¿=—óÔÿ—ùÏ~s?žÇÁ~wȾp÷ÎÎù~z¯ê§QÖ¾@Ÿž½¿=Oóºüí/,øE¾G`à9«Gö¹Ý”• ùÆÀ.î©G•œ±©*v$ñÁ®»•³Øô磗ˆÐ „¯"6ÿYZkÀEdŒ d;PZcžM.3RŒ·¾Î!”O†üþ† ?ówUª–pbêEâýÿI ŒŸø™tÑï%„¿â¾ÿ;b¦HŠëZÝ|ßôÖb\$÷_7×®¼º0$Êä¨ÄÅÓ 1VdGžÓ6E5ÆF?ºþ²oÿKlÒâ]ò§ â«Óž9KÊ^Rò•SPCµ·ÿ,pŒ8QÀÉç0“Ko£­Fÿsž‚˜w-‹{ ZÝ|ß7Íó|ß7ÍòÊ:%/ÀY¨D ؃Âóç7èYsIOÓ(;ËÍQÇ«±ÃbºÁ·_7Íó|ß7Íÿ/5¹°9w¤€®¥8_û„çñT`L–ªÊ\º°û†i,ȬÚÀÑžÅìªÀáfð5í45÷Ìñk•E5jÌ*¯»ú¤+S±õ®Ë¼˜àö,Íïÿæ{ʤ”±ÆÉµ3º‡\“ãQüqr<9ÂÀS7ÿ9®õdˆS…4B½×,²¾½y<<:M’¹gža­’QWÂ8 % ËîtE¿½:ù¶›0gCZÕº JíªåJÌ|D6¦{GYmÏŽ.¥&lNL0…Ÿu¤…kuó|ß7—õ¢a`/ÿ{™SÛÝü7 $T¼rÁÙÂ;Ýg<Ë’2Æç¦N·¤íuöA¤„Òøy‘ôRFåLm‡Eåí ÃÇ-{Z™çjs £; Œ«Ãa)b- ÿ~#-ûEã”Z€£án1‘¤»TatØdm ~/€Q„ƒQ·bÜid&³Õ ~¸½dF€™Å6?PCµ·ÿ/oM„„{«‹ïi芅€ߣ”KÌe°l6 †Ãa°Ø#¼öÓ}F›êP2¹¡uêÌ”‚‚‡Ã(ò3µ÷±®ÞéT¸²ßÝ«cvŸ”)ûy7ì|ÈÆÿ}Ž‹½Ì-Ñwi—åORŽ[Y‡¡ÀpEá4ÃìÞ,¬‡A”Kh•ƒAÿwD,‰M ˆ/$jdÆz¤Îÿ;„¬i̬i̬i̬i̬i̬i̬iì„ÿ ¨Œ,Â÷BE%Ï'™D‡HXåî˜À9ÔC÷.»í€×fr`èŸ#âRC޶ƽ{½„ç i•(^ÞNѤÃåY~}ðÞߣŒ²Gs‘pœ°Øæl†Ão9Ðzü$hbƒ6ç0è§Á €1OèF³MíÕf'¬k—šÌ'€»Þ¥ ªŠ§­G0Z÷ÀaÕC;Â,¡ço­\oËxãÕõQô4$/„Òøyº>Z‹ïdË€ÿàOïq³[>.ùwþ[U)%MWKt.¡/ôfy é ‡÷šý^ Ôh$±×ùÌÆ€¯ÈÃ%@…* K,¶™"¡±r¿éVas‰dbÖ¤Ð6>E4)ËÿSÐ,.`¯Ý¿rŸÝÆ:‹-,'*Ñ…íºa!½Oô'׃uMÐTý?ÿ+ÝÆ:‹ÿ{Šn§ÁøþÈ"@ $$•÷oÝÆ:ƒy…p²Û9°Â'™ySF9ëöÐV-7dõÇ/g)VÔleü©ÀŠ© „ƒ¢z $%Ê­´Öb&hÂÌB•«`XAèjï­\oEïÌP¹ÙÒ_{øUƒi‡GÙõbVþül€LÀøoìj€PéØô))b©î[/ú¢{·ç÷*¬drŽ]ÀÍcRªúS¤çA®‹ÿ2ç÷øP*ª>”š Ånˆâ,ÕÑFÎ ûDW«% Çd – òº.t&-ÖøñB¤mÂ>…0H,§ä³ÀÁÒ—"†‹Æ0™Š6]d6™2ð91=ÛW_†ÏßänSÍëì sùUì]æW‡ÔE+2æÜf0(ˆFENÓ ±ž‡ZLQ`N‡ð€lú‰uxm ÁãjƶGÿ0·ŽÎ&µ[Í–Œí¦³^å0¤F$‰¹©iý -¡ìÉAUvÉ«”°Vv×]v²7‚¹áÆUh¶®ÑÅþ;è'ƒ·§gmjx‹/õ§Ã:3 È»tìïãàI)—­lmmùòø4äù *®Êø™%ª·.ŒSÍŒ™Å-êÅÇqŸã‡n #éÇà‹ãCXþÉî£Ï¼ ÁR«pð3MÕµJ‹c=óË]?b¼´ ‚¼ßXï^]4Öÿý¿!þ–c¥à×àû Êwõp³£UÓ<”£“cñ`‹å†/'¿¬Š¾êXýw'µÖãIÒ(È£ÿaÒ’©ÛˆÎqZƒÒüÎ˹þz|y˜ z•†,PHÉPìÑ[—§¢Q|Ÿj)”Ò'µ7z iôžÓ¢Éµjy5¤0µSK² ¥›Òc,wp[oØA¢¾ªÑEFÛJ€HFvg>ÛÊ®}a½wÙd¨ë<%1/Ý`çgû5gGT¦x #oîq¨N¦o¼¦WÖ0„„¤SêBv8[ƒ»x6c0"}¸ÒÇ!އ‡?® ÿ=WôŽXȦs†¯Wa!/šl*<¡3¤×ÄÀ®³¨î’ëéHNýq!ï=Ra!/øûÎm…`Ð^Ôõê©:/8ú’•ÚŒ° £Òê)+톃W®]lÃË’ŠÂ¸ÇÙÖ~ŸÓ7€9{²_î `ž|¥@üeÎHjÂM|uýe(@ $œ# ™í¹~>%—-g²õø!ä(f3HA]ošùí Æ)´Éo{à?°ÞC:n,³ vÒw}'´bèwP,?*B!ì¼~ÿ~I·ßÿΟòA6ú!±}‡óŠpóx­zŽ1ø™u|òÀ¾pY‹1*ún›‰T˜¬7ð/bV9¼Ñ?ÿ|¿8_Ÿ%Ìt%Y¦ š.œûL¼ý5Ÿ­\€¿äÐ&Ê §YÔUEQTUÎH(*yH¨F#!¡ÖÅ<£´WkØîHÎâ#?þf¿a®@4º}ʦXÖjTUnþjÊœ{ò“m¶Ûõ±÷0b\/Ä/h¸žßÖÛê’ï¸olÓ^×c»AÆàB,dИÏé–ù Ž¶ÇÖs^ÀvÑ–RB½Ò.ªc ¡bL¯b@ÁV; },Ñßø?ÞŒá8¥°tÑ–ø™$—ôèÙÄØ§«QþØã6—´Ñ%¶)Ù6 Å® $6œo5b YÝ!­cõ ËÄÞ¡¥ÕàÐUèPÖÛÕµC?¥é€a!,¦Ï $%Š€ Bv%eýAdUH?š(¤Ð¥è›[2êêë2èS¡e»ªfb»&é•Ë-'¾Ç£ÊðÂx7#LLV®mô€tñšb¨Ùü"¼ ²Ùqû¯%鈴~#€7>iG¸ÿIã B'E£¿HôIΔNfŽ€¡Î‚ë{ÅÎäâ ³†Ä‰Dßoê~g‡¯÷I›`€&Ŷy\í–>NͪjTÇœ¿zÎÕW^çFƒrËW”ô|›˜®ZEðQÖ ?«7É`Yî{z!™_ ú?ðœÿ­‡|‹ÄÉTì–Mñ=š¡ÔH9@ùíùjg¿Uë|º6tC9…BÜÖÚÄ`Üû]àt Bçv£K³ÏŒePñ?8õý©œyûT3ó_Ú¡ùɵ3‰ùÈþqùùÇþrA'öŸ~ÔoíFý¨|ôE?¡$ü"ŸÎ à5¸ù}Š Oâ°( ùŸu˜uˆU5ÏÖá# øVÝ|ß7Íó|ß7ú!µw_7Íó|ß7Íó|ß7ãqbuµºù¾o›æù¾o›æùºR Œ?O—³·ÿ.ðk¸ $#Ÿš±ÏüpŒ ig@PNø9l/“ ZÝ|ß7Íó|ß7Íó|ß7î0þo›æù¾o›æù¾o›æù¾o›þÃþëæù¾o›æù¾o›æù¾o›ç Ž?O—³·ÿ.ðk¸ $#Ÿš±ÏüpŒ ig@PNø9l/“ ZÝ|ß7Íó|ß7Íó|ß7î0þo›æù¾o›æù¾o›æù¾o›þÃþëæù¾o›æù¾o›æù¾o›ç Ž?O—³·ù`Ê•öþµá²@0{Ÿš±Ïó¨¡_¨fnÌ(' üù X¶ëæù¾o›æù¾iOºB$w_7Íó|ß7Íó|ß7Ìî,8ˆVÝ|ß7Íó|ß7ÍóvŽ~äòTàLΚǪºéWI(„ƒÏÝ»zkÿ~O•ÔHKÝ»zkÿ~O•ÔHKÝ»zbÏ9aF¨4B rH=õÿ} ÞR!†÷‰³¡"S›â$6F*(Ì×Rw«Àoõξ®pH.XÝ6t$JsËñøàlŒ2T²è–þ@÷I/õξ®pH.XÝ6t$JsËñøàlŒ2T²è–þ@÷I/õĪº-^D îÿMM ›¢ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A@ÿ1A?ÿPN*ÿC?=ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1ïÿ cØÿeAÿ| ÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ@\ÿC:>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿqïÿ¥èÿ.K]ÿ`"ÿˆÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿ‰ÿPgÿoMÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿµýÿ«ëÿ0G_ÿ68Eÿa$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿƒUÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿ»ÿÿªêÿ0G_ÿ86Gÿ59Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚UÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿµüÿºÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿºÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿºÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€VÿVÿnNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€VÿVÿnNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ59Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿnNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿ´üÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿpîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ.ðÿ-ðÿ1îÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ.ðÿ-ðÿ1îÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ.ðÿ-ðÿ1îÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿmNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ.òÿ-ðÿ1îÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿˆÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿnNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ-òÿ1îÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿnNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ26Yÿ /Öÿ1ïÿqîÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ†ÿOgÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿVÿnNÿA;>ÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ25Yÿ 2Óÿqðÿµüÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ59Fÿ_%ÿQdÿ‚UÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿVÿ€VÿmNÿA;>ÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ86Fÿ1:Zÿ s×ÿµýÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ59FÿPP'ÿ{kÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ|mÿ}mÿd\ÿ88Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Mÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ::Fÿ\]#ÿ~ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ‚ÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\#ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Mÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\#ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Mÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\#ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\#ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\#ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿz§ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿ{¨ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿ{¨ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿ{¨ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ5;Nÿ{¨ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿÿnnÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ4=Qÿ}«ÿ¸ûÿ¼ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ»ÿÿ¼ÿÿ¬êÿ0H_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ]]#ÿllÿ::Eÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ'\|ÿ’Éÿ–Îÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ•Íÿ–Îÿоÿ2CYÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ::EÿLL4ÿ99Fÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ6:Mÿ5;Nÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ5;Mÿ6:Lÿ77Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77H–77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77H–77H77H77HY77H™77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H–77H™77HY77Hÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ü?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(@€ @ÃÃ77H77H77H77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H 77H77H77H77H77H77H77HÃ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÀ77HÃ77H77H77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ86Eÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Iÿ76Iÿ76Iÿ76Iÿ76Iÿ76Iÿ76Iÿ76Iÿ76Iÿ76Iÿ66Iÿ76Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ2>Wÿ"VŽÿ Y”ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y“ÿ Y”ÿ#UŠÿ4;Qÿ77Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ78Gÿ?L3ÿBT+ÿBS,ÿBS,ÿBS,ÿBS,ÿBS,ÿBS,ÿBS,ÿAS,ÿCU,ÿ?F=ÿ76Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ5:Nÿ`¤ÿ‡úÿŠÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿ€êÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿR€ÿR€ÿR€ÿR€ÿR€ÿR€ÿSÿi”ÿSe+ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿR€ÿR€ÿR€ÿR€ÿR€ÿSÿh“ÿ©ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿR€ÿR€ÿR€ÿR€ÿSÿh”ÿ©ÿ«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿR€ÿR€ÿR€ÿSÿh”ÿ©ÿ€ªÿ€«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿR€ÿR€ÿSÿh”ÿ©ÿ€ªÿ€ªÿ€«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿR€ÿSÿh”ÿ©ÿ€ªÿ€ªÿ€ªÿ€«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿR€ÿSÿh”ÿ©ÿ€ªÿ€ªÿ€ªÿ€ªÿ€«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿRÿSÿh”ÿ©ÿ€ªÿ€ªÿ€ªÿ€ªÿ€ªÿ€«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿKnÿS‚ÿh”ÿ©ÿ€ªÿ€ªÿ€ªÿ€ªÿ€ªÿ€ªÿ€«ÿUf*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ`£ÿ‡ùÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ8:EÿLoÿi–ÿªÿ€«ÿ€«ÿ€«ÿ€«ÿ€«ÿ€«ÿ€«ÿ¬ÿUg*ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Gÿ69Lÿ_´ÿ‡ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ89Eÿ_tÿ}™ÿšÿ~™ÿ~™ÿ~™ÿ~™ÿ~™ÿ~™ÿ~šÿ~šÿQ].ÿ65Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Eÿ5–ÿ[õÿ‡ýÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿ‰ÿÿŠÿÿêÿ0A_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ:9Eÿn`ÿ€oÿnÿnÿnÿnÿnÿnÿnÿnÿe[ÿ<ÿ0A?ÿ0A?ÿ0A?ÿ0A?ÿ0A?ÿ0A?ÿ0A?ÿ0A?ÿ4C=ÿSN)ÿ=;Bÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1ñÿdÝÿeAÿ| ÿ€ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ } ÿITÿ=8Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1ïÿsôÿ¦èÿ.J\ÿ`"ÿˆÿŠÿŠÿŠÿŠÿŠÿŠÿŠÿ‡ÿbaÿgJÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1ïÿróÿ¶ÿÿªêÿ0G_ÿ68Eÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ†ÿbaÿ‚UÿeKÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ.ðÿ.ðÿ.ðÿ-ðÿ1ïÿróÿµýÿ»ÿÿªêÿ0G_ÿ86Gÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ‰ÿ†ÿbaÿ‚Uÿ€VÿeKÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ.ðÿ.ðÿ-ðÿ1ïÿróÿµýÿºÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ‰ÿ†ÿbaÿ‚Uÿ€Vÿ€VÿeKÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ.ðÿ-ðÿ1ïÿróÿµýÿºÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ‰ÿ†ÿbaÿ‚Uÿ€Vÿ€Vÿ€VÿeJÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ.ðÿ-ðÿ1ïÿróÿµýÿºÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‰ÿ‰ÿ†ÿbaÿ‚Uÿ€Vÿ€Vÿ€Vÿ€VÿeJÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ.òÿ-ðÿ1ïÿróÿµýÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿŠÿ†ÿbaÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿeJÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ3˜ÿ-òÿ1ïÿróÿµýÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ‡ÿ‡ÿbaÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿeJÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ87Fÿ2˜ÿ1ñÿróÿµýÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ69Fÿ`$ÿ„ÿbaÿ‚Uÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€Vÿ€VÿeJÿ<9Cÿ67Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ86Eÿ6–ÿrõÿµýÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ59Fÿ!]%ÿc`ÿWÿWÿWÿWÿWÿWÿWÿWÿWÿdLÿ<:Cÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿwµÿµÿÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ68FÿWS%ÿ}sÿuÿ~uÿ~uÿ~uÿ~uÿ~uÿ~uÿ~uÿ~uÿQO.ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\]#ÿ~ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿ€€ÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿ€€ÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿ€€ÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿ€€ÿ€€ÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6:Mÿy¥ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿ~~ÿÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ76Gÿ6;Mÿz¦ÿ¶úÿºÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿ¹ÿÿºÿÿªêÿ0G_ÿ76Gÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ99Fÿ\\$ÿÿUU*ÿ66Iÿ77Hÿ77Hÿ77Hÿ77Hÿ77HÀ77H 77H77H77H 77HÀ77Hÿ77Hÿ77Hÿ77Hÿ77Hÿ5 image/svg+xml ksnip-master/icons/ksnip_icons.qrc000066400000000000000000000027331457262621600176540ustar00rootroot00000000000000 ksnip.svg light/ksnip.svg light/clock.svg light/crop.svg light/save.svg light/saveAs.svg light/copy.svg light/paste.svg light/pasteEmbedded.svg light/undo.svg light/redo.svg light/currentScreen.svg light/drawRect.svg light/lastRect.svg light/activeWindow.svg light/windowUnderCursor.svg light/fullScreen.svg light/pin.svg light/wayland.svg light/delete.svg light/action.svg dark/ksnip.svg dark/clock.svg dark/crop.svg dark/save.svg dark/saveAs.svg dark/copy.svg dark/paste.svg dark/pasteEmbedded.svg dark/undo.svg dark/redo.svg dark/currentScreen.svg dark/drawRect.svg dark/lastRect.svg dark/activeWindow.svg dark/windowUnderCursor.svg dark/fullScreen.svg dark/pin.svg dark/wayland.svg dark/delete.svg dark/action.svg ksnip-master/icons/ksnip_windows_icon.rc000066400000000000000000000000731457262621600210550ustar00rootroot00000000000000IDI_ICON1 ICON DISCARDABLE "ksnip.ico"ksnip-master/icons/light/000077500000000000000000000000001457262621600157305ustar00rootroot00000000000000ksnip-master/icons/light/action.svg000066400000000000000000000043741457262621600177360ustar00rootroot00000000000000 image/svg+xmlksnip-master/icons/light/activeWindow.svg000066400000000000000000000053771457262621600211300ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/clock.svg000066400000000000000000000054071457262621600175520ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/copy.svg000066400000000000000000000114321457262621600174240ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/crop.svg000066400000000000000000000123331457262621600174160ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/currentScreen.svg000066400000000000000000000120051457262621600212710ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/delete.svg000066400000000000000000000057671457262621600177320ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/drawRect.svg000066400000000000000000000133071457262621600202300ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/fullScreen.svg000066400000000000000000000146311457262621600205600ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/ksnip.svg000066400000000000000000000116551457262621600176050ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/lastRect.svg000066400000000000000000000135311457262621600202350ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/paste.svg000066400000000000000000000076241457262621600175760ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/pasteEmbedded.svg000066400000000000000000000053161457262621600212040ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/pin.svg000066400000000000000000000045341457262621600172450ustar00rootroot00000000000000 image/svg+xmlksnip-master/icons/light/redo.svg000066400000000000000000000075071457262621600174130ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/save.svg000066400000000000000000000066131457262621600174150ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/saveAs.svg000066400000000000000000000212601457262621600176740ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/undo.svg000066400000000000000000000075131457262621600174240ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/wayland.svg000066400000000000000000000201001457262621600201010ustar00rootroot00000000000000 image/svg+xml ksnip-master/icons/light/windowUnderCursor.svg000066400000000000000000000107141457262621600221570ustar00rootroot00000000000000 image/svg+xml ksnip-master/snap/000077500000000000000000000000001457262621600144475ustar00rootroot00000000000000ksnip-master/snap/snapcraft.yaml000066400000000000000000000040301457262621600173110ustar00rootroot00000000000000name: ksnip base: core18 adopt-info: ksnip icon: desktop/ksnip.svg grade: stable confinement: strict compression: lzo apps: ksnip: command: bin/ksnip common-id: org.ksnip.ksnip environment: # Set theme fix on gnome/gtk XDG_CURRENT_DESKTOP: $XDG_CURRENT_DESKTOP:Unity:Unity7 QT_QPA_PLATFORMTHEME: gtk3 desktop: share/applications/org.ksnip.ksnip.desktop extensions: [kde-neon] plugs: - home - removable-media - unity7 - network - network-manager-observe - network-observe - opengl architectures: - build-on: amd64 parts: ksnip: source: . plugin: cmake parse-info: [share/metainfo/org.ksnip.ksnip.appdata.xml] after: - kimageannotator build-snaps: - kde-frameworks-5-core18-sdk build-packages: - libglvnd-dev - libx11-dev stage-packages: - curl - ftp configflags: - -DCMAKE_FIND_ROOT_PATH=/snap/kde-frameworks-5-core18-sdk/current;/snap/kimageannotator/current - -DBUILD_TESTS:BOOL=OFF override-pull: | snapcraftctl pull sed -i 's|Icon=.*|Icon=share/icons/hicolor/scalable/apps/ksnip.svg|g' desktop/org.ksnip.ksnip.desktop snapcraftctl set-version $(cat CMakeLists.txt | grep project\(ksnip | cut -d" " -f5 | cut -d")" -f1) kimageannotator: source: https://github.com/ksnip/kImageAnnotator.git plugin: cmake after: - kcolorpicker configflags: - -DCMAKE_FIND_ROOT_PATH=/snap/kde-frameworks-5-core18-sdk/current;/snap/kcolorpicker/current - -DBUILD_EXAMPLE:BOOL=OFF - -DBUILD_TESTS:BOOL=OFF kcolorpicker: source: https://github.com/ksnip/kColorPicker.git plugin: cmake configflags: - -DCMAKE_FIND_ROOT_PATH=/snap/kde-frameworks-5-core18-sdk/current cleanup: after: [kcolorpicker, kimageannotator, ksnip] plugin: nil build-snaps: [ kde-frameworks-5-core18 ] override-prime: | set -eux cd /snap/kde-frameworks-5-core18/current find . -type f,l -exec rm -f $SNAPCRAFT_PRIME/{} \; ksnip-master/src/000077500000000000000000000000001457262621600142755ustar00rootroot00000000000000ksnip-master/src/BuildConfig.h.in000066400000000000000000000005001457262621600172330ustar00rootroot00000000000000#ifndef KSNIP_BUILDCONFIG_H #define KSNIP_BUILDCONFIG_H // Variables passed from CMAKE #define KSNIP_VERSION "@KSNIP_VERSION@" #define KSNIP_BUILD_NUMBER "@BUILD_NUMBER@" #define KSNIP_LANG_INSTALL_DIR "@KSNIP_LANG_INSTALL_DIR@" #define KIMAGEANNOTATOR_LANG_INSTALL_DIR "@KIMAGEANNOTATOR_LANG_INSTALL_DIR@" #endif ksnip-master/src/CMakeLists.txt000066400000000000000000000467201457262621600170460ustar00rootroot00000000000000set(KSNIP_SRCS ${CMAKE_SOURCE_DIR}/src/main.cpp ${CMAKE_SOURCE_DIR}/src/backend/config/IConfig.h ${CMAKE_SOURCE_DIR}/src/backend/config/Config.cpp ${CMAKE_SOURCE_DIR}/src/backend/config/ConfigOptions.cpp ${CMAKE_SOURCE_DIR}/src/backend/commandLine/CommandLine.cpp ${CMAKE_SOURCE_DIR}/src/backend/commandLine/CommandLineCaptureHandler.cpp ${CMAKE_SOURCE_DIR}/src/backend/commandLine/ICommandLineCaptureHandler.h ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/IImageGrabber.h ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/AbstractImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/AbstractRectAreaImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/IUploader.h ${CMAKE_SOURCE_DIR}/src/backend/uploader/UploadHandler.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/IUploadHandler.h ${CMAKE_SOURCE_DIR}/src/backend/uploader/imgur/IImgurUploader.h ${CMAKE_SOURCE_DIR}/src/backend/uploader/imgur/ImgurWrapper.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/imgur/ImgurResponse.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/imgur/ImgurUploader.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/imgur/ImgurResponseLogger.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/script/IScriptUploader.h ${CMAKE_SOURCE_DIR}/src/backend/uploader/script/ScriptUploader.cpp ${CMAKE_SOURCE_DIR}/src/backend/uploader/ftp/IFtpUploader.h ${CMAKE_SOURCE_DIR}/src/backend/uploader/ftp/FtpUploader.cpp ${CMAKE_SOURCE_DIR}/src/backend/saver/SavePathProvider.cpp ${CMAKE_SOURCE_DIR}/src/backend/saver/ImageSaver.cpp ${CMAKE_SOURCE_DIR}/src/backend/saver/WildcardResolver.cpp ${CMAKE_SOURCE_DIR}/src/backend/saver/UniqueNameProvider.cpp ${CMAKE_SOURCE_DIR}/src/backend/saver/NameProvider.cpp ${CMAKE_SOURCE_DIR}/src/backend/CapturePrinter.cpp ${CMAKE_SOURCE_DIR}/src/backend/TranslationLoader.cpp ${CMAKE_SOURCE_DIR}/src/backend/WatermarkImageLoader.cpp ${CMAKE_SOURCE_DIR}/src/backend/recentImages/RecentImagesPathStore.cpp ${CMAKE_SOURCE_DIR}/src/backend/recentImages/ImagePathStorage.cpp ${CMAKE_SOURCE_DIR}/src/backend/ipc/IpcServer.cpp ${CMAKE_SOURCE_DIR}/src/backend/ipc/IpcClient.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/BootstrapperFactory.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/StandAloneBootstrapper.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/ImageFromStdInputReader.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/singleInstance/InstanceLock.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/singleInstance/SingleInstanceClientBootstrapper.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/singleInstance/SingleInstanceServerBootstrapper.cpp ${CMAKE_SOURCE_DIR}/src/bootstrapper/singleInstance/SingleInstanceParameterTranslator.cpp ${CMAKE_SOURCE_DIR}/src/common/adapter/fileDialog/FileDialogAdapter.cpp ${CMAKE_SOURCE_DIR}/src/common/helper/MathHelper.cpp ${CMAKE_SOURCE_DIR}/src/common/helper/PathHelper.cpp ${CMAKE_SOURCE_DIR}/src/common/helper/FileUrlHelper.cpp ${CMAKE_SOURCE_DIR}/src/common/helper/RectHelper.cpp ${CMAKE_SOURCE_DIR}/src/common/helper/EnumTranslator.cpp ${CMAKE_SOURCE_DIR}/src/common/helper/FileDialogFilterHelper.cpp ${CMAKE_SOURCE_DIR}/src/common/loader/IconLoader.cpp ${CMAKE_SOURCE_DIR}/src/common/handler/DelayHandler.cpp ${CMAKE_SOURCE_DIR}/src/common/handler/IDelayHandler.h ${CMAKE_SOURCE_DIR}/src/common/provider/ApplicationTitleProvider.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/NewCaptureNameProvider.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/PathFromCaptureProvider.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/scaledSizeProvider/ScaledSizeProvider.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/TempFileProvider.cpp ${CMAKE_SOURCE_DIR}/src/common/platform/HdpiScaler.cpp ${CMAKE_SOURCE_DIR}/src/common/platform/PlatformChecker.cpp ${CMAKE_SOURCE_DIR}/src/common/platform/CommandRunner.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/directoryPathProvider/DirectoryPathProvider.cpp ${CMAKE_SOURCE_DIR}/src/dependencyInjector/DependencyInjector.cpp ${CMAKE_SOURCE_DIR}/src/dependencyInjector/DependencyInjectorBootstrapper.cpp ${CMAKE_SOURCE_DIR}/src/widgets/CustomToolButton.cpp ${CMAKE_SOURCE_DIR}/src/widgets/CustomCursor.cpp ${CMAKE_SOURCE_DIR}/src/widgets/NumericComboBox.cpp ${CMAKE_SOURCE_DIR}/src/widgets/CustomSpinBox.cpp ${CMAKE_SOURCE_DIR}/src/widgets/CaptureModePicker.cpp ${CMAKE_SOURCE_DIR}/src/widgets/ColorButton.cpp ${CMAKE_SOURCE_DIR}/src/widgets/MainToolBar.cpp ${CMAKE_SOURCE_DIR}/src/widgets/KeySequenceLineEdit.cpp ${CMAKE_SOURCE_DIR}/src/widgets/CustomLineEdit.cpp ${CMAKE_SOURCE_DIR}/src/widgets/ProcessIndicator.cpp ${CMAKE_SOURCE_DIR}/src/gui/MainWindow.cpp ${CMAKE_SOURCE_DIR}/src/gui/RecentImagesMenu.cpp ${CMAKE_SOURCE_DIR}/src/gui/ImgurHistoryDialog.cpp ${CMAKE_SOURCE_DIR}/src/gui/TrayIcon.cpp ${CMAKE_SOURCE_DIR}/src/gui/actions/Action.cpp ${CMAKE_SOURCE_DIR}/src/gui/actions/ActionProcessor.cpp ${CMAKE_SOURCE_DIR}/src/gui/actions/ActionsMenu.cpp ${CMAKE_SOURCE_DIR}/src/gui/clipboard/ClipboardAdapter.cpp ${CMAKE_SOURCE_DIR}/src/gui/clipboard/IClipboard.h ${CMAKE_SOURCE_DIR}/src/gui/imageAnnotator/KImageAnnotatorAdapter.cpp ${CMAKE_SOURCE_DIR}/src/gui/imageAnnotator/IImageAnnotator.h ${CMAKE_SOURCE_DIR}/src/gui/desktopService/DesktopServiceAdapter.cpp ${CMAKE_SOURCE_DIR}/src/gui/fileService/FileService.cpp ${CMAKE_SOURCE_DIR}/src/gui/directoryService/DirectoryService.cpp ${CMAKE_SOURCE_DIR}/src/gui/widgetVisibilityHandler/WidgetVisibilityHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/widgetVisibilityHandler/GnomeWaylandWidgetVisibilityHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/widgetVisibilityHandler/WidgetVisibilityHandlerFactory.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/AbstractSnippingArea.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/SnippingAreaAdorner.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/AdornerMagnifyingGlass.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/AdornerRulers.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/AdornerPositionInfo.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/AdornerSizeInfo.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/SnippingAreaResizer.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/SnippingAreaSelector.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/SnippingAreaSelectorInfoText.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/SnippingAreaResizerInfoText.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/AbstractSnippingAreaInfoText.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/AnnotationSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/ApplicationSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/ImageGrabberSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/HotKeySettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/SaverSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/StickerSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/SnippingAreaSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/SettingsDialog.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/SettingsFilter.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/TrayIconSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/WatermarkSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/actions/ActionsSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/actions/ActionSettingTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/actions/EmptyActionSettingTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/uploader/UploaderSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/uploader/ImgurUploaderSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/uploader/ScriptUploaderSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/uploader/FtpUploaderSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/settingsDialog/plugins/PluginsSettings.cpp ${CMAKE_SOURCE_DIR}/src/gui/aboutDialog/AboutDialog.cpp ${CMAKE_SOURCE_DIR}/src/gui/aboutDialog/AboutTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/aboutDialog/VersionTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/aboutDialog/AuthorTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/aboutDialog/DonateTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/aboutDialog/ContactTab.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/GlobalHotKey.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/NativeKeyEventFilter.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/GlobalHotKeyHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/HotKeyMap.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/keyHandler/DummyKeyHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/keyHandler/KeyHandlerFactory.cpp ${CMAKE_SOURCE_DIR}/src/gui/notificationService/NotificationServiceFactory.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/SaveOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/RenameOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/AddWatermarkOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/UpdateWatermarkOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/WatermarkImagePreparer.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/CanDiscardOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/UploadOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/HandleUploadResultOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/NotifyOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/DeleteImageOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/CopyAsDataUriOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/operations/LoadImageFromFileOperation.cpp ${CMAKE_SOURCE_DIR}/src/gui/captureHandler/CaptureTabStateHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/captureHandler/ICaptureTabStateHandler.h ${CMAKE_SOURCE_DIR}/src/gui/captureHandler/CaptureHandlerFactory.cpp ${CMAKE_SOURCE_DIR}/src/gui/captureHandler/SingleCaptureHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/captureHandler/MultiCaptureHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/captureHandler/TabContextMenuAction.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/IModelessWindow.h ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/IModelessWindowCreator.h ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/ModelessWindowHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/pinWindow/PinWindow.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/pinWindow/PinWindowCreator.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/pinWindow/PinWindowHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/ocrWindow/OcrWindow.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/ocrWindow/OcrWindowCreator.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/ocrWindow/OcrWindowHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/messageBoxService/MessageBoxService.cpp ${CMAKE_SOURCE_DIR}/src/gui/windowResizer/WindowResizer.cpp ${CMAKE_SOURCE_DIR}/src/gui/dragAndDrop/DragAndDropProcessor.cpp ${CMAKE_SOURCE_DIR}/src/logging/LogOutputHandler.cpp ${CMAKE_SOURCE_DIR}/src/logging/ConsoleLogger.cpp ${CMAKE_SOURCE_DIR}/src/logging/NoneLogger.cpp ${CMAKE_SOURCE_DIR}/src/plugins/PluginInfo.cpp ${CMAKE_SOURCE_DIR}/src/plugins/IPluginManager.h ${CMAKE_SOURCE_DIR}/src/plugins/PluginManager.cpp ${CMAKE_SOURCE_DIR}/src/plugins/PluginFinder.cpp ${CMAKE_SOURCE_DIR}/src/plugins/PluginLoader.cpp ) if (APPLE) list(APPEND KSNIP_SRCS ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/MacImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/MacWrapper.cpp ${CMAKE_SOURCE_DIR}/src/backend/config/MacConfig.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/MacSnippingArea.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/keyHandler/MacKeyHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/KeySequenceToMacKeyCodeTranslator.cpp ${CMAKE_SOURCE_DIR}/src/plugins/searchPathProvider/MacPluginSearchPathProvider.cpp ) elseif (UNIX) list(APPEND KSNIP_SRCS ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/BaseX11ImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/X11ImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/GnomeX11ImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/KdeWaylandImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/X11Wrapper.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/GnomeX11Wrapper.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/GnomeWaylandImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/WaylandImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/config/WaylandConfig.cpp ${CMAKE_SOURCE_DIR}/src/common/adapter/fileDialog/SnapFileDialogAdapter.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/directoryPathProvider/SnapDirectoryPathProvider.cpp ${CMAKE_SOURCE_DIR}/src/common/provider/scaledSizeProvider/GnomeScaledSizeProvider.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/X11SnippingArea.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/WaylandSnippingArea.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/keyHandler/X11KeyHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/KeySequenceToX11KeyCodeTranslator.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/X11ErrorLogger.cpp ${CMAKE_SOURCE_DIR}/src/gui/notificationService/FreeDesktopNotificationService.cpp ${CMAKE_SOURCE_DIR}/src/gui/notificationService/KdeDesktopNotificationService.cpp ${CMAKE_SOURCE_DIR}/src/gui/desktopService/SnapDesktopServiceAdapter.cpp ${CMAKE_SOURCE_DIR}/src/plugins/searchPathProvider/LinuxPluginSearchPathProvider.cpp ) elseif (WIN32) list(APPEND KSNIP_SRCS ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/WinImageGrabber.cpp ${CMAKE_SOURCE_DIR}/src/backend/imageGrabber/WinWrapper.cpp ${CMAKE_SOURCE_DIR}/src/gui/snippingArea/WinSnippingArea.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/keyHandler/WinKeyHandler.cpp ${CMAKE_SOURCE_DIR}/src/gui/globalHotKeys/KeySequenceToWinKeyCodeTranslator.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/ocrWindow/WinOcrWindow.cpp ${CMAKE_SOURCE_DIR}/src/gui/modelessWindows/ocrWindow/WinOcrWindowCreator.cpp ${CMAKE_SOURCE_DIR}/src/plugins/WinPluginLoader.cpp ${CMAKE_SOURCE_DIR}/src/plugins/searchPathProvider/WinPluginSearchPathProvider.cpp ) endif () # Set the sources variable in the top-level as well, since the tests/ # directory wants to (re)build as well. set(KSNIP_SRCS ${KSNIP_SRCS} PARENT_SCOPE) if (WIN32) set(CPACK_GENERATOR WIX) set(CPACK_PACKAGE_NAME "ksnip") set(CPACK_PACKAGE_VENDOR "ksnip") set(CPACK_WIX_UPGRADE_GUID "4c7ed545-c0dd-4d45-bf69-c29c7998f668") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Cross-platform screenshot tool that provides many annotation features for your screenshots.") set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") set(CPACK_PACKAGE_INSTALL_DIRECTORY "ksnip") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt") set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/icons/ksnip.ico") INCLUDE(CPack) add_executable(ksnip ${KSNIP_SRCS} ${CMAKE_SOURCE_DIR}/icons/ksnip_icons.qrc ${CMAKE_SOURCE_DIR}/icons/ksnip_windows_icon.rc) elseif (APPLE) set(MACOSX_BUNDLE_EXECUTABLE_NAME "ksnip") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.ksnip.ksnip") set(MACOSX_BUNDLE_ICON_FILE "ksnip.icns") set(MACOSX_BUNDLE_INFO_STRING "Cross-Platform Screenshot and Annotation Tool") set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION}) set(MACOSX_BUNDLE_LONG_VERSION_STRING ${KSNIP_VERSION}) set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}) set(MACOSX_ICON ${CMAKE_SOURCE_DIR}/icons/ksnip.icns) set_source_files_properties(${MACOSX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") add_executable(ksnip MACOSX_BUNDLE ${KSNIP_SRCS} ${CMAKE_SOURCE_DIR}/icons/ksnip_icons.qrc ${MACOSX_ICON}) else () add_executable(ksnip ${KSNIP_SRCS} ${CMAKE_SOURCE_DIR}/icons/ksnip_icons.qrc) endif () set(DEPENDENCY_LIBRARIES Qt5::Widgets Qt5::Network Qt5::Xml Qt5::PrintSupport Qt5::Svg ) if (APPLE) list(APPEND DEPENDENCY_LIBRARIES kImageAnnotator::kImageAnnotator kColorPicker::kColorPicker "-framework CoreGraphics -framework AppKit" ) elseif (UNIX) list(APPEND DEPENDENCY_LIBRARIES Qt5::DBus Qt5::X11Extras kImageAnnotator::kImageAnnotator kColorPicker::kColorPicker XCB::XFIXES ) # X11::X11 imported target only available with sufficiently new CMake if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.14.0) list(APPEND DEPENDENCY_LIBRARIES X11::X11) else() list(APPEND DEPENDENCY_LIBRARIES X11) endif() # This is the "UNIX AND NOT APPLE" case, which is the Free Desktop # world: Linux and the BSDs and Illumos. To simplify #ifdefs in # the source, add a UNIX_X11 defined to be used instead of __linux__ etc. # While the "X11" part of the define isn't necessarily accurate, # it is easy to spot. target_compile_definitions(ksnip PRIVATE UNIX_X11) elseif (WIN32) list(APPEND DEPENDENCY_LIBRARIES Qt5::WinExtras kImageAnnotator::kImageAnnotator kColorPicker Dwmapi ) endif () target_link_libraries(ksnip ${DEPENDENCY_LIBRARIES}) # install target if (WIN32) install(TARGETS ksnip RUNTIME DESTINATION .) find_program(WINDEPLOYQT windeployqt HINTS $ENV{QTDIR} PATH_SUFFIXES bin) SET(WINDEPLOYQT_PARAMETERS "--no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --release") install(CODE "execute_process(COMMAND ${WINDEPLOYQT} ${WINDEPLOYQT_PARAMETERS} . WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX})") find_program(COPY cp) if (DEFINED ENV{OPENSSL_DIR}) file(TO_CMAKE_PATH "$ENV{OPENSSL_DIR}" OPENSSL_DIR) install(CODE "execute_process(COMMAND ${COPY} ${OPENSSL_DIR}/*.dll \${CMAKE_INSTALL_PREFIX})") else () message("OPENSSL_DIR not set, not able to install openssl dependencies, skipping.") endif() if (DEFINED ENV{COMPILE_RUNTIME_DIR}) file(TO_CMAKE_PATH "$ENV{COMPILE_RUNTIME_DIR}" COMPILE_RUNTIME_DIR) install(CODE "execute_process(COMMAND ${COPY} ${COMPILE_RUNTIME_DIR}/*.dll \${CMAKE_INSTALL_PREFIX})") else () message("COMPILE_RUNTIME_DIR not set, not able to install compile runtime dependencies, skipping.") endif() if (DEFINED ENV{KIMAGEANNOTATOR_DIR}) file(TO_CMAKE_PATH "$ENV{KIMAGEANNOTATOR_DIR}" KIMAGEANNOTATOR_DIR) install(CODE "execute_process(COMMAND ${COPY} -r \"${KIMAGEANNOTATOR_DIR}/${KIMAGEANNOTATOR_LANG_INSTALL_DIR}\" \${CMAKE_INSTALL_PREFIX})") else () message("KIMAGEANNOTATOR_DIR not set, not able to install kImageAnnotator translations, skipping.") endif() set_property(INSTALL "ksnip.exe" PROPERTY CPACK_START_MENU_SHORTCUTS "ksnip Screenshot Tool" ) elseif (UNIX AND NOT APPLE) install(TARGETS ksnip RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) else () message("DEBUG: NOT WIN32, NOT UNIX") endif () # uninstall target if (UNIX AND NOT APPLE) if(NOT TARGET uninstall) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) endif () endif () ksnip-master/src/backend/000077500000000000000000000000001457262621600156645ustar00rootroot00000000000000ksnip-master/src/backend/CapturePrinter.cpp000066400000000000000000000045241457262621600213440ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CapturePrinter.h" CapturePrinter::CapturePrinter(QWidget *parent) : mParent(parent) { Q_ASSERT(mParent != nullptr); } void CapturePrinter::print(const QImage &image, const QString &defaultPath) { QPrinter printer; printer.setOutputFileName(defaultPath); printer.setOutputFormat(QPrinter::NativeFormat); QPrintDialog printDialog(&printer, mParent); if (printDialog.exec() == QDialog::Accepted) { printCapture(image, &printer); } } void CapturePrinter::printCapture(const QImage &image, QPrinter *p) { QPainter painter; painter.begin(p); auto xScale = p->pageRect().width() / double(image.width()); auto yScale = p->pageRect().height() / double(image.height()); auto scale = qMin(xScale, yScale); painter.translate(p->paperRect().x() + p->pageRect().width() / 2, p->paperRect().y() + p->pageRect().height() / 2); painter.scale(scale, scale); painter.translate(-image.width() / 2, -image.height() / 2); painter.drawImage(QPoint(0, 0), image); painter.end(); } void CapturePrinter::printPreview(const QImage &image, const QString &defaultPath) { QPrinter printer; printer.setOutputFileName(defaultPath); printer.setOutputFormat(QPrinter::NativeFormat); QPrintPreviewDialog printDialog(&printer, mParent, Qt::Window | Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); connect(&printDialog, &QPrintPreviewDialog::paintRequested, [this, image](QPrinter *p) { printCapture(image, p); }); printDialog.exec(); } ksnip-master/src/backend/CapturePrinter.h000066400000000000000000000025141457262621600210060ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTUREPRINTER_H #define KSNIP_CAPTUREPRINTER_H #include #include #include #include class CapturePrinter : public QObject { Q_OBJECT public: explicit CapturePrinter(QWidget *parent); ~CapturePrinter() override = default; void print(const QImage &image, const QString &defaultPath); void printPreview(const QImage &image, const QString &defaultPath); private: QWidget *mParent; private slots: void printCapture(const QImage &image, QPrinter *p); }; #endif //KSNIP_CAPTUREPRINTER_H ksnip-master/src/backend/ITranslationLoader.h000066400000000000000000000020751457262621600215770ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ITRANSLATIONLOADER_H #define KSNIP_ITRANSLATIONLOADER_H class QApplication; class ITranslationLoader { public: ITranslationLoader() = default; ~ITranslationLoader() = default; virtual void load(const QApplication &app) = 0; }; #endif //KSNIP_ITRANSLATIONLOADER_H ksnip-master/src/backend/TranslationLoader.cpp000066400000000000000000000075021457262621600220210ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TranslationLoader.h" TranslationLoader::TranslationLoader(const QSharedPointer &logger) : mLogger(logger) { } void TranslationLoader::load(const QApplication &app) { auto ksnipTranslator = new QTranslator(); auto kImageAnnotatorTranslator = new QTranslator(); auto pathToKsnipTranslations = QString(KSNIP_LANG_INSTALL_DIR); auto pathToKImageAnnotatorTranslations = QString(KIMAGEANNOTATOR_LANG_INSTALL_DIR); loadTranslations(app, ksnipTranslator, pathToKsnipTranslations, QLatin1String("ksnip")); loadTranslations(app, kImageAnnotatorTranslator, pathToKImageAnnotatorTranslations, QLatin1String("kImageAnnotator")); } void TranslationLoader::loadTranslations(const QApplication &app, QTranslator *translator, QString &path, const QString &applicationName) { auto translationSuccessfullyLoaded = loadTranslationFromAbsolutePath(translator, path, applicationName); if (!translationSuccessfullyLoaded) { translationSuccessfullyLoaded = loadTranslationFromRelativePath(translator, path, applicationName); } // Translation loading for AppImage if (!translationSuccessfullyLoaded) { translationSuccessfullyLoaded = loadTranslationForAppImage(translator, path, applicationName); } // Translation loading for Snap if (!translationSuccessfullyLoaded) { translationSuccessfullyLoaded = loadTranslationForSnap(translator, path, applicationName); } if (translationSuccessfullyLoaded) { app.installTranslator(translator); } else { qWarning("Unable to find any translation files for %s.", qPrintable(applicationName)); } } bool TranslationLoader::loadTranslationFromAbsolutePath(QTranslator *translator, const QString &path, const QString &applicationName) { return loadTranslation(translator, path, applicationName); } bool TranslationLoader::loadTranslationFromRelativePath(QTranslator *translator, const QString &path, const QString &applicationName) { auto relativePathToAppDir = QCoreApplication::applicationDirPath() + QLatin1String("/"); return loadTranslation(translator, relativePathToAppDir + path, applicationName); } bool TranslationLoader::loadTranslationForAppImage(QTranslator *translator, const QString &path, const QString &applicationName) { auto relativePathToAppDir = QCoreApplication::applicationDirPath() + QLatin1String("/../.."); return loadTranslation(translator, relativePathToAppDir + path, applicationName); } bool TranslationLoader::loadTranslationForSnap(QTranslator *translator, const QString &path, const QString &applicationName) { auto relativePathToSnapVersionDir = QCoreApplication::applicationDirPath() + QLatin1String("/.."); return loadTranslation(translator, relativePathToSnapVersionDir + path, applicationName); } bool TranslationLoader::loadTranslation(QTranslator *translator, const QString &path, const QString &applicationName) { auto separator = QLatin1String("_"); bool isSuccessful = translator->load(QLocale(), applicationName, separator, path); mLogger->log(QString("Loading translation for %1 from %2").arg(applicationName, path), isSuccessful); return isSuccessful; } ksnip-master/src/backend/TranslationLoader.h000066400000000000000000000037041457262621600214660ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_TRANSLATIONLOADER_H #define KSNIP_TRANSLATIONLOADER_H #include #include #include "ITranslationLoader.h" #include "BuildConfig.h" #include "src/logging/ILogger.h" class TranslationLoader : public ITranslationLoader { public: explicit TranslationLoader(const QSharedPointer &logger); ~TranslationLoader() = default; void load(const QApplication &app) override; private: QSharedPointer mLogger; bool loadTranslationFromAbsolutePath(QTranslator *translator, const QString &path, const QString &applicationName); bool loadTranslationFromRelativePath(QTranslator *translator, const QString &path, const QString &applicationName); bool loadTranslationForAppImage(QTranslator *translator, const QString &path, const QString &applicationName); bool loadTranslation(QTranslator *translator, const QString &path, const QString &applicationName); bool loadTranslationForSnap(QTranslator *translator, const QString &path, const QString &applicationName); void loadTranslations(const QApplication &app, QTranslator *translator, QString &path, const QString &applicationName); }; #endif //KSNIP_TRANSLATIONLOADER_H ksnip-master/src/backend/WatermarkImageLoader.cpp000066400000000000000000000025621457262621600224240ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WatermarkImageLoader.h" WatermarkImageLoader::WatermarkImageLoader() { mImageName = QLatin1String("watermark_image.png"); mPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); mImagePath = mPath + QLatin1String("/") + mImageName; } QPixmap WatermarkImageLoader::load() const { return QPixmap(mImagePath); } bool WatermarkImageLoader::save(const QPixmap &image) const { if(image.isNull()) { return false; } createPathIfRequired(); return image.save(mImagePath); } void WatermarkImageLoader::createPathIfRequired() const { QDir qdir; qdir.mkpath(mPath); } ksnip-master/src/backend/WatermarkImageLoader.h000066400000000000000000000023601457262621600220650ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WATERMARKIMAGELOADER_H #define KSNIP_WATERMARKIMAGELOADER_H #include #include #include #include class WatermarkImageLoader { public: explicit WatermarkImageLoader(); ~WatermarkImageLoader() = default; QPixmap load() const; bool save(const QPixmap &image) const; private: QString mImageName; QString mPath; QString mImagePath; void createPathIfRequired() const; }; #endif //KSNIP_WATERMARKIMAGELOADER_H ksnip-master/src/backend/commandLine/000077500000000000000000000000001457262621600201125ustar00rootroot00000000000000ksnip-master/src/backend/commandLine/CommandLine.cpp000066400000000000000000000176311457262621600230140ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CommandLine.h" CommandLine::CommandLine(const QCoreApplication &app, const QList &captureModes) { setApplicationDescription(translateText(QLatin1String("Ksnip Screenshot Tool"))); addHelpOption(); addVersionOptions(); addImageGrabberOptions(captureModes); addDefaultOptions(); addPositionalArguments(); process(app); } CommandLine::~CommandLine() { delete mRectAreaOption; delete mLastRectAreaOption; delete mFullScreenOption; delete mCurrentScreenOption; delete mActiveWindowOption; delete mWindowUnderCursorOption; delete mPortalOption; delete mDelayOption; delete mCursorOption; delete mEditOption; delete mSaveOption; delete mSaveToOption; delete mVersionOption; delete mUploadOption; } void CommandLine::addImageGrabberOptions(const QList &captureModes) { if (captureModes.contains(CaptureModes::RectArea)) { mRectAreaOption = addOption(QLatin1String("r"), QLatin1String("rectarea"), QLatin1String("Select a rectangular area from where to take a screenshot.")); } if (captureModes.contains(CaptureModes::LastRectArea)) { mLastRectAreaOption = addOption(QLatin1String("l"), QLatin1String("lastrectarea"), QLatin1String("Take a screenshot using last selected rectangular area.")); } if (captureModes.contains(CaptureModes::FullScreen)) { mFullScreenOption = addOption(QLatin1String("f"), QLatin1String("fullscreen"), QLatin1String("Capture the fullscreen including all monitors.")); } if (captureModes.contains(CaptureModes::CurrentScreen)) { mCurrentScreenOption = addOption(QLatin1String("m"), QLatin1String("current"), QLatin1String("Capture the screen (monitor) where the mouse cursor is currently located.")); } if (captureModes.contains(CaptureModes::ActiveWindow)) { mActiveWindowOption = addOption(QLatin1String("a"), QLatin1String("active"), QLatin1String("Capture the window that currently has input focus.")); } if (captureModes.contains(CaptureModes::WindowUnderCursor)) { mWindowUnderCursorOption = addOption(QLatin1String("u"), QLatin1String("windowundercursor"), QLatin1String("Capture the window that is currently under the mouse cursor.")); } if (captureModes.contains(CaptureModes::Portal)) { mWindowUnderCursorOption = addOption(QLatin1String("t"), QLatin1String("portal"), QLatin1String("Uses the screenshot Portal for taking screenshot.")); } } void CommandLine::addDefaultOptions() { mDelayOption = addParameterOption(QLatin1String("d"), QLatin1String("delay"), QLatin1String("Delay before taking the screenshot."), QLatin1String("seconds")); mCursorOption = addOption(QLatin1String("c"), QLatin1String("cursor"), QLatin1String("Capture mouse cursor on screenshot.")); mEditOption = addParameterOption(QLatin1String("e"), QLatin1String("edit"), QLatin1String("Edit existing image in ksnip."), QLatin1String("image")); mSaveOption = addOption(QLatin1String("s"), QLatin1String("save"), QLatin1String("Save screenshot to default location without opening in editor.")); mSaveToOption = addParameterOption(QLatin1String("p"),QLatin1String("saveto"),QLatin1String("Save screenshot to provided path without opening in editor."), QLatin1String("path")); mUploadOption = addOption(QLatin1String("o"), QLatin1String("upload"), QLatin1String("Upload screenshot via default uploader without opening in editor.")); } void CommandLine::addVersionOptions() { mVersionOption = addOption(QLatin1String("v"), QLatin1String("version"), QLatin1String("Displays version information.")); } QString CommandLine::translateText(const QString &text) { return QCoreApplication::translate("main", text.toLatin1()); } QCommandLineOption* CommandLine::addOption(const QString &shortName, const QString &longName, const QString &description) { auto newOption = new QCommandLineOption({shortName, longName}, translateText(description)); QCommandLineParser::addOption(*newOption); return newOption; } QCommandLineOption* CommandLine::addParameterOption(const QString &shortName, const QString &longName, const QString &description, const QString ¶meter) { auto newOption = new QCommandLineOption({shortName, longName}, translateText(description), translateText(parameter), QString()); QCommandLineParser::addOption(*newOption); return newOption; } bool CommandLine::isRectAreaSet() const { return mRectAreaOption != nullptr && isSet(*mRectAreaOption); } bool CommandLine::isLastRectAreaSet() const { return mLastRectAreaOption != nullptr && isSet(*mLastRectAreaOption); } bool CommandLine::isFullScreenSet() const { return mFullScreenOption != nullptr && isSet(*mFullScreenOption); } bool CommandLine::isCurrentScreenSet() const { return mCurrentScreenOption != nullptr && isSet(*mCurrentScreenOption); } bool CommandLine::isActiveWindowSet() const { return mActiveWindowOption != nullptr && isSet(*mActiveWindowOption); } bool CommandLine::isWindowsUnderCursorSet() const { return mWindowUnderCursorOption != nullptr && isSet(*mWindowUnderCursorOption); } bool CommandLine::isPortalSet() const { return mPortalOption != nullptr && isSet(*mPortalOption); } bool CommandLine::isDelaySet() const { return mDelayOption != nullptr && isSet(*mDelayOption); } bool CommandLine::isCursorSet() const { return mCursorOption != nullptr && isSet(*mCursorOption); } bool CommandLine::isEditSet() const { return (mEditOption != nullptr && isSet(*mEditOption)) || positionalArguments().count() == 1; } bool CommandLine::isSaveSet() const { return (mSaveOption != nullptr && isSet(*mSaveOption)) || (mSaveToOption != nullptr && isSet(*mSaveToOption)); } bool CommandLine::isVersionSet() const { return mVersionOption != nullptr && isSet(*mVersionOption); } int CommandLine::delay() const { auto valid = true; auto delay = value(*mDelayOption).toInt(&valid); return valid && delay >= 0 ? delay : -1; } QString CommandLine::imagePath() const { return positionalArguments().count() == 1 ? positionalArguments().first() : value(*mEditOption); } QString CommandLine::saveToPath() const { return value(*mSaveToOption); } bool CommandLine::isCaptureModeSet() const { return isRectAreaSet() || isLastRectAreaSet() || isFullScreenSet() || isCurrentScreenSet() || isActiveWindowSet() || isWindowsUnderCursorSet(); } bool CommandLine::isUploadSet() const { return mUploadOption != nullptr && isSet(*mUploadOption); } CaptureModes CommandLine::captureMode() const { if (isFullScreenSet()) { return CaptureModes::FullScreen; } else if (isCurrentScreenSet()) { return CaptureModes::CurrentScreen; } else if (isActiveWindowSet()) { return CaptureModes::ActiveWindow; } else if (isWindowsUnderCursorSet()) { return CaptureModes::WindowUnderCursor; } else if (isLastRectAreaSet()) { return CaptureModes::LastRectArea; } else if (isPortalSet()) { return CaptureModes::Portal; } else { return CaptureModes::RectArea; } } void CommandLine::addPositionalArguments() { addPositionalArgument(QLatin1String("image"), QLatin1String("Edit existing image in ksnip"), QLatin1String("[image]")); } ksnip-master/src/backend/commandLine/CommandLine.h000066400000000000000000000056431457262621600224610ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COMMANDLINE_H #define KSNIP_COMMANDLINE_H #include #include #include #include #include "src/common/enum/CaptureModes.h" class CommandLine : public QCommandLineParser { public: CommandLine(const QCoreApplication &app, const QList &captureModes); ~CommandLine(); bool isRectAreaSet() const; bool isLastRectAreaSet() const; bool isFullScreenSet() const; bool isCurrentScreenSet() const; bool isActiveWindowSet() const; bool isWindowsUnderCursorSet() const; bool isPortalSet() const; bool isDelaySet() const; bool isCursorSet() const; bool isEditSet() const; bool isSaveSet() const; bool isVersionSet() const; bool isCaptureModeSet() const; bool isUploadSet() const; int delay() const; QString imagePath() const; QString saveToPath() const; CaptureModes captureMode() const; private: QCommandLineOption *mRectAreaOption = nullptr; QCommandLineOption *mLastRectAreaOption = nullptr; QCommandLineOption *mFullScreenOption = nullptr; QCommandLineOption *mCurrentScreenOption = nullptr; QCommandLineOption *mActiveWindowOption = nullptr; QCommandLineOption *mWindowUnderCursorOption = nullptr; QCommandLineOption *mPortalOption = nullptr; QCommandLineOption *mDelayOption = nullptr; QCommandLineOption *mCursorOption = nullptr; QCommandLineOption *mEditOption = nullptr; QCommandLineOption *mSaveOption = nullptr; QCommandLineOption *mSaveToOption = nullptr; QCommandLineOption *mVersionOption = nullptr; QCommandLineOption *mUploadOption = nullptr; void addImageGrabberOptions(const QList &captureModes); void addDefaultOptions(); void addVersionOptions(); QString translateText(const QString &text); QCommandLineOption* addOption(const QString &shortName, const QString &longName, const QString &description); QCommandLineOption* addParameterOption(const QString &shortName, const QString &longName, const QString &description, const QString ¶meter); void addPositionalArguments(); }; #endif //KSNIP_COMMANDLINE_H ksnip-master/src/backend/commandLine/CommandLineCaptureHandler.cpp000066400000000000000000000061041457262621600256270ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CommandLineCaptureHandler.h" CommandLineCaptureHandler::CommandLineCaptureHandler( const QSharedPointer &imageGrabber, const QSharedPointer &uploadHandler, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider) : mImageGrabber(imageGrabber), mUploadHandler(uploadHandler), mImageSaver(imageSaver), mSavePathProvider(savePathProvider), mIsWithSave(false), mIsWithUpload(false) { connect(mImageGrabber.data(), &IImageGrabber::finished, this, &CommandLineCaptureHandler::processCapture); connect(mImageGrabber.data(), &IImageGrabber::canceled, this, &CommandLineCaptureHandler::canceled); connect(mUploadHandler.data(), &IUploader::finished, this, &CommandLineCaptureHandler::uploadFinished); } void CommandLineCaptureHandler::captureAndProcessScreenshot(const CommandLineCaptureParameter ¶meter) { mIsWithSave = parameter.isWithSave; mIsWithUpload = parameter.isWithUpload; mSavePath = parameter.savePath; mImageGrabber->grabImage(parameter.captureMode, parameter.isWithCursor, parameter.delay); } void CommandLineCaptureHandler::processCapture(const CaptureDto &capture) { mCurrentCapture = capture; if (mIsWithSave) { saveCapture(mCurrentCapture); } if (mIsWithUpload) { mUploadHandler->upload(capture.screenshot.toImage()); } else { finished(mCurrentCapture); } } void CommandLineCaptureHandler::saveCapture(const CaptureDto &capture) { auto savePath = mSavePath.isEmpty() ? mSavePathProvider->savePath() : mSavePath; auto isSaveSuccessful = mImageSaver->save(capture.screenshot.toImage(), savePath); if (isSaveSuccessful) { qInfo("Capture saved to %s", qPrintable(savePath)); } else { qWarning("Failed to save capture to %s", qPrintable(savePath)); } } QList CommandLineCaptureHandler::supportedCaptureModes() const { return mImageGrabber->supportedCaptureModes(); } void CommandLineCaptureHandler::uploadFinished(const UploadResult &result) { if (result.isError()) { auto enumTranslator = EnumTranslator::instance(); qWarning("Upload failed: %s", qPrintable(enumTranslator->toString(result.status))); } else { qInfo("Upload finished"); } if (result.hasContent()) { qInfo("Upload result: %s", qPrintable(result.content)); } finished(mCurrentCapture); } ksnip-master/src/backend/commandLine/CommandLineCaptureHandler.h000066400000000000000000000045031457262621600252750ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COMMANDLINECAPTUREHANDLER_H #define KSNIP_COMMANDLINECAPTUREHANDLER_H #include #include "ICommandLineCaptureHandler.h" #include "CommandLineCaptureParameter.h" #include "src/backend/imageGrabber/IImageGrabber.h" #include "src/backend/saver/IImageSaver.h" #include "src/backend/saver/ISavePathProvider.h" #include "src/backend/uploader/IUploadHandler.h" #include "src/common/dtos/CaptureFromFileDto.h" #include "src/common/helper/EnumTranslator.h" #include "src/dependencyInjector/DependencyInjector.h" class CommandLineCaptureHandler : public ICommandLineCaptureHandler { public: explicit CommandLineCaptureHandler( const QSharedPointer &imageGrabber, const QSharedPointer &uploadHandler, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider); ~CommandLineCaptureHandler() override = default; void captureAndProcessScreenshot(const CommandLineCaptureParameter ¶meter) override; QList supportedCaptureModes() const override; private: QSharedPointer mImageGrabber; QSharedPointer mUploadHandler; QSharedPointer mImageSaver; QSharedPointer mSavePathProvider; QString mSavePath; bool mIsWithSave; bool mIsWithUpload; CaptureDto mCurrentCapture; private slots: void processCapture(const CaptureDto &capture); void saveCapture(const CaptureDto &capture); void uploadFinished(const UploadResult &result); }; #endif //KSNIP_COMMANDLINECAPTUREHANDLER_H ksnip-master/src/backend/commandLine/CommandLineCaptureParameter.h000066400000000000000000000030131457262621600256330ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COMMANDLINECAPTUREPARAMETER_H #define KSNIP_COMMANDLINECAPTUREPARAMETER_H #include #include "src/common/enum/CaptureModes.h" struct CommandLineCaptureParameter { CaptureModes captureMode = CaptureModes::RectArea; int delay = 0; bool isWithCursor = false; bool isWithSave = false; bool isWithUpload = false; QString savePath = QString(); explicit CommandLineCaptureParameter() = default; explicit CommandLineCaptureParameter(CaptureModes captureMode, int delay, bool isWithCursor) { this->captureMode = captureMode; this->delay = delay; this->isWithCursor = isWithCursor; this->isWithSave = false; this->savePath = QString(); this->isWithUpload = false; } }; #endif //KSNIP_COMMANDLINECAPTUREPARAMETER_H ksnip-master/src/backend/commandLine/ICommandLineCaptureHandler.h000066400000000000000000000026661457262621600254160ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICOMMANDLINECAPTUREHANDLER_H #define KSNIP_ICOMMANDLINECAPTUREHANDLER_H #include #include "src/common/enum/CaptureModes.h" struct CommandLineCaptureParameter; struct CaptureDto; class ICommandLineCaptureHandler : public QObject { Q_OBJECT public: explicit ICommandLineCaptureHandler() = default; ~ICommandLineCaptureHandler() override = default; virtual void captureAndProcessScreenshot(const CommandLineCaptureParameter ¶meter) = 0; virtual QList supportedCaptureModes() const = 0; signals: void finished(const CaptureDto &captureDto); void canceled(); }; #endif //KSNIP_ICOMMANDLINECAPTUREHANDLER_H ksnip-master/src/backend/config/000077500000000000000000000000001457262621600171315ustar00rootroot00000000000000ksnip-master/src/backend/config/Config.cpp000066400000000000000000001127341457262621600210520ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "Config.h" Config::Config(const QSharedPointer &directoryPathProvider) : mDirectoryPathProvider(directoryPathProvider) { } // Application bool Config::rememberPosition() const { return loadValue(ConfigOptions::rememberPositionString(), true).toBool(); } void Config::setRememberPosition(bool enabled) { if (rememberPosition() == enabled) { return; } saveValue(ConfigOptions::rememberPositionString(), enabled); } bool Config::promptSaveBeforeExit() const { return loadValue(ConfigOptions::promptSaveBeforeExitString(), true).toBool(); } void Config::setPromptSaveBeforeExit(bool enabled) { if (promptSaveBeforeExit() == enabled) { return; } saveValue(ConfigOptions::promptSaveBeforeExitString(), enabled); } bool Config::autoCopyToClipboardNewCaptures() const { return loadValue(ConfigOptions::autoCopyToClipboardNewCapturesString(), false).toBool(); } void Config::setAutoCopyToClipboardNewCaptures(bool enabled) { if (autoCopyToClipboardNewCaptures() == enabled) { return; } saveValue(ConfigOptions::autoCopyToClipboardNewCapturesString(), enabled); } bool Config::autoSaveNewCaptures() const { return loadValue(ConfigOptions::autoSaveNewCapturesString(), false).toBool(); } void Config::setAutoSaveNewCaptures(bool enabled) { if (autoSaveNewCaptures() == enabled) { return; } saveValue(ConfigOptions::autoSaveNewCapturesString(), enabled); } bool Config::autoHideDocks() const { return loadValue(ConfigOptions::autoHideDocksString(), false).toBool(); } void Config::setAutoHideDocks(bool enabled) { if (autoHideDocks() == enabled) { return; } saveValue(ConfigOptions::autoHideDocksString(), enabled); } bool Config::autoResizeToContent() const { return loadValue(ConfigOptions::autoResizeToContentString(), true).toBool(); } void Config::setAutoResizeToContent(bool enabled) { if (autoResizeToContent() == enabled) { return; } saveValue(ConfigOptions::autoResizeToContentString(), enabled); } int Config::resizeToContentDelay() const { return loadValue(ConfigOptions::resizeToContentDelayString(), 10).toInt(); } void Config::setResizeToContentDelay(int ms) { if (resizeToContentDelay() == ms) { return; } saveValue(ConfigOptions::resizeToContentDelayString(), ms); } bool Config::overwriteFile() const { return loadValue(ConfigOptions::overwriteFileEnabledString(), false).toBool(); } void Config::setOverwriteFile(bool enabled) { if (overwriteFile() == enabled) { return; } saveValue(ConfigOptions::overwriteFileEnabledString(), enabled); } bool Config::useTabs() const { return loadValue(ConfigOptions::useTabsString(), true).toBool(); } void Config::setUseTabs(bool enabled) { if (useTabs() == enabled) { return; } saveValue(ConfigOptions::useTabsString(), enabled); emit annotatorConfigChanged(); } bool Config::autoHideTabs() const { return loadValue(ConfigOptions::autoHideTabsString(), false).toBool(); } void Config::setAutoHideTabs(bool enabled) { if (autoHideTabs() == enabled) { return; } saveValue(ConfigOptions::autoHideTabsString(), enabled); emit annotatorConfigChanged(); } bool Config::captureOnStartup() const { return loadValue(ConfigOptions::captureOnStartupString(), false).toBool(); } void Config::setCaptureOnStartup(bool enabled) { if (captureOnStartup() == enabled) { return; } saveValue(ConfigOptions::captureOnStartupString(), enabled); } QPoint Config::windowPosition() const { // If we are not saving the position we return the default and ignore what // has been save earlier if (!rememberPosition()) { return { 200, 200 }; } auto defaultPosition = QPoint(200, 200); return loadValue(ConfigOptions::positionString(), defaultPosition).value(); } void Config::setWindowPosition(const QPoint& position) { if (windowPosition() == position) { return; } saveValue(ConfigOptions::positionString(), position); } CaptureModes Config::captureMode() const { // If we are not storing the tool selection, always return the rect area as default if (!rememberToolSelection()) { return CaptureModes::RectArea; } return loadValue(ConfigOptions::captureModeString(), (int)CaptureModes::RectArea).value(); } void Config::setCaptureMode(CaptureModes mode) { if (captureMode() == mode) { return; } saveValue(ConfigOptions::captureModeString(), static_cast(mode)); } QString Config::saveDirectory() const { auto saveDirectoryString = loadValue(ConfigOptions::saveDirectoryString(), mDirectoryPathProvider->home()).toString(); if (!saveDirectoryString.isEmpty()) { return saveDirectoryString + QLatin1String("/"); } else { return {}; } } void Config::setSaveDirectory(const QString& path) { if (saveDirectory() == path) { return; } saveValue(ConfigOptions::saveDirectoryString(), path); } QString Config::saveFilename() const { auto defaultFilename = QLatin1String("ksnip_$Y$M$D-$T"); auto filename = loadValue(ConfigOptions::saveFilenameString(), defaultFilename).toString(); if (filename.isEmpty() || filename.isNull()) { filename = defaultFilename; } return filename; } void Config::setSaveFilename(const QString& filename) { if (saveFilename() == filename) { return; } saveValue(ConfigOptions::saveFilenameString(), filename); } QString Config::saveFormat() const { auto defaultFormat = QLatin1String("png"); auto format = loadValue(ConfigOptions::saveFormatString(), defaultFormat).toString(); if (format.isEmpty() || format.isNull()) { format = defaultFormat; } return format; } void Config::setSaveFormat(const QString& format) { if (saveFormat() == format) { return; } saveValue(ConfigOptions::saveFormatString(), format); } QString Config::applicationStyle() const { auto defaultStyle = QLatin1String("Fusion"); return loadValue(ConfigOptions::applicationStyleString(), defaultStyle).toString(); } void Config::setApplicationStyle(const QString &style) { if (applicationStyle() == style) { return; } saveValue(ConfigOptions::applicationStyleString(), style); } TrayIconDefaultActionMode Config::defaultTrayIconActionMode() const { return loadValue(ConfigOptions::trayIconDefaultActionModeString(), (int)TrayIconDefaultActionMode::ShowEditor).value(); } void Config::setDefaultTrayIconActionMode(TrayIconDefaultActionMode mode) { if (defaultTrayIconActionMode() == mode) { return; } saveValue(ConfigOptions::trayIconDefaultActionModeString(), static_cast(mode)); } CaptureModes Config::defaultTrayIconCaptureMode() const { return loadValue(ConfigOptions::trayIconDefaultCaptureModeString(), (int)CaptureModes::RectArea).value(); } void Config::setDefaultTrayIconCaptureMode(CaptureModes mode) { if (defaultTrayIconCaptureMode() == mode) { return; } saveValue(ConfigOptions::trayIconDefaultCaptureModeString(), static_cast(mode)); } bool Config::useTrayIcon() const { return loadValue(ConfigOptions::useTrayIconString(), true).toBool(); } void Config::setUseTrayIcon(bool enabled) { if (useTrayIcon() == enabled) { return; } saveValue(ConfigOptions::useTrayIconString(), enabled); } bool Config::minimizeToTray() const { return loadValue(ConfigOptions::minimizeToTrayString(), true).toBool(); } void Config::setMinimizeToTray(bool enabled) { if (minimizeToTray() == enabled) { return; } saveValue(ConfigOptions::minimizeToTrayString(), enabled); } bool Config::closeToTray() const { return loadValue(ConfigOptions::closeToTrayString(), true).toBool(); } void Config::setCloseToTray(bool enabled) { if (closeToTray() == enabled) { return; } saveValue(ConfigOptions::closeToTrayString(), enabled); } bool Config::trayIconNotificationsEnabled() const { return loadValue(ConfigOptions::trayIconNotificationsEnabledString(), true).toBool(); } void Config::setTrayIconNotificationsEnabled(bool enabled) { if (trayIconNotificationsEnabled() == enabled) { return; } saveValue(ConfigOptions::trayIconNotificationsEnabledString(), enabled); } bool Config::platformSpecificNotificationServiceEnabled() const { return loadValue(ConfigOptions::platformSpecificNotificationServiceEnabledString(), true).toBool(); } void Config::setPlatformSpecificNotificationServiceEnabled(bool enabled) { if (platformSpecificNotificationServiceEnabled() == enabled) { return; } saveValue(ConfigOptions::platformSpecificNotificationServiceEnabledString(), enabled); } bool Config::startMinimizedToTray() const { return loadValue(ConfigOptions::startMinimizedToTrayString(), false).toBool(); } void Config::setStartMinimizedToTray(bool enabled) { if (startMinimizedToTray() == enabled) { return; } saveValue(ConfigOptions::startMinimizedToTrayString(), enabled); } bool Config::rememberLastSaveDirectory() const { return loadValue(ConfigOptions::rememberLastSaveDirectoryString(), false).toBool(); } void Config::setRememberLastSaveDirectory(bool enabled) { if (rememberLastSaveDirectory() == enabled) { return; } saveValue(ConfigOptions::rememberLastSaveDirectoryString(), enabled); } bool Config::useSingleInstance() const { return loadValue(ConfigOptions::useSingleInstanceString(), true).toBool(); } void Config::setUseSingleInstance(bool enabled) { if (useSingleInstance() == enabled) { return; } saveValue(ConfigOptions::useSingleInstanceString(), enabled); } bool Config::hideMainWindowDuringScreenshot() const { return loadValue(ConfigOptions::hideMainWindowDuringScreenshotString(), true).toBool(); } void Config::setHideMainWindowDuringScreenshot(bool enabled) { if (hideMainWindowDuringScreenshot() == enabled) { return; } saveValue(ConfigOptions::hideMainWindowDuringScreenshotString(), enabled); } bool Config::allowResizingRectSelection() const { return loadValue(ConfigOptions::allowResizingRectSelectionString(), false).toBool(); } void Config::setAllowResizingRectSelection(bool enabled) { if (allowResizingRectSelection() == enabled) { return; } saveValue(ConfigOptions::allowResizingRectSelectionString(), enabled); } bool Config::showSnippingAreaInfoText() const { return loadValue(ConfigOptions::showSnippingAreaInfoTextString(), true).toBool(); } void Config::setShowSnippingAreaInfoText(bool enabled) { if (showSnippingAreaInfoText() == enabled) { return; } saveValue(ConfigOptions::showSnippingAreaInfoTextString(), enabled); } bool Config::snippingAreaOffsetEnable() const { return loadValue(ConfigOptions::snippingAreaOffsetEnableString(), false).toBool(); } void Config::setSnippingAreaOffsetEnable(bool enabled) { if (snippingAreaOffsetEnable() == enabled) { return; } saveValue(ConfigOptions::snippingAreaOffsetEnableString(), enabled); emit snippingAreaChangedChanged(); } QPointF Config::snippingAreaOffset() const { return loadValue(ConfigOptions::snippingAreaOffsetString(), QPointF(0, 0)).value(); } void Config::setSnippingAreaOffset(const QPointF &offset) { if (snippingAreaOffset() == offset) { return; } saveValue(ConfigOptions::snippingAreaOffsetString(), offset); emit snippingAreaChangedChanged(); } int Config::implicitCaptureDelay() const { return loadValue(ConfigOptions::implicitCaptureDelayString(), 200).value(); } void Config::setImplicitCaptureDelay(int delay) { if (implicitCaptureDelay() == delay) { return; } saveValue(ConfigOptions::implicitCaptureDelayString(), delay); emit delayChanged(); } SaveQualityMode Config::saveQualityMode() const { return loadValue(ConfigOptions::saveQualityModeString(), (int)SaveQualityMode::Default).value(); } void Config::setSaveQualityMode(SaveQualityMode mode) { if (saveQualityMode() == mode) { return; } saveValue(ConfigOptions::saveQualityModeString(), static_cast(mode)); } int Config::saveQualityFactor() const { return loadValue(ConfigOptions::saveQualityFactorString(), 50).toInt(); } void Config::setSaveQualityFactor(int factor) { if (saveQualityFactor() == factor) { return; } saveValue(ConfigOptions::saveQualityFactorString(), factor); } bool Config::isDebugEnabled() const { return loadValue(ConfigOptions::isDebugEnabledString(), false).toBool(); } void Config::setIsDebugEnabled(bool enabled) { if (isDebugEnabled() == enabled) { return; } saveValue(ConfigOptions::isDebugEnabledString(), enabled); } QString Config::tempDirectory() const { return loadValue(ConfigOptions::tempDirectoryString(), QDir::tempPath()).toString(); } void Config::setTempDirectory(const QString& path) { if (tempDirectory() == path) { return; } saveValue(ConfigOptions::tempDirectoryString(), path); } // Annotator bool Config::rememberToolSelection() const { return loadValue(ConfigOptions::rememberToolSelectionString(), true).toBool(); } void Config::setRememberToolSelection(bool enabled) { if (rememberToolSelection() == enabled) { return; } saveValue(ConfigOptions::rememberToolSelectionString(), enabled); } bool Config::switchToSelectToolAfterDrawingItem() const { return loadValue(ConfigOptions::switchToSelectToolAfterDrawingItemString(), false).toBool(); } void Config::setSwitchToSelectToolAfterDrawingItem(bool enabled) { if (switchToSelectToolAfterDrawingItem() == enabled) { return; } saveValue(ConfigOptions::switchToSelectToolAfterDrawingItemString(), enabled); emit annotatorConfigChanged(); } bool Config::selectItemAfterDrawing() const { return loadValue(ConfigOptions::selectItemAfterDrawingString(), true).toBool(); } void Config::setSelectItemAfterDrawing(bool enabled) { if (selectItemAfterDrawing() == enabled) { return; } saveValue(ConfigOptions::selectItemAfterDrawingString(), enabled); emit annotatorConfigChanged(); } bool Config::numberToolSeedChangeUpdatesAllItems() const { return loadValue(ConfigOptions::numberToolSeedChangeUpdatesAllItemsString(), true).toBool(); } void Config::setNumberToolSeedChangeUpdatesAllItems(bool enabled) { if (numberToolSeedChangeUpdatesAllItems() == enabled) { return; } saveValue(ConfigOptions::numberToolSeedChangeUpdatesAllItemsString(), enabled); emit annotatorConfigChanged(); } bool Config::smoothPathEnabled() const { return loadValue(ConfigOptions::smoothPathEnabledString(), true).toBool(); } void Config::setSmoothPathEnabled(bool enabled) { if (smoothPathEnabled() == enabled) { return; } saveValue(ConfigOptions::smoothPathEnabledString(), enabled); emit annotatorConfigChanged(); } int Config::smoothFactor() const { return loadValue(ConfigOptions::smoothPathFactorString(), 7).toInt(); } void Config::setSmoothFactor(int factor) { if (smoothFactor() == factor) { return; } saveValue(ConfigOptions::smoothPathFactorString(), factor); emit annotatorConfigChanged(); } bool Config::rotateWatermarkEnabled() const { return loadValue(ConfigOptions::rotateWatermarkEnabledString(), true).toBool(); } void Config::setRotateWatermarkEnabled(bool enabled) { if (rotateWatermarkEnabled() == enabled) { return; } saveValue(ConfigOptions::rotateWatermarkEnabledString(), enabled); } QStringList Config::stickerPaths() const { return loadValue(ConfigOptions::stickerPathsString(), QVariant::fromValue(QStringList())).value(); } void Config::setStickerPaths(const QStringList &paths) { if (stickerPaths() == paths) { return; } saveValue(ConfigOptions::stickerPathsString(), QVariant::fromValue(paths)); emit annotatorConfigChanged(); } bool Config::useDefaultSticker() const { return loadValue(ConfigOptions::useDefaultStickerString(), true).toBool(); } void Config::setUseDefaultSticker(bool enabled) { if (useDefaultSticker() == enabled) { return; } saveValue(ConfigOptions::useDefaultStickerString(), enabled); emit annotatorConfigChanged(); } QColor Config::canvasColor() const { return loadValue(ConfigOptions::canvasColorString(), QColor(Qt::white)).value(); } void Config::setCanvasColor(const QColor &color) { if (canvasColor() == color) { return; } saveValue(ConfigOptions::canvasColorString(), color); emit annotatorConfigChanged(); } bool Config::isControlsWidgetVisible() const { return loadValue(ConfigOptions::isControlsWidgetVisibleString(), false).toBool(); } void Config::setIsControlsWidgetVisible(bool isVisible) { if (isControlsWidgetVisible() == isVisible) { return; } saveValue(ConfigOptions::isControlsWidgetVisibleString(), isVisible); emit annotatorConfigChanged(); } // Image Grabber bool Config::isFreezeImageWhileSnippingEnabledReadOnly() const { return false; } bool Config::freezeImageWhileSnippingEnabled() const { return loadValue(ConfigOptions::freezeImageWhileSnippingEnabledString(), true).toBool(); } void Config::setFreezeImageWhileSnippingEnabled(bool enabled) { if (freezeImageWhileSnippingEnabled() == enabled) { return; } saveValue(ConfigOptions::freezeImageWhileSnippingEnabledString(), enabled); } bool Config::captureCursor() const { return loadValue(ConfigOptions::captureCursorString(), true).toBool(); } void Config::setCaptureCursor(bool enabled) { if (captureCursor() == enabled) { return; } saveValue(ConfigOptions::captureCursorString(), enabled); } bool Config::snippingAreaRulersEnabled() const { return loadValue(ConfigOptions::snippingAreaRulersEnabledString(), true).toBool(); } void Config::setSnippingAreaRulersEnabled(bool enabled) { if (snippingAreaRulersEnabled() == enabled) { return; } saveValue(ConfigOptions::snippingAreaRulersEnabledString(), enabled); } bool Config::snippingAreaPositionAndSizeInfoEnabled() const { return loadValue(ConfigOptions::snippingAreaPositionAndSizeInfoEnabledString(), true).toBool(); } void Config::setSnippingAreaPositionAndSizeInfoEnabled(bool enabled) { if (snippingAreaPositionAndSizeInfoEnabled() == enabled) { return; } saveValue(ConfigOptions::snippingAreaPositionAndSizeInfoEnabledString(), enabled); } bool Config::showMainWindowAfterTakingScreenshotEnabled() const { return loadValue(ConfigOptions::showMainWindowAfterTakingScreenshotEnabledString(), true).toBool(); } void Config::setShowMainWindowAfterTakingScreenshotEnabled(bool enabled) { if (showMainWindowAfterTakingScreenshotEnabled() == enabled) { return; } saveValue(ConfigOptions::showMainWindowAfterTakingScreenshotEnabledString(), enabled); } bool Config::isSnippingAreaMagnifyingGlassEnabledReadOnly() const { return false; } bool Config::snippingAreaMagnifyingGlassEnabled() const { return loadValue(ConfigOptions::snippingAreaMagnifyingGlassEnabledString(), true).toBool(); } void Config::setSnippingAreaMagnifyingGlassEnabled(bool enabled) { if (snippingAreaMagnifyingGlassEnabled() == enabled) { return; } saveValue(ConfigOptions::snippingAreaMagnifyingGlassEnabledString(), enabled); } int Config::captureDelay() const { return loadValue(ConfigOptions::captureDelayString(), 0).toInt(); } void Config::setCaptureDelay(int delay) { if (captureDelay() == delay) { return; } saveValue(ConfigOptions::captureDelayString(), delay); } int Config::snippingCursorSize() const { return loadValue(ConfigOptions::snippingCursorSizeString(), 1).toInt(); } void Config::setSnippingCursorSize(int size) { if (snippingCursorSize() == size) { return; } saveValue(ConfigOptions::snippingCursorSizeString(), size); } QColor Config::snippingCursorColor() const { auto defaultColor = QColor(27, 20, 77); return loadValue(ConfigOptions::snippingCursorColorString(), defaultColor).value(); } void Config::setSnippingCursorColor(const QColor& color) { if (snippingCursorColor() == color) { return; } saveValue(ConfigOptions::snippingCursorColorString(), color); } QColor Config::snippingAdornerColor() const { return loadValue(ConfigOptions::snippingAdornerColorString(), QColor(Qt::red)).value(); } void Config::setSnippingAdornerColor(const QColor& color) { if (snippingAdornerColor() == color) { return; } saveValue(ConfigOptions::snippingAdornerColorString(), color); } int Config::snippingAreaTransparency() const { return loadValue(ConfigOptions::snippingAreaTransparencyString(), 150).value(); } void Config::setSnippingAreaTransparency(int transparency) { if (snippingAreaTransparency() == transparency) { return; } saveValue(ConfigOptions::snippingAreaTransparencyString(), transparency); } QRect Config::lastRectArea() const { return loadValue(ConfigOptions::lastRectAreaString(), QRect()).value(); } void Config::setLastRectArea(const QRect &rectArea) { if (lastRectArea() == rectArea) { return; } saveValue(ConfigOptions::lastRectAreaString(), rectArea); } bool Config::isForceGenericWaylandEnabledReadOnly() const { return true; } bool Config::forceGenericWaylandEnabled() const { return loadValue(ConfigOptions::forceGenericWaylandEnabledString(), false).toBool(); } void Config::setForceGenericWaylandEnabled(bool enabled) { if (forceGenericWaylandEnabled() == enabled) { return; } saveValue(ConfigOptions::forceGenericWaylandEnabledString(), enabled); } bool Config::isScaleGenericWaylandScreenshotEnabledReadOnly() const { return true; } bool Config::scaleGenericWaylandScreenshotsEnabled() const { return loadValue(ConfigOptions::scaleWaylandScreenshotsEnabledString(), false).toBool(); } void Config::setScaleGenericWaylandScreenshots(bool enabled) { if (scaleGenericWaylandScreenshotsEnabled() == enabled) { return; } saveValue(ConfigOptions::scaleWaylandScreenshotsEnabledString(), enabled); } // Uploader bool Config::confirmBeforeUpload() const { return loadValue(ConfigOptions::confirmBeforeUploadString(), true).toBool(); } void Config::setConfirmBeforeUpload(bool enabled) { if (confirmBeforeUpload() == enabled) { return; } saveValue(ConfigOptions::confirmBeforeUploadString(), enabled); } UploaderType Config::uploaderType() const { return loadValue(ConfigOptions::uploaderTypeString(), static_cast(UploaderType::Imgur)).value(); } void Config::setUploaderType(UploaderType type) { if (uploaderType() == type) { return; } saveValue(ConfigOptions::uploaderTypeString(), static_cast(type)); } // Imgur Uploader QString Config::imgurUsername() const { auto defaultUsername = QLatin1String(""); return loadValue(ConfigOptions::imgurUsernameString(), defaultUsername).toString(); } void Config::setImgurUsername(const QString& username) { if (imgurUsername() == username) { return; } saveValue(ConfigOptions::imgurUsernameString(), username); } QByteArray Config::imgurClientId() const { auto defaultClientId = QLatin1String(""); return loadValue(ConfigOptions::imgurClientIdString(), defaultClientId).toByteArray(); } void Config::setImgurClientId(const QString& clientId) { if (imgurClientId() == clientId) { return; } saveValue(ConfigOptions::imgurClientIdString(), clientId); } QByteArray Config::imgurClientSecret() const { auto defaultClientSecret = QLatin1String(""); return loadValue(ConfigOptions::imgurClientSecretString(), defaultClientSecret).toByteArray(); } void Config::setImgurClientSecret(const QString& clientSecret) { if (imgurClientSecret() == clientSecret) { return; } saveValue(ConfigOptions::imgurClientSecretString(), clientSecret); } QByteArray Config::imgurAccessToken() const { auto defaultAccessToken = QLatin1String(""); return loadValue(ConfigOptions::imgurAccessTokenString(), defaultAccessToken).toByteArray(); } void Config::setImgurAccessToken(const QString& accessToken) { if (imgurAccessToken() == accessToken) { return; } saveValue(ConfigOptions::imgurAccessTokenString(), accessToken); } QByteArray Config::imgurRefreshToken() const { auto defaultRefreshToken = QLatin1String(""); return loadValue(ConfigOptions::imgurRefreshTokenString(), defaultRefreshToken).toByteArray(); } void Config::setImgurRefreshToken(const QString& refreshToken) { if (imgurRefreshToken() == refreshToken) { return; } saveValue(ConfigOptions::imgurRefreshTokenString(), refreshToken); } bool Config::imgurForceAnonymous() const { return loadValue(ConfigOptions::imgurForceAnonymousString(), false).toBool(); } void Config::setImgurForceAnonymous(bool enabled) { if (imgurForceAnonymous() == enabled) { return; } saveValue(ConfigOptions::imgurForceAnonymousString(), enabled); } bool Config::imgurLinkDirectlyToImage() const { return loadValue(ConfigOptions::imgurLinkDirectlyToImageString(), false).toBool(); } void Config::setImgurLinkDirectlyToImage(bool enabled) { if (imgurLinkDirectlyToImage() == enabled) { return; } saveValue(ConfigOptions::imgurLinkDirectlyToImageString(), enabled); } bool Config::imgurAlwaysCopyToClipboard() const { return loadValue(ConfigOptions::imgurAlwaysCopyToClipboardString(), false).toBool(); } void Config::setImgurAlwaysCopyToClipboard(bool enabled) { if (imgurAlwaysCopyToClipboard() == enabled) { return; } saveValue(ConfigOptions::imgurAlwaysCopyToClipboardString(), enabled); } bool Config::imgurOpenLinkInBrowser() const { return loadValue(ConfigOptions::imgurOpenLinkInBrowserString(), true).toBool(); } void Config::setImgurOpenLinkInBrowser(bool enabled) { if (imgurOpenLinkInBrowser() == enabled) { return; } saveValue(ConfigOptions::imgurOpenLinkInBrowserString(), enabled); } QString Config::imgurUploadTitle() const { return loadValue(ConfigOptions::imgurUploadTitleString(), DefaultValues::ImgurUploadTitle).toString(); } void Config::setImgurUploadTitle(const QString &uploadTitle) { if (imgurUploadTitle() == uploadTitle) { return; } saveValue(ConfigOptions::imgurUploadTitleString(), uploadTitle); } QString Config::imgurUploadDescription() const { return loadValue(ConfigOptions::imgurUploadDescriptionString(), DefaultValues::ImgurUploadDescription).toString(); } void Config::setImgurUploadDescription(const QString &uploadDescription) { if (imgurUploadDescription() == uploadDescription) { return; } saveValue(ConfigOptions::imgurUploadDescriptionString(), uploadDescription); } QString Config::imgurBaseUrl() const { return loadValue(ConfigOptions::imgurBaseUrlString(), DefaultValues::ImgurBaseUrl).toString(); } void Config::setImgurBaseUrl(const QString &baseUrl) { if (imgurBaseUrl() == baseUrl) { return; } saveValue(ConfigOptions::imgurBaseUrlString(), baseUrl); } // Script Uploader QString Config::uploadScriptPath() const { return loadValue(ConfigOptions::uploadScriptPathString(), QString()).toString(); } void Config::setUploadScriptPath(const QString &path) { if (uploadScriptPath() == path) { return; } saveValue(ConfigOptions::uploadScriptPathString(), path); } bool Config::uploadScriptCopyOutputToClipboard() const { return loadValue(ConfigOptions::uploadScriptCopyOutputToClipboardString(), false).toBool(); } void Config::setUploadScriptCopyOutputToClipboard(bool enabled) { if (uploadScriptCopyOutputToClipboard() == enabled) { return; } saveValue(ConfigOptions::uploadScriptCopyOutputToClipboardString(), enabled); } QString Config::uploadScriptCopyOutputFilter() const { return loadValue(ConfigOptions::uploadScriptCopyOutputFilterString(), QString()).toString(); } void Config::setUploadScriptCopyOutputFilter(const QString ®ex) { if (uploadScriptCopyOutputFilter() == regex) { return; } saveValue(ConfigOptions::uploadScriptCopyOutputFilterString(), regex); } bool Config::uploadScriptStopOnStdErr() const { return loadValue(ConfigOptions::uploadScriptStopOnStdErrString(), true).toBool(); } void Config::setUploadScriptStopOnStdErr(bool enabled) { if (uploadScriptStopOnStdErr() == enabled) { return; } saveValue(ConfigOptions::uploadScriptStopOnStdErrString(), enabled); } // FTP Uploader bool Config::ftpUploadForceAnonymous() const { return loadValue(ConfigOptions::ftpUploadForceAnonymousString(), false).toBool(); } void Config::setFtpUploadForceAnonymous(bool enabled) { if (ftpUploadForceAnonymous() == enabled) { return; } saveValue(ConfigOptions::ftpUploadForceAnonymousString(), enabled); } QString Config::ftpUploadUrl() const { return loadValue(ConfigOptions::ftpUploadUrlString(), QString()).toString(); } void Config::setFtpUploadUrl(const QString &path) { if (ftpUploadUrl() == path) { return; } saveValue(ConfigOptions::ftpUploadUrlString(), path); } QString Config::ftpUploadUsername() const { return loadValue(ConfigOptions::ftpUploadUsernameString(), QString()).toString(); } void Config::setFtpUploadUsername(const QString &username) { if (ftpUploadUsername() == username) { return; } saveValue(ConfigOptions::ftpUploadUsernameString(), username); } QString Config::ftpUploadPassword() const { return loadValue(ConfigOptions::ftpUploadPasswordString(), QString()).toString(); } void Config::setFtpUploadPassword(const QString &password) { if (ftpUploadPassword() == password) { return; } saveValue(ConfigOptions::ftpUploadPasswordString(), password); } // HotKeys bool Config::isGlobalHotKeysEnabledReadOnly() const { return false; } bool Config::globalHotKeysEnabled() const { return loadValue(ConfigOptions::globalHotKeysEnabledString(), true).toBool(); } void Config::setGlobalHotKeysEnabled(bool enabled) { if (globalHotKeysEnabled() == enabled) { return; } saveValue(ConfigOptions::globalHotKeysEnabledString(), enabled); emit hotKeysChanged(); } QKeySequence Config::rectAreaHotKey() const { return loadValue(ConfigOptions::rectAreaHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_R)).value(); } void Config::setRectAreaHotKey(const QKeySequence &keySequence) { if (rectAreaHotKey() == keySequence) { return; } saveValue(ConfigOptions::rectAreaHotKeyString(), keySequence); emit hotKeysChanged(); } QKeySequence Config::lastRectAreaHotKey() const { return loadValue(ConfigOptions::lastRectAreaHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_L)).value(); } void Config::setLastRectAreaHotKey(const QKeySequence &keySequence) { if (lastRectAreaHotKey() == keySequence) { return; } saveValue(ConfigOptions::lastRectAreaHotKeyString(), keySequence); emit hotKeysChanged(); } QKeySequence Config::fullScreenHotKey() const { return loadValue(ConfigOptions::fullScreenHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_F)).value(); } void Config::setFullScreenHotKey(const QKeySequence &keySequence) { if (fullScreenHotKey() == keySequence) { return; } saveValue(ConfigOptions::fullScreenHotKeyString(), keySequence); emit hotKeysChanged(); } QKeySequence Config::currentScreenHotKey() const { return loadValue(ConfigOptions::currentScreenHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_C)).value(); } void Config::setCurrentScreenHotKey(const QKeySequence &keySequence) { if (currentScreenHotKey() == keySequence) { return; } saveValue(ConfigOptions::currentScreenHotKeyString(), keySequence); emit hotKeysChanged(); } QKeySequence Config::activeWindowHotKey() const { return loadValue(ConfigOptions::activeWindowHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_A)).value(); } void Config::setActiveWindowHotKey(const QKeySequence &keySequence) { if (activeWindowHotKey() == keySequence) { return; } saveValue(ConfigOptions::activeWindowHotKeyString(), keySequence); emit hotKeysChanged(); } QKeySequence Config::windowUnderCursorHotKey() const { return loadValue(ConfigOptions::windowUnderCursorHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_U)).value(); } void Config::setWindowUnderCursorHotKey(const QKeySequence &keySequence) { if (windowUnderCursorHotKey() == keySequence) { return; } saveValue(ConfigOptions::windowUnderCursorHotKeyString(), keySequence); emit hotKeysChanged(); } QKeySequence Config::portalHotKey() const { return loadValue(ConfigOptions::portalHotKeyString(), QKeySequence(Qt::ALT + Qt::SHIFT + Qt::Key_T)).value(); } void Config::setPortalHotKey(const QKeySequence &keySequence) { if (portalHotKey() == keySequence) { return; } saveValue(ConfigOptions::portalHotKeyString(), keySequence); emit hotKeysChanged(); } // Actions QList Config::actions() { QList actions; auto count = mConfig.beginReadArray(ConfigOptions::actionsString()); for (auto index = 0; index < count; index++) { mConfig.setArrayIndex(index); Action action; action.setName(mConfig.value(ConfigOptions::actionNameString()).toString()); action.setShortcut(mConfig.value(ConfigOptions::actionShortcutString()).value()); action.setIsGlobalShortcut(mConfig.value(ConfigOptions::actionShortcutIsGlobalString(), true).value()); action.setIsCaptureEnabled(mConfig.value(ConfigOptions::actionIsCaptureEnabledString()).toBool()); action.setIncludeCursor(mConfig.value(ConfigOptions::actionIncludeCursorString()).toBool()); action.setCaptureDelay(mConfig.value(ConfigOptions::actionCaptureDelayString()).toInt()); action.setCaptureMode(mConfig.value(ConfigOptions::actionCaptureModeString()).value()); action.setIsPinImageEnabled(mConfig.value(ConfigOptions::actionIsPinImageEnabledString()).toBool()); action.setIsUploadEnabled(mConfig.value(ConfigOptions::actionIsUploadEnabledString()).toBool()); action.setIsOpenDirectoryEnabled(mConfig.value(ConfigOptions::actionIsOpenDirectoryEnabledString()).toBool()); action.setIsCopyToClipboardEnabled(mConfig.value(ConfigOptions::actionIsCopyToClipboardEnabledString()).toBool()); action.setIsSaveEnabled(mConfig.value(ConfigOptions::actionIsSaveEnabledString()).toBool()); action.setIsHideMainWindowEnabled(mConfig.value(ConfigOptions::actionIsHideMainWindowEnabledString()).toBool()); actions.append(action); } mConfig.endArray(); return actions; } void Config::setActions(const QList &actions) { auto savedActions = this->actions(); if(savedActions == actions) { return; } mConfig.remove(ConfigOptions::actionsString()); auto count = actions.count(); mConfig.beginWriteArray(ConfigOptions::actionsString()); for (auto index = 0; index < count; ++index) { const auto& action = actions.at(index); mConfig.setArrayIndex(index); mConfig.setValue(ConfigOptions::actionNameString(), action.name()); mConfig.setValue(ConfigOptions::actionShortcutString(), action.shortcut()); mConfig.setValue(ConfigOptions::actionShortcutIsGlobalString(), action.isGlobalShortcut()); mConfig.setValue(ConfigOptions::actionIsCaptureEnabledString(), action.isCaptureEnabled()); mConfig.setValue(ConfigOptions::actionIncludeCursorString(), action.includeCursor()); mConfig.setValue(ConfigOptions::actionCaptureDelayString(), action.captureDelay()); mConfig.setValue(ConfigOptions::actionCaptureModeString(), static_cast(action.captureMode())); mConfig.setValue(ConfigOptions::actionIsPinImageEnabledString(), action.isPinImageEnabled()); mConfig.setValue(ConfigOptions::actionIsUploadEnabledString(), action.isUploadEnabled()); mConfig.setValue(ConfigOptions::actionIsOpenDirectoryEnabledString(), action.isOpenDirectoryEnabled()); mConfig.setValue(ConfigOptions::actionIsCopyToClipboardEnabledString(), action.isCopyToClipboardEnabled()); mConfig.setValue(ConfigOptions::actionIsSaveEnabledString(), action.isSaveEnabled()); mConfig.setValue(ConfigOptions::actionIsHideMainWindowEnabledString(), action.isHideMainWindowEnabled()); } mConfig.endArray(); emit actionsChanged(); emit hotKeysChanged(); } QString Config::pluginPath() const { return loadValue(ConfigOptions::pluginPathString()).toString(); } void Config::setPluginPath(const QString &path) { if (pluginPath() == path) { return; } saveValue(ConfigOptions::pluginPathString(), path); } QList Config::pluginInfos() { QList pluginInfos; auto count = mConfig.beginReadArray(ConfigOptions::pluginInfosString()); for (auto index = 0; index < count; index++) { mConfig.setArrayIndex(index); auto path = mConfig.value(ConfigOptions::pluginInfoPathString()).toString(); auto type = mConfig.value(ConfigOptions::pluginInfoTypeString()).value(); auto version = mConfig.value(ConfigOptions::pluginInfoVersionString()).toString(); PluginInfo pluginInfo(type, version, path); pluginInfos.append(pluginInfo); } mConfig.endArray(); return pluginInfos; } void Config::setPluginInfos(const QList &pluginInfos) { auto savedPluginInfos = this->pluginInfos(); if(savedPluginInfos == pluginInfos) { return; } mConfig.remove(ConfigOptions::pluginInfosString()); auto count = pluginInfos.count(); mConfig.beginWriteArray(ConfigOptions::pluginInfosString()); for (auto index = 0; index < count; ++index) { const auto& pluginInfo = pluginInfos.at(index); mConfig.setArrayIndex(index); mConfig.setValue(ConfigOptions::pluginInfoPathString(), pluginInfo.path()); mConfig.setValue(ConfigOptions::pluginInfoTypeString(), static_cast(pluginInfo.type())); mConfig.setValue(ConfigOptions::pluginInfoVersionString(), pluginInfo.version()); } mConfig.endArray(); emit pluginsChanged(); } bool Config::customPluginSearchPathEnabled() const { return loadValue(ConfigOptions::customPluginSearchPathEnabledString(), false).toBool(); } void Config::setCustomPluginSearchPathEnabled(bool enabled) { if (customPluginSearchPathEnabled() == enabled) { return; } saveValue(ConfigOptions::customPluginSearchPathEnabledString(), enabled); } // Misc void Config::saveValue(const QString &key, const QVariant &value) { mConfig.setValue(key, value); mConfig.sync(); } QVariant Config::loadValue(const QString &key, const QVariant &defaultValue) const { return mConfig.value(key, defaultValue); } ksnip-master/src/backend/config/Config.h000066400000000000000000000301341457262621600205100ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software override; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation override; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY override; 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 override; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_CONFIG_H #define KSNIP_CONFIG_H #include #include #include #include #include #include "IConfig.h" #include "ConfigOptions.h" #include "src/common/helper/PathHelper.h" #include "src/common/constants/DefaultValues.h" #include "src/common/provider/directoryPathProvider/IDirectoryPathProvider.h" #include "src/plugins/PluginInfo.h" #include "src/gui/actions/Action.h" class Config : public IConfig { Q_OBJECT public: explicit Config(const QSharedPointer &directoryPathProvider); ~Config() override = default; // Application bool rememberPosition() const override; void setRememberPosition(bool enabled) override; bool promptSaveBeforeExit() const override; void setPromptSaveBeforeExit(bool enabled) override; bool autoCopyToClipboardNewCaptures() const override; void setAutoCopyToClipboardNewCaptures(bool enabled) override; bool autoSaveNewCaptures() const override; void setAutoSaveNewCaptures(bool enabled) override; bool autoHideDocks() const override; void setAutoHideDocks(bool enabled) override; bool autoResizeToContent() const override; void setAutoResizeToContent(bool enabled) override; int resizeToContentDelay() const override; void setResizeToContentDelay(int ms) override; bool overwriteFile() const override; void setOverwriteFile(bool enabled) override; bool useTabs() const override; void setUseTabs(bool enabled) override; bool autoHideTabs() const override; void setAutoHideTabs(bool enabled) override; bool captureOnStartup() const override; void setCaptureOnStartup(bool enabled) override; QPoint windowPosition() const override; void setWindowPosition(const QPoint &position) override; CaptureModes captureMode() const override; void setCaptureMode(CaptureModes mode) override; QString saveDirectory() const override; void setSaveDirectory(const QString &path) override; QString saveFilename() const override; void setSaveFilename(const QString &filename) override; QString saveFormat() const override; void setSaveFormat(const QString &format) override; QString applicationStyle() const override; void setApplicationStyle(const QString &style) override; TrayIconDefaultActionMode defaultTrayIconActionMode() const override; void setDefaultTrayIconActionMode(TrayIconDefaultActionMode mode) override; CaptureModes defaultTrayIconCaptureMode() const override; void setDefaultTrayIconCaptureMode(CaptureModes mode) override; bool useTrayIcon() const override; void setUseTrayIcon(bool enabled) override; bool minimizeToTray() const override; void setMinimizeToTray(bool enabled) override; bool closeToTray() const override; void setCloseToTray(bool enabled) override; bool trayIconNotificationsEnabled() const override; void setTrayIconNotificationsEnabled(bool enabled) override; bool platformSpecificNotificationServiceEnabled() const override; void setPlatformSpecificNotificationServiceEnabled(bool enabled) override; bool startMinimizedToTray() const override; void setStartMinimizedToTray(bool enabled) override; bool rememberLastSaveDirectory() const override; void setRememberLastSaveDirectory(bool enabled) override; bool useSingleInstance() const override; void setUseSingleInstance(bool enabled) override; SaveQualityMode saveQualityMode() const override; void setSaveQualityMode(SaveQualityMode mode) override; int saveQualityFactor() const override; void setSaveQualityFactor(int factor) override; bool isDebugEnabled() const override; void setIsDebugEnabled(bool enabled) override; QString tempDirectory() const override; void setTempDirectory(const QString &path) override; // Annotator bool rememberToolSelection() const override; void setRememberToolSelection(bool enabled) override; bool switchToSelectToolAfterDrawingItem() const override; void setSwitchToSelectToolAfterDrawingItem(bool enabled) override; bool selectItemAfterDrawing() const override; void setSelectItemAfterDrawing(bool enabled) override; bool numberToolSeedChangeUpdatesAllItems() const override; void setNumberToolSeedChangeUpdatesAllItems(bool enabled) override; bool smoothPathEnabled() const override; void setSmoothPathEnabled(bool enabled) override; int smoothFactor() const override; void setSmoothFactor(int factor) override; bool rotateWatermarkEnabled() const override; void setRotateWatermarkEnabled(bool enabled) override; QStringList stickerPaths() const override; void setStickerPaths(const QStringList &paths) override; bool useDefaultSticker() const override; void setUseDefaultSticker(bool enabled) override; QColor canvasColor() const override; void setCanvasColor(const QColor &color) override; bool isControlsWidgetVisible() const override; void setIsControlsWidgetVisible(bool isVisible) override; // Image Grabber bool isFreezeImageWhileSnippingEnabledReadOnly() const override; bool freezeImageWhileSnippingEnabled() const override; void setFreezeImageWhileSnippingEnabled(bool enabled) override; bool captureCursor() const override; void setCaptureCursor(bool enabled) override; bool snippingAreaRulersEnabled() const override; void setSnippingAreaRulersEnabled(bool enabled) override; bool snippingAreaPositionAndSizeInfoEnabled() const override; void setSnippingAreaPositionAndSizeInfoEnabled(bool enabled) override; bool showMainWindowAfterTakingScreenshotEnabled() const override; void setShowMainWindowAfterTakingScreenshotEnabled(bool enabled) override; bool isSnippingAreaMagnifyingGlassEnabledReadOnly() const override; bool snippingAreaMagnifyingGlassEnabled() const override; void setSnippingAreaMagnifyingGlassEnabled(bool enabled) override; int captureDelay() const override; void setCaptureDelay(int delay) override; int snippingCursorSize() const override; void setSnippingCursorSize(int size) override; QColor snippingCursorColor() const override; void setSnippingCursorColor(const QColor &color) override; QColor snippingAdornerColor() const override; void setSnippingAdornerColor(const QColor &color) override; int snippingAreaTransparency() const override; void setSnippingAreaTransparency(int transparency) override; QRect lastRectArea() const override; void setLastRectArea(const QRect &rectArea) override; bool isForceGenericWaylandEnabledReadOnly() const override; bool forceGenericWaylandEnabled() const override; void setForceGenericWaylandEnabled(bool enabled) override; bool isScaleGenericWaylandScreenshotEnabledReadOnly() const override; bool scaleGenericWaylandScreenshotsEnabled() const override; void setScaleGenericWaylandScreenshots(bool enabled) override; bool hideMainWindowDuringScreenshot() const override; void setHideMainWindowDuringScreenshot(bool enabled) override; bool allowResizingRectSelection() const override; void setAllowResizingRectSelection(bool enabled) override; bool showSnippingAreaInfoText() const override; void setShowSnippingAreaInfoText(bool enabled) override; bool snippingAreaOffsetEnable() const override; void setSnippingAreaOffsetEnable(bool enabled) override; QPointF snippingAreaOffset() const override; void setSnippingAreaOffset(const QPointF &offset) override; int implicitCaptureDelay() const override; void setImplicitCaptureDelay(int delay) override; // Uploader bool confirmBeforeUpload() const override; void setConfirmBeforeUpload(bool enabled) override; UploaderType uploaderType() const override; void setUploaderType(UploaderType type) override; // Imgur Uploader QString imgurUsername() const override; void setImgurUsername(const QString &username) override; QByteArray imgurClientId() const override; void setImgurClientId(const QString &clientId) override; QByteArray imgurClientSecret() const override; void setImgurClientSecret(const QString &clientSecret) override; QByteArray imgurAccessToken() const override; void setImgurAccessToken(const QString &accessToken) override; QByteArray imgurRefreshToken() const override; void setImgurRefreshToken(const QString &refreshToken) override; bool imgurForceAnonymous() const override; void setImgurForceAnonymous(bool enabled) override; bool imgurLinkDirectlyToImage() const override; void setImgurLinkDirectlyToImage(bool enabled) override; bool imgurAlwaysCopyToClipboard() const override; void setImgurAlwaysCopyToClipboard(bool enabled) override; bool imgurOpenLinkInBrowser() const override; void setImgurOpenLinkInBrowser(bool enabled) override; QString imgurUploadTitle() const override; void setImgurUploadTitle(const QString &uploadTitle) override; QString imgurUploadDescription() const override; void setImgurUploadDescription(const QString &uploadDescription) override; QString imgurBaseUrl() const override; void setImgurBaseUrl(const QString &baseUrl) override; // Script Uploader QString uploadScriptPath() const override; void setUploadScriptPath(const QString &path) override; bool uploadScriptCopyOutputToClipboard() const override; void setUploadScriptCopyOutputToClipboard(bool enabled) override; QString uploadScriptCopyOutputFilter() const override; void setUploadScriptCopyOutputFilter(const QString ®ex) override; bool uploadScriptStopOnStdErr() const override; void setUploadScriptStopOnStdErr(bool enabled) override; // FTP Uploader bool ftpUploadForceAnonymous() const override; void setFtpUploadForceAnonymous(bool enabled) override; QString ftpUploadUrl() const override; void setFtpUploadUrl(const QString &path) override; QString ftpUploadUsername() const override; void setFtpUploadUsername(const QString &username) override; QString ftpUploadPassword() const override; void setFtpUploadPassword(const QString &password) override; // HotKeys bool isGlobalHotKeysEnabledReadOnly() const override; bool globalHotKeysEnabled() const override; void setGlobalHotKeysEnabled(bool enabled) override; QKeySequence rectAreaHotKey() const override; void setRectAreaHotKey(const QKeySequence &keySequence) override; QKeySequence lastRectAreaHotKey() const override; void setLastRectAreaHotKey(const QKeySequence &keySequence) override; QKeySequence fullScreenHotKey() const override; void setFullScreenHotKey(const QKeySequence &keySequence) override; QKeySequence currentScreenHotKey() const override; void setCurrentScreenHotKey(const QKeySequence &keySequence) override; QKeySequence activeWindowHotKey() const override; void setActiveWindowHotKey(const QKeySequence &keySequence) override; QKeySequence windowUnderCursorHotKey() const override; void setWindowUnderCursorHotKey(const QKeySequence &keySequence) override; QKeySequence portalHotKey() const override; void setPortalHotKey(const QKeySequence &keySequence) override; // Actions QList actions() override; void setActions(const QList &actions) override; // Plugins QString pluginPath() const override; void setPluginPath(const QString &path) override; QList pluginInfos() override; void setPluginInfos(const QList &pluginInfos) override; bool customPluginSearchPathEnabled() const override; void setCustomPluginSearchPathEnabled(bool enabled) override; private: QSettings mConfig; const QSharedPointer mDirectoryPathProvider; void saveValue(const QString &key, const QVariant &value); QVariant loadValue(const QString &key, const QVariant &defaultValue = QVariant()) const; }; #endif // KSNIP_CONFIG_H ksnip-master/src/backend/config/ConfigOptions.cpp000066400000000000000000000371051457262621600224240ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ConfigOptions.h" QString ConfigOptions::rememberPositionString() { return applicationSectionString() + QLatin1String("SavePosition"); } QString ConfigOptions::promptSaveBeforeExitString() { return applicationSectionString() + QLatin1String("PromptSaveBeforeExit"); } QString ConfigOptions::autoCopyToClipboardNewCapturesString() { return applicationSectionString() + QLatin1String("AutoCopyToClipboardNewCaptures"); } QString ConfigOptions::autoSaveNewCapturesString() { return applicationSectionString() + QLatin1String("AutoSaveNewCaptures"); } QString ConfigOptions::rememberToolSelectionString() { return annotatorSectionString() + QLatin1String("SaveToolsSelection"); } QString ConfigOptions::switchToSelectToolAfterDrawingItemString() { return annotatorSectionString() + QLatin1String("SwitchToSelectToolAfterDrawingItem"); } QString ConfigOptions::selectItemAfterDrawingString() { return annotatorSectionString() + QLatin1String("SelectItemAfterDrawing"); } QString ConfigOptions::numberToolSeedChangeUpdatesAllItemsString() { return annotatorSectionString() + QLatin1String("NumberToolSeedChangeUpdatesAllItems"); } QString ConfigOptions::useTabsString() { return applicationSectionString() + QLatin1String("UseTabs"); } QString ConfigOptions::autoHideTabsString() { return applicationSectionString() + QLatin1String("AutoHideTabs"); } QString ConfigOptions::captureOnStartupString() { return applicationSectionString() + QLatin1String("CaptureOnStartup"); } QString ConfigOptions::autoHideDocksString() { return applicationSectionString() + QLatin1String("AutoHideDocks"); } QString ConfigOptions::autoResizeToContentString() { return applicationSectionString() + QLatin1String("AutoResizeToContent"); } QString ConfigOptions::resizeToContentDelayString() { return applicationSectionString() + QLatin1String("ResizeToContentDelay"); } QString ConfigOptions::overwriteFileEnabledString() { return applicationSectionString() + QLatin1String("OverwriteFileEnabled"); } QString ConfigOptions::freezeImageWhileSnippingEnabledString() { return imageGrabberSectionString() + QLatin1String("FreezeImageWhileSnippingEnabled"); } QString ConfigOptions::positionString() { return mainWindowSectionString() + QLatin1String("Position"); } QString ConfigOptions::captureModeString() { return imageGrabberSectionString() + QLatin1String("CaptureMode"); } QString ConfigOptions::saveQualityModeString() { return saveSectionString() + QLatin1String("SaveQualityMode"); } QString ConfigOptions::saveQualityFactorString() { return saveSectionString() + QLatin1String("SaveQualityFactor"); } QString ConfigOptions::isDebugEnabledString() { return applicationSectionString() + QLatin1String("IsDebugEnabled"); } QString ConfigOptions::tempDirectoryString() { return applicationSectionString() + QLatin1String("TempDirectory"); } QString ConfigOptions::saveDirectoryString() { return applicationSectionString() + QLatin1String("SaveDirectory"); } QString ConfigOptions::saveFilenameString() { return applicationSectionString() + QLatin1String("SaveFilename"); } QString ConfigOptions::saveFormatString() { return applicationSectionString() + QLatin1String("SaveFormat"); } QString ConfigOptions::applicationStyleString() { return applicationSectionString() + QLatin1String("ApplicationStyle"); } QString ConfigOptions::trayIconDefaultActionModeString() { return applicationSectionString() + QLatin1String("TrayIconDefaultActionMode"); } QString ConfigOptions::trayIconDefaultCaptureModeString() { return applicationSectionString() + QLatin1String("TrayIconDefaultCaptureMode"); } QString ConfigOptions::useTrayIconString() { return applicationSectionString() + QLatin1String("UseTrayIcon"); } QString ConfigOptions::minimizeToTrayString() { return applicationSectionString() + QLatin1String("MinimizeToTray"); } QString ConfigOptions::closeToTrayString() { return applicationSectionString() + QLatin1String("CloseToTray"); } QString ConfigOptions::trayIconNotificationsEnabledString() { return applicationSectionString() + QLatin1String("TrayIconNotificationsEnabled"); } QString ConfigOptions::platformSpecificNotificationServiceEnabledString() { return applicationSectionString() + QLatin1String("PlatformSpecificNotificationServiceEnabled"); } QString ConfigOptions::startMinimizedToTrayString() { return applicationSectionString() + QLatin1String("StartMinimizedToTray"); } QString ConfigOptions::rememberLastSaveDirectoryString() { return applicationSectionString() + QLatin1String("RememberLastSaveDirectory"); } QString ConfigOptions::useSingleInstanceString() { return applicationSectionString() + QLatin1String("UseSingleInstanceString"); } QString ConfigOptions::hideMainWindowDuringScreenshotString() { return applicationSectionString() + QLatin1String("HideMainWindowDuringScreenshot"); } QString ConfigOptions::allowResizingRectSelectionString() { return applicationSectionString() + QLatin1String("AllowResizingRectSelection"); } QString ConfigOptions::showSnippingAreaInfoTextString() { return applicationSectionString() + QLatin1String("ShowSnippingAreaInfoText"); } QString ConfigOptions::snippingAreaOffsetEnableString() { return snippingAreaSectionString() + QLatin1String("SnippingAreaOffsetEnable"); } QString ConfigOptions::snippingAreaOffsetString() { return snippingAreaSectionString() + QLatin1String("SnippingAreaOffset"); } QString ConfigOptions::implicitCaptureDelayString() { return imageGrabberSectionString() + QLatin1String("ImplicitCaptureDelay"); } QString ConfigOptions::smoothPathEnabledString() { return annotatorSectionString() + QLatin1String("SmoothPathEnabled"); } QString ConfigOptions::smoothPathFactorString() { return annotatorSectionString() + QLatin1String("SmoothPathFactor"); } QString ConfigOptions::rotateWatermarkEnabledString() { return annotatorSectionString() + QLatin1String("RotateWatermark"); } QString ConfigOptions::stickerPathsString() { return annotatorSectionString() + QLatin1String("StickerPaths"); } QString ConfigOptions::useDefaultStickerString() { return annotatorSectionString() + QLatin1String("UseDefaultSticker"); } QString ConfigOptions::isControlsWidgetVisibleString() { return annotatorSectionString() + QLatin1String("IsControlsWidgetVisible"); } QString ConfigOptions::captureCursorString() { return imageGrabberSectionString() + QLatin1String("CaptureCursor"); } QString ConfigOptions::snippingAreaRulersEnabledString() { return imageGrabberSectionString() + QLatin1String("SnippingAreaRulersEnabled"); } QString ConfigOptions::snippingAreaPositionAndSizeInfoEnabledString() { return imageGrabberSectionString() + QLatin1String("SnippingAreaPositionAndSizeInfoEnabled"); } QString ConfigOptions::snippingAreaMagnifyingGlassEnabledString() { return imageGrabberSectionString() + QLatin1String("SnippingAreaMagnifyingGlassEnabled"); } QString ConfigOptions::showMainWindowAfterTakingScreenshotEnabledString() { return imageGrabberSectionString() + QLatin1String("ShowMainWindowAfterTakingScreenshotEnabled"); } QString ConfigOptions::captureDelayString() { return imageGrabberSectionString() + QLatin1String("CaptureDelay"); } QString ConfigOptions::snippingCursorSizeString() { return imageGrabberSectionString() + QLatin1String("SnippingCursorSize"); } QString ConfigOptions::snippingCursorColorString() { return imageGrabberSectionString() + QLatin1String("SnippingCursorColor"); } QString ConfigOptions::snippingAdornerColorString() { return imageGrabberSectionString() + QLatin1String("SnippingAdornerColor"); } QString ConfigOptions::snippingAreaTransparencyString() { return imageGrabberSectionString() + QLatin1String("SnippingAreaTransparency"); } QString ConfigOptions::lastRectAreaString() { return imageGrabberSectionString() + QLatin1String("LastRectArea"); } QString ConfigOptions::forceGenericWaylandEnabledString() { return imageGrabberSectionString() + QLatin1String("ForceGenericWaylandEnabled"); } QString ConfigOptions::scaleWaylandScreenshotsEnabledString() { return imageGrabberSectionString() + QLatin1String("ScaleGenericWaylandScreenshotsEnabledString"); } QString ConfigOptions::imgurUsernameString() { return imgurSectionString() + QLatin1String("Username"); } QString ConfigOptions::imgurClientIdString() { return imgurSectionString() + QLatin1String("ClientId"); } QString ConfigOptions::imgurClientSecretString() { return imgurSectionString() + QLatin1String("ClientSecret"); } QString ConfigOptions::imgurAccessTokenString() { return imgurSectionString() + QLatin1String("AccessToken"); } QString ConfigOptions::imgurRefreshTokenString() { return imgurSectionString() + QLatin1String("RefreshToken"); } QString ConfigOptions::imgurForceAnonymousString() { return imgurSectionString() + QLatin1String("ForceAnonymous"); } QString ConfigOptions::imgurLinkDirectlyToImageString() { return imgurSectionString() + QLatin1String("OpenLinkDirectlyToImage"); } QString ConfigOptions::imgurOpenLinkInBrowserString() { return imgurSectionString() + QLatin1String("OpenLinkInBrowser"); } QString ConfigOptions::imgurUploadTitleString() { return imgurSectionString() + QLatin1String("UploadTitle"); } QString ConfigOptions::imgurUploadDescriptionString() { return imgurSectionString() + QLatin1String("UploadDescription"); } QString ConfigOptions::imgurAlwaysCopyToClipboardString() { return imgurSectionString() + QLatin1String("AlwaysCopyToClipboard"); } QString ConfigOptions::imgurBaseUrlString() { return imgurSectionString() + QLatin1String("BaseUrl"); } QString ConfigOptions::uploadScriptPathString() { return uploadScriptSectionString() + QLatin1String("UploadScriptPath"); } QString ConfigOptions::confirmBeforeUploadString() { return uploaderSectionString() + QLatin1String("ConfirmBeforeUpload"); } QString ConfigOptions::uploaderTypeString() { return uploaderSectionString() + QLatin1String("UploaderType"); } QString ConfigOptions::canvasColorString() { return annotatorSectionString() + QLatin1String("CanvasColor"); } QString ConfigOptions::actionsString() { return QLatin1String("Actions"); } QString ConfigOptions::actionNameString() { return QLatin1String("Name"); } QString ConfigOptions::actionShortcutString() { return QLatin1String("Shortcut"); } QString ConfigOptions::actionShortcutIsGlobalString() { return QLatin1String("IsGlobalShortcutString"); } QString ConfigOptions::actionIsCaptureEnabledString() { return QLatin1String("IsCaptureEnabled"); } QString ConfigOptions::actionIncludeCursorString() { return QLatin1String("IncludeCursor"); } QString ConfigOptions::actionCaptureDelayString() { return QLatin1String("CaptureDelay"); } QString ConfigOptions::actionCaptureModeString() { return QLatin1String("CaptureMode"); } QString ConfigOptions::actionIsPinImageEnabledString() { return QLatin1String("IsPinImageEnabled"); } QString ConfigOptions::actionIsUploadEnabledString() { return QLatin1String("IsUploadEnabled"); } QString ConfigOptions::actionIsOpenDirectoryEnabledString() { return QLatin1String("IsOpenDirectoryEnabled"); } QString ConfigOptions::actionIsCopyToClipboardEnabledString() { return QLatin1String("IsCopyToClipboardEnabled"); } QString ConfigOptions::actionIsSaveEnabledString() { return QLatin1String("IsSaveEnabled"); } QString ConfigOptions::actionIsHideMainWindowEnabledString() { return QLatin1String("IsHideMainWindowEnabled"); } QString ConfigOptions::pluginPathString() { return pluginsSectionString() + QLatin1String("PluginOcrPath"); } QString ConfigOptions::customPluginSearchPathEnabledString() { return pluginsSectionString() + QLatin1String("CustomPluginSearchPathEnabled"); } QString ConfigOptions::pluginInfosString() { return pluginsSectionString() + QLatin1String("PluginInfos"); } QString ConfigOptions::pluginInfoPathString() { return pluginsSectionString() + QLatin1String("PluginInfoPath"); } QString ConfigOptions::pluginInfoTypeString() { return pluginsSectionString() + QLatin1String("PluginInfoType"); } QString ConfigOptions::pluginInfoVersionString() { return pluginsSectionString() + QLatin1String("PluginInfoVersion"); } QString ConfigOptions::uploadScriptCopyOutputToClipboardString() { return uploadScriptSectionString() + QLatin1String("CopyOutputToClipboard"); } QString ConfigOptions::uploadScriptStopOnStdErrString() { return uploadScriptSectionString() + QLatin1String("UploadScriptStoOnStdErr"); } QString ConfigOptions::uploadScriptCopyOutputFilterString() { return uploadScriptSectionString() + QLatin1String("CopyOutputFilter"); } QString ConfigOptions::ftpUploadForceAnonymousString() { return ftpUploadSectionString() + QLatin1String("ForceAnonymous"); } QString ConfigOptions::ftpUploadUrlString() { return ftpUploadSectionString() + QLatin1String("Url"); } QString ConfigOptions::ftpUploadUsernameString() { return ftpUploadSectionString() + QLatin1String("Username"); } QString ConfigOptions::ftpUploadPasswordString() { return ftpUploadSectionString() + QLatin1String("Password"); } QString ConfigOptions::globalHotKeysEnabledString() { return hotKeysSectionString() + QLatin1String("GlobalHotKeysEnabled"); } QString ConfigOptions::rectAreaHotKeyString() { return hotKeysSectionString() + QLatin1String("RectAreaHotKey"); } QString ConfigOptions::lastRectAreaHotKeyString() { return hotKeysSectionString() + QLatin1String("LastRectAreaHotKey"); } QString ConfigOptions::fullScreenHotKeyString() { return hotKeysSectionString() + QLatin1String("FullScreenHotKey"); } QString ConfigOptions::currentScreenHotKeyString() { return hotKeysSectionString() + QLatin1String("CurrentScreenHotKey"); } QString ConfigOptions::activeWindowHotKeyString() { return hotKeysSectionString() + QLatin1String("ActiveWindowHotKey"); } QString ConfigOptions::windowUnderCursorHotKeyString() { return hotKeysSectionString() + QLatin1String("WindowUnderCursorHotKey"); } QString ConfigOptions::portalHotKeyString() { return hotKeysSectionString() + QLatin1String("PortalHotKey"); } QString ConfigOptions::applicationSectionString() { return QLatin1String("Application/"); } QString ConfigOptions::imageGrabberSectionString() { return QLatin1String("ImageGrabber/"); } QString ConfigOptions::annotatorSectionString() { return QLatin1String("Painter/"); } QString ConfigOptions::uploaderSectionString() { return QLatin1String("Uploader/"); } QString ConfigOptions::imgurSectionString() { return QLatin1String("Imgur/"); } QString ConfigOptions::uploadScriptSectionString() { return QLatin1String("UploadScript/"); } QString ConfigOptions::ftpUploadSectionString() { return QLatin1String("FtpUpload/"); } QString ConfigOptions::hotKeysSectionString() { return QLatin1String("HotKeys/"); } QString ConfigOptions::mainWindowSectionString() { return QLatin1String("MainWindow/"); } QString ConfigOptions::saveSectionString() { return QLatin1String("Save/"); } QString ConfigOptions::pluginsSectionString() { return QLatin1String("Plugins/"); } QString ConfigOptions::snippingAreaSectionString() { return QLatin1String("SnippingArea/"); } ksnip-master/src/backend/config/ConfigOptions.h000066400000000000000000000146261457262621600220740ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CONFIGOPTIONS_H #define KSNIP_CONFIGOPTIONS_H #include class ConfigOptions { public: static QString rememberPositionString(); static QString promptSaveBeforeExitString(); static QString autoCopyToClipboardNewCapturesString(); static QString autoSaveNewCapturesString(); static QString rememberToolSelectionString(); static QString switchToSelectToolAfterDrawingItemString(); static QString selectItemAfterDrawingString(); static QString numberToolSeedChangeUpdatesAllItemsString(); static QString useTabsString(); static QString autoHideTabsString(); static QString captureOnStartupString(); static QString freezeImageWhileSnippingEnabledString(); static QString positionString(); static QString autoHideDocksString(); static QString autoResizeToContentString(); static QString resizeToContentDelayString(); static QString overwriteFileEnabledString(); static QString captureModeString(); static QString saveQualityModeString(); static QString saveQualityFactorString(); static QString isDebugEnabledString(); static QString tempDirectoryString(); static QString saveDirectoryString(); static QString saveFilenameString(); static QString saveFormatString(); static QString applicationStyleString(); static QString trayIconDefaultActionModeString(); static QString trayIconDefaultCaptureModeString(); static QString useTrayIconString(); static QString minimizeToTrayString(); static QString closeToTrayString(); static QString trayIconNotificationsEnabledString(); static QString platformSpecificNotificationServiceEnabledString(); static QString startMinimizedToTrayString(); static QString rememberLastSaveDirectoryString(); static QString useSingleInstanceString(); static QString hideMainWindowDuringScreenshotString(); static QString allowResizingRectSelectionString(); static QString showSnippingAreaInfoTextString(); static QString snippingAreaOffsetEnableString(); static QString snippingAreaOffsetString(); static QString implicitCaptureDelayString(); static QString smoothPathEnabledString(); static QString smoothPathFactorString(); static QString rotateWatermarkEnabledString(); static QString stickerPathsString(); static QString useDefaultStickerString(); static QString isControlsWidgetVisibleString(); static QString captureCursorString(); static QString snippingAreaRulersEnabledString(); static QString snippingAreaPositionAndSizeInfoEnabledString(); static QString snippingAreaMagnifyingGlassEnabledString(); static QString showMainWindowAfterTakingScreenshotEnabledString(); static QString captureDelayString(); static QString snippingCursorSizeString(); static QString snippingCursorColorString(); static QString snippingAdornerColorString(); static QString snippingAreaTransparencyString(); static QString lastRectAreaString(); static QString forceGenericWaylandEnabledString(); static QString scaleWaylandScreenshotsEnabledString(); static QString imgurUsernameString(); static QString imgurClientIdString(); static QString imgurClientSecretString(); static QString imgurAccessTokenString(); static QString imgurRefreshTokenString(); static QString imgurForceAnonymousString(); static QString imgurLinkDirectlyToImageString(); static QString imgurOpenLinkInBrowserString(); static QString imgurUploadTitleString(); static QString imgurUploadDescriptionString(); static QString imgurAlwaysCopyToClipboardString(); static QString imgurBaseUrlString(); static QString uploadScriptPathString(); static QString confirmBeforeUploadString(); static QString uploadScriptCopyOutputToClipboardString(); static QString uploadScriptStopOnStdErrString(); static QString uploadScriptCopyOutputFilterString(); static QString ftpUploadForceAnonymousString(); static QString ftpUploadUrlString(); static QString ftpUploadUsernameString(); static QString ftpUploadPasswordString(); static QString globalHotKeysEnabledString(); static QString rectAreaHotKeyString(); static QString lastRectAreaHotKeyString(); static QString fullScreenHotKeyString(); static QString currentScreenHotKeyString(); static QString activeWindowHotKeyString(); static QString windowUnderCursorHotKeyString(); static QString portalHotKeyString(); static QString uploaderTypeString(); static QString canvasColorString(); static QString actionsString(); static QString actionNameString(); static QString actionShortcutString(); static QString actionShortcutIsGlobalString(); static QString actionIsCaptureEnabledString(); static QString actionIncludeCursorString(); static QString actionCaptureDelayString(); static QString actionCaptureModeString(); static QString actionIsPinImageEnabledString(); static QString actionIsUploadEnabledString(); static QString actionIsOpenDirectoryEnabledString(); static QString actionIsCopyToClipboardEnabledString(); static QString actionIsSaveEnabledString(); static QString actionIsHideMainWindowEnabledString(); static QString pluginPathString(); static QString customPluginSearchPathEnabledString(); static QString pluginInfosString(); static QString pluginInfoPathString(); static QString pluginInfoTypeString(); static QString pluginInfoVersionString(); private: static QString applicationSectionString(); static QString imageGrabberSectionString(); static QString annotatorSectionString(); static QString uploaderSectionString(); static QString imgurSectionString(); static QString uploadScriptSectionString(); static QString ftpUploadSectionString(); static QString hotKeysSectionString(); static QString mainWindowSectionString(); static QString saveSectionString(); static QString pluginsSectionString(); static QString snippingAreaSectionString(); }; #endif //KSNIP_CONFIGOPTIONS_H ksnip-master/src/backend/config/IConfig.h000066400000000000000000000306151457262621600206250ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software = 0; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation = 0; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY = 0; 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 = 0; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICONFIG_H #define KSNIP_ICONFIG_H #include #include "src/common/enum/TrayIconDefaultActionMode.h" #include "src/common/enum/UploaderType.h" #include "src/common/enum/SaveQualityMode.h" #include "src/common/enum/CaptureModes.h" class Action; class PluginInfo; class IConfig : public QObject { Q_OBJECT public: IConfig() = default; ~IConfig() override = default; // Application virtual bool rememberPosition() const = 0; virtual void setRememberPosition(bool enabled) = 0; virtual bool promptSaveBeforeExit() const = 0; virtual void setPromptSaveBeforeExit(bool enabled) = 0; virtual bool autoCopyToClipboardNewCaptures() const = 0; virtual void setAutoCopyToClipboardNewCaptures(bool enabled) = 0; virtual bool autoSaveNewCaptures() const = 0; virtual void setAutoSaveNewCaptures(bool enabled) = 0; virtual bool autoHideDocks() const = 0; virtual void setAutoHideDocks(bool enabled) = 0; virtual bool autoResizeToContent() const = 0; virtual void setAutoResizeToContent(bool enabled) = 0; virtual int resizeToContentDelay() const = 0; virtual void setResizeToContentDelay(int ms) = 0; virtual bool overwriteFile() const = 0; virtual void setOverwriteFile(bool enabled) = 0; virtual bool useTabs() const = 0; virtual void setUseTabs(bool enabled) = 0; virtual bool autoHideTabs() const = 0; virtual void setAutoHideTabs(bool enabled) = 0; virtual bool captureOnStartup() const = 0; virtual void setCaptureOnStartup(bool enabled) = 0; virtual QPoint windowPosition() const = 0; virtual void setWindowPosition(const QPoint &position) = 0; virtual CaptureModes captureMode() const = 0; virtual void setCaptureMode(CaptureModes mode) = 0; virtual QString saveDirectory() const = 0; virtual void setSaveDirectory(const QString &path) = 0; virtual QString saveFilename() const = 0; virtual void setSaveFilename(const QString &filename) = 0; virtual QString saveFormat() const = 0; virtual void setSaveFormat(const QString &format) = 0; virtual QString applicationStyle() const = 0; virtual void setApplicationStyle(const QString &style) = 0; virtual TrayIconDefaultActionMode defaultTrayIconActionMode() const = 0; virtual void setDefaultTrayIconActionMode(TrayIconDefaultActionMode mode) = 0; virtual CaptureModes defaultTrayIconCaptureMode() const = 0; virtual void setDefaultTrayIconCaptureMode(CaptureModes mode) = 0; virtual bool useTrayIcon() const = 0; virtual void setUseTrayIcon(bool enabled) = 0; virtual bool minimizeToTray() const = 0; virtual void setMinimizeToTray(bool enabled) = 0; virtual bool closeToTray() const = 0; virtual void setCloseToTray(bool enabled) = 0; virtual bool trayIconNotificationsEnabled() const = 0; virtual void setTrayIconNotificationsEnabled(bool enabled) = 0; virtual bool platformSpecificNotificationServiceEnabled() const = 0; virtual void setPlatformSpecificNotificationServiceEnabled(bool enabled) = 0; virtual bool startMinimizedToTray() const = 0; virtual void setStartMinimizedToTray(bool enabled) = 0; virtual bool rememberLastSaveDirectory() const = 0; virtual void setRememberLastSaveDirectory(bool enabled) = 0; virtual bool useSingleInstance() const = 0; virtual void setUseSingleInstance(bool enabled) = 0; virtual SaveQualityMode saveQualityMode() const = 0; virtual void setSaveQualityMode(SaveQualityMode mode) = 0; virtual int saveQualityFactor() const = 0; virtual void setSaveQualityFactor(int factor) = 0; virtual bool isDebugEnabled() const = 0; virtual void setIsDebugEnabled(bool enabled) = 0; virtual QString tempDirectory() const = 0; virtual void setTempDirectory(const QString &path) = 0; // Annotator virtual bool rememberToolSelection() const = 0; virtual void setRememberToolSelection(bool enabled) = 0; virtual bool switchToSelectToolAfterDrawingItem() const = 0; virtual void setSwitchToSelectToolAfterDrawingItem(bool enabled) = 0; virtual bool selectItemAfterDrawing() const = 0; virtual void setSelectItemAfterDrawing(bool enabled) = 0; virtual bool numberToolSeedChangeUpdatesAllItems() const = 0; virtual void setNumberToolSeedChangeUpdatesAllItems(bool enabled) = 0; virtual bool smoothPathEnabled() const = 0; virtual void setSmoothPathEnabled(bool enabled) = 0; virtual int smoothFactor() const = 0; virtual void setSmoothFactor(int factor) = 0; virtual bool rotateWatermarkEnabled() const = 0; virtual void setRotateWatermarkEnabled(bool enabled) = 0; virtual QStringList stickerPaths() const = 0; virtual void setStickerPaths(const QStringList &paths) = 0; virtual bool useDefaultSticker() const = 0; virtual void setUseDefaultSticker(bool enabled) = 0; virtual QColor canvasColor() const = 0; virtual void setCanvasColor(const QColor &color) = 0; virtual bool isControlsWidgetVisible() const = 0; virtual void setIsControlsWidgetVisible(bool isVisible) = 0; // Image Grabber virtual bool isFreezeImageWhileSnippingEnabledReadOnly() const = 0; virtual bool freezeImageWhileSnippingEnabled() const = 0; virtual void setFreezeImageWhileSnippingEnabled(bool enabled) = 0; virtual bool captureCursor() const = 0; virtual void setCaptureCursor(bool enabled) = 0; virtual bool snippingAreaRulersEnabled() const = 0; virtual void setSnippingAreaRulersEnabled(bool enabled) = 0; virtual bool snippingAreaPositionAndSizeInfoEnabled() const = 0; virtual void setSnippingAreaPositionAndSizeInfoEnabled(bool enabled) = 0; virtual bool showMainWindowAfterTakingScreenshotEnabled() const = 0; virtual void setShowMainWindowAfterTakingScreenshotEnabled(bool enabled) = 0; virtual bool isSnippingAreaMagnifyingGlassEnabledReadOnly() const = 0; virtual bool snippingAreaMagnifyingGlassEnabled() const = 0; virtual void setSnippingAreaMagnifyingGlassEnabled(bool enabled) = 0; virtual int captureDelay() const = 0; virtual void setCaptureDelay(int delay) = 0; virtual int snippingCursorSize() const = 0; virtual void setSnippingCursorSize(int size) = 0; virtual QColor snippingCursorColor() const = 0; virtual void setSnippingCursorColor(const QColor &color) = 0; virtual QColor snippingAdornerColor() const = 0; virtual void setSnippingAdornerColor(const QColor &color) = 0; virtual int snippingAreaTransparency() const = 0; virtual void setSnippingAreaTransparency(int transparency) = 0; virtual QRect lastRectArea() const = 0; virtual void setLastRectArea(const QRect &rectArea) = 0; virtual bool isForceGenericWaylandEnabledReadOnly() const = 0; virtual bool forceGenericWaylandEnabled() const = 0; virtual void setForceGenericWaylandEnabled(bool enabled) = 0; virtual bool isScaleGenericWaylandScreenshotEnabledReadOnly() const = 0; virtual bool scaleGenericWaylandScreenshotsEnabled() const = 0; virtual void setScaleGenericWaylandScreenshots(bool enabled) = 0; virtual bool hideMainWindowDuringScreenshot() const = 0; virtual void setHideMainWindowDuringScreenshot(bool enabled) = 0; virtual bool allowResizingRectSelection() const = 0; virtual void setAllowResizingRectSelection(bool enabled) = 0; virtual bool showSnippingAreaInfoText() const = 0; virtual void setShowSnippingAreaInfoText(bool enabled) = 0; virtual bool snippingAreaOffsetEnable() const = 0; virtual void setSnippingAreaOffsetEnable(bool enabled) = 0; virtual QPointF snippingAreaOffset() const = 0; virtual void setSnippingAreaOffset(const QPointF &offset) = 0; virtual int implicitCaptureDelay() const = 0; virtual void setImplicitCaptureDelay(int delay) = 0; // Uploader virtual bool confirmBeforeUpload() const = 0; virtual void setConfirmBeforeUpload(bool enabled) = 0; virtual UploaderType uploaderType() const = 0; virtual void setUploaderType(UploaderType type) = 0; // Imgur Uploader virtual QString imgurUsername() const = 0; virtual void setImgurUsername(const QString &username) = 0; virtual QByteArray imgurClientId() const = 0; virtual void setImgurClientId(const QString &clientId) = 0; virtual QByteArray imgurClientSecret() const = 0; virtual void setImgurClientSecret(const QString &clientSecret) = 0; virtual QByteArray imgurAccessToken() const = 0; virtual void setImgurAccessToken(const QString &accessToken) = 0; virtual QByteArray imgurRefreshToken() const = 0; virtual void setImgurRefreshToken(const QString &refreshToken) = 0; virtual bool imgurForceAnonymous() const = 0; virtual void setImgurForceAnonymous(bool enabled) = 0; virtual bool imgurLinkDirectlyToImage() const = 0; virtual void setImgurLinkDirectlyToImage(bool enabled) = 0; virtual bool imgurAlwaysCopyToClipboard() const = 0; virtual void setImgurAlwaysCopyToClipboard(bool enabled) = 0; virtual bool imgurOpenLinkInBrowser() const = 0; virtual void setImgurOpenLinkInBrowser(bool enabled) = 0; virtual QString imgurUploadTitle() const = 0; virtual void setImgurUploadTitle(const QString &uploadTitle) = 0; virtual QString imgurUploadDescription() const = 0; virtual void setImgurUploadDescription(const QString &uploadDescription) = 0; virtual QString imgurBaseUrl() const = 0; virtual void setImgurBaseUrl(const QString &baseUrl) = 0; // Script Uploader virtual QString uploadScriptPath() const = 0; virtual void setUploadScriptPath(const QString &path) = 0; virtual bool uploadScriptCopyOutputToClipboard() const = 0; virtual void setUploadScriptCopyOutputToClipboard(bool enabled) = 0; virtual QString uploadScriptCopyOutputFilter() const = 0; virtual void setUploadScriptCopyOutputFilter(const QString ®ex) = 0; virtual bool uploadScriptStopOnStdErr() const = 0; virtual void setUploadScriptStopOnStdErr(bool enabled) = 0; // FTP Uploader virtual bool ftpUploadForceAnonymous() const = 0; virtual void setFtpUploadForceAnonymous(bool enabled) = 0; virtual QString ftpUploadUrl() const = 0; virtual void setFtpUploadUrl(const QString &path) = 0; virtual QString ftpUploadUsername() const = 0; virtual void setFtpUploadUsername(const QString &username) = 0; virtual QString ftpUploadPassword() const = 0; virtual void setFtpUploadPassword(const QString &password) = 0; // HotKeys virtual bool isGlobalHotKeysEnabledReadOnly() const = 0; virtual bool globalHotKeysEnabled() const = 0; virtual void setGlobalHotKeysEnabled(bool enabled) = 0; virtual QKeySequence rectAreaHotKey() const = 0; virtual void setRectAreaHotKey(const QKeySequence &keySequence) = 0; virtual QKeySequence lastRectAreaHotKey() const = 0; virtual void setLastRectAreaHotKey(const QKeySequence &keySequence) = 0; virtual QKeySequence fullScreenHotKey() const = 0; virtual void setFullScreenHotKey(const QKeySequence &keySequence) = 0; virtual QKeySequence currentScreenHotKey() const = 0; virtual void setCurrentScreenHotKey(const QKeySequence &keySequence) = 0; virtual QKeySequence activeWindowHotKey() const = 0; virtual void setActiveWindowHotKey(const QKeySequence &keySequence) = 0; virtual QKeySequence windowUnderCursorHotKey() const = 0; virtual void setWindowUnderCursorHotKey(const QKeySequence &keySequence) = 0; virtual QKeySequence portalHotKey() const = 0; virtual void setPortalHotKey(const QKeySequence &keySequence) = 0; // Actions virtual QList actions() = 0; virtual void setActions(const QList &actions) = 0; // Plugins virtual QString pluginPath() const = 0; virtual void setPluginPath(const QString &path) = 0; virtual QList pluginInfos() = 0; virtual void setPluginInfos(const QList &pluginInfos) = 0; virtual bool customPluginSearchPathEnabled() const = 0; virtual void setCustomPluginSearchPathEnabled(bool enabled) = 0; signals: void annotatorConfigChanged() const; void hotKeysChanged() const; void actionsChanged() const; void pluginsChanged() const; void snippingAreaChangedChanged() const; void delayChanged() const; }; #endif //KSNIP_ICONFIG_H ksnip-master/src/backend/config/MacConfig.cpp000066400000000000000000000023311457262621600214620ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MacConfig.h" MacConfig::MacConfig(const QSharedPointer &directoryPathProvider) : Config(directoryPathProvider) { } bool MacConfig::isFreezeImageWhileSnippingEnabledReadOnly() const { return true; } bool MacConfig::freezeImageWhileSnippingEnabled() const { return true; } bool MacConfig::isGlobalHotKeysEnabledReadOnly() const { return true; } bool MacConfig::globalHotKeysEnabled() const { return false; }ksnip-master/src/backend/config/MacConfig.h000066400000000000000000000024261457262621600211340ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KSNIPMACCONFIG_H #define KSNIP_KSNIPMACCONFIG_H #include "Config.h" class MacConfig : public Config { public: explicit MacConfig(const QSharedPointer &directoryPathProvider); ~MacConfig() override = default; bool isFreezeImageWhileSnippingEnabledReadOnly() const override; bool freezeImageWhileSnippingEnabled() const override; bool isGlobalHotKeysEnabledReadOnly() const override; bool globalHotKeysEnabled() const override; }; #endif //KSNIP_KSNIPMACCONFIG_H ksnip-master/src/backend/config/WaylandConfig.cpp000066400000000000000000000040221457262621600223600ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WaylandConfig.h" WaylandConfig::WaylandConfig(const QSharedPointer &directoryPathProvider, const QSharedPointer &platformChecker) : Config(directoryPathProvider), mPlatformChecker(platformChecker) { } bool WaylandConfig::isFreezeImageWhileSnippingEnabledReadOnly() const { return true; } bool WaylandConfig::freezeImageWhileSnippingEnabled() const { return false; } bool WaylandConfig::isGlobalHotKeysEnabledReadOnly() const { return true; } bool WaylandConfig::globalHotKeysEnabled() const { return false; } bool WaylandConfig::isSnippingAreaMagnifyingGlassEnabledReadOnly() const { return true; } bool WaylandConfig::snippingAreaMagnifyingGlassEnabled() const { return false; } bool WaylandConfig::isForceGenericWaylandEnabledReadOnly() const { return isOnlyGenericScreenshotSupported(); } bool WaylandConfig::isScaleGenericWaylandScreenshotEnabledReadOnly() const { return false; } bool WaylandConfig::forceGenericWaylandEnabled() const { if (isOnlyGenericScreenshotSupported()) { return true; } return Config::forceGenericWaylandEnabled(); } bool WaylandConfig::isOnlyGenericScreenshotSupported() const { return mPlatformChecker->gnomeVersion() >= 41 || mPlatformChecker->isSnap(); } ksnip-master/src/backend/config/WaylandConfig.h000066400000000000000000000034711457262621600220340ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WAYLANDCONFIG_H #define KSNIP_WAYLANDCONFIG_H #include "Config.h" #include "src/common/platform/IPlatformChecker.h" class WaylandConfig : public Config { public: explicit WaylandConfig(const QSharedPointer &directoryPathProvider, const QSharedPointer &platformChecker); ~WaylandConfig() override = default; bool isFreezeImageWhileSnippingEnabledReadOnly() const override; bool freezeImageWhileSnippingEnabled() const override; bool isGlobalHotKeysEnabledReadOnly() const override; bool globalHotKeysEnabled() const override; bool isSnippingAreaMagnifyingGlassEnabledReadOnly() const override; bool snippingAreaMagnifyingGlassEnabled() const override; bool isForceGenericWaylandEnabledReadOnly() const override; bool forceGenericWaylandEnabled() const override; bool isScaleGenericWaylandScreenshotEnabledReadOnly() const override; private: QSharedPointer mPlatformChecker; bool isOnlyGenericScreenshotSupported() const; }; #endif //KSNIP_WAYLANDCONFIG_H ksnip-master/src/backend/imageGrabber/000077500000000000000000000000001457262621600202335ustar00rootroot00000000000000ksnip-master/src/backend/imageGrabber/AbstractImageGrabber.cpp000066400000000000000000000052751457262621600247430ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AbstractImageGrabber.h" AbstractImageGrabber::AbstractImageGrabber(const QSharedPointer &config) : mConfig(config), mIsCaptureCursorEnabled(false), mCaptureDelay(0), mCaptureMode(CaptureModes::FullScreen), mImplicitCaptureDelay(mConfig->implicitCaptureDelay()) { } bool AbstractImageGrabber::isCaptureModeSupported(CaptureModes captureMode) const { return mSupportedCaptureModes.contains(captureMode); } QList AbstractImageGrabber::supportedCaptureModes() const { return mSupportedCaptureModes; } void AbstractImageGrabber::grabImage(CaptureModes captureMode, bool captureCursor, int delay) { setIsCaptureCursorEnabled(captureCursor); setCaptureDelay(delay); setCaptureMode(captureMode); QTimer::singleShot(captureDelay(), this, &AbstractImageGrabber::grab); } void AbstractImageGrabber::addSupportedCaptureMode(CaptureModes captureMode) { mSupportedCaptureModes.append(captureMode); } void AbstractImageGrabber::setCaptureDelay(int delay) { mCaptureDelay = delay; } int AbstractImageGrabber::captureDelay() const { return mCaptureDelay; } CaptureModes AbstractImageGrabber::captureMode() const { return mCaptureMode; } void AbstractImageGrabber::setCaptureMode(CaptureModes captureMode) { if (isCaptureModeSupported(captureMode)) { mCaptureMode = captureMode; } else { qWarning("Unsupported Capture Mode selected, falling back to full screen."); mCaptureMode = CaptureModes::FullScreen; } } bool AbstractImageGrabber::isCaptureDelayBelowMin() const { return mCaptureDelay <= mImplicitCaptureDelay; } bool AbstractImageGrabber::isCaptureCursorEnabled() const { return mIsCaptureCursorEnabled; } void AbstractImageGrabber::setIsCaptureCursorEnabled(bool enabled) { mIsCaptureCursorEnabled = enabled; } void AbstractImageGrabber::delayChanged() { mImplicitCaptureDelay = mConfig->implicitCaptureDelay(); } ksnip-master/src/backend/imageGrabber/AbstractImageGrabber.h000066400000000000000000000041241457262621600244000ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ABSTRACTIMAGEGRABBER_H #define KSNIP_ABSTRACTIMAGEGRABBER_H #include #include #include "IImageGrabber.h" #include "src/common/handler/DelayHandler.h" #include "src/backend/config/IConfig.h" class AbstractImageGrabber : public IImageGrabber { Q_OBJECT public: explicit AbstractImageGrabber(const QSharedPointer &config); ~AbstractImageGrabber() override = default; bool isCaptureModeSupported(CaptureModes captureMode) const override; QList supportedCaptureModes() const override; void grabImage(CaptureModes captureMode, bool captureCursor, int delay) override; protected: QSharedPointer mConfig; void addSupportedCaptureMode(CaptureModes captureMode); void setCaptureDelay(int delay); int captureDelay() const; void setCaptureMode(CaptureModes captureMode); CaptureModes captureMode() const; bool isCaptureDelayBelowMin() const; bool isCaptureCursorEnabled() const; void setIsCaptureCursorEnabled(bool enabled); protected slots: virtual void grab() = 0; private: QList mSupportedCaptureModes; int mCaptureDelay; CaptureModes mCaptureMode; bool mIsCaptureCursorEnabled; int mImplicitCaptureDelay; private slots: void delayChanged(); }; #endif //KSNIP_ABSTRACTIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/AbstractRectAreaImageGrabber.cpp000066400000000000000000000161231457262621600263440ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AbstractRectAreaImageGrabber.h" AbstractRectAreaImageGrabber::AbstractRectAreaImageGrabber(AbstractSnippingArea *snippingArea, const QSharedPointer &config) : AbstractImageGrabber(config), mSnippingArea(snippingArea), mFreezeImageWhileSnipping(mConfig->freezeImageWhileSnippingEnabled()) { Q_ASSERT(mSnippingArea != nullptr); connectSnippingAreaCancel(); } AbstractRectAreaImageGrabber::~AbstractRectAreaImageGrabber() { delete mSnippingArea; } void AbstractRectAreaImageGrabber::grabImage(CaptureModes captureMode, bool captureCursor, int delay) { setIsCaptureCursorEnabled(captureCursor); setCaptureDelay(delay); setCaptureMode(captureMode); if (isRectAreaCaptureWithoutBackground()) { openSnippingAreaWithoutBackground(); } else { QTimer::singleShot(captureDelay(), this, &AbstractRectAreaImageGrabber::prepareGrab); } } /* * Returns the rect of the screen where the mouse cursor is currently located */ QRect AbstractRectAreaImageGrabber::currentScreenRect() const { #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) auto screen = QGuiApplication::screenAt(QCursor::pos()); if (screen == nullptr) { screen = QGuiApplication::primaryScreen(); } return screen->geometry(); #else auto screen = QApplication::desktop()->screenNumber(QCursor::pos()); return QApplication::desktop()->screenGeometry(screen); #endif } QRect AbstractRectAreaImageGrabber::lastRectArea() const { auto rectArea = mConfig->lastRectArea(); if(rectArea.isNull()) { qWarning("ImageGrabber: No RectArea found, capturing full screen."); return fullScreenRect(); } return rectArea; } void AbstractRectAreaImageGrabber::openSnippingAreaWithoutBackground() { connectSnippingAreaFinish(); mSnippingArea->showWithoutBackground(); } void AbstractRectAreaImageGrabber::openSnippingAreaWithBackground(const QPixmap& background) { connectSnippingAreaFinish(); mSnippingArea->showWithBackground(background); } QRect AbstractRectAreaImageGrabber::selectedSnippingAreaRect() const { return mSnippingArea->selectedRectArea(); } QPixmap AbstractRectAreaImageGrabber::snippingAreaBackground() const { return mSnippingArea->background(); } QPixmap AbstractRectAreaImageGrabber::getScreenshotFromRect(const QRect &rect) const { auto screen = QGuiApplication::primaryScreen(); auto windowId = QApplication::desktop()->winId(); auto rectPosition = rect.topLeft(); return screen->grabWindow(windowId, rectPosition.x(), rectPosition.y(), rect.width(), rect.height()); } QPixmap AbstractRectAreaImageGrabber::getScreenshot() const { if (isRectAreaCaptureWithBackground()) { return snippingAreaBackground().copy(mCaptureRect); } else { return getScreenshotFromRect(mCaptureRect); } } void AbstractRectAreaImageGrabber::setCaptureRectFromCorrectSource() { switch (captureMode()) { case CaptureModes::RectArea: mCaptureRect = selectedSnippingAreaRect(); break; case CaptureModes::LastRectArea: mCaptureRect = lastRectArea(); break; case CaptureModes::CurrentScreen: mCaptureRect = currentScreenRect(); break; case CaptureModes::ActiveWindow: mCaptureRect = activeWindowRect(); if (mCaptureRect.isNull()) { qWarning("ImageGrabber::getActiveWindow: Found no window with focus."); mCaptureRect = currentScreenRect(); } break; default: mCaptureRect = fullScreenRect(); } } bool AbstractRectAreaImageGrabber::isSnippingAreaBackgroundTransparent() const { return !mFreezeImageWhileSnipping; } void AbstractRectAreaImageGrabber::prepareGrab() { if (isRectAreaCaptureWithBackground()) { openSnippingArea(); } else { grab(); } } void AbstractRectAreaImageGrabber::grab() { setCaptureRectFromCorrectSource(); CaptureDto capture(getScreenshot()); if (shouldCaptureCursor()) { capture.cursor = getCursorRelativeToScreenshot(); } emit finished(capture); } CursorDto AbstractRectAreaImageGrabber::getCursorRelativeToScreenshot() const { auto cursor = getCursorImageWithPositionFromCorrectSource(); if (mCaptureRect.contains(cursor.position)) { cursor.position -= mCaptureRect.topLeft(); // The final cursor is inserted with offset from 0,0 return cursor; } else { return {}; } } bool AbstractRectAreaImageGrabber::shouldCaptureCursor() const { return isCaptureCursorEnabled() && !(captureMode() == CaptureModes::RectArea && isCaptureDelayBelowMin()); } void AbstractRectAreaImageGrabber::openSnippingArea() { if (isSnippingAreaBackgroundTransparent()) { openSnippingAreaWithoutBackground(); } else { auto screenRect = fullScreenRect(); auto background = getScreenshotFromRect(screenRect); storeCursorForPostProcessing(screenRect); openSnippingAreaWithBackground(background); } } void AbstractRectAreaImageGrabber::storeCursorForPostProcessing(const QRect &screenRect) { auto offset = screenRect.topLeft(); auto cursorWithPosition = getCursorWithPosition(); cursorWithPosition.position -= offset; // Fix in case left most monitor has negative position mStoredCursorImageWithPosition = cursorWithPosition; } void AbstractRectAreaImageGrabber::connectSnippingAreaCancel() { connect(mSnippingArea, &AbstractSnippingArea::canceled, this, &AbstractRectAreaImageGrabber::canceled); } void AbstractRectAreaImageGrabber::connectSnippingAreaFinish() { disconnectSnippingAreaFinish(); if (isSnippingAreaBackgroundTransparent()) { connect(mSnippingArea, &AbstractSnippingArea::finished, [this]() { QTimer::singleShot(captureDelay(), this, &AbstractRectAreaImageGrabber::grab); }); } else { connect(mSnippingArea, &AbstractSnippingArea::finished, this, &AbstractRectAreaImageGrabber::grab); } } void AbstractRectAreaImageGrabber::disconnectSnippingAreaFinish() { disconnect(mSnippingArea, &AbstractSnippingArea::finished, nullptr, nullptr); } CursorDto AbstractRectAreaImageGrabber::getCursorImageWithPositionFromCorrectSource() const { return isRectAreaCaptureWithBackground() ? mStoredCursorImageWithPosition : getCursorWithPosition(); } bool AbstractRectAreaImageGrabber::isRectAreaCaptureWithBackground() const { return captureMode() == CaptureModes::RectArea && !isSnippingAreaBackgroundTransparent(); } bool AbstractRectAreaImageGrabber::isRectAreaCaptureWithoutBackground() const { return captureMode() == CaptureModes::RectArea && isSnippingAreaBackgroundTransparent(); } ksnip-master/src/backend/imageGrabber/AbstractRectAreaImageGrabber.h000066400000000000000000000051641457262621600260140ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ABSTRACTRECTAREAIMAGEGRABBER_H #define KSNIP_ABSTRACTRECTAREAIMAGEGRABBER_H #include #include #include "AbstractImageGrabber.h" #include "src/gui/snippingArea/AbstractSnippingArea.h" class AbstractRectAreaImageGrabber : public AbstractImageGrabber { Q_OBJECT public: explicit AbstractRectAreaImageGrabber(AbstractSnippingArea *snippingArea, const QSharedPointer &config); ~AbstractRectAreaImageGrabber() override; void grabImage(CaptureModes captureMode, bool captureCursor, int delay) override; virtual QRect currentScreenRect() const; virtual QRect fullScreenRect() const = 0; virtual QRect activeWindowRect() const = 0; virtual QRect lastRectArea() const; protected: QRect mCaptureRect; CursorDto mStoredCursorImageWithPosition; void openSnippingAreaWithoutBackground(); void openSnippingAreaWithBackground(const QPixmap &background); QRect selectedSnippingAreaRect() const; QPixmap snippingAreaBackground() const; QPixmap getScreenshotFromRect(const QRect &rect) const; QPixmap getScreenshot() const; void setCaptureRectFromCorrectSource(); virtual bool isSnippingAreaBackgroundTransparent() const; virtual CursorDto getCursorWithPosition() const = 0; protected slots: void prepareGrab(); void grab() override; private: AbstractSnippingArea* mSnippingArea; bool mFreezeImageWhileSnipping; void openSnippingArea(); void connectSnippingAreaCancel(); void connectSnippingAreaFinish(); void disconnectSnippingAreaFinish(); bool shouldCaptureCursor() const; CursorDto getCursorImageWithPositionFromCorrectSource() const; bool isRectAreaCaptureWithBackground() const; bool isRectAreaCaptureWithoutBackground() const; CursorDto getCursorRelativeToScreenshot() const; void storeCursorForPostProcessing(const QRect &screenRect); }; #endif // KSNIP_ABSTRACTRECTAREAIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/BaseX11ImageGrabber.cpp000066400000000000000000000036501457262621600243370ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "BaseX11ImageGrabber.h" BaseX11ImageGrabber::BaseX11ImageGrabber(X11Wrapper *x11Wrapper, const QSharedPointer &config) : AbstractRectAreaImageGrabber(new X11SnippingArea(config), config), mX11Wrapper(x11Wrapper) { addSupportedCaptureMode(CaptureModes::RectArea); addSupportedCaptureMode(CaptureModes::LastRectArea); addSupportedCaptureMode(CaptureModes::FullScreen); addSupportedCaptureMode(CaptureModes::CurrentScreen); addSupportedCaptureMode(CaptureModes::ActiveWindow); } BaseX11ImageGrabber::~BaseX11ImageGrabber() { delete mX11Wrapper; } bool BaseX11ImageGrabber::isSnippingAreaBackgroundTransparent() const { return mX11Wrapper->isCompositorActive() && AbstractRectAreaImageGrabber::isSnippingAreaBackgroundTransparent(); } QRect BaseX11ImageGrabber::activeWindowRect() const { auto rect = mX11Wrapper->getActiveWindowRect(); return mHdpiScaler.unscale(rect); } QRect BaseX11ImageGrabber::fullScreenRect() const { auto rect = mX11Wrapper->getFullScreenRect(); return mHdpiScaler.unscale(rect); } CursorDto BaseX11ImageGrabber::getCursorWithPosition() const { return mX11Wrapper->getCursorWithPosition(); } ksnip-master/src/backend/imageGrabber/BaseX11ImageGrabber.h000066400000000000000000000027661457262621600240130ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef X11IMAGEGRABBER_H #define X11IMAGEGRABBER_H #include "AbstractRectAreaImageGrabber.h" #include "X11Wrapper.h" #include "src/common/platform/HdpiScaler.h" #include "src/gui/snippingArea/X11SnippingArea.h" class BaseX11ImageGrabber : public AbstractRectAreaImageGrabber { public: explicit BaseX11ImageGrabber(X11Wrapper *x11Wrapper, const QSharedPointer &config); ~BaseX11ImageGrabber() override; protected: QRect fullScreenRect() const override; QRect activeWindowRect() const override; bool isSnippingAreaBackgroundTransparent() const override; CursorDto getCursorWithPosition() const override; private: X11Wrapper *mX11Wrapper; HdpiScaler mHdpiScaler; }; #endif // X11IMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/GnomeWaylandImageGrabber.cpp000066400000000000000000000060421457262621600255560ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GnomeWaylandImageGrabber.h" GnomeWaylandImageGrabber::GnomeWaylandImageGrabber(const QSharedPointer &config) : AbstractRectAreaImageGrabber(new WaylandSnippingArea(config), config) { addSupportedCaptureMode(CaptureModes::RectArea); addSupportedCaptureMode(CaptureModes::LastRectArea); addSupportedCaptureMode(CaptureModes::ActiveWindow); addSupportedCaptureMode(CaptureModes::FullScreen); addSupportedCaptureMode(CaptureModes::CurrentScreen); } QRect GnomeWaylandImageGrabber::activeWindowRect() const { // Gnome Wayland captures active window directly return {}; } CursorDto GnomeWaylandImageGrabber::getCursorWithPosition() const { // Gnome Wayland merges the cursor already return {}; } void GnomeWaylandImageGrabber::grab() { QDBusInterface interface(QLatin1String("org.gnome.Shell.Screenshot"), QLatin1String("/org/gnome/Shell/Screenshot"), QLatin1String("org.gnome.Shell.Screenshot")); QDBusPendingReply reply; if (captureMode() == CaptureModes::ActiveWindow) { reply = interface.asyncCall(QLatin1String("ScreenshotWindow"), true, isCaptureCursorEnabled(), false, tmpScreenshotFilename()); } else { reply = interface.asyncCall(QLatin1String("Screenshot"), isCaptureCursorEnabled(), false, tmpScreenshotFilename()); } reply.waitForFinished(); if (reply.isError()) { qCritical("Invalid reply from DBus: %s", qPrintable(reply.error().message())); emit canceled(); } else { auto pathToTmpScreenshot = reply.argumentAt<1>(); postProcessing(QPixmap(pathToTmpScreenshot)); } } void GnomeWaylandImageGrabber::postProcessing(const QPixmap& pixmap) { if (captureMode() == CaptureModes::ActiveWindow) { emit finished(CaptureDto(pixmap)); } else { setCaptureRectFromCorrectSource(); emit finished(CaptureDto(pixmap.copy(mCaptureRect))); } } QString GnomeWaylandImageGrabber::tmpScreenshotFilename() const { auto path = QLatin1String("/tmp/"); auto filename = QLatin1String("ksnip-") + QString::number(MathHelper::randomInt()); auto extension = QLatin1String(".png"); return path + filename + extension; } QRect GnomeWaylandImageGrabber::fullScreenRect() const { // Copy with empty rect will return full screen return {}; } ksnip-master/src/backend/imageGrabber/GnomeWaylandImageGrabber.h000066400000000000000000000030501457262621600252170ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef GNOMEWAYLANDIMAGEGRABBER_H #define GNOMEWAYLANDIMAGEGRABBER_H #include #include #include #include "AbstractRectAreaImageGrabber.h" #include "src/common/helper/MathHelper.h" #include "src/gui/snippingArea/WaylandSnippingArea.h" class GnomeWaylandImageGrabber : public AbstractRectAreaImageGrabber { public: explicit GnomeWaylandImageGrabber(const QSharedPointer &config); QRect fullScreenRect() const override; QRect activeWindowRect() const override; protected: void grab() override; CursorDto getCursorWithPosition() const override; private: void postProcessing(const QPixmap &pixmap); QString tmpScreenshotFilename() const; }; #endif // GNOMEWAYLANDIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/GnomeX11ImageGrabber.cpp000066400000000000000000000017061457262621600245320ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GnomeX11ImageGrabber.h" GnomeX11ImageGrabber::GnomeX11ImageGrabber(const QSharedPointer &config) : BaseX11ImageGrabber(new GnomeX11Wrapper, config) { } ksnip-master/src/backend/imageGrabber/GnomeX11ImageGrabber.h000066400000000000000000000022031457262621600241700ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_GNOMEX11IMAGEGRABBER_H #define KSNIP_GNOMEX11IMAGEGRABBER_H #include "BaseX11ImageGrabber.h" #include "GnomeX11Wrapper.h" class GnomeX11ImageGrabber : public BaseX11ImageGrabber { public: explicit GnomeX11ImageGrabber(const QSharedPointer &config); ~GnomeX11ImageGrabber() override = default; }; #endif //KSNIP_GNOMEX11IMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/GnomeX11Wrapper.cpp000066400000000000000000000041541457262621600236430ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GnomeX11Wrapper.h" QRect GnomeX11Wrapper::getActiveWindowRect() const { auto windowId = X11Wrapper::getActiveWindowId(); auto windowRect = X11Wrapper::getWindowRect(windowId); auto frameExtents = getGtkFrameExtents(windowId); return windowRect.adjusted(frameExtents.left, frameExtents.top, -frameExtents.right, -frameExtents.bottom); } GnomeX11Wrapper::FrameExtents GnomeX11Wrapper::getGtkFrameExtents(unsigned int windowId) { FrameExtents values{}; auto connection = QX11Info::connection(); auto atom_cookie = xcb_intern_atom(connection, 0, strlen("_GTK_FRAME_EXTENTS"), "_GTK_FRAME_EXTENTS"); ScopedCPointer atom_reply(xcb_intern_atom_reply(connection, atom_cookie, nullptr)); if (!atom_reply.isNull()) { auto cookie = xcb_get_property(connection, 0, windowId, atom_reply->atom, XCB_ATOM_CARDINAL, 0, 4); ScopedCPointer reply(xcb_get_property_reply(connection, cookie, nullptr)); if (!reply.isNull()) { int length = xcb_get_property_value_length(reply.data()); if (length != 0) { auto gtkFrameExtents = static_cast(xcb_get_property_value(reply.data())); values.left = (int)gtkFrameExtents[0]; values.right = (int)gtkFrameExtents[1]; values.top = (int)gtkFrameExtents[2]; values.bottom = (int)gtkFrameExtents[3]; } } } return values; } ksnip-master/src/backend/imageGrabber/GnomeX11Wrapper.h000066400000000000000000000024011457262621600233010ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_GNOMEX11WRAPPER_H #define KSNIP_GNOMEX11WRAPPER_H #include #include #include "X11Wrapper.h" class GnomeX11Wrapper : public X11Wrapper { public: GnomeX11Wrapper() = default; ~GnomeX11Wrapper() = default; QRect getActiveWindowRect() const override; private: struct FrameExtents { int left; int right; int top; int bottom; }; static FrameExtents getGtkFrameExtents(unsigned int windowId); }; #endif //KSNIP_GNOMEX11WRAPPER_H ksnip-master/src/backend/imageGrabber/IImageGrabber.h000066400000000000000000000026021457262621600230240ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMAGEGRABBER_H #define KSNIP_IIMAGEGRABBER_H #include "src/common/enum/CaptureModes.h" #include "src/common/dtos/CaptureDto.h" class IImageGrabber : public QObject { Q_OBJECT public: explicit IImageGrabber() = default; ~IImageGrabber() override = default; virtual bool isCaptureModeSupported(CaptureModes captureMode) const = 0; virtual QList supportedCaptureModes() const = 0; virtual void grabImage(CaptureModes captureMode, bool captureCursor, int delay) = 0; signals: void finished(const CaptureDto &capture) const; void canceled() const; }; #endif //KSNIP_IIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/ImageGrabberFactory.cpp000066400000000000000000000037411457262621600246030ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImageGrabberFactory.h" AbstractImageGrabber* ImageGrabberFactory::createImageGrabber() { #if defined(__APPLE__) return new MacImageGrabber(); #endif #if defined(UNIX_X11) if (PlatformChecker::instance()->isX11()) { if(PlatformChecker::instance()->isGnome()) { return new GnomeX11ImageGrabber(); } else { return new X11ImageGrabber(); } } else if (PlatformChecker::instance()->isWayland()) { auto config = KsnipConfigProvider::instance(); if (config->forceGenericWaylandEnabled() || PlatformChecker::instance()->isSnap() || PlatformChecker::instance()->gnomeVersion() >= 41) { return new WaylandImageGrabber(); } else if(PlatformChecker::instance()->isKde()) { return new KdeWaylandImageGrabber(); } else if (PlatformChecker::instance()->isGnome()) { return new GnomeWaylandImageGrabber(); } else { qCritical("Unknown wayland platform, using default wayland Image Grabber."); return new WaylandImageGrabber(); } } else { qCritical("Unknown platform, using default X11 Image Grabber."); return new X11ImageGrabber(); } #endif #if defined(_WIN32) return new WinImageGrabber(); #endif } ksnip-master/src/backend/imageGrabber/KdeWaylandImageGrabber.cpp000066400000000000000000000071631457262621600252210ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * Most part of this class comes from the KWinWaylandImageGrabber implementation * from KDE Spectacle, implemented by Martin Graesslin */ #include "KdeWaylandImageGrabber.h" static int readData(int fd, QByteArray& data) { // implementation based on QtWayland file qwaylanddataoffer.cpp char buffer[4096]; int retryCount = 0; int n; while (true) { n = QT_READ(fd, buffer, sizeof buffer); // give user 30 sec to click a window, afterwards considered as error if (n == -1 && (errno == EAGAIN) && ++retryCount < 30000) { usleep(1000); } else { break; } } if (n > 0) { data.append(buffer, n); n = readData(fd, data); } return n; } static QImage readImage(int pipeFd) { QByteArray content; if (readData(pipeFd, content) != 0) { close(pipeFd); return QImage(); } close(pipeFd); QDataStream dataStream(content); QImage image; dataStream >> image; return image; }; KdeWaylandImageGrabber::KdeWaylandImageGrabber(const QSharedPointer &config) : AbstractImageGrabber(config) { addSupportedCaptureMode(CaptureModes::WindowUnderCursor); addSupportedCaptureMode(CaptureModes::CurrentScreen); addSupportedCaptureMode(CaptureModes::FullScreen); } void KdeWaylandImageGrabber::grab() { if (captureMode() == CaptureModes::FullScreen) { prepareDBus(QLatin1String("screenshotFullscreen"), isCaptureCursorEnabled()); } else if (captureMode() == CaptureModes::CurrentScreen) { prepareDBus(QLatin1String("screenshotScreen"), isCaptureCursorEnabled()); } else { int mask = 1; if (isCaptureCursorEnabled()) { mask |= 1 << 1; } prepareDBus(QLatin1String("interactive"), mask); } } template void KdeWaylandImageGrabber::prepareDBus(const QString& mode, T mask) { int pipeFds[2]; if (pipe2(pipeFds, O_CLOEXEC | O_NONBLOCK) != 0) { emit canceled(); return; } callDBus(pipeFds[1], mode, mask); startReadImage(pipeFds[0]); close(pipeFds[1]); } template void KdeWaylandImageGrabber::callDBus(int writeFd, const QString& mode, T mask) { QDBusInterface interface(QLatin1String("org.kde.KWin"), QLatin1String("/Screenshot"), QLatin1String("org.kde.kwin.Screenshot")); interface.asyncCall(mode, QVariant::fromValue(QDBusUnixFileDescriptor(writeFd)), mask); } void KdeWaylandImageGrabber::startReadImage(int readPipe) { auto watcher = new QFutureWatcher(this); QObject::connect(watcher, &QFutureWatcher::finished, this, [watcher, this] { watcher->deleteLater(); auto image = watcher->result(); emit finished(CaptureDto(QPixmap::fromImage(image))); }); watcher->setFuture(QtConcurrent::run(readImage, readPipe)); } ksnip-master/src/backend/imageGrabber/KdeWaylandImageGrabber.h000066400000000000000000000032331457262621600246600ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KDEWAYLANDIMAGEGRABBER_H #define KSNIP_KDEWAYLANDIMAGEGRABBER_H #include #include #include #include #include #include #include #include #include #include "AbstractImageGrabber.h" class KdeWaylandImageGrabber : public AbstractImageGrabber { public: explicit KdeWaylandImageGrabber(const QSharedPointer &config); ~KdeWaylandImageGrabber() override = default; protected: void grab() override; private: void startReadImage(int readPipe); template void prepareDBus(const QString& mode, T mask); template void callDBus(int writeFd, const QString& mode, T mask); }; #endif // KSNIP_KDEWAYLANDIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/MacImageGrabber.cpp000066400000000000000000000030311457262621600236640ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MacImageGrabber.h" MacImageGrabber::MacImageGrabber(const QSharedPointer &config) : AbstractRectAreaImageGrabber(new MacSnippingArea(config), config), mMacWrapper(new MacWrapper) { addSupportedCaptureMode(CaptureModes::RectArea); addSupportedCaptureMode(CaptureModes::LastRectArea); addSupportedCaptureMode(CaptureModes::FullScreen); addSupportedCaptureMode(CaptureModes::CurrentScreen); } QRect MacImageGrabber::fullScreenRect() const { return mMacWrapper->getFullScreenRect(); } QRect MacImageGrabber::activeWindowRect() const { // Not supported for MacOs return {}; } CursorDto MacImageGrabber::getCursorWithPosition() const { // MacOs currently captures always mouse by itself return {}; } ksnip-master/src/backend/imageGrabber/MacImageGrabber.h000066400000000000000000000026021457262621600233340ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MACIMAGEGRABBER_H #define KSNIP_MACIMAGEGRABBER_H #include "AbstractRectAreaImageGrabber.h" #include "MacWrapper.h" #include "src/gui/snippingArea/MacSnippingArea.h" class MacImageGrabber : public AbstractRectAreaImageGrabber { Q_OBJECT public: explicit MacImageGrabber(const QSharedPointer &config); ~MacImageGrabber() override = default; protected slots: QRect fullScreenRect() const override; QRect activeWindowRect() const override; CursorDto getCursorWithPosition() const override; private: MacWrapper *mMacWrapper; }; #endif //KSNIP_MACIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/MacWrapper.cpp000066400000000000000000000021061457262621600227770ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MacWrapper.h" QRect MacWrapper::getFullScreenRect() const { auto mainDisplayID = CGMainDisplayID(); auto screenWidth = (int)CGDisplayPixelsWide(mainDisplayID); auto screenHeight = (int)CGDisplayPixelsHigh(mainDisplayID); return {0, 0, screenWidth, screenHeight}; } ksnip-master/src/backend/imageGrabber/MacWrapper.h000066400000000000000000000020371457262621600224470ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MACWRAPPER_H #define KSNIP_MACWRAPPER_H #include #include "CoreGraphics/CGDirectDisplay.h" #include "src/common/dtos/CursorDto.h" class MacWrapper { public: QRect getFullScreenRect() const; }; #endif //KSNIP_MACWRAPPER_H ksnip-master/src/backend/imageGrabber/WaylandImageGrabber.cpp000066400000000000000000000075051457262621600245750ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WaylandImageGrabber.h" WaylandImageGrabber::WaylandImageGrabber(const QSharedPointer &config) : AbstractImageGrabber(config), mRequestTokenCounter(1) { addSupportedCaptureMode(CaptureModes::Portal); } void WaylandImageGrabber::grab() { auto message = getDBusMessage(); auto pendingCall = QDBusConnection::sessionBus().asyncCall(message); auto watcher = new QDBusPendingCallWatcher(pendingCall); connect(watcher, &QDBusPendingCallWatcher::finished, this, &WaylandImageGrabber::portalResponse); } QDBusMessage WaylandImageGrabber::getDBusMessage() { auto message = QDBusMessage::createMethodCall( QLatin1String("org.freedesktop.portal.Desktop"), QLatin1String("/org/freedesktop/portal/desktop"), QLatin1String("org.freedesktop.portal.Screenshot"), QLatin1String("Screenshot")); message << QLatin1String("wayland:") << QVariantMap{ {QLatin1String("interactive"), false}, {QLatin1String("handle_token"), getRequestToken()} }; return message; } void WaylandImageGrabber::gotScreenshotResponse(uint response, const QVariantMap& results) { if (isResponseValid(response, results)) { auto path = getPathToScreenshot(results); auto screenshot = createPixmapFromPath(path); if(isTemporaryImage(path)) { emit finished(CaptureDto(screenshot)); } else { emit finished(CaptureFromFileDto(screenshot, path)); } } else { qCritical("Failed to take screenshot"); } } QPixmap WaylandImageGrabber::createPixmapFromPath(const QString &path) const { auto capture = QPixmap::fromImage(QImage(path)); if(mConfig->scaleGenericWaylandScreenshotsEnabled()) { capture.setDevicePixelRatio(mHdpiScaler.scaleFactor()); } return capture; } bool WaylandImageGrabber::isResponseValid(uint response, const QVariantMap &results) { return !response && results.contains(QLatin1String("uri")); } bool WaylandImageGrabber::isTemporaryImage(const QString &path) { return path.contains(QLatin1String("/tmp/")); } QString WaylandImageGrabber::getPathToScreenshot(const QVariantMap &results) { auto uri = results.value(QLatin1String("uri")).toString(); return uri.remove(QLatin1String("file://")); } QString WaylandImageGrabber::getRequestToken() { mRequestTokenCounter += 1; return QString("u%1").arg(mRequestTokenCounter); } void WaylandImageGrabber::portalResponse(QDBusPendingCallWatcher *watcher) { QDBusPendingReply reply = *watcher; if (reply.isError()) { qCritical("Error: %s", qPrintable(reply.error().message())); } else { QDBusConnection::sessionBus().connect(QString(), reply.value().path(), QLatin1String("org.freedesktop.portal.Request"), QLatin1String("Response"), this, SLOT(gotScreenshotResponse(uint,QVariantMap))); } } ksnip-master/src/backend/imageGrabber/WaylandImageGrabber.h000066400000000000000000000035731457262621600242430ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WAYLANDIMAGEGRABBER_H #define KSNIP_WAYLANDIMAGEGRABBER_H #include #include #include #include "AbstractImageGrabber.h" #include "src/common/dtos/CaptureFromFileDto.h" #include "src/common/platform/HdpiScaler.h" class WaylandImageGrabber : public AbstractImageGrabber { Q_OBJECT public: explicit WaylandImageGrabber(const QSharedPointer &config); ~WaylandImageGrabber() override = default; public slots: void gotScreenshotResponse(uint response, const QVariantMap& results); protected: void grab() override; private: int mRequestTokenCounter; HdpiScaler mHdpiScaler; QString getRequestToken(); static QString getPathToScreenshot(const QVariantMap &results); static bool isTemporaryImage(const QString &path); static bool isResponseValid(uint response, const QVariantMap &results); QDBusMessage getDBusMessage(); private slots: void portalResponse(QDBusPendingCallWatcher *watcher); QPixmap createPixmapFromPath(const QString &path) const; }; #endif //KSNIP_WAYLANDIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/WinImageGrabber.cpp000066400000000000000000000032041457262621600237230ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinImageGrabber.h" WinImageGrabber::WinImageGrabber(const QSharedPointer &config) : AbstractRectAreaImageGrabber(new WinSnippingArea(config), config), mWinWrapper(new WinWrapper) { addSupportedCaptureMode(CaptureModes::RectArea); addSupportedCaptureMode(CaptureModes::LastRectArea); addSupportedCaptureMode(CaptureModes::FullScreen); addSupportedCaptureMode(CaptureModes::ActiveWindow); addSupportedCaptureMode(CaptureModes::CurrentScreen); } QRect WinImageGrabber::activeWindowRect() const { auto rect = mWinWrapper->getActiveWindowRect(); return mHdpiScaler.unscale(rect); } QRect WinImageGrabber::fullScreenRect() const { auto rect = mWinWrapper->getFullScreenRect(); return mHdpiScaler.unscale(rect); } CursorDto WinImageGrabber::getCursorWithPosition() const { return mWinWrapper->getCursorWithPosition(); } ksnip-master/src/backend/imageGrabber/WinImageGrabber.h000066400000000000000000000027001457262621600233700ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINIMAGEGRABBER_H #define KSNIP_WINIMAGEGRABBER_H #include "AbstractRectAreaImageGrabber.h" #include "WinWrapper.h" #include "src/gui/snippingArea/WinSnippingArea.h" #include "src/common/platform/HdpiScaler.h" class WinImageGrabber : public AbstractRectAreaImageGrabber { Q_OBJECT public: explicit WinImageGrabber(const QSharedPointer &config); ~WinImageGrabber() override = default; protected: QRect fullScreenRect() const override; QRect activeWindowRect() const override; CursorDto getCursorWithPosition() const override; private: WinWrapper *mWinWrapper; HdpiScaler mHdpiScaler; }; #endif //KSNIP_WINIMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/WinWrapper.cpp000066400000000000000000000057351457262621600230470ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinWrapper.h" QRect WinWrapper::getFullScreenRect() const { auto height = GetSystemMetrics(SM_CYVIRTUALSCREEN); auto width = GetSystemMetrics(SM_CXVIRTUALSCREEN); auto x = GetSystemMetrics(SM_XVIRTUALSCREEN); auto y = GetSystemMetrics(SM_YVIRTUALSCREEN); return {x, y, width, height}; } QRect WinWrapper::getActiveWindowRect() const { RECT window, frame; auto handle = GetForegroundWindow(); GetWindowRect(handle, &window); DwmGetWindowAttribute(handle, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT)); return {QPoint(frame.left, frame.top), QPoint(frame.right, frame.bottom)}; } CursorDto WinWrapper::getCursorWithPosition() const { CURSORINFO cursorInfo = { sizeof(cursorInfo) }; GetCursorInfo(&cursorInfo); auto cursorPosition = getCursorPosition(QRect(), cursorInfo); auto cursorPixmap = getCursorPixmap(cursorInfo); return {cursorPixmap, cursorPosition}; } QPoint WinWrapper::getCursorPosition(const QRect &rect, const CURSORINFO &cursor) const { ICONINFOEXW iconInfo = { sizeof(iconInfo) }; GetIconInfoExW(cursor.hCursor, &iconInfo); auto x = cursor.ptScreenPos.x - (int)iconInfo.xHotspot; auto y = cursor.ptScreenPos.y - (int)iconInfo.yHotspot; return { x, y }; } QPixmap WinWrapper::getCursorPixmap(const CURSORINFO &cursor) const { // Get Cursor Size auto cursorWidth = GetSystemMetrics(SM_CXCURSOR); auto cursorHeight = GetSystemMetrics(SM_CYCURSOR); // Get your device contexts. auto screenHandle = GetDC(nullptr); auto memoryHandle = CreateCompatibleDC(screenHandle); // Create the bitmap to use as a canvas. auto canvasBitmap = CreateCompatibleBitmap(screenHandle, cursorWidth, cursorHeight); // Select the bitmap into the device context. auto oldBitmap = SelectObject(memoryHandle, canvasBitmap); // Draw the cursor into the canvas. DrawIcon(memoryHandle, 0, 0, cursor.hCursor); // Convert to QPixmap auto cursorPixmap = fromHBITMAP(canvasBitmap, QtWin::HBitmapAlpha); // Clean up after yourself. SelectObject(memoryHandle, oldBitmap); DeleteObject(canvasBitmap); DeleteDC(memoryHandle); ReleaseDC(nullptr, screenHandle); return cursorPixmap; } ksnip-master/src/backend/imageGrabber/WinWrapper.h000066400000000000000000000024371457262621600225100ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINWRAPPER_H #define KSNIP_WINWRAPPER_H #include #include #include #include #include "src/common/dtos/CursorDto.h" class WinWrapper { public: QRect getFullScreenRect() const; QRect getActiveWindowRect() const; CursorDto getCursorWithPosition() const; private: QPixmap getCursorPixmap(const CURSORINFO &cursor) const; QPoint getCursorPosition(const QRect &rect, const CURSORINFO &cursor) const; }; #endif //KSNIP_WINWRAPPER_H ksnip-master/src/backend/imageGrabber/X11ImageGrabber.cpp000066400000000000000000000016621457262621600235450ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "X11ImageGrabber.h" X11ImageGrabber::X11ImageGrabber(const QSharedPointer &config) : BaseX11ImageGrabber(new X11Wrapper, config) { } ksnip-master/src/backend/imageGrabber/X11ImageGrabber.h000066400000000000000000000021401457262621600232020ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_X11IMAGEGRABBER_H #define KSNIP_X11IMAGEGRABBER_H #include "BaseX11ImageGrabber.h" #include "X11Wrapper.h" class X11ImageGrabber : public BaseX11ImageGrabber { public: explicit X11ImageGrabber(const QSharedPointer &config); ~X11ImageGrabber() override = default; }; #endif //KSNIP_X11IMAGEGRABBER_H ksnip-master/src/backend/imageGrabber/X11Wrapper.cpp000066400000000000000000000105531457262621600226550ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * blendCursorImage() and getNativeCursorPosition() functions have been taken * from KDE Spectacle X11ImageGrabber and slightly modified to fit this * implementation. */ #include "X11Wrapper.h" #include bool X11Wrapper::isCompositorActive() const { auto display = QX11Info::display(); auto prop_atom = XInternAtom(display, "_NET_WM_CM_S0", false); return XGetSelectionOwner(display, prop_atom) != None; } QRect X11Wrapper::getFullScreenRect() const { return getWindowRect(QX11Info::appRootWindow()); } QRect X11Wrapper::getActiveWindowRect() const { auto windowId = getActiveWindowId(); return getWindowRect(windowId); } QRect X11Wrapper::getWindowRect(xcb_window_t windowId) const { // In case of window id 0 return empty rect if (windowId == 0) { return {}; } auto connection = QX11Info::connection(); auto geomCookie = xcb_get_geometry_unchecked(connection, windowId); ScopedCPointer geomReply(xcb_get_geometry_reply(connection, geomCookie, nullptr)); return { geomReply->x, geomReply->y, geomReply->width, geomReply->height }; } xcb_window_t X11Wrapper::getActiveWindowId() const { xcb_query_tree_cookie_t treeCookie; auto connection = QX11Info::connection(); ScopedCPointer focusReply(xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr)); // Get ID of focused window, however, this must not always be the top level // window so we loop through parents and search for the top level window. auto windowId = focusReply->focus; while (true) { treeCookie = xcb_query_tree_unchecked(connection, windowId); ScopedCPointer treeReply(xcb_query_tree_reply(connection, treeCookie, nullptr)); if (!treeReply) { return 0; } // If the root window it is equal to the parent or the window ID itself // the this must be the top level window. if (windowId == treeReply->root || treeReply->parent == treeReply->root) { return windowId; } else { windowId = treeReply->parent; } } } QPoint X11Wrapper::getNativeCursorPosition() const { // QCursor::pos() is not used because it requires additional calculations. // Its value is the offset to the origin of the current screen is in // device-independent pixels while the origin itself uses native pixels. auto xcbConn = QX11Info::connection(); auto pointerCookie = xcb_query_pointer_unchecked(xcbConn, QX11Info::appRootWindow()); ScopedCPointer pointerReply(xcb_query_pointer_reply(xcbConn, pointerCookie, nullptr)); return { pointerReply->root_x, pointerReply->root_y }; } CursorDto X11Wrapper::getCursorWithPosition() const { auto cursorPosition = getNativeCursorPosition(); // now we can get the image and start processing auto xcbConn = QX11Info::connection(); auto cursorCookie = xcb_xfixes_get_cursor_image_unchecked(xcbConn); ScopedCPointer cursorReply(xcb_xfixes_get_cursor_image_reply(xcbConn, cursorCookie, nullptr)); if (cursorReply.isNull()) { return CursorDto(); } auto pixelData = xcb_xfixes_get_cursor_image_cursor_image(cursorReply.data()); if (!pixelData) { return CursorDto(); } // process the image into a QImage auto cursorImage = QImage((quint8 *) pixelData, cursorReply->width, cursorReply->height, QImage::Format_ARGB32_Premultiplied); // a small fix for the cursor position for fancier cursor cursorPosition -= QPoint(cursorReply->xhot, cursorReply->yhot); return { QPixmap::fromImage(cursorImage, Qt::AutoColor), cursorPosition }; } ksnip-master/src/backend/imageGrabber/X11Wrapper.h000066400000000000000000000032221457262621600223150ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef X11WRAPPER_H #define X11WRAPPER_H #include #include #include "src/common/dtos/CursorDto.h" class X11Wrapper { public: X11Wrapper() = default; ~X11Wrapper() = default; virtual bool isCompositorActive() const; virtual QRect getFullScreenRect() const; virtual QRect getActiveWindowRect() const; virtual CursorDto getCursorWithPosition() const; protected: QPoint getNativeCursorPosition() const; QRect getWindowRect(xcb_window_t window) const; xcb_window_t getActiveWindowId() const; }; /* * QScopedPointer class overwritten to free pointers that need to be freed by * free() instead of delete. */ template class ScopedCPointer : public QScopedPointer { public: explicit ScopedCPointer(T *p = 0) : QScopedPointer(p) {} }; #endif // X11WRAPPER_H ksnip-master/src/backend/ipc/000077500000000000000000000000001457262621600164375ustar00rootroot00000000000000ksnip-master/src/backend/ipc/IpcClient.cpp000066400000000000000000000022031457262621600210120ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "IpcClient.h" IpcClient::IpcClient() : mLocalSocket(new QLocalSocket(this)) { } IpcClient::~IpcClient() { delete mLocalSocket; } void IpcClient::connectTo(const QString &name) { mLocalSocket->connectToServer(name); } void IpcClient::send(const QByteArray &data) { mLocalSocket->write(data); mLocalSocket->waitForBytesWritten(); } ksnip-master/src/backend/ipc/IpcClient.h000066400000000000000000000021401457262621600204570ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPCCLIENT_H #define KSNIP_IPCCLIENT_H #include class IpcClient : public QObject { Q_OBJECT public: IpcClient(); ~IpcClient() override; void connectTo(const QString &name); void send(const QByteArray &data); private: QLocalSocket *mLocalSocket; }; #endif //KSNIP_IPCCLIENT_H ksnip-master/src/backend/ipc/IpcServer.cpp000066400000000000000000000030241457262621600210440ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "IpcServer.h" IpcServer::IpcServer() : mLocalServer(new QLocalServer()) { mLocalServer->setSocketOptions(QLocalServer::WorldAccessOption); } IpcServer::~IpcServer() { delete mLocalServer; } bool IpcServer::listen(const QString &name) { auto hasStarted = mLocalServer->listen(name); connect(mLocalServer, &QLocalServer::newConnection, this, &IpcServer::newConnection); return hasStarted; } void IpcServer::newConnection() { auto clientConnection = mLocalServer->nextPendingConnection(); connect(clientConnection, &QLocalSocket::readyRead, this, &IpcServer::processData); } void IpcServer::processData() { auto clientSocket = dynamic_cast(sender()); auto data = clientSocket->readAll(); emit received(data); } ksnip-master/src/backend/ipc/IpcServer.h000066400000000000000000000023051457262621600205120ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_LOCALSERVER_H #define KSNIP_LOCALSERVER_H #include #include class IpcServer : public QObject { Q_OBJECT public: IpcServer(); ~IpcServer() override; bool listen(const QString &name); signals: void received(const QByteArray &data); private: QLocalServer *mLocalServer; private slots: void newConnection(); void processData(); }; #endif //KSNIP_LOCALSERVER_H ksnip-master/src/backend/recentImages/000077500000000000000000000000001457262621600202725ustar00rootroot00000000000000ksnip-master/src/backend/recentImages/IImagePathStorage.h000066400000000000000000000021351457262621600237410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMAGEPATHSTORAGE_H #define KSNIP_IIMAGEPATHSTORAGE_H #include class IImagePathStorage { public: virtual ~IImagePathStorage() = default; virtual void store(const QString &value, int index) = 0; virtual QString load(int index) = 0; virtual int count() = 0; }; #endif //KSNIP_IIMAGEPATHSTORAGE_H ksnip-master/src/backend/recentImages/IRecentImageService.h000066400000000000000000000021131457262621600242550ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IRECENTIMAGESERVICE_H #define KSNIP_IRECENTIMAGESERVICE_H class IRecentImageService { public: virtual ~IRecentImageService() = default; virtual void storeImagePath(const QString &imagePath) = 0; virtual QStringList getRecentImagesPath() const = 0; }; #endif //KSNIP_IRECENTIMAGESERVICE_H ksnip-master/src/backend/recentImages/ImagePathStorage.cpp000066400000000000000000000030461457262621600241650ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImagePathStorage.h" ImagePathStorage::ImagePathStorage() : mSettingsGroupPrefix(QLatin1String("recentImagesPath")), mSettingsGroupKey(QLatin1String("imagePath")) { } void ImagePathStorage::store(const QString &value, int index) { mSettings.beginWriteArray(mSettingsGroupPrefix); mSettings.setArrayIndex(index); mSettings.setValue(mSettingsGroupKey, value); mSettings.endArray(); mSettings.sync(); } QString ImagePathStorage::load(int index) { mSettings.beginReadArray(mSettingsGroupPrefix); mSettings.setArrayIndex(index); auto value = mSettings.value(mSettingsGroupKey).toString(); mSettings.endArray(); return value; } int ImagePathStorage::count() { auto count = mSettings.beginReadArray(mSettingsGroupPrefix); mSettings.endArray(); return count; } ksnip-master/src/backend/recentImages/ImagePathStorage.h000066400000000000000000000024111457262621600236250ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEPATHSTORAGE_H #define KSNIP_IMAGEPATHSTORAGE_H #include #include "IImagePathStorage.h" class ImagePathStorage : public IImagePathStorage { public: ImagePathStorage(); ~ImagePathStorage() override = default; void store(const QString &value, int index) override; QString load(int index) override; int count() override; private: QSettings mSettings; const QString mSettingsGroupPrefix; const QString mSettingsGroupKey; }; #endif //KSNIP_IMAGEPATHSTORAGE_H ksnip-master/src/backend/recentImages/RecentImagesPathStore.cpp000066400000000000000000000036711457262621600252050ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "RecentImagesPathStore.h" RecentImagesPathStore::RecentImagesPathStore(const QSharedPointer &imagePathStorage) : mImagePathStorage(imagePathStorage), mMaxRecentItems(10) { Q_ASSERT(mImagePathStorage != nullptr); loadRecentImagesPath(); } void RecentImagesPathStore::loadRecentImagesPath() { const auto storedImageCount = mImagePathStorage->count(); for (auto i = 0; i < storedImageCount; ++i) { mRecentImagesPathCache.enqueue(mImagePathStorage->load(i)); } } void RecentImagesPathStore::storeImagePath(const QString &imagePath) { if (mRecentImagesPathCache.contains(imagePath)) { return; } if (mRecentImagesPathCache.size() == mMaxRecentItems) { mRecentImagesPathCache.dequeue(); } mRecentImagesPathCache.enqueue(imagePath); saveRecentImagesPath(); } void RecentImagesPathStore::saveRecentImagesPath() { for (auto i = 0 ; i < mRecentImagesPathCache.size(); ++i) { mImagePathStorage->store(mRecentImagesPathCache.at(i), i); } } QStringList RecentImagesPathStore::getRecentImagesPath() const { QStringList reversedList = mRecentImagesPathCache; std::reverse(reversedList.begin(), reversedList.end()); return reversedList; } ksnip-master/src/backend/recentImages/RecentImagesPathStore.h000066400000000000000000000030261457262621600246440ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RECENTIMAGESPATHSTORE_H #define KSNIP_RECENTIMAGESPATHSTORE_H #include #include #include #include "IImagePathStorage.h" #include "IRecentImageService.h" class RecentImagesPathStore : public IRecentImageService { public: explicit RecentImagesPathStore(const QSharedPointer &imagePathStorage); ~RecentImagesPathStore() override = default; void storeImagePath(const QString &imagePath) override; QStringList getRecentImagesPath() const override; private: const QSharedPointer mImagePathStorage; QQueue mRecentImagesPathCache; const int mMaxRecentItems; void loadRecentImagesPath(); void saveRecentImagesPath(); }; #endif //KSNIP_RECENTIMAGESPATHSTORE_H ksnip-master/src/backend/saver/000077500000000000000000000000001457262621600170045ustar00rootroot00000000000000ksnip-master/src/backend/saver/IImageSaver.h000066400000000000000000000020251457262621600213100ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMAGESAVER_H #define KSNIP_IIMAGESAVER_H class QString; class IImageSaver { public: IImageSaver() = default; ~IImageSaver() = default; virtual bool save(const QImage &image, const QString &path) = 0; }; #endif //KSNIP_IIMAGESAVER_H ksnip-master/src/backend/saver/ISavePathProvider.h000066400000000000000000000022201457262621600225100ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ISAVEPATHPROVIDER_H #define KSNIP_ISAVEPATHPROVIDER_H class QString; class ISavePathProvider { public: ISavePathProvider() = default; ~ISavePathProvider() = default; virtual QString savePath() const = 0; virtual QString savePathWithFormat(const QString& format) const = 0; virtual QString saveDirectory() const = 0; }; #endif //KSNIP_ISAVEPATHPROVIDER_H ksnip-master/src/backend/saver/ImageSaver.cpp000066400000000000000000000035021457262621600215330ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImageSaver.h" ImageSaver::ImageSaver(const QSharedPointer &config) : mConfig(config) { } bool ImageSaver::save(const QImage &image, const QString &path) { ensurePathExists(path); auto fullPath = ensureFilenameHasFormat(path); auto isSuccessful = image.save(fullPath, nullptr, getSaveQuality()); if (!isSuccessful) { qCritical("Unable to save file '%s'", qPrintable(fullPath)); } return isSuccessful; } void ImageSaver::ensurePathExists(const QString &path) { auto directory = PathHelper::extractParentDirectory(path); QDir dir(directory); if(!dir.exists()) { dir.mkpath(QLatin1String(".")); } } QString ImageSaver::ensureFilenameHasFormat(const QString &path) { auto format = PathHelper::extractFormat(path); if(format.isEmpty()) { return path + QLatin1String(".") + mConfig->saveFormat(); } return path; } int ImageSaver::getSaveQuality() { auto defaultQualityFactor = -1; return mConfig->saveQualityMode() == SaveQualityMode::Default ? defaultQualityFactor : mConfig->saveQualityFactor(); } ksnip-master/src/backend/saver/ImageSaver.h000066400000000000000000000026261457262621600212060ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGESAVER_H #define KSNIP_IMAGESAVER_H #include #include #include #include "IImageSaver.h" #include "src/backend/config/IConfig.h" #include "src/common/helper/PathHelper.h" class ImageSaver : public IImageSaver { public: explicit ImageSaver(const QSharedPointer &config); ~ImageSaver() = default; bool save(const QImage &image, const QString &path); private: QSharedPointer mConfig; static void ensurePathExists(const QString &path); QString ensureFilenameHasFormat(const QString &path); int getSaveQuality(); }; #endif //KSNIP_IMAGESAVER_H ksnip-master/src/backend/saver/NameProvider.cpp000066400000000000000000000017171457262621600221110ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "NameProvider.h" QString NameProvider::makeFilename(const QString& path, const QString& filename, const QString& format) { return path + filename + format; } ksnip-master/src/backend/saver/NameProvider.h000066400000000000000000000020641457262621600215520ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NAMEPROVIDER_H #define KSNIP_NAMEPROVIDER_H #include #include class NameProvider { public: static QString makeFilename(const QString &path, const QString &filename, const QString &format = QString()); }; #endif //KSNIP_NAMEPROVIDER_H ksnip-master/src/backend/saver/SavePathProvider.cpp000066400000000000000000000036261457262621600227450ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SavePathProvider.h" SavePathProvider::SavePathProvider(const QSharedPointer &config) : mConfig(config) { } QString SavePathProvider::savePath() const { if (mConfig->overwriteFile()) { return NameProvider::makeFilename(saveDirectory(), getFilename(), getFormat(mConfig->saveFormat())); } else { return UniqueNameProvider::makeUniqueFilename(saveDirectory(), getFilename(), getFormat(mConfig->saveFormat())); } } QString SavePathProvider::savePathWithFormat(const QString &format) const { return UniqueNameProvider::makeUniqueFilename(saveDirectory(), getFilename(), getFormat(format)); } QString SavePathProvider::getFilename() const { auto filename = WildcardResolver::replaceDateTimeWildcards(mConfig->saveFilename()); return WildcardResolver::replaceNumberWildcards(filename, saveDirectory(), getFormat(mConfig->saveFormat())); } QString SavePathProvider::getFormat(const QString &format) const { return format.startsWith(QLatin1Char('.')) ? format : QLatin1Char('.') + format; } QString SavePathProvider::saveDirectory() const { return WildcardResolver::replaceDateTimeWildcards(mConfig->saveDirectory()); } ksnip-master/src/backend/saver/SavePathProvider.h000066400000000000000000000030351457262621600224040ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SAVEPATHPROVIDER_H #define KSNIP_SAVEPATHPROVIDER_H #include #include "ISavePathProvider.h" #include "src/backend/saver/WildcardResolver.h" #include "src/backend/saver/NameProvider.h" #include "src/backend/saver/UniqueNameProvider.h" #include "src/backend/config/IConfig.h" class SavePathProvider : public ISavePathProvider { public: explicit SavePathProvider(const QSharedPointer &config); ~SavePathProvider() = default; QString savePath() const override; QString savePathWithFormat(const QString& format) const override; QString saveDirectory() const override; private: QSharedPointer mConfig; QString getFormat(const QString &format) const; QString getFilename() const; }; #endif //KSNIP_SAVEPATHPROVIDER_H ksnip-master/src/backend/saver/UniqueNameProvider.cpp000066400000000000000000000025031457262621600232720ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "UniqueNameProvider.h" QString UniqueNameProvider::makeUniqueFilename(const QString& path, const QString& filename, const QString& format) { auto uniqueFilename = path + filename + format; if (QFile::exists(uniqueFilename)) { auto i = 1; auto openingParentheses = QLatin1String("("); auto closingParentheses = QLatin1String(")") ; while (QFile::exists(uniqueFilename)) { i++; uniqueFilename = path + filename + openingParentheses + QString::number(i) + closingParentheses + format; } } return uniqueFilename; }ksnip-master/src/backend/saver/UniqueNameProvider.h000066400000000000000000000021221457262621600227340ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UNIQUENAMEPROVIDER_H #define KSNIP_UNIQUENAMEPROVIDER_H #include #include class UniqueNameProvider { public: static QString makeUniqueFilename(const QString &path, const QString &filename, const QString &format = QString()); }; #endif //KSNIP_UNIQUENAMEPROVIDER_H ksnip-master/src/backend/saver/WildcardResolver.cpp000066400000000000000000000061701457262621600227670ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WildcardResolver.h" QString WildcardResolver::replaceDateTimeWildcards(const QString &filename) { auto filenameWithoutWildcards = filename; filenameWithoutWildcards.replace(QLatin1String("$Y"), QDateTime::currentDateTime().toString(QLatin1String("yyyy"))); filenameWithoutWildcards.replace(QLatin1String("$M"), QDateTime::currentDateTime().toString(QLatin1String("MM"))); filenameWithoutWildcards.replace(QLatin1String("$D"), QDateTime::currentDateTime().toString(QLatin1String("dd"))); filenameWithoutWildcards.replace(QLatin1String("$T"), QDateTime::currentDateTime().toString(QLatin1String("hhmmss"))); filenameWithoutWildcards.replace(QLatin1String("$h"), QDateTime::currentDateTime().toString(QLatin1String("hh"))); filenameWithoutWildcards.replace(QLatin1String("$m"), QDateTime::currentDateTime().toString(QLatin1String("mm"))); filenameWithoutWildcards.replace(QLatin1String("$s"), QDateTime::currentDateTime().toString(QLatin1String("ss"))); return filenameWithoutWildcards; } QString WildcardResolver::replaceNumberWildcards(const QString &filename, const QString &directory, const QString &format) { auto filenameWithoutWildcards = filename; auto wildcard = QLatin1Char('#'); if(filenameWithoutWildcards.contains(wildcard)) { auto firstWildcardIndex = filename.indexOf(wildcard); auto lastWildcardIndex = filename.lastIndexOf(wildcard); auto leftPart = filename.left(firstWildcardIndex); auto rightPart = filename.mid(lastWildcardIndex + 1); auto digitCount = filename.count(wildcard); auto highestNumber = getHighestWildcardNumber(directory, leftPart, rightPart, format); filenameWithoutWildcards = leftPart + QString("%1").arg(highestNumber + 1, digitCount, 10, QChar('0')) + rightPart; } return filenameWithoutWildcards; } int WildcardResolver::getHighestWildcardNumber(const QString &directory, const QString &leftPart, const QString &rightPart, const QString &format) { auto rightPartWithFormat = rightPart + format; QDir parentDirectory(directory); auto number = 0; auto allFiles = parentDirectory.entryList({ QLatin1String("*") + format }, QDir::Files); for(auto file : allFiles) { if(file.startsWith(leftPart) && file.endsWith(rightPartWithFormat)) { file.remove(leftPart); file.remove(rightPartWithFormat); auto currentNumber = file.toInt(); number = qMax(number, currentNumber); } } return number; }ksnip-master/src/backend/saver/WildcardResolver.h000066400000000000000000000025031457262621600224300ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WILDCARDRESOLVER_H #define KSNIP_WILDCARDRESOLVER_H #include #include #include #include class WildcardResolver { public: static QString replaceDateTimeWildcards(const QString &filename); static QString replaceNumberWildcards(const QString &filename, const QString &directory, const QString &format); private: static int getHighestWildcardNumber(const QString &directory, const QString &leftPart, const QString &rightPart, const QString &format); }; #endif //KSNIP_WILDCARDRESOLVER_H ksnip-master/src/backend/uploader/000077500000000000000000000000001457262621600174775ustar00rootroot00000000000000ksnip-master/src/backend/uploader/IUploadHandler.h000066400000000000000000000020231457262621600225000ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IUPLOADHANDLER_H #define KSNIP_IUPLOADHANDLER_H #include "IUploader.h" class IUploadHandler : public IUploader { Q_OBJECT public: IUploadHandler() = default; ~IUploadHandler() override = default; }; #endif //KSNIP_IUPLOADHANDLER_H ksnip-master/src/backend/uploader/IUploader.h000066400000000000000000000023171457262621600215370ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IUPLOADER_H #define KSNIP_IUPLOADER_H #include #include "UploadResult.h" #include "src/common/enum/UploaderType.h" class QImage; class IUploader : public QObject { Q_OBJECT public: IUploader() = default; ~IUploader() override = default; virtual void upload(const QImage &image) = 0; virtual UploaderType type() const = 0; signals: void finished(const UploadResult &result); }; #endif //KSNIP_IUPLOADER_H ksnip-master/src/backend/uploader/UploadHandler.cpp000066400000000000000000000030261457262621600227260ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "UploadHandler.h" UploadHandler::UploadHandler( const QSharedPointer &config, const QSharedPointer &ftpUploader, const QSharedPointer &scriptUploader, const QSharedPointer &imgurUploader) : mConfig(config) { insertUploader(imgurUploader); insertUploader(scriptUploader); insertUploader(ftpUploader); } void UploadHandler::upload(const QImage &image) { mTypeToUploaderMap[type()]->upload(image); } UploaderType UploadHandler::type() const { return mConfig->uploaderType(); } void UploadHandler::insertUploader(const QSharedPointer &uploader) { mTypeToUploaderMap[uploader->type()] = uploader; connect(uploader.data(), &IUploader::finished, this, &IUploader::finished); } ksnip-master/src/backend/uploader/UploadHandler.h000066400000000000000000000033231457262621600223730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADHANDLER_H #define KSNIP_UPLOADHANDLER_H #include #include #include "IUploadHandler.h" #include "src/backend/uploader/imgur/IImgurUploader.h" #include "src/backend/uploader/script/IScriptUploader.h" #include "src/backend/uploader/ftp/IFtpUploader.h" #include "src/backend/config/IConfig.h" class UploadHandler : public IUploadHandler { public: explicit UploadHandler( const QSharedPointer &config, const QSharedPointer &ftpUploader, const QSharedPointer &scriptUploader, const QSharedPointer &imgurUploader); ~UploadHandler() override = default; void upload(const QImage &image) override; UploaderType type() const override; private: QSharedPointer mConfig; QMap> mTypeToUploaderMap; void insertUploader(const QSharedPointer &uploader); }; #endif //KSNIP_UPLOADHANDLER_H ksnip-master/src/backend/uploader/UploadResult.h000066400000000000000000000027621457262621600223020ustar00rootroot00000000000000/* * Copyright (C) 2030 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADRESULT_H #define KSNIP_UPLOADRESULT_H #include #include "src/common/enum/UploadStatus.h" #include "src/common/enum/UploaderType.h" struct UploadResult { UploadStatus status; UploaderType type; QString content; explicit UploadResult(UploadStatus status, UploaderType type) { this->status = status; this->type = type; } explicit UploadResult(UploadStatus status, UploaderType type, const QString &content) { this->status = status; this->type = type; this->content = content; } bool isError() const { return this->status != UploadStatus::NoError; } bool hasContent() const { return !this->content.isEmpty() && !this->content.isNull(); } }; #endif //KSNIP_UPLOADRESULT_H ksnip-master/src/backend/uploader/ftp/000077500000000000000000000000001457262621600202705ustar00rootroot00000000000000ksnip-master/src/backend/uploader/ftp/FtpUploader.cpp000066400000000000000000000067751457262621600232400ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "FtpUploader.h" FtpUploader::FtpUploader(const QSharedPointer &config, const QSharedPointer &logger) : mConfig(config), mLogger(logger), mReply(nullptr) { } void FtpUploader::upload(const QImage &image) { // Convert the image into a byteArray auto imageByteArray = getImageAsByteArray(image); auto url = getUploadUrl(); mLogger->log(QString("FTP upload started to %1").arg(url.toString(QUrl::RemoveUserInfo))); mReply = mNetworkAccessManager.put(QNetworkRequest(url), imageByteArray); connect(mReply, &QNetworkReply::uploadProgress, this, &FtpUploader::uploadProgress); connect(mReply, &QNetworkReply::finished, this, &FtpUploader::uploadDone); } QByteArray FtpUploader::getImageAsByteArray(const QImage &image) { QByteArray imageByteArray; QBuffer buffer(&imageByteArray); image.save(&buffer, "PNG"); return imageByteArray; } QUrl FtpUploader::getUploadUrl() const { QUrl url(mConfig->ftpUploadUrl() + QLatin1String("/") + getFilename()); if(mConfig->ftpUploadForceAnonymous()) { mLogger->log(QLatin1String("Enforcing anonymous FTP upload.")); } else { url.setUserName(mConfig->ftpUploadUsername()); url.setPassword(mConfig->ftpUploadPassword()); } return url.adjusted(QUrl::NormalizePathSegments); } QString FtpUploader::getFilename() { return QLatin1String("ksnip_") + QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm:ss"); } UploaderType FtpUploader::type() const { return UploaderType::Ftp; } void FtpUploader::uploadProgress(qint64 bytesSent, qint64 bytesTotal) { mLogger->log(QString("Uploaded %1 of %2 bytes.").arg(QString::number(bytesSent), QString::number(bytesTotal))); } void FtpUploader::uploadDone() { mLogger->log(QLatin1String("FTP uploaded finished with status %1."), mReply->error()); emit finished(UploadResult(mapErrorTypeToStatus(mReply->error()), type())); mReply->deleteLater(); } UploadStatus FtpUploader::mapErrorTypeToStatus(QNetworkReply::NetworkError errorType) { switch (errorType) { case QNetworkReply::NetworkError::NoError: return UploadStatus::NoError; case QNetworkReply::NetworkError::TimeoutError: return UploadStatus::TimedOut; case QNetworkReply::NetworkError::ConnectionRefusedError: case QNetworkReply::NetworkError::RemoteHostClosedError: case QNetworkReply::NetworkError::HostNotFoundError: case QNetworkReply::NetworkError::TemporaryNetworkFailureError: case QNetworkReply::NetworkError::ServiceUnavailableError: return UploadStatus::ConnectionError; case QNetworkReply::NetworkError::ContentOperationNotPermittedError: case QNetworkReply::NetworkError::ContentAccessDenied: case QNetworkReply::NetworkError::AuthenticationRequiredError: return UploadStatus::PermissionError; default: return UploadStatus::UnknownError; } } ksnip-master/src/backend/uploader/ftp/FtpUploader.h000066400000000000000000000034141457262621600226700ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FTPUPLOADER_H #define KSNIP_FTPUPLOADER_H #include #include #include #include #include #include "IFtpUploader.h" #include "src/backend/config/IConfig.h" #include "src/logging/ILogger.h" class FtpUploader : public IFtpUploader { public: FtpUploader(const QSharedPointer &config, const QSharedPointer &logger); ~FtpUploader() override = default; void upload(const QImage &image) override; UploaderType type() const override; private: QSharedPointer mConfig; QSharedPointer mLogger; QNetworkAccessManager mNetworkAccessManager; QNetworkReply *mReply; static UploadStatus mapErrorTypeToStatus(QNetworkReply::NetworkError errorType); static QString getFilename(); static QByteArray getImageAsByteArray(const QImage &image); QUrl getUploadUrl() const; private slots: void uploadProgress(qint64 bytesSent, qint64 bytesTotal); void uploadDone(); }; #endif //KSNIP_FTPUPLOADER_H ksnip-master/src/backend/uploader/ftp/IFtpUploader.h000066400000000000000000000020221457262621600227730ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IFTPUPLOADER_H #define KSNIP_IFTPUPLOADER_H #include "src/backend/uploader/IUploader.h" class IFtpUploader : public IUploader { public: IFtpUploader() = default; ~IFtpUploader() override = default; }; #endif //KSNIP_IFTPUPLOADER_H ksnip-master/src/backend/uploader/imgur/000077500000000000000000000000001457262621600206225ustar00rootroot00000000000000ksnip-master/src/backend/uploader/imgur/IImgurUploader.h000066400000000000000000000020471457262621600236660ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMGURUPLOADER_H #define KSNIP_IIMGURUPLOADER_H #include "src/backend/uploader/IUploader.h" class IImgurUploader : public IUploader { public: explicit IImgurUploader() = default; ~IImgurUploader() override = default; }; #endif //KSNIP_IIMGURUPLOADER_H ksnip-master/src/backend/uploader/imgur/ImgurResponse.cpp000066400000000000000000000022611457262621600241310ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "ImgurResponse.h" ImgurResponse::ImgurResponse(const QString &link, const QString &deleteHash) { mLink = link; mDeleteHash = deleteHash; mTimeStamp = QDateTime::currentDateTime(); } QString ImgurResponse::link() const { return mLink; } QString ImgurResponse::deleteHash() const { return mDeleteHash; } QDateTime ImgurResponse::timeStamp() const { return mTimeStamp; } ksnip-master/src/backend/uploader/imgur/ImgurResponse.h000066400000000000000000000023321457262621600235750ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_IMGURRESPONSE_H #define KSNIP_IMGURRESPONSE_H #include #include class ImgurResponse { public: explicit ImgurResponse(const QString &link, const QString &deleteHash); ~ImgurResponse() = default; QString link() const; QString deleteHash() const; QDateTime timeStamp() const; private: QString mLink; QString mDeleteHash; QDateTime mTimeStamp; }; #endif //KSNIP_IMGURRESPONSE_H ksnip-master/src/backend/uploader/imgur/ImgurResponseLogger.cpp000066400000000000000000000045171457262621600252770ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include "ImgurResponseLogger.h" ImgurResponseLogger::ImgurResponseLogger() { mLogFilename = QLatin1String("imgur_history.txt"); mLogPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); mLogFilePath = mLogPath + QLatin1String("/") + mLogFilename; } void ImgurResponseLogger::log(const ImgurResponse &response) { createPathIfRequired(); auto logEntry = getLogEntry(response); writeLogEntry(logEntry); } void ImgurResponseLogger::writeLogEntry(const QString &logEntry) const { QFile file(mLogFilePath); auto fileOpened = file.open(QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text); if(fileOpened) { QTextStream stream(&file); stream << logEntry << endl; } } void ImgurResponseLogger::createPathIfRequired() const { QDir qdir; qdir.mkpath(mLogPath); } QString ImgurResponseLogger::getLogEntry(const ImgurResponse &response) const { auto separator = QLatin1String(","); auto deleteLink = QLatin1String("https://imgur.com/delete/") + response.deleteHash(); auto timestamp = response.timeStamp().toString(QLatin1String("dd.MM.yyyy hh:mm:ss")); return timestamp + separator + response.link() + separator + deleteLink; } QStringList ImgurResponseLogger::getLogs() const { auto logEntries = QStringList(); QFile file(mLogFilePath); auto fileOpened = file.open(QIODevice::ReadOnly); if (fileOpened) { QTextStream stream(&file); while (!stream.atEnd()) { auto entry = stream.readLine(); logEntries.append(entry); } } return logEntries; } ksnip-master/src/backend/uploader/imgur/ImgurResponseLogger.h000066400000000000000000000026271457262621600247440ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_IMGURRESPONSELOGGER_H #define KSNIP_IMGURRESPONSELOGGER_H #include #include #include #include "ImgurResponse.h" class ImgurResponseLogger { public: explicit ImgurResponseLogger(); ~ImgurResponseLogger() = default; void log(const ImgurResponse &response); QStringList getLogs() const; private: QString mLogFilename; QString mLogPath; QString mLogFilePath; void createPathIfRequired() const; QString getLogEntry(const ImgurResponse &response) const; void writeLogEntry(const QString &logEntry) const; }; #endif //KSNIP_IMGURRESPONSELOGGER_H ksnip-master/src/backend/uploader/imgur/ImgurUploader.cpp000066400000000000000000000105151457262621600241070ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImgurUploader.h" ImgurUploader::ImgurUploader(const QSharedPointer &config) : mConfig(config), mImgurWrapper(new ImgurWrapper(mConfig->imgurBaseUrl(), nullptr)), mImgurResponseLogger(new ImgurResponseLogger) { connect(mImgurWrapper, &ImgurWrapper::uploadFinished, this, &ImgurUploader::imgurUploadFinished); connect(mImgurWrapper, &ImgurWrapper::error, this, &ImgurUploader::imgurError); connect(mImgurWrapper, &ImgurWrapper::tokenUpdated, this, &ImgurUploader::imgurTokenUpdated); connect(mImgurWrapper, &ImgurWrapper::tokenRefreshRequired, this, &ImgurUploader::imgurTokenRefresh); } UploaderType ImgurUploader::type() const { return UploaderType::Imgur; } ImgurUploader::~ImgurUploader() { delete mImgurWrapper; delete mImgurResponseLogger; } void ImgurUploader::upload(const QImage &image) { mImage = image; const auto uploadTitle = mConfig->imgurUploadTitle(); const auto uploadDescription = mConfig->imgurUploadDescription(); if (!mConfig->imgurForceAnonymous() && !mConfig->imgurAccessToken().isEmpty()) { mImgurWrapper->startUpload(mImage, uploadTitle, uploadDescription, mConfig->imgurAccessToken()); } else { mImgurWrapper->startUpload(mImage, uploadTitle, uploadDescription); } } void ImgurUploader::imgurUploadFinished(const ImgurResponse &response) { qInfo("%s", qPrintable(tr("Upload to imgur.com finished!"))); mImgurResponseLogger->log(response); auto url = formatResponseUrl(response); emit finished(UploadResult(UploadStatus::NoError, type(), url)); } QString ImgurUploader::formatResponseUrl(const ImgurResponse &response) const { if (!mConfig->imgurLinkDirectlyToImage()) { return response.link().remove(QLatin1String(".png")); } return response.link(); } void ImgurUploader::imgurError(QNetworkReply::NetworkError networkError, const QString &message) { qCritical("MainWindow: Imgur uploader returned error: '%s'", qPrintable(message)); emit finished(UploadResult(mapErrorTypeToStatus(networkError), type(), message)); } UploadStatus ImgurUploader::mapErrorTypeToStatus(QNetworkReply::NetworkError errorType) { switch (errorType) { case QNetworkReply::NetworkError::NoError: return UploadStatus::NoError; case QNetworkReply::NetworkError::TimeoutError: return UploadStatus::TimedOut; case QNetworkReply::NetworkError::ConnectionRefusedError: case QNetworkReply::NetworkError::RemoteHostClosedError: case QNetworkReply::NetworkError::HostNotFoundError: case QNetworkReply::NetworkError::TemporaryNetworkFailureError: case QNetworkReply::NetworkError::ServiceUnavailableError: return UploadStatus::ConnectionError; case QNetworkReply::NetworkError::ContentOperationNotPermittedError: case QNetworkReply::NetworkError::ContentAccessDenied: case QNetworkReply::NetworkError::AuthenticationRequiredError: return UploadStatus::PermissionError; case QNetworkReply::ProtocolFailure: return UploadStatus::WebError; default: return UploadStatus::UnknownError; } } void ImgurUploader::imgurTokenUpdated(const QString &accessToken, const QString &refreshToken, const QString &username) { mConfig->setImgurAccessToken(accessToken.toUtf8()); mConfig->setImgurRefreshToken(refreshToken.toUtf8()); mConfig->setImgurUsername(username); qInfo("%s", qPrintable(tr("Received new token, trying upload again…"))); upload(mImage); } void ImgurUploader::imgurTokenRefresh() { mImgurWrapper->refreshToken(mConfig->imgurRefreshToken(), mConfig->imgurClientId(), mConfig->imgurClientSecret()); qInfo("%s", qPrintable(tr("Imgur token has expired, requesting new token…"))); } ksnip-master/src/backend/uploader/imgur/ImgurUploader.h000066400000000000000000000037311457262621600235560ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMGURUPLOADER_H #define KSNIP_IMGURUPLOADER_H #include #include "IImgurUploader.h" #include "ImgurWrapper.h" #include "ImgurResponseLogger.h" #include "src/backend/uploader/IUploader.h" #include "src/backend/uploader/UploadResult.h" #include "src/backend/config/IConfig.h" #include "src/common/constants/DefaultValues.h" class ImgurUploader : public IImgurUploader { Q_OBJECT public: explicit ImgurUploader(const QSharedPointer &config); ~ImgurUploader() override; void upload(const QImage &image) override; UploaderType type() const override; private: QSharedPointer mConfig; ImgurWrapper *mImgurWrapper; ImgurResponseLogger *mImgurResponseLogger; QImage mImage; static UploadStatus mapErrorTypeToStatus(QNetworkReply::NetworkError errorType); private slots: void imgurUploadFinished(const ImgurResponse &response); void imgurError(QNetworkReply::NetworkError networkError, const QString &message); void imgurTokenUpdated(const QString &accessToken, const QString &refreshToken, const QString &username); void imgurTokenRefresh(); QString formatResponseUrl(const ImgurResponse &response) const; }; #endif //KSNIP_IMGURUPLOADER_H ksnip-master/src/backend/uploader/imgur/ImgurWrapper.cpp000066400000000000000000000222451457262621600237570ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "ImgurWrapper.h" ImgurWrapper::ImgurWrapper(const QString &imgurUrl, QObject *parent) : mBaseImgurUrl(imgurUrl), QObject(parent), mAccessManager(new QNetworkAccessManager(this)) { connect(mAccessManager, &QNetworkAccessManager::finished, this, &ImgurWrapper::handleReply); // Client ID that will only be used for anonymous upload mClientId = "16d41e28a3ba71e"; } /* * This function starts the upload, depending if an access token was provided * this will be either an account upload on an anonymous upload. If the upload * was successful the upload Fished signal will be emitted which holds the url * to the image. */ void ImgurWrapper::startUpload(const QImage& image, const QString &title, const QString &description, const QByteArray& accessToken) const { // Convert the image into a byteArray QByteArray imageByteArray; QBuffer buffer(&imageByteArray); image.save(&buffer, "PNG"); // Create the network request for posting the image QUrl url(mBaseImgurUrl + QLatin1String("/3/upload.xml")); QUrlQuery urlQuery; // Add params that we send with the picture urlQuery.addQueryItem(QLatin1String("title"), title); urlQuery.addQueryItem(QLatin1String("description"), description); url.setQuery(urlQuery); QNetworkRequest request; request.setUrl(url); request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); // If an access token was sent, we upload to account, otherwise we upload // anonymously if (accessToken.isEmpty()) { request.setRawHeader("Authorization", "Client-ID " + mClientId); } else { request.setRawHeader("Authorization", "Bearer " + accessToken); } // Post the image mAccessManager->post(request, imageByteArray); } /* * This functions requests an access token, it only starts the request, the * tokenUpdate signal will be emitted if the request was successful or otherwise * the tokenError. */ void ImgurWrapper::getAccessToken(const QByteArray& pin, const QByteArray& clientId, const QByteArray& clientSecret) const { QNetworkRequest request; // Build the URL that we will request the token from. The XML indicates we // want the response in XML format. request.setUrl(QUrl(mBaseImgurUrl + QLatin1String("/oauth2/token.xml"))); request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); // Prepare the params that we send with the request QByteArray params; params.append("client_id=" + clientId); params.append("&client_secret=" + clientSecret); params.append("&grant_type=pin"); params.append("&pin=" + pin); // Request the token mAccessManager->post(request, params); } /* * The imgur token expires after some time, when this happens, and you try to * post an image the server responds with 403, and we emit the * tokenRefreshRequired signal, after which this function should be called to * refresh the token. */ void ImgurWrapper::refreshToken(const QByteArray& refreshToken, const QByteArray& clientId, const QByteArray& clientSecret) const { QNetworkRequest request; // Build the URL that we will request the token from. The XML indicates we // want the response in XML format request.setUrl(QUrl(mBaseImgurUrl + QLatin1String("/oauth2/token.xml"))); request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String("application/x-www-form-urlencoded")); // Prepare the params QByteArray params; params.append("refresh_token=" + refreshToken); params.append("&client_id=" + clientId); params.append("&client_secret=" + clientSecret); params.append("&grant_type=refresh_token"); // Request the token mAccessManager->post(request, params); } /* * Returns a URL that can be opened in a browser to request the pin. The * function is not opening the pin window in the browser, it only returns the * correct url to it. */ QUrl ImgurWrapper::pinRequestUrl(const QString& clientId) const { QUrl url(mBaseImgurUrl + QLatin1String("/oauth2/authorize")); QUrlQuery urlQuery; urlQuery.addQueryItem(QLatin1String("client_id"), clientId); urlQuery.addQueryItem(QLatin1String("response_type"), QLatin1String("pin")); url.setQuery(urlQuery); return url; } /* * This function handles the default response, a 200OK and any error message is * returned in a data root element. 200OK is returned when posting an image was * successful, 403 is mostly returned when a token has expired, anything else is * an error that we currently cannot handle */ void ImgurWrapper::handleDataResponse(const QDomElement& element) const { if (element.attribute(QLatin1String("status")) == QLatin1String("200") && !element.elementsByTagName(QLatin1String("link")).isEmpty()) { auto link = element.elementsByTagName(QLatin1String("link")).at(0).toElement().text(); auto deleteHash = element.elementsByTagName(QLatin1String("deletehash")).at(0).toElement().text(); emit uploadFinished(ImgurResponse(link, deleteHash)); } else if (element.attribute(QLatin1String("status")) == QLatin1String("403")) { emit tokenRefreshRequired(); } else { if (element.elementsByTagName(QLatin1String("error")).isEmpty()) { emit error(QNetworkReply::ProtocolFailure, QLatin1String("Server responded with ") + element.attribute(QLatin1String("status"))); } else { emit error(QNetworkReply::ProtocolFailure, QLatin1String("Server responded with ") + element.attribute(QLatin1String("status")) + QLatin1String(": ") + element.elementsByTagName(QLatin1String("error")).at(0).toElement().text()); } } } /* * Called when a new token was received, either when first time getting access * or refreshing a token */ void ImgurWrapper::handleTokenResponse(const QDomElement& element) const { if (!element.elementsByTagName(QLatin1String("access_token")).isEmpty() && !element.elementsByTagName(QLatin1String("refresh_token")).isEmpty() && !element.elementsByTagName(QLatin1String("account_username")).isEmpty() ) { emit tokenUpdated(element.elementsByTagName(QLatin1String("access_token")).at(0).toElement().text(), element.elementsByTagName(QLatin1String("refresh_token")).at(0).toElement().text(), element.elementsByTagName(QLatin1String("account_username")).at(0).toElement().text() ); } else { emit error(QNetworkReply::ProtocolFailure, QLatin1String("Expected token response was received, something went wrong.")); } } /* * This function will be called when we've got the reply from imgur */ void ImgurWrapper::handleReply(QNetworkReply* reply) { // Only for troubleshooting, if reply->readAll is called the parser will fail! // qDebug("----------------------------------------------------------------"); // qDebug("Reply code:\n%s", qPrintable(reply->readAll())); // qDebug("----------------------------------------------------------------"); // Check network return code, if we get no error or if we get a status 202, // proceed, the 202 is returned for invalid token, we will request a new // token. if (reply->error() != QNetworkReply::NoError && reply->error() != QNetworkReply::ContentOperationNotPermittedError) { emit error(reply->error(), QLatin1String("Network Error(") + QString::number(reply->error()) + QLatin1String("): ") + reply->errorString()); reply->deleteLater(); return; } QDomDocument doc; QString errorMessage; int errorLine; int errorColumn; // Try to parse reply into xml reader if (!doc.setContent(reply->readAll(), false, &errorMessage, &errorLine, &errorColumn)) { emit error(QNetworkReply::ProtocolFailure, QLatin1String("Parse error: ") + errorMessage + QLatin1String(", line:") + QString::number(errorLine) + QLatin1String(", column:") + QString::number(errorColumn)); reply->deleteLater(); return; } // See if we have an upload reply, token response or error auto rootElement = doc.documentElement(); if (rootElement.tagName() == QLatin1String("data")) { handleDataResponse(rootElement); } else if (rootElement.tagName() == QLatin1String("response")) { handleTokenResponse(rootElement); } else { emit error(QNetworkReply::ProtocolFailure, QLatin1String("Received unexpected reply from imgur server.")); } reply->deleteLater(); } ksnip-master/src/backend/uploader/imgur/ImgurWrapper.h000066400000000000000000000042501457262621600234200ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_IMGURWRAPPER_H #define KSNIP_IMGURWRAPPER_H #include #include #include #include #include #include #include #include "ImgurResponse.h" class ImgurWrapper : public QObject { Q_OBJECT public: explicit ImgurWrapper(const QString &imgurUrl, QObject *parent); void startUpload(const QImage &image, const QString &title, const QString &description, const QByteArray &accessToken = nullptr) const; void getAccessToken(const QByteArray &pin, const QByteArray &clientId, const QByteArray &clientSecret) const; void refreshToken(const QByteArray &refreshToken, const QByteArray &clientId, const QByteArray &clientSecret) const; QUrl pinRequestUrl(const QString &clientId) const; signals: void uploadFinished(const ImgurResponse &response) const; void error(QNetworkReply::NetworkError networkError, const QString &message) const; void tokenUpdated(const QString &accessToken, const QString &refreshToken, const QString &username) const; void tokenRefreshRequired() const; private: QNetworkAccessManager *mAccessManager; QByteArray mClientId; QString mBaseImgurUrl; void handleDataResponse(const QDomElement &element) const; void handleTokenResponse(const QDomElement &element) const; private slots: void handleReply(QNetworkReply *reply); }; #endif // KSNIP_IMGURWRAPPER_H ksnip-master/src/backend/uploader/script/000077500000000000000000000000001457262621600210035ustar00rootroot00000000000000ksnip-master/src/backend/uploader/script/IScriptUploader.h000066400000000000000000000020441457262621600242250ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ISCRIPTUPLOADER_H #define KSNIP_ISCRIPTUPLOADER_H #include "src/backend/uploader/IUploader.h" class IScriptUploader : public IUploader { public: IScriptUploader() = default; ~IScriptUploader() override = default; }; #endif //KSNIP_ISCRIPTUPLOADER_H ksnip-master/src/backend/uploader/script/ScriptUploader.cpp000066400000000000000000000072511457262621600244540ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ScriptUploader.h" ScriptUploader::ScriptUploader(const QSharedPointer &config, const QSharedPointer &tempFileProvider) : mConfig(config), mTempFileProvider(tempFileProvider) { connect(&mProcessHandler, QOverload::of(&QProcess::finished), this, &ScriptUploader::scriptFinished); connect(&mProcessHandler, &QProcess::errorOccurred, this, &ScriptUploader::errorOccurred); } void ScriptUploader::upload(const QImage &image) { if(saveImageLocally(image)) { mProcessHandler.start(mConfig->uploadScriptPath(), { mPathToTmpImage }); } else { auto result = UploadResult(UploadStatus::UnableToSaveTemporaryImage, type()); emit finished(result); } } UploaderType ScriptUploader::type() const { return UploaderType::Script; } bool ScriptUploader::saveImageLocally(const QImage &image) { mPathToTmpImage = mTempFileProvider->tempFile(); return image.save(mPathToTmpImage); } void ScriptUploader::scriptFinished(int exitCode, QProcess::ExitStatus exitStatus) { Q_UNUSED(exitCode); Q_UNUSED(exitStatus); auto stdErrOutput = mProcessHandler.readAllStandardError(); if(mConfig->uploadScriptStopOnStdErr() && !stdErrOutput.isEmpty()) { handleError(UploadStatus::ScriptWroteToStdErr, stdErrOutput); } else if(exitStatus == QProcess::ExitStatus::NormalExit) { handleSuccess(); } } void ScriptUploader::handleSuccess() { auto output = QString(mProcessHandler.readAllStandardOutput()); auto result = parseOutput(output); writeToConsole(output); emit finished(UploadResult(UploadStatus::NoError, type(), result)); } QString ScriptUploader::parseOutput(const QString &output) const { auto outputFilter = mConfig->uploadScriptCopyOutputFilter(); auto result = output; if(!outputFilter.isEmpty()) { QRegularExpression regEx(outputFilter); auto expressionMatch = regEx.match(output); if(expressionMatch.hasMatch()) { result = expressionMatch.captured(0); } } return result; } void ScriptUploader::errorOccurred(QProcess::ProcessError errorType) { auto status = mapErrorTypeToStatus(errorType); auto stdErrOutput = mProcessHandler.readAllStandardError(); handleError(status, stdErrOutput); } void ScriptUploader::handleError(const UploadStatus &status, const QString &stdErrOutput) { writeToConsole(stdErrOutput); emit finished(UploadResult(status, type())); } UploadStatus ScriptUploader::mapErrorTypeToStatus(QProcess::ProcessError errorType) const { switch (errorType) { case QProcess::FailedToStart: return UploadStatus::FailedToStart; case QProcess::Crashed: return UploadStatus::Crashed; case QProcess::Timedout: return UploadStatus::TimedOut; case QProcess::ReadError: return UploadStatus::ReadError; case QProcess::WriteError: return UploadStatus::WriteError; default: return UploadStatus::UnknownError; } } void ScriptUploader::writeToConsole(const QString &output) const { qInfo("%s", qPrintable(output)); } ksnip-master/src/backend/uploader/script/ScriptUploader.h000066400000000000000000000040631457262621600241170ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SCRIPTUPLOADER_H #define KSNIP_SCRIPTUPLOADER_H #include #include #include #include #include "src/backend/uploader/script/IScriptUploader.h" #include "src/backend/config/IConfig.h" #include "src/common/enum/UploadStatus.h" #include "src/common/provider/ITempFileProvider.h" class ScriptUploader : public IScriptUploader { Q_OBJECT public: explicit ScriptUploader(const QSharedPointer &config, const QSharedPointer &tempFileProvider); ~ScriptUploader() override = default; void upload(const QImage &image) override; UploaderType type() const override; private: QSharedPointer mConfig; QSharedPointer mTempFileProvider; QProcess mProcessHandler; QString mPathToTmpImage; private slots: void scriptFinished(int exitCode, QProcess::ExitStatus exitStatus); void errorOccurred(QProcess::ProcessError error); bool saveImageLocally(const QImage &image); QString parseOutput(const QString &output) const; void writeToConsole(const QString &output) const; UploadStatus mapErrorTypeToStatus(QProcess::ProcessError errorType) const; void handleSuccess(); void handleError(const UploadStatus &status, const QString &stdErrOutput); }; #endif //KSNIP_SCRIPTUPLOADER_H ksnip-master/src/bootstrapper/000077500000000000000000000000001457262621600170215ustar00rootroot00000000000000ksnip-master/src/bootstrapper/BootstrapperFactory.cpp000066400000000000000000000031561457262621600235460ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "BootstrapperFactory.h" QSharedPointer BootstrapperFactory::create(DependencyInjector *dependencyInjector) { auto logger = dependencyInjector->get(); auto config = dependencyInjector->get(); if(config->useSingleInstance()) { if (mInstanceLock.lock()) { logger->log(QLatin1String("SingleInstance mode detected, we are the server")); return QSharedPointer(new SingleInstanceServerBootstrapper(dependencyInjector)); } else { logger->log(QLatin1String("SingleInstance mode detected, we are the client")); return QSharedPointer(new SingleInstanceClientBootstrapper(dependencyInjector)); } } else { logger->log(QLatin1String("StandAlone mode detected")); return QSharedPointer(new StandAloneBootstrapper(dependencyInjector)); } } ksnip-master/src/bootstrapper/BootstrapperFactory.h000066400000000000000000000026711457262621600232140ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_BOOTSTRAPPERFACTORY_H #define KSNIP_BOOTSTRAPPERFACTORY_H #include #include #include "src/bootstrapper/singleInstance/SingleInstanceServerBootstrapper.h" #include "src/bootstrapper/singleInstance/SingleInstanceClientBootstrapper.h" #include "src/bootstrapper/singleInstance/InstanceLock.h" #include "src/dependencyInjector/DependencyInjector.h" class BootstrapperFactory { public: BootstrapperFactory() = default; ~BootstrapperFactory() = default; QSharedPointer create(DependencyInjector *dependencyInjector); private: InstanceLock mInstanceLock; }; #endif //KSNIP_BOOTSTRAPPERFACTORY_H ksnip-master/src/bootstrapper/IBootstrapper.h000066400000000000000000000017251457262621600217740ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IBOOTSTRAPPER_H #define KSNIP_IBOOTSTRAPPER_H class IBootstrapper { public: virtual int start(const QApplication &app) = 0; }; #endif //KSNIP_IBOOTSTRAPPER_H ksnip-master/src/bootstrapper/IImageFromStdInputReader.h000066400000000000000000000021471457262621600237730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMAGEFROMSTINPUTREADER_H #define KSNIP_IIMAGEFROMSTINPUTREADER_H class QByteArray; class IImageFromStdInputReader { public: explicit IImageFromStdInputReader() = default; ~IImageFromStdInputReader() = default; virtual QByteArray read() const = 0; }; #endif //KSNIP_IIMAGEFROMSTINPUTREADER_H ksnip-master/src/bootstrapper/ImageFromStdInputReader.cpp000066400000000000000000000022101457262621600242040ustar00rootroot00000000000000/* * Copyright (C) 2023 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImageFromStdInputReader.h" QByteArray ImageFromStdInputReader::read() const { QByteArray imageAsByteArray; while (!std::cin.eof()) { char string[1024]; std::cin.read(string, sizeof(string)); auto length = std::cin.gcount(); imageAsByteArray.append(string, length); } return imageAsByteArray; } ksnip-master/src/bootstrapper/ImageFromStdInputReader.h000066400000000000000000000022721457262621600236610ustar00rootroot00000000000000/* * Copyright (C) 2023 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEFROMSTDINPUTREADER_H #define KSNIP_IMAGEFROMSTDINPUTREADER_H #include #include #include "IImageFromStdInputReader.h" class ImageFromStdInputReader : public IImageFromStdInputReader { public: ImageFromStdInputReader() = default; ~ImageFromStdInputReader() = default; QByteArray read() const override; }; #endif //KSNIP_IMAGEFROMSTDINPUTREADER_H ksnip-master/src/bootstrapper/StandAloneBootstrapper.cpp000066400000000000000000000151331457262621600241650ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "StandAloneBootstrapper.h" StandAloneBootstrapper::StandAloneBootstrapper(DependencyInjector *dependencyInjector) : mCommandLine(nullptr), mMainWindow(nullptr), mCommandLineCaptureHandler(nullptr), mLogger(dependencyInjector->get()), mImageFromStdInputReader(dependencyInjector->get()), mDependencyInjector(dependencyInjector) { } StandAloneBootstrapper::~StandAloneBootstrapper() { delete mCommandLine; } int StandAloneBootstrapper::start(const QApplication &app) { app.setQuitOnLastWindowClosed(false); createCommandLineParser(app); if (isVersionRequested()) { return showVersion(); } if (isStartedWithoutArguments()) { return startKsnip(app); } if (isEditRequested()) { return startKsnipAndEditImage(app); } if (isCommandLineCaptureRequested()) { return takeCaptureAndProcess(app); } return takeCaptureAndStartKsnip(app); } int StandAloneBootstrapper::takeCaptureAndProcess(const QApplication &app) { connect(mCommandLineCaptureHandler.data(), &ICommandLineCaptureHandler::finished, this, &StandAloneBootstrapper::close); connect(mCommandLineCaptureHandler.data(), &ICommandLineCaptureHandler::canceled, this, &StandAloneBootstrapper::close); CommandLineCaptureParameter parameter(getCaptureMode(), getDelay(), getCaptureCursor()); parameter.isWithSave = getIsSave(); parameter.isWithUpload = getIsUpload(); parameter.savePath = getSavePath(); mCommandLineCaptureHandler->captureAndProcessScreenshot(parameter); return app.exec(); } bool StandAloneBootstrapper::getIsUpload() const { return mCommandLine->isUploadSet(); } bool StandAloneBootstrapper::getIsSave() const { return mCommandLine->isSaveSet(); } bool StandAloneBootstrapper::isCommandLineCaptureRequested() const { return getIsSave() || getIsUpload(); } bool StandAloneBootstrapper::isEditRequested() const { return mCommandLine->isEditSet(); } bool StandAloneBootstrapper::isVersionRequested() const { return mCommandLine->isVersionSet(); } bool StandAloneBootstrapper::isStartedWithoutArguments() { auto arguments = QCoreApplication::arguments(); return arguments.count() <= 1; } int StandAloneBootstrapper::takeCaptureAndStartKsnip(const QApplication &app) { loadTranslations(app); connect(mCommandLineCaptureHandler.data(), &ICommandLineCaptureHandler::finished, this, &StandAloneBootstrapper::openMainWindow); connect(mCommandLineCaptureHandler.data(), &ICommandLineCaptureHandler::canceled, this, &StandAloneBootstrapper::close); CommandLineCaptureParameter parameter(getCaptureMode(), getDelay(), getCaptureCursor()); mCommandLineCaptureHandler->captureAndProcessScreenshot(parameter); return app.exec(); } bool StandAloneBootstrapper::getCaptureCursor() const { return mCommandLine->isCursorSet(); } int StandAloneBootstrapper::getDelay() const { auto delay = 0; if (mCommandLine->isDelaySet()) { delay = mCommandLine->delay(); if (delay < 0) { qWarning("Delay flag set without value, ignoring delay."); delay = 0; } } return delay * 1000; } bool StandAloneBootstrapper::getSave() const { return mCommandLine->isSaveSet(); } QString StandAloneBootstrapper::getSavePath() const { return mCommandLine->saveToPath(); } CaptureModes StandAloneBootstrapper::getCaptureMode() const { if (mCommandLine->isCaptureModeSet()) { return mCommandLine->captureMode(); } else { qWarning("No capture mode selected, using default."); return CaptureModes::RectArea; } } int StandAloneBootstrapper::startKsnipAndEditImage(const QApplication &app) { auto pathToImage = getImagePath(); auto pixmap = getPixmapFromCorrectSource(pathToImage); if (pixmap.isNull()) { qWarning("Unable to open image file %s.", qPrintable(pathToImage)); return 1; } else { loadTranslations(app); if(PathHelper::isPipePath(pathToImage)) { openMainWindow(CaptureDto(pixmap)); } else { openMainWindow(CaptureFromFileDto(pixmap, pathToImage)); } return app.exec(); } } QPixmap StandAloneBootstrapper::getPixmapFromCorrectSource(const QString &pathToImage) const { if (PathHelper::isPipePath(pathToImage)) { qInfo("Reading image from stdin."); return getPixmapFromStdin(); } else { return { pathToImage }; } } QPixmap StandAloneBootstrapper::getPixmapFromStdin() const { auto imageAsByteArray = mImageFromStdInputReader->read(); QPixmap pixmap; pixmap.loadFromData(imageAsByteArray); return pixmap; } QString StandAloneBootstrapper::getImagePath() const { return mCommandLine->imagePath(); } int StandAloneBootstrapper::startKsnip(const QApplication &app) { loadTranslations(app); createMainWindow(); return app.exec(); } int StandAloneBootstrapper::showVersion() { QTextStream stream(stdout); stream << QLatin1String("Version: ") + qPrintable(KSNIP_VERSION) + QLatin1String("\n"); stream << QLatin1String("Build: ") + qPrintable(KSNIP_BUILD_NUMBER) + QLatin1String("\n"); return 0; } void StandAloneBootstrapper::createMainWindow() { Q_ASSERT(mMainWindow == nullptr); DependencyInjectorBootstrapper::BootstrapGui(mDependencyInjector); mMainWindow = new MainWindow(mDependencyInjector); } void StandAloneBootstrapper::createCommandLineParser(const QApplication &app) { Q_ASSERT(mCommandLine == nullptr); Q_ASSERT(mCommandLineCaptureHandler == nullptr); DependencyInjectorBootstrapper::BootstrapCommandLine(mDependencyInjector); mCommandLineCaptureHandler = mDependencyInjector->get(); mCommandLine = new CommandLine (app, mCommandLineCaptureHandler->supportedCaptureModes()); } void StandAloneBootstrapper::loadTranslations(const QApplication &app) { auto translationLoader = mDependencyInjector->get(); translationLoader->load(app); } void StandAloneBootstrapper::openMainWindow(const CaptureDto &captureDto) { createMainWindow(); mMainWindow->processCapture(captureDto); } void StandAloneBootstrapper::close() { QCoreApplication::quit(); } ksnip-master/src/bootstrapper/StandAloneBootstrapper.h000066400000000000000000000055101457262621600236300ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_STANDALONEBOOTSTRAPPER_H #define KSNIP_STANDALONEBOOTSTRAPPER_H #include #include "BuildConfig.h" #include "src/bootstrapper/IBootstrapper.h" #include "src/bootstrapper/IImageFromStdInputReader.h" #include "src/gui/MainWindow.h" #include "src/backend/TranslationLoader.h" #include "src/backend/commandLine/CommandLine.h" #include "src/backend/commandLine/ICommandLineCaptureHandler.h" #include "src/backend/commandLine/CommandLineCaptureParameter.h" #include "src/dependencyInjector/DependencyInjectorBootstrapper.h" class StandAloneBootstrapper : public QObject, public IBootstrapper { Q_OBJECT public: explicit StandAloneBootstrapper(DependencyInjector *dependencyInjector); ~StandAloneBootstrapper() override; int start(const QApplication &app) override; protected: MainWindow *mMainWindow; QSharedPointer mLogger; void createCommandLineParser(const QApplication &app); static int showVersion(); static bool isStartedWithoutArguments(); bool isVersionRequested() const; bool isEditRequested() const; CaptureModes getCaptureMode() const; int getDelay() const; QString getImagePath() const; bool getCaptureCursor() const; bool getSave() const; QString getSavePath() const; private: DependencyInjector *mDependencyInjector; CommandLine *mCommandLine; QSharedPointer mCommandLineCaptureHandler; QSharedPointer mImageFromStdInputReader; void loadTranslations(const QApplication &app); virtual void createMainWindow(); int startKsnip(const QApplication &app); int startKsnipAndEditImage(const QApplication &app); int takeCaptureAndStartKsnip(const QApplication &app); QPixmap getPixmapFromCorrectSource(const QString &pathToImage) const; QPixmap getPixmapFromStdin() const; bool isCommandLineCaptureRequested() const; int takeCaptureAndProcess(const QApplication &app); bool getIsSave() const; bool getIsUpload() const; private slots: void openMainWindow(const CaptureDto &captureDto); void close(); }; #endif //KSNIP_STANDALONEBOOTSTRAPPER_H ksnip-master/src/bootstrapper/singleInstance/000077500000000000000000000000001457262621600217675ustar00rootroot00000000000000ksnip-master/src/bootstrapper/singleInstance/InstanceLock.cpp000066400000000000000000000026251457262621600250550ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "InstanceLock.h" InstanceLock::InstanceLock() { mSingular = new QSharedMemory(QLatin1String("KsnipInstanceLock"), this); } InstanceLock::~InstanceLock() { if(mSingular->isAttached()) { mSingular->detach(); } } bool InstanceLock::lock() { if (create()) { return true; } else { attachDetach(); return create(); } } bool InstanceLock::create() { if (mSingular->create(1)) { mSingular->lock(); mSingular->unlock(); return true; } return false; } bool InstanceLock::attachDetach() { if (mSingular->attach(QSharedMemory::ReadOnly)) { mSingular->detach(); return true; } return false; }ksnip-master/src/bootstrapper/singleInstance/InstanceLock.h000066400000000000000000000021351457262621600245160ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_INSTANCELOCK_H #define KSNIP_INSTANCELOCK_H #include class InstanceLock : public QObject { Q_OBJECT public: InstanceLock(); ~InstanceLock() override; bool lock(); private: QSharedMemory *mSingular; bool create(); bool attachDetach(); }; #endif //KSNIP_INSTANCELOCK_H ksnip-master/src/bootstrapper/singleInstance/SingleInstanceClientBootstrapper.cpp000066400000000000000000000053151457262621600311510ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SingleInstanceClientBootstrapper.h" SingleInstanceClientBootstrapper::SingleInstanceClientBootstrapper(DependencyInjector *dependencyInjector) : StandAloneBootstrapper(dependencyInjector), mIpcClient(new IpcClient), mImageFromStdInputReader(dependencyInjector->get()) { mIpcClient->connectTo(SingleInstance::ServerName); } SingleInstanceClientBootstrapper::~SingleInstanceClientBootstrapper() { delete mIpcClient; } int SingleInstanceClientBootstrapper::start(const QApplication &app) { createCommandLineParser(app); if (isVersionRequested()) { return showVersion(); } else { return notifyServer(); } } bool SingleInstanceClientBootstrapper::isImagePathValid(const QString &imagePath) { QPixmap pixmap(imagePath); return !pixmap.isNull(); } int SingleInstanceClientBootstrapper::notifyServer() const { SingleInstanceParameter parameter; if (isStartedWithoutArguments()) { mLogger->log(QLatin1String("Starting without arguments")); parameter = SingleInstanceParameter(); } else if (isEditRequested()) { auto imagePath = getImagePath(); if (PathHelper::isPipePath(imagePath)) { mLogger->log(QLatin1String("Edit image from stdin")); auto imageAsByteArray = mImageFromStdInputReader->read(); parameter = SingleInstanceParameter(imageAsByteArray.toBase64()); } else if (isImagePathValid(imagePath)) { mLogger->log(QLatin1String("Edit image from file path")); parameter = SingleInstanceParameter(imagePath); } else { qWarning("Unable to open image file %s.", qPrintable(imagePath)); return 1; } } else { parameter = SingleInstanceParameter(getCaptureMode(), getSave(), getSavePath(), getCaptureCursor(), getDelay()); } mIpcClient->send(mParameterTranslator.translate(parameter)); mLogger->log(QLatin1String("Notification sent to server, closing client..")); return 0; } ksnip-master/src/bootstrapper/singleInstance/SingleInstanceClientBootstrapper.h000066400000000000000000000034471457262621600306220ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLEINSTANCECLIENTBOOTSTRAPPER_H #define KSNIP_SINGLEINSTANCECLIENTBOOTSTRAPPER_H #include #include "src/bootstrapper/StandAloneBootstrapper.h" #include "src/bootstrapper/IBootstrapper.h" #include "src/bootstrapper/IImageFromStdInputReader.h" #include "src/bootstrapper/singleInstance/SingleInstanceConstants.h" #include "src/bootstrapper/singleInstance/SingleInstanceParameterTranslator.h" #include "src/backend/ipc/IpcClient.h" class SingleInstanceClientBootstrapper : public StandAloneBootstrapper { public: explicit SingleInstanceClientBootstrapper(DependencyInjector *dependencyInjector); ~SingleInstanceClientBootstrapper() override; int start(const QApplication &app) override; private: IpcClient *mIpcClient; SingleInstanceParameterTranslator mParameterTranslator; QSharedPointer mImageFromStdInputReader; static bool isImagePathValid(const QString &imagePath); int notifyServer() const; }; #endif //KSNIP_SINGLEINSTANCECLIENTBOOTSTRAPPER_H ksnip-master/src/bootstrapper/singleInstance/SingleInstanceConstants.h000066400000000000000000000021111457262621600267360ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLEINSTANCECONSTANTS_H #define KSNIP_SINGLEINSTANCECONSTANTS_H #include inline namespace SingleInstance { const QString ServerName(QStringLiteral("org.ksnip.ksnip.singleInstanceServer")); } // namespace SingleInstance #endif //KSNIP_SINGLEINSTANCECONSTANTS_H ksnip-master/src/bootstrapper/singleInstance/SingleInstanceParameter.h000066400000000000000000000041301457262621600267050ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLEINSTANCEPARAMETER_H #define KSNIP_SINGLEINSTANCEPARAMETER_H #include #include "src/bootstrapper/singleInstance/SingleInstanceStartupModes.h" #include "src/common/enum/CaptureModes.h" struct SingleInstanceParameter { SingleInstanceStartupModes startupMode; CaptureModes captureMode; QString imagePath; bool save{}; bool captureCursor{}; int delay{}; QString savePath; QByteArray imageAsByteArray; SingleInstanceParameter() { this->startupMode = SingleInstanceStartupModes::Start; } explicit SingleInstanceParameter(const QString &path) { this->startupMode = SingleInstanceStartupModes::Edit; this->imagePath = path; } explicit SingleInstanceParameter(const QByteArray &imageAsByteArray) { this->startupMode = SingleInstanceStartupModes::Edit; this->imageAsByteArray = imageAsByteArray; } SingleInstanceParameter(CaptureModes captureMode, bool save, const QString &savePath, bool captureCursor, int delay) { this->startupMode = SingleInstanceStartupModes::Capture; this->captureMode = captureMode; this->save = save; this->captureCursor = captureCursor; this->savePath = savePath; this->delay = delay; } bool isImageAsByteArraySet() const { return !this->imageAsByteArray.isNull() && !this->imageAsByteArray.isEmpty(); } }; #endif //KSNIP_SINGLEINSTANCEPARAMETER_H ksnip-master/src/bootstrapper/singleInstance/SingleInstanceParameterTranslator.cpp000066400000000000000000000131421457262621600313150ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SingleInstanceParameterTranslator.h" QByteArray SingleInstanceParameterTranslator::translate(const SingleInstanceParameter ¶meter) const { switch (parameter.startupMode) { case SingleInstanceStartupModes::Edit: if(parameter.isImageAsByteArraySet()) { return getEditImageParameters(parameter.imageAsByteArray); } else { return getEditPathParameters(parameter.imagePath); } case SingleInstanceStartupModes::Capture: return getCaptureParameters(parameter.captureMode, parameter.save, parameter.savePath, parameter.captureCursor, parameter.delay); default: return getStartParameter(); } } SingleInstanceParameter SingleInstanceParameterTranslator::translate(const QByteArray &byteArray) const { auto parameters = byteArray.split(getSeparator()[0]); if(parameters.empty()) { qCritical("Startup mode must be provided."); return {}; } auto startupMode = parameters[0]; if (startupMode == getEditPathParameter() && parameters.count() == 2) { auto pathToImage = QString(parameters[1]); return SingleInstanceParameter(pathToImage); } else if (startupMode == getEditImageParameter() && parameters.count() == 2) { auto imageAsByteArray = QByteArray::fromBase64(parameters[1]); return SingleInstanceParameter(imageAsByteArray); } else if (startupMode == getCaptureParameter() && parameters.count() == 6){ auto captureMode = getCaptureMode(parameters[1]); auto save = getBoolean(parameters[2]); auto savePath = getPathParameter(parameters[3]); auto captureCursor = getBoolean(parameters[4]); auto delay = parameters[5].toInt(); return SingleInstanceParameter(captureMode, save, savePath, captureCursor, delay); } else { return {}; } } CaptureModes SingleInstanceParameterTranslator::getCaptureMode(const QByteArray &captureMode) { if (captureMode == QByteArray("rectArea")) { return CaptureModes::RectArea; } else if (captureMode == QByteArray("lastRectArea")) { return CaptureModes::LastRectArea; } else if (captureMode == QByteArray("fullScreen")) { return CaptureModes::FullScreen; } else if (captureMode == QByteArray("currentScreen")) { return CaptureModes::CurrentScreen; } else if (captureMode == QByteArray("activeWindow")) { return CaptureModes::ActiveWindow; } else if (captureMode == QByteArray("portal")) { return CaptureModes::Portal; } else { return CaptureModes::WindowUnderCursor; } } QByteArray SingleInstanceParameterTranslator::getStartParameter() { return {"start"}; } QByteArray SingleInstanceParameterTranslator::getEditPathParameters(const QString &path) { return getEditPathParameter() + getSeparator() + getPathParameter(path); } QByteArray SingleInstanceParameterTranslator::getEditImageParameters(const QByteArray &image) { return getEditImageParameter() + getSeparator() + image; } QByteArray SingleInstanceParameterTranslator::getEditPathParameter() { return {"edit-path"}; } QByteArray SingleInstanceParameterTranslator::getEditImageParameter() { return {"edit-image"}; } QByteArray SingleInstanceParameterTranslator::getCaptureParameters(CaptureModes captureModes, bool save, const QString &savePath, bool captureCursor, int delay) { return getCaptureParameter() + getSeparator() + getCaptureModeParameter(captureModes) + getSeparator() + getBooleanString(save) + getSeparator() + getPathParameter(savePath) + getSeparator() + getCaptureCursorParameter(captureCursor) + getSeparator() + getDelayParameter(delay); } QByteArray SingleInstanceParameterTranslator::getCaptureParameter() { return {"capture"}; } QByteArray SingleInstanceParameterTranslator::getCaptureModeParameter(const CaptureModes &captureModes) { switch (captureModes) { case CaptureModes::LastRectArea: return {"lastRectArea"}; case CaptureModes::FullScreen: return {"fullScreen"}; case CaptureModes::CurrentScreen: return {"currentScreen"}; case CaptureModes::ActiveWindow: return {"activeWindow"}; case CaptureModes::WindowUnderCursor: return {"windowUnderCursor"}; case CaptureModes::Portal: return {"portal"}; default: return {"rectArea"}; } } QByteArray SingleInstanceParameterTranslator::getSeparator() { return {";"}; } QByteArray SingleInstanceParameterTranslator::getPathParameter(const QString &path) { return path.toLatin1(); } QByteArray SingleInstanceParameterTranslator::getBooleanString(bool value) { return value ? QByteArray("true") : QByteArray("false"); } QByteArray SingleInstanceParameterTranslator::getCaptureCursorParameter(bool captureCursor) { return getBooleanString(captureCursor); } QByteArray SingleInstanceParameterTranslator::getDelayParameter(int delay) { return QString::number(delay).toLatin1(); } bool SingleInstanceParameterTranslator::getBoolean(const QByteArray &value) { return value == QByteArray("true"); } ksnip-master/src/bootstrapper/singleInstance/SingleInstanceParameterTranslator.h000066400000000000000000000043211457262621600307610ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLEINSTANCEPARAMETERTRANSLATOR_H #define KSNIP_SINGLEINSTANCEPARAMETERTRANSLATOR_H #include #include #include "src/bootstrapper/singleInstance/SingleInstanceParameter.h" class SingleInstanceParameterTranslator { public: SingleInstanceParameterTranslator() = default; ~SingleInstanceParameterTranslator() = default; QByteArray translate(const SingleInstanceParameter ¶meter) const; SingleInstanceParameter translate(const QByteArray &byteArray) const; private: static QByteArray getStartParameter(); static QByteArray getEditPathParameters(const QString &path); static QByteArray getEditImageParameters(const QByteArray &image); static QByteArray getCaptureParameters(CaptureModes captureModes, bool save, const QString &savePath, bool captureCursor, int delay); static QByteArray getSeparator(); static QByteArray getPathParameter(const QString &path); static QByteArray getCaptureModeParameter(const CaptureModes &captureModes); static QByteArray getBooleanString(bool value); static QByteArray getCaptureCursorParameter(bool captureCursor); static QByteArray getDelayParameter(int delay); static QByteArray getEditPathParameter(); static QByteArray getEditImageParameter(); static QByteArray getCaptureParameter(); static CaptureModes getCaptureMode(const QByteArray &captureMode); static bool getBoolean(const QByteArray &value); }; #endif //KSNIP_SINGLEINSTANCEPARAMETERTRANSLATOR_H ksnip-master/src/bootstrapper/singleInstance/SingleInstanceServerBootstrapper.cpp000066400000000000000000000063431457262621600312030ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SingleInstanceServerBootstrapper.h" SingleInstanceServerBootstrapper::SingleInstanceServerBootstrapper(DependencyInjector *dependencyInjector) : StandAloneBootstrapper(dependencyInjector), mIpcServer(new IpcServer) { } SingleInstanceServerBootstrapper::~SingleInstanceServerBootstrapper() { delete mIpcServer; } int SingleInstanceServerBootstrapper::start(const QApplication &app) { startServer(); return StandAloneBootstrapper::start(app); } void SingleInstanceServerBootstrapper::startServer() const { mIpcServer->listen(SingleInstance::ServerName); connect(mIpcServer, &IpcServer::received, this, &SingleInstanceServerBootstrapper::processData); } void SingleInstanceServerBootstrapper::processData(const QByteArray &data) { mLogger->log(QLatin1String("Single instance server received data from client")); auto parameter = mParameterTranslator.translate(data); switch (parameter.startupMode) { case SingleInstanceStartupModes::Start: mLogger->log(QLatin1String("Start triggered.")); show(); break; case SingleInstanceStartupModes::Edit: if(parameter.isImageAsByteArraySet()) { mLogger->log(QLatin1String("Edit triggered with image received as byte array")); QPixmap pixmap; pixmap.loadFromData(parameter.imageAsByteArray); mMainWindow->processCapture(CaptureDto(pixmap)); } else { mLogger->log(QLatin1String("Edit triggered with image received as image path")); processImage(parameter.imagePath); } break; case SingleInstanceStartupModes::Capture: mLogger->log(QLatin1String("Capture triggered")); capture(parameter); break; } } void SingleInstanceServerBootstrapper::capture(const SingleInstanceParameter ¶meter) const { mLogger->log(QLatin1String("Single instance server was request to take screenshot")); mMainWindow->captureScreenshot(parameter.captureMode, parameter.captureCursor, parameter.delay); } void SingleInstanceServerBootstrapper::show() const { mLogger->log(QLatin1String("Single instance server was request to show main window")); mMainWindow->show(); } void SingleInstanceServerBootstrapper::processImage(const QString &imagePath) { mLogger->log(QString("Single instance server was request to open image %1.").arg(imagePath)); QPixmap pixmap(imagePath); auto captureDto = CaptureFromFileDto(pixmap, imagePath); mMainWindow->processCapture(captureDto); } ksnip-master/src/bootstrapper/singleInstance/SingleInstanceServerBootstrapper.h000066400000000000000000000033571457262621600306520ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLEINSTANCESERVERBOOTSTRAPPER_H #define KSNIP_SINGLEINSTANCESERVERBOOTSTRAPPER_H #include "src/bootstrapper/StandAloneBootstrapper.h" #include "src/bootstrapper/singleInstance/SingleInstanceConstants.h" #include "src/bootstrapper/singleInstance/SingleInstanceParameterTranslator.h" #include "src/backend/ipc/IpcServer.h" class SingleInstanceServerBootstrapper : public StandAloneBootstrapper { Q_OBJECT public: explicit SingleInstanceServerBootstrapper(DependencyInjector *dependencyInjector); ~SingleInstanceServerBootstrapper() override; int start(const QApplication &app) override; private: IpcServer *mIpcServer; SingleInstanceParameterTranslator mParameterTranslator; void show() const; void processImage(const QString &imagePath); void capture(const SingleInstanceParameter ¶meter) const; private slots: void processData(const QByteArray &data); void startServer() const; }; #endif //KSNIP_SINGLEINSTANCESERVERBOOTSTRAPPER_H ksnip-master/src/bootstrapper/singleInstance/SingleInstanceStartupModes.h000066400000000000000000000017511457262621600274250ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLEINSTANCESTARTUPMODES_H #define KSNIP_SINGLEINSTANCESTARTUPMODES_H enum class SingleInstanceStartupModes { Start, Edit, Capture }; #endif //KSNIP_SINGLEINSTANCESTARTUPMODES_H ksnip-master/src/common/000077500000000000000000000000001457262621600155655ustar00rootroot00000000000000ksnip-master/src/common/adapter/000077500000000000000000000000001457262621600172055ustar00rootroot00000000000000ksnip-master/src/common/adapter/fileDialog/000077500000000000000000000000001457262621600212445ustar00rootroot00000000000000ksnip-master/src/common/adapter/fileDialog/FileDialogAdapter.cpp000066400000000000000000000036371457262621600252610ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "FileDialogAdapter.h" QString FileDialogAdapter::getExistingDirectory(QWidget *parent, const QString &title, const QString &directory) { return QFileDialog::getExistingDirectory(parent, title, directory, QFileDialog::ShowDirsOnly | mOptions); } QString FileDialogAdapter::getOpenFileName(QWidget *parent, const QString &title, const QString &directory) { return QFileDialog::getOpenFileName(parent, title, directory, nullptr, nullptr, mOptions); } QStringList FileDialogAdapter::getOpenFileNames(QWidget *parent, const QString &title, const QString &directory, const QString &filter) { return QFileDialog::getOpenFileNames(parent, title, directory, filter, nullptr, mOptions); } QString FileDialogAdapter::getSavePath(QWidget *parent, const QString &title, const QString &path, const QString &filter) { QFileDialog saveDialog(parent, title, path, filter); saveDialog.setAcceptMode(QFileDialog::AcceptSave); saveDialog.setOptions(mOptions); if (saveDialog.exec() == QDialog::Accepted) { return saveDialog.selectedFiles().first(); } return {}; } void FileDialogAdapter::addOption(QFileDialog::Option option) { mOptions |= option; } ksnip-master/src/common/adapter/fileDialog/FileDialogAdapter.h000066400000000000000000000031601457262621600247150ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FILEDIALOGADAPTER_H #define KSNIP_FILEDIALOGADAPTER_H #include #include "IFileDialogService.h" class FileDialogAdapter : public IFileDialogService { public: explicit FileDialogAdapter() = default; ~FileDialogAdapter() override = default; QString getExistingDirectory(QWidget *parent, const QString &title, const QString &directory) override; QString getOpenFileName(QWidget *parent, const QString &title, const QString &directory) override; QStringList getOpenFileNames(QWidget *parent, const QString &title, const QString &directory, const QString &filter) override; QString getSavePath(QWidget *parent, const QString &title, const QString &path, const QString &filter) override; protected: void addOption(QFileDialog::Option option); private: QFileDialog::Options mOptions; }; #endif //KSNIP_FILEDIALOGADAPTER_H ksnip-master/src/common/adapter/fileDialog/IFileDialogService.h000066400000000000000000000027001457262621600250450ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IFILEDIALOGSERVICE_H #define KSNIP_IFILEDIALOGSERVICE_H class IFileDialogService { public: IFileDialogService() = default; virtual ~IFileDialogService() = default; virtual QString getExistingDirectory(QWidget *parent, const QString &title, const QString &directory) = 0; virtual QString getOpenFileName(QWidget *parent, const QString &title, const QString &directory) = 0; virtual QStringList getOpenFileNames(QWidget *parent, const QString &title, const QString &directory, const QString &filter) = 0; virtual QString getSavePath(QWidget *parent, const QString &title, const QString &path, const QString &filter) = 0; }; #endif //KSNIP_IFILEDIALOGSERVICE_H ksnip-master/src/common/adapter/fileDialog/SnapFileDialogAdapter.cpp000066400000000000000000000016351457262621600260770ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnapFileDialogAdapter.h" SnapFileDialogAdapter::SnapFileDialogAdapter() { addOption(QFileDialog::DontUseNativeDialog); } ksnip-master/src/common/adapter/fileDialog/SnapFileDialogAdapter.h000066400000000000000000000021021457262621600255320ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNAPFILEDIALOGADAPTER_H #define KSNIP_SNAPFILEDIALOGADAPTER_H #include "FileDialogAdapter.h" class SnapFileDialogAdapter : public FileDialogAdapter { public: explicit SnapFileDialogAdapter(); ~SnapFileDialogAdapter() override = default; }; #endif //KSNIP_SNAPFILEDIALOGADAPTER_H ksnip-master/src/common/constants/000077500000000000000000000000001457262621600176015ustar00rootroot00000000000000ksnip-master/src/common/constants/DefaultValues.h000066400000000000000000000022501457262621600225150ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DEFAULTVALUES_H #define KSNIP_DEFAULTVALUES_H #include inline namespace DefaultValues { const QString ImgurBaseUrl = QStringLiteral("https://api.imgur.com"); const QString ImgurUploadTitle = QStringLiteral("Ksnip Screenshot"); const QString ImgurUploadDescription = QStringLiteral("Screenshot uploaded via Ksnip"); } // namespace Constants #endif //KSNIP_DEFAULTVALUES_H ksnip-master/src/common/constants/FileDialogFilters.h000066400000000000000000000021021457262621600232750ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FIXEDVALUES_H #define KSNIP_FIXEDVALUES_H #include inline namespace FileDialogFilters { const QString ImageFiles = QLatin1String("(*.png *.gif *.jpg *.jpeg *.bmp);;"); const QString AllFiles = QLatin1String("(*)"); } // namespace Constants #endif //KSNIP_FIXEDVALUES_H ksnip-master/src/common/dtos/000077500000000000000000000000001457262621600165365ustar00rootroot00000000000000ksnip-master/src/common/dtos/CaptureDto.h000066400000000000000000000023041457262621600207600ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTUREDTO_H #define KSNIP_CAPTUREDTO_H #include "CursorDto.h" struct CaptureDto { QPixmap screenshot; CursorDto cursor; explicit CaptureDto() = default; explicit CaptureDto(const QPixmap &screenshot) { this->screenshot = screenshot.copy(); } virtual bool isValid() const { return !screenshot.isNull(); } bool isCursorValid() const { return cursor.isValid(); } }; #endif //KSNIP_CAPTUREDTO_H ksnip-master/src/common/dtos/CaptureFromFileDto.h000066400000000000000000000021741457262621600224110ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTUREFROMFILEDTO_H #define KSNIP_CAPTUREFROMFILEDTO_H #include "CaptureDto.h" #include "FilePathDto.h" struct CaptureFromFileDto : public CaptureDto, public FilePathDto { explicit CaptureFromFileDto(const QPixmap &screenshot, const QString &path) : CaptureDto(screenshot){ this->path = path; } }; #endif //KSNIP_CAPTUREFROMFILEDTO_H ksnip-master/src/common/dtos/CursorDto.h000066400000000000000000000022001457262621600206250ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CURSORDTO_H #define KSNIP_CURSORDTO_H #include #include struct CursorDto { QPixmap image; QPoint position; CursorDto& operator =(const CursorDto& other) { image = other.image.copy(); position = other.position; return *this; } bool isValid() const { return !image.isNull(); } }; #endif //KSNIP_CURSORDTO_H ksnip-master/src/common/dtos/FilePathDto.h000066400000000000000000000016451457262621600210600ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ABSTRACTFILEPATH_H #define KSNIP_ABSTRACTFILEPATH_H struct FilePathDto { QString path; }; #endif //KSNIP_ABSTRACTFILEPATH_H ksnip-master/src/common/dtos/RenameResultDto.h000066400000000000000000000021451457262621600217660ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RENAMERESULTDTO_H #define KSNIP_RENAMERESULTDTO_H #include "FilePathDto.h" struct RenameResultDto : public FilePathDto { bool isSuccessful; explicit RenameResultDto(bool isSuccessful, const QString &path) { this->isSuccessful = isSuccessful; this->path = path; } }; #endif //KSNIP_RENAMERESULTDTO_H ksnip-master/src/common/dtos/SaveResultDto.h000066400000000000000000000021221457262621600214500ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SAVERESULTDTO_H #define KSNIP_SAVERESULTDTO_H #include "FilePathDto.h" struct SaveResultDto : public FilePathDto { bool isSuccessful; explicit SaveResultDto(bool isSuccessful, const QString &path) { this->isSuccessful = isSuccessful; this->path = path; } }; #endif //KSNIP_SAVERESULTDTO_H ksnip-master/src/common/enum/000077500000000000000000000000001457262621600165315ustar00rootroot00000000000000ksnip-master/src/common/enum/CaptureModes.h000066400000000000000000000023431457262621600212770ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTUREMODES_H #define KSNIP_CAPTUREMODES_H #include #include #include enum class CaptureModes { RectArea, LastRectArea, FullScreen, CurrentScreen, ActiveWindow, WindowUnderCursor, Portal }; inline uint qHash(const CaptureModes captureMode, uint seed) { return qHash(static_cast(captureMode), seed); } Q_DECLARE_METATYPE(CaptureModes) #endif // KSNIP_CAPTUREMODES_H ksnip-master/src/common/enum/Environment.h000066400000000000000000000016651457262621600212160ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ENVIRONMENT_H #define KSNIP_ENVIRONMENT_H enum class Environment { Gnome, KDE, Unknown }; #endif //KSNIP_ENVIRONMENT_H ksnip-master/src/common/enum/MessageBoxResponse.h000066400000000000000000000017041457262621600224600ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MESSAGEBOXRESPONSE_H #define KSNIP_MESSAGEBOXRESPONSE_H enum class MessageBoxResponse { Yes, No, Cancel }; #endif //KSNIP_MESSAGEBOXRESPONSE_H ksnip-master/src/common/enum/NotificationTypes.h000066400000000000000000000017171457262621600223630ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NOTIFICATIONTYPES_H #define KSNIP_NOTIFICATIONTYPES_H enum class NotificationTypes { Information, Warning, Critical }; #endif //KSNIP_NOTIFICATIONTYPES_H ksnip-master/src/common/enum/PackageManager.h000066400000000000000000000016731457262621600215370ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PACKAGEMANAGER_H #define KSNIP_PACKAGEMANAGER_H enum class PackageManager { Snap, Flatpak, Unknown }; #endif //KSNIP_PACKAGEMANAGER_H ksnip-master/src/common/enum/Platform.h000066400000000000000000000016531457262621600204730ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLATFORM_H #define KSNIP_PLATFORM_H enum class Platform { X11, Wayland, Unknown }; #endif //KSNIP_PLATFORM_H ksnip-master/src/common/enum/PluginType.h000066400000000000000000000017021457262621600210020ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLUGINTYPE_H #define KSNIP_PLUGINTYPE_H #include enum class PluginType { Ocr }; Q_DECLARE_METATYPE(PluginType) #endif //KSNIP_PLUGINTYPE_H ksnip-master/src/common/enum/SaveQualityMode.h000066400000000000000000000017221457262621600217600ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SAVEQUALITYMODE_H #define KSNIP_SAVEQUALITYMODE_H enum class SaveQualityMode { Default, Factor }; Q_DECLARE_METATYPE(SaveQualityMode) #endif //KSNIP_SAVEQUALITYMODE_H ksnip-master/src/common/enum/TrayIconDefaultActionMode.h000066400000000000000000000020101457262621600236730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_TRAYICONDEFAULTACTIONMODE_H #define KSNIP_TRAYICONDEFAULTACTIONMODE_H enum class TrayIconDefaultActionMode { ShowEditor, Capture }; Q_DECLARE_METATYPE(TrayIconDefaultActionMode) #endif //KSNIP_TRAYICONDEFAULTACTIONMODE_H ksnip-master/src/common/enum/UploadStatus.h000066400000000000000000000023711457262621600213350ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADSTATUS_H #define KSNIP_UPLOADSTATUS_H enum class UploadStatus { NoError, UnableToSaveTemporaryImage, FailedToStart, // file not found, resource error Crashed, TimedOut, ReadError, WriteError, WebError, UnknownError, ScriptWroteToStdErr, ConnectionError, PermissionError }; inline uint qHash(const UploadStatus uploadStatus, uint seed) { return qHash(static_cast(uploadStatus), seed); } #endif //KSNIP_UPLOADSTATUS_H ksnip-master/src/common/enum/UploaderType.h000066400000000000000000000017471457262621600213300ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADERTYPE_H #define KSNIP_UPLOADERTYPE_H #include enum class UploaderType { Imgur, Script, Ftp }; Q_DECLARE_METATYPE(UploaderType) #endif //KSNIP_UPLOADERTYPE_H ksnip-master/src/common/handler/000077500000000000000000000000001457262621600172025ustar00rootroot00000000000000ksnip-master/src/common/handler/DelayHandler.cpp000066400000000000000000000023601457262621600222430ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DelayHandler.h" DelayHandler::DelayHandler(const QSharedPointer &config) : mConfig(config), mImplicitDelay(config->implicitCaptureDelay()) { connect(mConfig.data(), &IConfig::delayChanged, this, &DelayHandler::delayChanged); } int DelayHandler::getDelay(int delay, bool isVisible) { return isVisible && delay < mImplicitDelay ? mImplicitDelay : delay; } void DelayHandler::delayChanged() { mImplicitDelay = mConfig->implicitCaptureDelay(); } ksnip-master/src/common/handler/DelayHandler.h000066400000000000000000000024111457262621600217050ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DELAYHANDLER_H #define KSNIP_DELAYHANDLER_H #include #include "IDelayHandler.h" #include "src/backend/config/IConfig.h" class DelayHandler : public IDelayHandler { public: explicit DelayHandler(const QSharedPointer &config); ~DelayHandler() override = default; int getDelay(int delay, bool isVisible) override; private: int mImplicitDelay; QSharedPointer mConfig; private slots: void delayChanged(); }; #endif //KSNIP_DELAYHANDLER_H ksnip-master/src/common/handler/IDelayHandler.h000066400000000000000000000021061457262621600220170ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IDELAYHANDLER_H #define KSNIP_IDELAYHANDLER_H #include class IDelayHandler : public QObject { Q_OBJECT public: explicit IDelayHandler() = default; ~IDelayHandler() override = default; virtual int getDelay(int delay, bool isVisible) = 0; }; #endif //KSNIP_IDELAYHANDLER_H ksnip-master/src/common/helper/000077500000000000000000000000001457262621600170445ustar00rootroot00000000000000ksnip-master/src/common/helper/EnumTranslator.cpp000066400000000000000000000061661457262621600225370ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "EnumTranslator.h" EnumTranslator *EnumTranslator::instance() { static EnumTranslator instance; return &instance; } QString EnumTranslator::toTranslatedString(CaptureModes captureMode) const { Q_ASSERT(mCaptureModeMap.contains(captureMode)); return mCaptureModeMap[captureMode]; } QString EnumTranslator::toString(UploadStatus uploadStatus) const { Q_ASSERT(mUploadStatusMap.contains(uploadStatus)); return mUploadStatusMap[uploadStatus]; } QString EnumTranslator::toString(PluginType pluginType) const { Q_ASSERT(mPluginTypeMap.contains(pluginType)); return mPluginTypeMap[pluginType]; } EnumTranslator::EnumTranslator() { mapCaptureModeEnum(); mapUploadStatusEnum(); mapPluginTypeEnum(); } void EnumTranslator::mapUploadStatusEnum() { mUploadStatusMap[UploadStatus::NoError] = QLatin1String("No Error"); mUploadStatusMap[UploadStatus::ConnectionError] = QLatin1String("Connection Error"); mUploadStatusMap[UploadStatus::PermissionError] = QLatin1String("Permission Error"); mUploadStatusMap[UploadStatus::TimedOut] = QLatin1String("Timed Out"); mUploadStatusMap[UploadStatus::Crashed] = QLatin1String("Crashed"); mUploadStatusMap[UploadStatus::FailedToStart] = QLatin1String("Failed To Start"); mUploadStatusMap[UploadStatus::ReadError] = QLatin1String("Read Error"); mUploadStatusMap[UploadStatus::ScriptWroteToStdErr] = QLatin1String("Script Wrote To StdErr"); mUploadStatusMap[UploadStatus::UnableToSaveTemporaryImage] = QLatin1String("Unable To Save Temporary Image"); mUploadStatusMap[UploadStatus::UnknownError] = QLatin1String("Unknown Error"); mUploadStatusMap[UploadStatus::WebError] = QLatin1String("Web Error"); mUploadStatusMap[UploadStatus::WriteError] = QLatin1String("Write Error"); } void EnumTranslator::mapCaptureModeEnum() { mCaptureModeMap[CaptureModes::RectArea] = tr("Rectangular Area"); mCaptureModeMap[CaptureModes::LastRectArea] = tr("Last Rectangular Area"); mCaptureModeMap[CaptureModes::FullScreen] = tr("Full Screen (All Monitors)"); mCaptureModeMap[CaptureModes::CurrentScreen] = tr("Current Screen"); mCaptureModeMap[CaptureModes::ActiveWindow] = tr("Active Window"); mCaptureModeMap[CaptureModes::WindowUnderCursor] = tr("Window Under Cursor"); mCaptureModeMap[CaptureModes::Portal] = tr("Screenshot Portal"); } void EnumTranslator::mapPluginTypeEnum() { mPluginTypeMap[PluginType::Ocr] = QLatin1String("OCR"); } ksnip-master/src/common/helper/EnumTranslator.h000066400000000000000000000030251457262621600221730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ENUMTRANSLATOR_H #define KSNIP_ENUMTRANSLATOR_H #include #include #include "src/common/enum/CaptureModes.h" #include "src/common/enum/UploadStatus.h" #include "src/common/enum/PluginType.h" class EnumTranslator : public QObject { Q_OBJECT public: static EnumTranslator *instance(); QString toTranslatedString(CaptureModes captureMode) const; QString toString(UploadStatus uploadStatus) const; QString toString(PluginType pluginType) const; private: QMap mCaptureModeMap; QMap mUploadStatusMap; QMap mPluginTypeMap; EnumTranslator(); void mapCaptureModeEnum(); void mapUploadStatusEnum(); void mapPluginTypeEnum(); }; #endif //KSNIP_ENUMTRANSLATOR_H ksnip-master/src/common/helper/FileDialogFilterHelper.cpp000066400000000000000000000017541457262621600240640ustar00rootroot00000000000000#include "FileDialogFilterHelper.h" #include #include const QString &FileDialogFilterHelper::ImageFilesImport() { const static QString importfilter(FileDialogFilterHelper::ImageFiles(true)); return importfilter; } const QString &FileDialogFilterHelper::ImageFilesExport() { const static QString exportfilter(FileDialogFilterHelper::ImageFiles(false)); return exportfilter; } const QString &FileDialogFilterHelper::AllFiles() { const static QString allfiles_str(QLatin1String("(*)")); return allfiles_str; } QString FileDialogFilterHelper::ImageFiles(bool import) { QList supported_formats = import ? QImageReader::supportedImageFormats() : QImageWriter::supportedImageFormats(); QString filter_str(QLatin1String("(")); for (int i = 0; i < supported_formats.count(); i++) { filter_str.append(((i == 0) ? "*." : " *.") + QString(supported_formats.at(i))); } filter_str.append(");;"); return filter_str; } ksnip-master/src/common/helper/FileDialogFilterHelper.h000066400000000000000000000005571457262621600235310ustar00rootroot00000000000000#ifndef KSNIP_FILEDIALOGFILTERHELPER_H #define KSNIP_FILEDIALOGFILTERHELPER_H #include class FileDialogFilterHelper { public: static const QString &ImageFilesImport(); static const QString &ImageFilesExport(); static const QString &AllFiles(); private: static QString ImageFiles(bool import); }; #endif // KSNIP_FILEDIALOGFILTERHELPER_H ksnip-master/src/common/helper/FileUrlHelper.cpp000066400000000000000000000023401457262621600222510ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "FileUrlHelper.h" QString FileUrlHelper::toPath(const QString &url) { auto path = url; return path.remove(filePrefix()); } QString FileUrlHelper::toFileUrl(const QString &path) { return filePrefix() + path; } QString FileUrlHelper::filePrefix() { #if defined(__APPLE__) return QLatin1String("file://"); #endif #if defined(UNIX_X11) return QLatin1String("file://"); #endif #if defined(_WIN32) return QLatin1String("file:///"); #endif } ksnip-master/src/common/helper/FileUrlHelper.h000066400000000000000000000020531457262621600217170ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FILEURLHELPER_H #define KSNIP_FILEURLHELPER_H #include class FileUrlHelper { public: static QString toPath(const QString &url); static QString toFileUrl(const QString &path); private: static QString filePrefix(); }; #endif //KSNIP_FILEURLHELPER_H ksnip-master/src/common/helper/MathHelper.cpp000066400000000000000000000021211457262621600215750ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MathHelper.h" int MathHelper::divideIntByReal(int integer, qreal real) { return static_cast((double)integer / real); } int MathHelper::multiplyIntWithReal(int integer, qreal real) { return static_cast((double)integer * real); } int MathHelper::randomInt() { return qrand(); } ksnip-master/src/common/helper/MathHelper.h000066400000000000000000000021271457262621600212500ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef MATHHELPER_H #define MATHHELPER_H #include #include #include #include class MathHelper { public: static int divideIntByReal(int integer, qreal real); static int multiplyIntWithReal(int integer, qreal real); static int randomInt(); }; #endif // MATHHELPER_H ksnip-master/src/common/helper/PathHelper.cpp000066400000000000000000000035001457262621600216020ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "PathHelper.h" bool PathHelper::isPathValid(const QString &path) { return !path.isNull() && !path.isEmpty(); } bool PathHelper::isPipePath(const QString &path) { return path == QLatin1String("-"); } bool PathHelper::isTempDirectory(const QString &path) { return path.startsWith(QDir::tempPath()); } QString PathHelper::extractParentDirectory(const QString& path) { return path.section(QLatin1Char('/'), 0, -2); } QString PathHelper::extractFilename(const QString& path) { auto filename = extractFilenameWithFormat(path); if (filename.contains(QLatin1Char('.'))) { return filename.section(QLatin1Char('.'), 0, -2); } else { return filename; } } QString PathHelper::extractFilenameWithFormat(const QString &path) { return path.section(QLatin1Char('/'), -1); } QString PathHelper::extractFormat(const QString& path) { auto filename = extractFilenameWithFormat(path); if (filename.contains(QLatin1Char('.'))) { return path.section(QLatin1Char('.'), -1); } else { return {}; } } ksnip-master/src/common/helper/PathHelper.h000066400000000000000000000025571457262621600212620ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_PATHHELPER_H #define KSNIP_PATHHELPER_H #include #include #include #include class PathHelper { public: static bool isPathValid(const QString &path); static bool isPipePath(const QString &path); static bool isTempDirectory(const QString &path); static QString extractParentDirectory(const QString &path); static QString extractFilename(const QString &path); static QString extractFilenameWithFormat(const QString &path); static QString extractFormat(const QString &path); }; #endif // KSNIP_PATHHELPER_H ksnip-master/src/common/helper/RectHelper.cpp000066400000000000000000000027601457262621600216120ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "RectHelper.h" QPointF RectHelper::topLeft(const QRectF &rect) { return rect.topLeft(); } QPointF RectHelper::top(const QRectF &rect) { return { rect.center().x(), rect.top() }; } QPointF RectHelper::topRight(const QRectF &rect) { return rect.topRight(); } QPointF RectHelper::right(const QRectF &rect) { return { rect.right(), rect.center().y() }; } QPointF RectHelper::bottomRight(const QRectF &rect) { return rect.bottomRight(); } QPointF RectHelper::bottom(const QRectF &rect) { return { rect.center().x(), rect.bottom() }; } QPointF RectHelper::bottomLeft(const QRectF &rect) { return rect.bottomLeft(); } QPointF RectHelper::left(const QRectF &rect) { return { rect.left(), rect.center().y() }; } ksnip-master/src/common/helper/RectHelper.h000066400000000000000000000025031457262621600212520ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RECTHELPER_H #define KSNIP_RECTHELPER_H #include class RectHelper { public: static QPointF topLeft(const QRectF &rect); static QPointF top(const QRectF &rect); static QPointF topRight(const QRectF &rect); static QPointF right(const QRectF &rect); static QPointF bottomRight(const QRectF &rect); static QPointF bottom(const QRectF &rect); static QPointF bottomLeft(const QRectF &rect); static QPointF left(const QRectF &rect); protected: RectHelper() = default; ~RectHelper() = default; }; #endif //KSNIP_RECTHELPER_H ksnip-master/src/common/loader/000077500000000000000000000000001457262621600170335ustar00rootroot00000000000000ksnip-master/src/common/loader/IIconLoader.h000066400000000000000000000020571457262621600213400ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IICONLOADER_H #define KSNIP_IICONLOADER_H class IIconLoader { public: IIconLoader() = default; virtual ~IIconLoader() = default; virtual QIcon load(const QString& name) = 0; virtual QIcon loadForTheme(const QString& name) = 0; }; #endif //KSNIP_IICONLOADER_H ksnip-master/src/common/loader/IconLoader.cpp000066400000000000000000000026371457262621600215660ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "IconLoader.h" QIcon IconLoader::load(const QString &name) { return QIcon(QLatin1String(":/icons/") + name); } QIcon IconLoader::loadForTheme(const QString& name) { auto type = getThemePrefix(); return QIcon(QLatin1String(":/icons/") + type + name); } QString IconLoader::getThemePrefix() { return isDarkTheme() ? QLatin1String("dark/") : QLatin1String("light/"); } double IconLoader::getThemeLuma() { auto color = QApplication::palette().background().color(); return 0.2126 * color.redF() + 0.7152 * color.greenF() + 0.0722 * color.blueF(); } bool IconLoader::isDarkTheme() { return getThemeLuma() > 0.4; } ksnip-master/src/common/loader/IconLoader.h000066400000000000000000000023711457262621600212260ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICONLOADER_H #define KSNIP_ICONLOADER_H #include #include #include #include "IIconLoader.h" class IconLoader : public IIconLoader { public: IconLoader() = default; ~IconLoader() override = default; QIcon load(const QString& name) override; QIcon loadForTheme(const QString& name) override; private: static bool isDarkTheme(); static QString getThemePrefix(); static double getThemeLuma(); }; #endif // KSNIP_ICONLOADER_H ksnip-master/src/common/platform/000077500000000000000000000000001457262621600174115ustar00rootroot00000000000000ksnip-master/src/common/platform/CommandRunner.cpp000066400000000000000000000024411457262621600226660ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CommandRunner.h" QString CommandRunner::getEnvironmentVariable(const QString& variable) const { return qgetenv(variable.toLatin1()); } bool CommandRunner::isEnvironmentVariableSet(const QString &variable) const { return QProcessEnvironment::systemEnvironment().contains(variable); } QString CommandRunner::readFile(const QString &path) const { QFile file(path); if (file.open(QFile::ReadOnly | QFile::Text)) { QTextStream inputStream(&file); return inputStream.readAll(); } else { return {}; } } ksnip-master/src/common/platform/CommandRunner.h000066400000000000000000000023051457262621600223320ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef COMMANDRUNNER_H #define COMMANDRUNNER_H #include #include #include #include "ICommandRunner.h" class CommandRunner : public ICommandRunner { public: QString getEnvironmentVariable(const QString &variable) const override; bool isEnvironmentVariableSet(const QString &variable) const override; QString readFile(const QString &path) const override; }; #endif // COMMANDRUNNER_H ksnip-master/src/common/platform/HdpiScaler.cpp000066400000000000000000000031761457262621600221420ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "HdpiScaler.h" QRect HdpiScaler::unscale(const QRect &rect) const { auto factor = scaleFactor(); return { static_cast(rect.x() / factor), static_cast(rect.y() / factor), static_cast(rect.width() / factor), static_cast(rect.height() / factor) }; } QRect HdpiScaler::scale(const QRect &rect) const { auto factor = scaleFactor(); return { static_cast(rect.x() * factor), static_cast(rect.y() * factor), static_cast(rect.width() * factor), static_cast(rect.height() * factor) }; } qreal HdpiScaler::scaleFactor() const { auto desktopWidget = QApplication::desktop(); #if defined(__APPLE__) auto myWindow = QGuiApplication::topLevelWindows().first(); return myWindow->devicePixelRatio(); #endif #if defined(UNIX_X11) || defined(_WIN32) return desktopWidget->devicePixelRatioF(); #endif } ksnip-master/src/common/platform/HdpiScaler.h000066400000000000000000000022411457262621600215770ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_HDPISCALER_H #define KSNIP_HDPISCALER_H #include #include #include #include #include class HdpiScaler { public: HdpiScaler() = default; ~HdpiScaler() = default; QRect unscale(const QRect &rect) const; QRect scale(const QRect &rect) const; qreal scaleFactor() const; }; #endif //KSNIP_HDPISCALER_H ksnip-master/src/common/platform/ICommandRunner.h000066400000000000000000000022761457262621600224520ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICOMMANDRUNNER_H #define KSNIP_ICOMMANDRUNNER_H class QString; class ICommandRunner { public: ICommandRunner() = default; virtual ~ICommandRunner() = default; virtual QString getEnvironmentVariable(const QString &variable) const = 0; virtual bool isEnvironmentVariableSet(const QString &variable) const = 0; virtual QString readFile(const QString &path) const = 0; }; #endif //KSNIP_ICOMMANDRUNNER_H ksnip-master/src/common/platform/IPlatformChecker.h000066400000000000000000000022421457262621600227440ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLATFORMCHECKER_H #define KSNIP_IPLATFORMCHECKER_H class IPlatformChecker { public: explicit IPlatformChecker() = default; virtual ~IPlatformChecker() = default; virtual bool isX11() = 0; virtual bool isWayland() = 0; virtual bool isKde() = 0; virtual bool isGnome() = 0; virtual bool isSnap() = 0; virtual int gnomeVersion() = 0; }; #endif //KSNIP_IPLATFORMCHECKER_H ksnip-master/src/common/platform/PlatformChecker.cpp000066400000000000000000000070561457262621600231760ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PlatformChecker.h" PlatformChecker::PlatformChecker(const QSharedPointer &commandRunner) : mCommandRunner(commandRunner), mEnvironment(Environment::Unknown), mPlatform(Platform::Unknown), mPackageManager(PackageManager::Unknown), mGnomeVersion(-1), mIsPlatformChecked(false), mIsEnvironmentChecked(false), mIsPacketManagerChecked(false), mIsGnomeVersionChecked(false) { } bool PlatformChecker::isX11() { checkPlatform(); return mPlatform == Platform::X11; } bool PlatformChecker::isWayland() { checkPlatform(); return mPlatform == Platform::Wayland; } bool PlatformChecker::isKde() { checkEnvironment(); return mEnvironment == Environment::KDE; } bool PlatformChecker::isGnome() { checkEnvironment(); return mEnvironment == Environment::Gnome; } bool PlatformChecker::isSnap() { checkPackageManager(); return mPackageManager == PackageManager::Snap; } int PlatformChecker::gnomeVersion() { checkVersion(); return mGnomeVersion; } void PlatformChecker::checkPlatform() { if(!mIsPlatformChecked) { auto output = mCommandRunner->getEnvironmentVariable(QLatin1String("XDG_SESSION_TYPE")); if (outputContainsValue(output, QLatin1String("x11"))) { mPlatform = Platform::X11; } else if (outputContainsValue(output, QLatin1String("wayland"))) { mPlatform = Platform::Wayland; } else { mPlatform = Platform::Unknown; } } mIsPlatformChecked = true; } void PlatformChecker::checkEnvironment() { if(!mIsEnvironmentChecked) { auto output = mCommandRunner->getEnvironmentVariable(QLatin1String("XDG_CURRENT_DESKTOP")); if (outputContainsValue(output, QLatin1String("kde"))) { mEnvironment = Environment::KDE; } else if (outputContainsValue(output, QLatin1String("gnome")) || outputContainsValue(output, QLatin1String("unity"))) { mEnvironment = Environment::Gnome; } else { mEnvironment = Environment::Unknown; } } mIsEnvironmentChecked = true; } void PlatformChecker::checkPackageManager() { if(!mIsPacketManagerChecked) { if (mCommandRunner->isEnvironmentVariableSet(QLatin1String("SNAP"))) { mPackageManager = PackageManager::Snap; } else { mPackageManager = PackageManager::Unknown; } mIsPacketManagerChecked = true; } } bool PlatformChecker::outputContainsValue(const QString& output, const QString& value) { return output.contains(value.toLatin1(), Qt::CaseInsensitive); } void PlatformChecker::checkVersion() { if(!mIsGnomeVersionChecked && isGnome()) { auto path = QLatin1String("/usr/share/gnome/gnome-version.xml"); QRegularExpression regex("(.+?)"); bool isParseSuccessful; auto value = regex.match(mCommandRunner->readFile(path)).captured(1).toInt(&isParseSuccessful); if(isParseSuccessful) { mGnomeVersion = value; } } mIsGnomeVersionChecked = true; } ksnip-master/src/common/platform/PlatformChecker.h000066400000000000000000000037171457262621600226430ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLATFORMCHECKER_H #define KSNIP_PLATFORMCHECKER_H #include #include #include #include "IPlatformChecker.h" #include "ICommandRunner.h" #include "src/common/enum/Platform.h" #include "src/common/enum/Environment.h" #include "src/common/enum/PackageManager.h" class PlatformChecker : public IPlatformChecker { public: explicit PlatformChecker(const QSharedPointer &commandRunner); ~PlatformChecker() override = default; bool isX11() override; bool isWayland() override; bool isKde() override; bool isGnome() override; bool isSnap() override; int gnomeVersion() override; private: QSharedPointer mCommandRunner; Platform mPlatform; Environment mEnvironment; PackageManager mPackageManager; int mGnomeVersion; bool mIsPlatformChecked; bool mIsEnvironmentChecked; bool mIsPacketManagerChecked; bool mIsGnomeVersionChecked; void checkPlatform(); void checkEnvironment(); void checkPackageManager(); static bool outputContainsValue(const QString& output, const QString& value); void checkVersion(); }; #endif // KSNIP_PLATFORMCHECKER_H ksnip-master/src/common/provider/000077500000000000000000000000001457262621600174175ustar00rootroot00000000000000ksnip-master/src/common/provider/ApplicationTitleProvider.cpp000066400000000000000000000024241457262621600251050ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ApplicationTitleProvider.h" QString ApplicationTitleProvider::getApplicationTitle(const QString &applicationName, const QString &pathToImage, const QString &unsavedString, bool isUnsaved) { auto applicationTitle = applicationName; if(!pathToImage.isEmpty()) { applicationTitle = applicationTitle + QLatin1String(" [") + pathToImage + QLatin1String("]"); } if (isUnsaved) { applicationTitle = QLatin1String("*") + applicationTitle + " - " + unsavedString; } return applicationTitle; } ksnip-master/src/common/provider/ApplicationTitleProvider.h000066400000000000000000000021451457262621600245520ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_APPLICATIONTITLEPROVIDER_H #define KSNIP_APPLICATIONTITLEPROVIDER_H #include class ApplicationTitleProvider { public: static QString getApplicationTitle(const QString &applicationName, const QString &pathToImage, const QString &unsavedString, bool isUnsaved); }; #endif //KSNIP_APPLICATIONTITLEPROVIDER_H ksnip-master/src/common/provider/ITempFileProvider.h000066400000000000000000000020511457262621600231170ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ITEMPFILEPROVIDER_H #define KSNIP_ITEMPFILEPROVIDER_H class QString; class ITempFileProvider { public: ITempFileProvider() = default; virtual ~ITempFileProvider() = default; virtual QString tempFile() = 0; }; #endif //KSNIP_ITEMPFILEPROVIDER_Hksnip-master/src/common/provider/NewCaptureNameProvider.cpp000066400000000000000000000023021457262621600245110ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "NewCaptureNameProvider.h" NewCaptureNameProvider::NewCaptureNameProvider() : mCaptureNumber(1) { } QString NewCaptureNameProvider::nextName(const QString &path) { auto isPathSet = PathHelper::isPathValid(path); return isPathSet ? PathHelper::extractFilename(path) : getNewName(); } QString NewCaptureNameProvider::getNewName() { return tr("Capture") + QLatin1String(" ") + QString::number(mCaptureNumber++); } ksnip-master/src/common/provider/NewCaptureNameProvider.h000066400000000000000000000023211457262621600241570ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NEWCAPTURENAMEPROVIDER_H #define KSNIP_NEWCAPTURENAMEPROVIDER_H #include #include #include "src/common/helper/PathHelper.h" class NewCaptureNameProvider : public QObject { Q_OBJECT public: NewCaptureNameProvider(); ~NewCaptureNameProvider() override = default; QString nextName(const QString &path); private: int mCaptureNumber; QString getNewName(); }; #endif //KSNIP_NEWCAPTURENAMEPROVIDER_H ksnip-master/src/common/provider/PathFromCaptureProvider.cpp000066400000000000000000000020511457262621600247000ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PathFromCaptureProvider.h" QString PathFromCaptureProvider::pathFrom(const CaptureDto &capture) const { auto captureFromFileDto = dynamic_cast(&capture); return captureFromFileDto != nullptr ? captureFromFileDto->path : QString(); } ksnip-master/src/common/provider/PathFromCaptureProvider.h000066400000000000000000000022051457262621600243460ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PATHFROMCAPTUREPROVIDER_H #define KSNIP_PATHFROMCAPTUREPROVIDER_H #include #include "src/common/dtos/CaptureFromFileDto.h" class PathFromCaptureProvider { public: PathFromCaptureProvider() = default; ~PathFromCaptureProvider() = default; QString pathFrom(const CaptureDto &capture) const; }; #endif //KSNIP_PATHFROMCAPTUREPROVIDER_H ksnip-master/src/common/provider/TempFileProvider.cpp000066400000000000000000000027551457262621600233540ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TempFileProvider.h" #include TempFileProvider::TempFileProvider(const QSharedPointer &config) : mConfig(config) { connect(qApp, &QCoreApplication::aboutToQuit, this, &TempFileProvider::removeTempFiles); } QString TempFileProvider::tempFile() { QTemporaryFile file(mConfig->tempDirectory() + QDir::separator() + QLatin1String("ksnip_tmp_XXXXXX.png")); file.setAutoRemove(false); if (!file.open()) { qWarning("Failed to created temporary file %s", qPrintable(file.fileName())); } mTempFiles.append(file.fileName()); return file.fileName(); } void TempFileProvider::removeTempFiles() { for(const auto& file : mTempFiles) { QFile(file).remove(); } } ksnip-master/src/common/provider/TempFileProvider.h000066400000000000000000000025451457262621600230160ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_TEMPFILEPROVIDER_H #define KSNIP_TEMPFILEPROVIDER_H #include #include #include #include "ITempFileProvider.h" #include "src/backend/config/IConfig.h" class TempFileProvider : public ITempFileProvider, public QObject { public: explicit TempFileProvider(const QSharedPointer &config); ~TempFileProvider() override = default; QString tempFile() override; private: QSharedPointer mConfig; QList mTempFiles; private slots: void removeTempFiles(); }; #endif //KSNIP_TEMPFILEPROVIDER_H ksnip-master/src/common/provider/directoryPathProvider/000077500000000000000000000000001457262621600237535ustar00rootroot00000000000000ksnip-master/src/common/provider/directoryPathProvider/DirectoryPathProvider.cpp000066400000000000000000000016001457262621600307500ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DirectoryPathProvider.h" QString DirectoryPathProvider::home() { return QDir::homePath(); } ksnip-master/src/common/provider/directoryPathProvider/DirectoryPathProvider.h000066400000000000000000000021701457262621600304200ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DIRECTORYPATHPROVIDER_H #define KSNIP_DIRECTORYPATHPROVIDER_H #include #include "IDirectoryPathProvider.h" class DirectoryPathProvider : public IDirectoryPathProvider { public: DirectoryPathProvider() = default; ~DirectoryPathProvider() override = default; QString home() override; }; #endif //KSNIP_DIRECTORYPATHPROVIDER_H ksnip-master/src/common/provider/directoryPathProvider/IDirectoryPathProvider.h000066400000000000000000000020521457262621600305300ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IDIRECTORYPATHPROVIDER_H #define KSNIP_IDIRECTORYPATHPROVIDER_H class IDirectoryPathProvider { public: IDirectoryPathProvider() = default; virtual ~IDirectoryPathProvider() = default; virtual QString home() = 0; }; #endif //KSNIP_IDIRECTORYPATHPROVIDER_H ksnip-master/src/common/provider/directoryPathProvider/SnapDirectoryPathProvider.cpp000066400000000000000000000016211457262621600315750ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnapDirectoryPathProvider.h" QString SnapDirectoryPathProvider::home() { return qgetenv("SNAP_REAL_HOME"); } ksnip-master/src/common/provider/directoryPathProvider/SnapDirectoryPathProvider.h000066400000000000000000000022501457262621600312410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNAPDIRECTORYPATHPROVIDER_H #define KSNIP_SNAPDIRECTORYPATHPROVIDER_H #include #include #include "IDirectoryPathProvider.h" class SnapDirectoryPathProvider : public IDirectoryPathProvider { public: SnapDirectoryPathProvider() = default; ~SnapDirectoryPathProvider() override = default; QString home() override; }; #endif //KSNIP_SNAPDIRECTORYPATHPROVIDER_H ksnip-master/src/common/provider/scaledSizeProvider/000077500000000000000000000000001457262621600232205ustar00rootroot00000000000000ksnip-master/src/common/provider/scaledSizeProvider/GnomeScaledSizeProvider.cpp000066400000000000000000000021401457262621600304500ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GnomeScaledSizeProvider.h" qreal GnomeScaledSizeProvider::getScaleFactor() { auto screen = QApplication::primaryScreen(); auto logicalDotsPerInch = (int) screen->logicalDotsPerInch(); auto physicalDotsPerInch = (int) screen->physicalDotsPerInch(); return (qreal)logicalDotsPerInch / (qreal)physicalDotsPerInch; } ksnip-master/src/common/provider/scaledSizeProvider/GnomeScaledSizeProvider.h000066400000000000000000000022421457262621600301200ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_GNOMESCALEDSIZEPROVIDER_H #define KSNIP_GNOMESCALEDSIZEPROVIDER_H #include #include #include "ScaledSizeProvider.h" class GnomeScaledSizeProvider : public ScaledSizeProvider { public: GnomeScaledSizeProvider() = default; ~GnomeScaledSizeProvider() = default; protected: qreal getScaleFactor() override; }; #endif //KSNIP_GNOMESCALEDSIZEPROVIDER_H ksnip-master/src/common/provider/scaledSizeProvider/IScaledSizeProvider.h000066400000000000000000000021161457262621600272430ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ISCALEDSIZEPROVIDER_H #define KSNIP_ISCALEDSIZEPROVIDER_H class IScaledSizeProvider { public: IScaledSizeProvider() = default; ~IScaledSizeProvider() = default; virtual QSize scaledSize(const QSize &size) = 0; virtual int scaledWidth(int width) = 0; }; #endif //KSNIP_ISCALEDSIZEPROVIDER_H ksnip-master/src/common/provider/scaledSizeProvider/ScaledSizeProvider.cpp000066400000000000000000000022421457262621600274650ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ScaledSizeProvider.h" QSize ScaledSizeProvider::scaledSize(const QSize &size) { return size * scaleFactor(); } int ScaledSizeProvider::scaledWidth(int width) { return static_cast(width * scaleFactor()); } qreal ScaledSizeProvider::scaleFactor() { static auto scaleFactor = getScaleFactor(); return scaleFactor; } qreal ScaledSizeProvider::getScaleFactor() { return 1; } ksnip-master/src/common/provider/scaledSizeProvider/ScaledSizeProvider.h000066400000000000000000000023401457262621600271310ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SCALEDSIZEPROVIDER_H #define KSNIP_SCALEDSIZEPROVIDER_H #include #include "IScaledSizeProvider.h" class ScaledSizeProvider : public IScaledSizeProvider { public: ScaledSizeProvider() = default; ~ScaledSizeProvider() = default; QSize scaledSize(const QSize &size) override; int scaledWidth(int width) override; protected: virtual qreal getScaleFactor(); private: qreal scaleFactor(); }; #endif //KSNIP_SCALEDSIZEPROVIDER_H ksnip-master/src/dependencyInjector/000077500000000000000000000000001457262621600201115ustar00rootroot00000000000000ksnip-master/src/dependencyInjector/DependencyInjector.cpp000066400000000000000000000015411457262621600243720ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DependencyInjector.h" int DependencyInjector::NextTypeId = 1; ksnip-master/src/dependencyInjector/DependencyInjector.h000066400000000000000000000066441457262621600240500ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * Implementation based on the Miniature IOC Container from phillipvoyle on codeproject.com, kudos to him. * Link: https://www.codeproject.com/Articles/1029836/A-Miniature-IOC-Container-in-Cplusplus */ #ifndef KSNIP_DEPENDENCYINJECTOR_H #define KSNIP_DEPENDENCYINJECTOR_H #include #include class DependencyInjector { private: static int NextTypeId; public: //one typeid per type template static int getTypeID() { static int typeId = NextTypeId++; return typeId; } class FactoryRoot { public: virtual ~FactoryRoot() = default; }; QMap> mFactories; template class CFactory: public FactoryRoot { private: std::function ()> mFunctor; public: ~CFactory() override = default; explicit CFactory(std::function ()> functor) : mFunctor(functor) { } QSharedPointer getObject() { return mFunctor(); } }; template QSharedPointer get() { auto typeId = getTypeID(); auto factoryBase = mFactories[typeId]; auto factory = qSharedPointerCast>(factoryBase); return factory->getObject(); } template void registerFunctor(std::function (QSharedPointer ...ts)> functor) { mFactories[getTypeID()] = QSharedPointer>::create([=]{ return functor(get()...); }); } // Register a single instance, always returns same instance, effectively single instance template void registerInstance(QSharedPointer t) { mFactories[getTypeID()] = QSharedPointer>::create([=]{ return t; }); } template void registerFunctor(QSharedPointer (*functor)(QSharedPointer ...ts)) { registerFunctor(std::function (QSharedPointer ...ts)>(functor)); } // Returns for every request a new instance template void registerFactory() { registerFunctor( std::function(QSharedPointer ...ts)>( [](QSharedPointer...arguments) -> QSharedPointer { return QSharedPointer::create(std::forward>(arguments)...); })); } template void registerInstance() { registerInstance(QSharedPointer::create(get()...)); } }; #endif //KSNIP_DEPENDENCYINJECTOR_H ksnip-master/src/dependencyInjector/DependencyInjectorBootstrapper.cpp000066400000000000000000000316671457262621600270130ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DependencyInjectorBootstrapper.h" #include "src/backend/TranslationLoader.h" #include "src/backend/config/Config.h" #include "src/backend/uploader/UploadHandler.h" #include "src/backend/uploader/ftp/FtpUploader.h" #include "src/backend/uploader/script/ScriptUploader.h" #include "src/backend/uploader/imgur/ImgurUploader.h" #include "src/backend/commandLine/CommandLineCaptureHandler.h" #include "src/backend/recentImages/RecentImagesPathStore.h" #include "src/backend/recentImages/ImagePathStorage.h" #include "src/backend/saver/SavePathProvider.h" #include "src/backend/saver/ImageSaver.h" #include "src/bootstrapper/ImageFromStdInputReader.h" #include "src/gui/fileService/FileService.h" #include "src/gui/directoryService/DirectoryService.h" #include "src/gui/clipboard/ClipboardAdapter.h" #include "src/gui/desktopService/DesktopServiceAdapter.h" #include "src/gui/messageBoxService/MessageBoxService.h" #include "src/gui/captureHandler/CaptureTabStateHandler.h" #include "src/gui/modelessWindows/ocrWindow/OcrWindowCreator.h" #include "src/gui/modelessWindows/ocrWindow/OcrWindowHandler.h" #include "src/gui/modelessWindows/pinWindow/PinWindowCreator.h" #include "src/gui/modelessWindows/pinWindow/PinWindowHandler.h" #include "src/logging/ConsoleLogger.h" #include "src/logging/NoneLogger.h" #include "src/common/loader/IconLoader.h" #include "src/common/platform/CommandRunner.h" #include "src/common/platform/PlatformChecker.h" #include "src/common/provider/directoryPathProvider/DirectoryPathProvider.h" #include "src/common/provider/scaledSizeProvider/ScaledSizeProvider.h" #include "src/common/handler/DelayHandler.h" #include "src/plugins/PluginManager.h" #include "src/plugins/PluginLoader.h" #include "src/plugins/PluginFinder.h" #include "src/common/provider/TempFileProvider.h" #if defined(__APPLE__) #include "src/backend/config/MacConfig.h" #include "src/backend/imageGrabber/MacImageGrabber.h" #include "src/common/adapter/fileDialog/FileDialogAdapter.h" #include "src/plugins/searchPathProvider/MacPluginSearchPathProvider.h" #endif #if defined(UNIX_X11) #include "src/backend/config/WaylandConfig.h" #include "src/backend/imageGrabber/X11ImageGrabber.h" #include "src/backend/imageGrabber/GnomeX11ImageGrabber.h" #include "src/backend/imageGrabber/WaylandImageGrabber.h" #include "src/backend/imageGrabber/KdeWaylandImageGrabber.h" #include "src/backend/imageGrabber/GnomeWaylandImageGrabber.h" #include "src/common/adapter/fileDialog/SnapFileDialogAdapter.h" #include "src/common/provider/directoryPathProvider/SnapDirectoryPathProvider.h" #include "src/common/provider/scaledSizeProvider/GnomeScaledSizeProvider.h" #include "src/gui/desktopService/SnapDesktopServiceAdapter.h" #include "src/plugins/searchPathProvider/LinuxPluginSearchPathProvider.h" #endif #if defined(_WIN32) #include "src/backend/imageGrabber/WinImageGrabber.h" #include "src/common/adapter/fileDialog/FileDialogAdapter.h" #include "src/plugins/WinPluginLoader.h" #include "src/gui/modelessWindows/ocrWindow/WinOcrWindowCreator.h" #include "src/plugins/searchPathProvider/WinPluginSearchPathProvider.h" #endif void DependencyInjectorBootstrapper::BootstrapCore(DependencyInjector *dependencyInjector) { dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); injectDirectoryPathProvider(dependencyInjector); injectConfig(dependencyInjector); injectLogger(dependencyInjector); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); } void DependencyInjectorBootstrapper::BootstrapCommandLine(DependencyInjector *dependencyInjector) { dependencyInjector->registerInstance(); injectImageGrabber(dependencyInjector); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); } void DependencyInjectorBootstrapper::BootstrapGui(DependencyInjector *dependencyInjector) { dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); injectDesktopServiceAdapter(dependencyInjector); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); injectFileDialogService(dependencyInjector); injectScaledSizeProvider(dependencyInjector); injectPluginLoader(dependencyInjector); injectPluginSearchPathProvider(dependencyInjector); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); injectOcrWindowCreator(dependencyInjector); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); dependencyInjector->registerInstance(); } void DependencyInjectorBootstrapper::injectDesktopServiceAdapter(DependencyInjector *dependencyInjector) { #if defined(UNIX_X11) auto platformChecker = dependencyInjector->get(); if(platformChecker->isSnap()) { dependencyInjector->registerInstance(); } else { dependencyInjector->registerInstance(); } #else dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectImageGrabber(DependencyInjector *dependencyInjector) { auto logger = dependencyInjector->get(); auto config = dependencyInjector->get(); #if defined(__APPLE__) logger->log(QLatin1String("MacImageGrabber selected")); dependencyInjector->registerFactory(); #endif #if defined(UNIX_X11) auto platformChecker = dependencyInjector->get(); if (platformChecker->isX11()) { if (platformChecker->isGnome()) { logger->log(QLatin1String("GnomeX11ImageGrabber selected")); dependencyInjector->registerFactory(); } else { logger->log(QLatin1String("X11ImageGrabber selected")); dependencyInjector->registerFactory(); } } else if (platformChecker->isWayland()) { if (config->forceGenericWaylandEnabled()) { logger->log(QLatin1String("WaylandImageGrabber selected")); dependencyInjector->registerFactory(); } else if (platformChecker->isKde()) { logger->log(QLatin1String("KdeWaylandImageGrabber selected")); dependencyInjector->registerFactory(); } else if (platformChecker->isGnome()) { logger->log(QLatin1String("GnomeWaylandImageGrabber selected")); dependencyInjector->registerFactory(); } else { qCritical("Unknown wayland platform, using default wayland Image Grabber."); logger->log(QLatin1String("WaylandImageGrabber selected")); dependencyInjector->registerFactory(); } } else { qCritical("Unknown platform, using default X11 Image Grabber."); dependencyInjector->registerFactory(); } #endif #if defined(_WIN32) logger->log(QLatin1String("WinImageGrabber selected")); dependencyInjector->registerFactory(); #endif } void DependencyInjectorBootstrapper::injectLogger(DependencyInjector *dependencyInjector) { auto config = dependencyInjector->get(); if (config->isDebugEnabled()) { dependencyInjector->registerInstance(); } else { dependencyInjector->registerInstance(); } } void DependencyInjectorBootstrapper::injectConfig(DependencyInjector *dependencyInjector) { #if defined(__APPLE__) dependencyInjector->registerInstance(); #endif #if defined(UNIX_X11) auto platformChecker = dependencyInjector->get(); if (platformChecker->isWayland()) { dependencyInjector->registerInstance(); } else { dependencyInjector->registerInstance(); } #endif #if defined(_WIN32) dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectFileDialogService(DependencyInjector *dependencyInjector) { #if defined(UNIX_X11) auto platformChecker = dependencyInjector->get(); if (platformChecker->isSnap()) { dependencyInjector->registerInstance(); } else { dependencyInjector->registerInstance(); } #else dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectDirectoryPathProvider(DependencyInjector *dependencyInjector) { #if defined(UNIX_X11) auto platformChecker = dependencyInjector->get(); if (platformChecker->isSnap()) { dependencyInjector->registerInstance(); } else { dependencyInjector->registerInstance(); } #else dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectScaledSizeProvider(DependencyInjector *dependencyInjector) { #if defined(UNIX_X11) auto platformChecker = dependencyInjector->get(); if(platformChecker->isGnome()) { dependencyInjector->registerInstance(); } else { dependencyInjector->registerInstance(); } #else dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectPluginLoader(DependencyInjector *dependencyInjector) { #if defined(_WIN32) dependencyInjector->registerInstance(); #else dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectPluginSearchPathProvider(DependencyInjector *dependencyInjector) { #if defined(__APPLE__) dependencyInjector->registerInstance(); #endif #if defined(UNIX_X11) dependencyInjector->registerInstance(); #endif #if defined(_WIN32) dependencyInjector->registerInstance(); #endif } void DependencyInjectorBootstrapper::injectOcrWindowCreator(DependencyInjector *dependencyInjector) { #if defined(_WIN32) dependencyInjector->registerInstance(); #else dependencyInjector->registerInstance(); #endif } ksnip-master/src/dependencyInjector/DependencyInjectorBootstrapper.h000066400000000000000000000040561457262621600264500ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DEPENDENCYINJECTORBOOTSTRAPPER_H #define KSNIP_DEPENDENCYINJECTORBOOTSTRAPPER_H #include "DependencyInjector.h" class DependencyInjectorBootstrapper { public: DependencyInjectorBootstrapper() = default; ~DependencyInjectorBootstrapper() = default; static void BootstrapCore(DependencyInjector *dependencyInjector); static void BootstrapCommandLine(DependencyInjector *dependencyInjector); static void BootstrapGui(DependencyInjector *dependencyInjector); private: static void injectConfig(DependencyInjector *dependencyInjector); static void injectLogger(DependencyInjector *dependencyInjector); static void injectImageGrabber(DependencyInjector *dependencyInjector); static void injectFileDialogService(DependencyInjector *dependencyInjector); static void injectDirectoryPathProvider(DependencyInjector *dependencyInjector); static void injectDesktopServiceAdapter(DependencyInjector *dependencyInjector); static void injectScaledSizeProvider(DependencyInjector *dependencyInjector); static void injectPluginLoader(DependencyInjector *dependencyInjector); static void injectPluginSearchPathProvider(DependencyInjector *dependencyInjector); static void injectOcrWindowCreator(DependencyInjector *dependencyInjector); }; #endif //KSNIP_DEPENDENCYINJECTORBOOTSTRAPPER_H ksnip-master/src/gui/000077500000000000000000000000001457262621600150615ustar00rootroot00000000000000ksnip-master/src/gui/IImageProcessor.h000066400000000000000000000020771457262621600202730ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMAGEPROCESSOR_H #define KSNIP_IIMAGEPROCESSOR_H #include "src/common/dtos/CaptureDto.h" class IImageProcessor { public: IImageProcessor() = default; ~IImageProcessor() = default; virtual void processImage(const CaptureDto &capture) = 0; }; #endif //KSNIP_IIMAGEPROCESSOR_H ksnip-master/src/gui/INotificationService.h000066400000000000000000000023501457262621600213120ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_INOTIFICATIONSERVICE_H #define KSNIP_INOTIFICATIONSERVICE_H class INotificationService { public: virtual void showInfo(const QString &title, const QString &message, const QString &contentUrl) = 0; virtual void showWarning(const QString &title, const QString &message, const QString &contentUrl) = 0; virtual void showCritical(const QString &title, const QString &message, const QString &contentUrl) = 0; }; #endif //KSNIP_INOTIFICATIONSERVICE_H ksnip-master/src/gui/ImgurHistoryDialog.cpp000066400000000000000000000053271457262621600213610ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImgurHistoryDialog.h" ImgurHistoryDialog::ImgurHistoryDialog() { setWindowTitle(QApplication::applicationName() + QLatin1String(" - ") + tr("Imgur History")); setMinimumWidth(650); setMinimumHeight(400); ImgurResponseLogger imgurResponseLogger; auto logEntries = imgurResponseLogger.getLogs(); createTable(logEntries.count()); populateTable(logEntries); mCloseButton = new QPushButton(tr("Close")); connect(mCloseButton, &QPushButton::clicked, this, &QDialog::close); mLayout = new QVBoxLayout; mLayout->addWidget(mTableWidget); mLayout->addWidget(mCloseButton); mLayout->setAlignment(Qt::AlignRight); setLayout(mLayout); } ImgurHistoryDialog::~ImgurHistoryDialog() { delete mTableWidget; delete mLayout; delete mCloseButton; } void ImgurHistoryDialog::createTable(int rowCount) { mTableWidget = new QTableWidget(rowCount, 3, this); mTableWidget->setHorizontalHeaderLabels(QStringList{ tr("Time Stamp"), tr("Link"), tr("Delete Link") }); auto header = mTableWidget->horizontalHeader(); header->setStretchLastSection(true); connect(mTableWidget, &QTableWidget::cellClicked, this, &ImgurHistoryDialog::cellClicked); } void ImgurHistoryDialog::populateTable(const QStringList &logEntries) { for (const auto &entry : logEntries) { addEntryToTable(entry, logEntries.indexOf(entry)); } mTableWidget->resizeColumnsToContents(); } void ImgurHistoryDialog::addEntryToTable(const QString &entry, int row) const { auto cells = entry.split(QLatin1String(",")); auto dateCell = new QTableWidgetItem(cells[0]); auto linkCell = new QTableWidgetItem(cells[1]); auto deleteLinkCell = new QTableWidgetItem(cells[2]); mTableWidget->setItem(row, 0, dateCell); mTableWidget->setItem(row, 1, linkCell); mTableWidget->setItem(row, 2, deleteLinkCell); } void ImgurHistoryDialog::cellClicked(int row, int column) const { if (column == 1 || column == 2) { auto cell = mTableWidget->item(row, column); QDesktopServices::openUrl(cell->text()); } } ksnip-master/src/gui/ImgurHistoryDialog.h000066400000000000000000000030421457262621600210160ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMGURHISTORYDIALOG_H #define KSNIP_IMGURHISTORYDIALOG_H #include #include #include #include #include #include #include #include #include "src/backend/uploader/imgur/ImgurResponseLogger.h" class ImgurHistoryDialog : public QDialog { Q_OBJECT public: explicit ImgurHistoryDialog(); ~ImgurHistoryDialog() override; private: QVBoxLayout *mLayout; QTableWidget *mTableWidget; QPushButton *mCloseButton; void addEntryToTable(const QString &entry, int row) const; void populateTable(const QStringList &logEntries); void createTable(int rowCount); private slots: void cellClicked(int row, int column) const; }; #endif //KSNIP_IMGURHISTORYDIALOG_H ksnip-master/src/gui/MainWindow.cpp000066400000000000000000000670401457262621600176500ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "MainWindow.h" MainWindow::MainWindow(DependencyInjector *dependencyInjector) : QMainWindow(), mDependencyInjector(dependencyInjector), mConfig(mDependencyInjector->get()), mImageGrabber(mDependencyInjector->get()), mPluginManager(mDependencyInjector->get()), mTrayIcon(new TrayIcon(mConfig, mDependencyInjector->get(), this)), mNotificationService(NotificationServiceFactory::create(mTrayIcon, mDependencyInjector->get(), mConfig)), mToolBar(nullptr), mImageAnnotator(new KImageAnnotatorAdapter), mSaveAsAction(new QAction(this)), mSaveAllAction(new QAction(this)), mUploadAction(new QAction(this)), mCopyAsDataUriAction(new QAction(this)), mPrintAction(new QAction(this)), mPrintPreviewAction(new QAction(this)), mQuitAction(new QAction(this)), mCopyPathAction(new QAction(this)), mRenameAction(new QAction(this)), mOpenDirectoryAction(new QAction(this)), mToggleDocksAction(new QAction(this)), mSettingsAction(new QAction(this)), mAboutAction(new QAction(this)), mOpenImageAction(new QAction(this)), mScaleAction(new QAction(this)), mRotateAction(new QAction(this)), mAddWatermarkAction(new QAction(this)), mPasteAction(new QAction(this)), mPasteEmbeddedAction(new QAction(this)), mPinAction(new QAction(this)), mRemoveImageAction(new QAction(this)), mModifyCanvasAction(new QAction(this)), mCloseWindowAction(new QAction(this)), mOcrAction(new QAction(this)), mCutAction(new QAction(this)), mMainLayout(layout()), mActionsMenu(new ActionsMenu(mConfig)), mRecentImagesMenu(new RecentImagesMenu(mDependencyInjector->get(), this)), mClipboard(mDependencyInjector->get()), mCapturePrinter(new CapturePrinter(this)), mGlobalHotKeyHandler(new GlobalHotKeyHandler(mImageGrabber->supportedCaptureModes(), mDependencyInjector->get(), mConfig)), mDragAndDropProcessor(new DragAndDropProcessor(this, mDependencyInjector->get())), mUploadHandler(mDependencyInjector->get()), mSessionManagerRequestedQuit(false), mResizeOnNormalize(false), mCaptureHandler(CaptureHandlerFactory::create(mImageAnnotator, mNotificationService, mDependencyInjector, this)), mPinWindowHandler(mDependencyInjector->get()), mVisibilityHandler(WidgetVisibilityHandlerFactory::create(this, mDependencyInjector->get())), mFileDialogService(mDependencyInjector->get()), mWindowResizer(new WindowResizer(this, mConfig, this)), mActionProcessor(new ActionProcessor), mSavePathProvider(mDependencyInjector->get()), mOcrWindowHandler(mDependencyInjector->get()), mDelayHandler(mDependencyInjector->get()) { initGui(); setPosition(); auto coreApplication = dynamic_cast(QCoreApplication::instance()); connect(coreApplication, &QGuiApplication::commitDataRequest, this, &MainWindow::sessionFinished); setAcceptDrops(true); coreApplication->installEventFilter(mDragAndDropProcessor); connect(mDragAndDropProcessor, &DragAndDropProcessor::fileDropped, this, &MainWindow::loadImageFromFile); connect(mDragAndDropProcessor, &DragAndDropProcessor::imageDropped, this, &MainWindow::loadImageFromPixmap); connect(mConfig.data(), &IConfig::annotatorConfigChanged, this, &MainWindow::setupImageAnnotator); connect(mImageGrabber.data(), &IImageGrabber::finished, this, &MainWindow::processCapture); connect(mImageGrabber.data(), &IImageGrabber::canceled, this, &MainWindow::captureCanceled); connect(mImageGrabber.data(), &IImageGrabber::canceled, mActionProcessor, &ActionProcessor::captureCanceled); connect(mGlobalHotKeyHandler, &GlobalHotKeyHandler::captureTriggered, this, &MainWindow::triggerCapture); connect(mGlobalHotKeyHandler, &GlobalHotKeyHandler::actionTriggered, this, &MainWindow::actionTriggered); connect(mUploadHandler.data(), &IUploadHandler::finished, this, &MainWindow::uploadFinished); connect(mRecentImagesMenu, &RecentImagesMenu::openRecentSelected, this, &MainWindow::loadImageFromFile); connect(this, &MainWindow::imageLoaded, mActionProcessor, &ActionProcessor::captureFinished); connect(mActionProcessor, &ActionProcessor::triggerCapture, this, &MainWindow::capture); connect(mActionProcessor, &ActionProcessor::triggerPinImage, mPinAction, &QAction::trigger); connect(mActionProcessor, &ActionProcessor::triggerUpload, mUploadAction, &QAction::trigger); connect(mActionProcessor, &ActionProcessor::triggerOpenDirectory, mCaptureHandler, &ICaptureHandler::openDirectory); connect(mActionProcessor, &ActionProcessor::triggerCopyToClipboard, mToolBar->copyToClipboardAction(), &QAction::trigger); connect(mActionProcessor, &ActionProcessor::triggerSave, mToolBar->saveAction(), &QAction::trigger); connect(mActionProcessor, &ActionProcessor::triggerShow, this, &MainWindow::showAfterAction); mCaptureHandler->addListener(this); handleGuiStartup(); setupImageAnnotator(); resize(minimumSize()); loadSettings(); } MainWindow::~MainWindow() { delete mImageAnnotator; delete mCapturePrinter; delete mDragAndDropProcessor; delete mCaptureHandler; delete mVisibilityHandler; delete mWindowResizer; delete mActionProcessor; delete mActionsMenu; } void MainWindow::handleGuiStartup() { if (mConfig->captureOnStartup()) { triggerCapture(mConfig->captureMode()); } else if (mTrayIcon->isVisible() && mConfig->startMinimizedToTray()) { showHidden(); } else { showEmpty(); } } void MainWindow::setPosition() { auto position = mConfig->windowPosition(); auto desktopGeometry = QApplication::desktop()->geometry(); if(!desktopGeometry.contains(position)) { auto screenCenter = desktopGeometry.center(); auto mainWindowSize = size(); position = QPoint(screenCenter.x() - mainWindowSize.width() / 2, screenCenter.y() - mainWindowSize.height() / 2); } move(position); } void MainWindow::captureScreenshot(CaptureModes captureMode, bool captureCursor, int delay) { mImageGrabber->grabImage(captureMode, captureCursor, delay); } void MainWindow::quit() { if(!mCaptureHandler->canClose()){ return; } mTrayIcon->hide(); QCoreApplication::exit(0); } void MainWindow::processCapture(const CaptureDto &capture) { if (!capture.isValid()) { auto title = tr("Unable to show image"); auto message = tr("No image provided but one was expected."); NotifyOperation operation(title, message, NotificationTypes::Critical, mNotificationService, mConfig); operation.execute(); showEmpty(); return; } processImage(capture); capturePostProcessing(); } void MainWindow::processImage(const CaptureDto &capture) { mCaptureHandler->load(capture); if (!mActionProcessor->isActionInProgress()) { // The action processor handles the showing of the main window showDefault(); } captureChanged(); setEnablements(true); emit imageLoaded(); } DragContent MainWindow::dragContent() const { return DragContent(mCaptureHandler->image(), mCaptureHandler->path(), mCaptureHandler->isSaved()); } void MainWindow::resizeToContent() { if(!mToolBar->isCollapsed() || mImageAnnotator->isVisible()) { mMainLayout->setSizeConstraint(QLayout::SetFixedSize); // Workaround that allows us to return to toolbar only size QMainWindow::adjustSize(); } else { setFixedSize(menuBar()->sizeHint()); } mMainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); setMinimumSize(minimumSizeHint()); // Workaround for issue #588 } bool MainWindow::isWindowMaximized() { return mVisibilityHandler->isMaximized(); } void MainWindow::capturePostProcessing() { if (mConfig->autoCopyToClipboardNewCaptures()) { copyCaptureToClipboard(); } if (mConfig->autoSaveNewCaptures()) { mCaptureHandler->save(); } } void MainWindow::showEmpty() { mVisibilityHandler->show(); captureChanged(); setEnablements(false); } void MainWindow::showHidden() { captureChanged(); setEnablements(false); mVisibilityHandler->hide(); } void MainWindow::showDefault() { auto enforceVisible = mConfig->showMainWindowAfterTakingScreenshotEnabled(); enforceVisible ? mVisibilityHandler->enforceVisible() : mVisibilityHandler->restoreState(); mWindowResizer->resize(); } QMenu* MainWindow::createPopupMenu() { // Filtering out the option to hide main toolbar which should no be allowed. auto filteredMenu = QMainWindow::createPopupMenu(); filteredMenu->removeAction(mToolBar->toggleViewAction()); return filteredMenu; } QSize MainWindow::sizeHint() const { auto minHeight = mToolBar->sizeHint().height(); auto minWidth = mToolBar->sizeHint().width(); auto annotatorSize = mImageAnnotator->sizeHint(); auto height = minHeight + annotatorSize.height(); auto width = minWidth > annotatorSize.width() ? minWidth : annotatorSize.width(); return { width, height }; } void MainWindow::moveEvent(QMoveEvent* event) { mConfig->setWindowPosition(pos()); QWidget::moveEvent(event); } void MainWindow::closeEvent(QCloseEvent* event) { if (!mSessionManagerRequestedQuit) { event->ignore(); } if (mTrayIcon->isVisible() && mConfig->closeToTray()) { mVisibilityHandler->hide(); } else { quit(); } } void MainWindow::changeEvent(QEvent *event) { if (event->type() == QEvent::WindowStateChange) { if(mResizeOnNormalize && !isMaximized()) { mResizeOnNormalize = false; resizeToContent(); } else if(isMinimized() && mTrayIcon->isVisible() && mConfig->minimizeToTray()) { event->ignore(); mVisibilityHandler->hide(); } mVisibilityHandler->updateState(); } QWidget::changeEvent(event); } void MainWindow::captureChanged() { mToolBar->setSaveActionEnabled(!mCaptureHandler->isSaved()); mCopyPathAction->setEnabled(mCaptureHandler->isPathValid()); mRenameAction->setEnabled(mCaptureHandler->isPathValid()); mOpenDirectoryAction->setEnabled(mCaptureHandler->isPathValid()); mRemoveImageAction->setEnabled(mCaptureHandler->isPathValid()); updateApplicationTitle(); } void MainWindow::updateApplicationTitle() { auto path = mCaptureHandler->path(); auto isUnsaved = !mCaptureHandler->isSaved(); auto applicationTitle = ApplicationTitleProvider::getApplicationTitle(QApplication::applicationName(), path, tr("Unsaved"), isUnsaved); setWindowTitle(applicationTitle); } void MainWindow::setEnablements(bool enabled) { mPrintAction->setEnabled(enabled); mPrintPreviewAction->setEnabled(enabled); mUploadAction->setEnabled(enabled); mCopyAsDataUriAction->setEnabled(enabled); mScaleAction->setEnabled(enabled); mRotateAction->setEnabled(enabled); mAddWatermarkAction->setEnabled(enabled); mToolBar->setCopyActionEnabled(enabled); mToolBar->setCropEnabled(enabled); mSaveAsAction->setEnabled(enabled); mSaveAllAction->setEnabled(enabled); mPinAction->setEnabled(enabled); mPasteEmbeddedAction->setEnabled(mClipboard->isPixmap() && mImageAnnotator->isVisible()); mRenameAction->setEnabled(enabled); mModifyCanvasAction->setEnabled(enabled); mCutAction->setEnabled(enabled); mActionProcessor->setPostProcessingEnabled(enabled); mOcrAction->setEnabled(mPluginManager->isAvailable(PluginType::Ocr) && enabled); } void MainWindow::loadSettings() { mToolBar->selectCaptureMode(mConfig->captureMode()); mToolBar->setCaptureDelay(mConfig->captureDelay() / 1000); if(mConfig->autoHideDocks()) { toggleDocks(); } } void MainWindow::triggerCapture(CaptureModes captureMode) { if(!mCaptureHandler->canTakeNew()){ return; } mConfig->setCaptureMode(captureMode); capture(captureMode, mConfig->captureCursor(), mConfig->captureDelay()); } void MainWindow::capture(CaptureModes captureMode, bool captureCursor, int delay) { auto isMainWindowVisible = !isMinimized(); auto adjustedDelay = mDelayHandler->getDelay(delay, isMainWindowVisible); hideMainWindowIfRequired(); captureScreenshot(captureMode, captureCursor, adjustedDelay); } void MainWindow::hideMainWindowIfRequired() { if (mConfig->hideMainWindowDuringScreenshot()) { mVisibilityHandler->makeInvisible(); } } void MainWindow::toggleDocks() { auto newIsCollapsedState = !mToolBar->isCollapsed(); mToolBar->setCollapsed(newIsCollapsedState); mImageAnnotator->setSettingsCollapsed(newIsCollapsedState); auto collapsedToggleText = newIsCollapsedState ? tr("Show Docks") : tr("Hide Docks"); mToggleDocksAction->setText(collapsedToggleText); mWindowResizer->resize(); } void MainWindow::initGui() { auto iconLoader = mDependencyInjector->get(); setWindowIcon(iconLoader->load(QLatin1String("ksnip"))); mToolBar = new MainToolBar( mImageGrabber->supportedCaptureModes(), mImageAnnotator->undoAction(), mImageAnnotator->redoAction(), iconLoader, mDependencyInjector->get()); connect(mToolBar, &MainToolBar::captureModeSelected, this, &MainWindow::triggerCapture); connect(mToolBar, &MainToolBar::saveActionTriggered, this, &MainWindow::saveClicked); connect(mToolBar, &MainToolBar::copyActionTriggered, this, &MainWindow::copyCaptureToClipboard); connect(mToolBar, &MainToolBar::captureDelayChanged, this, &MainWindow::captureDelayChanged); connect(mToolBar, &MainToolBar::cropActionTriggered, mImageAnnotator, &IImageAnnotator::showCropper); mSaveAsAction->setText(tr("Save As...")); mSaveAsAction->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_S); mSaveAsAction->setIcon(iconLoader->loadForTheme(QLatin1String("saveAs"))); connect(mSaveAsAction, &QAction::triggered, this, &MainWindow::saveAsClicked); mSaveAllAction->setText(tr("Save All")); mSaveAllAction->setIcon(iconLoader->loadForTheme(QLatin1String("save"))); connect(mSaveAllAction, &QAction::triggered, this, &MainWindow::saveAllClicked); mUploadAction->setText(tr("Upload")); mUploadAction->setToolTip(tr("Upload triggerCapture to external source")); mUploadAction->setShortcut(Qt::SHIFT + Qt::Key_U); connect(mUploadAction, &QAction::triggered, this, &MainWindow::upload); mCopyAsDataUriAction->setText(tr("Copy as data URI")); mCopyAsDataUriAction->setToolTip(tr("Copy triggerCapture to system clipboard")); connect(mCopyAsDataUriAction, &QAction::triggered, this, &MainWindow::copyAsDataUri); mPrintAction->setText(tr("Print")); mPrintAction->setToolTip(tr("Opens printer dialog and provide option to print image")); mPrintAction->setShortcut(Qt::CTRL + Qt::Key_P); mPrintAction->setIcon(QIcon::fromTheme(QLatin1String("document-print"))); connect(mPrintAction, &QAction::triggered, this, &MainWindow::printClicked); mPrintPreviewAction->setText(tr("Print Preview")); mPrintPreviewAction->setToolTip(tr("Opens Print Preview dialog where the image " "orientation can be changed")); mPrintPreviewAction->setIcon(QIcon::fromTheme(QLatin1String("document-print-preview"))); connect(mPrintPreviewAction, &QAction::triggered, this, &MainWindow::printPreviewClicked); mScaleAction->setText(tr("Scale")); mScaleAction->setToolTip(tr("Scale Image")); mScaleAction->setShortcut(Qt::SHIFT + Qt::Key_S); connect(mScaleAction, &QAction::triggered, this, &MainWindow::showScaleDialog); mRotateAction->setText(tr("Rotate")); mRotateAction->setToolTip(tr("Rotate Image")); mRotateAction->setShortcut(Qt::SHIFT + Qt::Key_O); connect(mRotateAction, &QAction::triggered, this, &MainWindow::showRotateDialog); mAddWatermarkAction->setText(tr("Add Watermark")); mAddWatermarkAction->setToolTip(tr("Add Watermark to captured image. Multiple watermarks can be added.")); mAddWatermarkAction->setShortcut(Qt::SHIFT + Qt::Key_W); connect(mAddWatermarkAction, &QAction::triggered, this, &MainWindow::addWatermark); mQuitAction->setText(tr("Quit")); mQuitAction->setShortcut(Qt::CTRL + Qt::Key_Q); mQuitAction->setIcon(QIcon::fromTheme(QLatin1String("application-exit"))); connect(mQuitAction, &QAction::triggered, this, &MainWindow::quit); mCloseWindowAction->setText(tr("Close Window")); mCloseWindowAction->setShortcut(Qt::SHIFT + Qt::Key_Escape); mCloseWindowAction->setIcon(QIcon::fromTheme(QLatin1String("window-close"))); connect(mCloseWindowAction, &QAction::triggered, this, &MainWindow::close); mCopyPathAction->setText(tr("Copy Path")); connect(mCopyPathAction, &QAction::triggered, mCaptureHandler, &ICaptureHandler::copyPath); mRenameAction->setText(tr("Rename")); mRenameAction->setShortcut(Qt::Key_F2); connect(mRenameAction, &QAction::triggered, mCaptureHandler, &ICaptureHandler::rename); mOpenDirectoryAction->setText(tr("Open Directory")); connect(mOpenDirectoryAction, &QAction::triggered, mCaptureHandler, &ICaptureHandler::openDirectory); mToggleDocksAction->setText(tr("Hide Docks")); mToggleDocksAction->setShortcut(Qt::Key_Tab); connect(mToggleDocksAction, &QAction::triggered, this, &MainWindow::toggleDocks); mSettingsAction->setText(tr("Settings")); mSettingsAction->setIcon(QIcon::fromTheme(QLatin1String("emblem-system"))); mSettingsAction->setShortcut(Qt::ALT + Qt::Key_F7); connect(mSettingsAction, &QAction::triggered, this, &MainWindow::showSettingsDialog); mAboutAction->setText(tr("&About")); mAboutAction->setIcon(iconLoader->load(QLatin1String("ksnip"))); connect(mAboutAction, &QAction::triggered, this, &MainWindow::showAboutDialog); mOpenImageAction->setText(tr("Open")); mOpenImageAction->setIcon(QIcon::fromTheme(QLatin1String("document-open"))); mOpenImageAction->setShortcut(Qt::CTRL + Qt::Key_O); connect(mOpenImageAction, &QAction::triggered, this, &MainWindow::showOpenImageDialog); mRecentImagesMenu->setTitle(tr("Open &Recent")); mRecentImagesMenu->setIcon(QIcon::fromTheme(QLatin1String("document-open"))); mPasteAction->setText(tr("Paste")); mPasteAction->setIcon(iconLoader->loadForTheme(QLatin1String("paste"))); mPasteAction->setShortcut(Qt::CTRL + Qt::Key_V); mPasteAction->setEnabled(mClipboard->isPixmap()); connect(mPasteAction, &QAction::triggered, this, &MainWindow::pasteFromClipboard); connect(mClipboard.data(), &IClipboard::changed, mPasteAction, &QAction::setEnabled); mPasteEmbeddedAction->setText(tr("Paste Embedded")); mPasteEmbeddedAction->setIcon(iconLoader->loadForTheme(QLatin1String("pasteEmbedded"))); mPasteEmbeddedAction->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); mPasteEmbeddedAction->setEnabled(mClipboard->isPixmap() && mImageAnnotator->isVisible()); connect(mPasteEmbeddedAction, &QAction::triggered, this, &MainWindow::pasteEmbeddedFromClipboard); connect(mClipboard.data(), &IClipboard::changed, [this] (bool isPixmap){ mPasteEmbeddedAction->setEnabled(isPixmap && mImageAnnotator->isVisible()); }); mPinAction->setText(tr("Pin")); mPinAction->setToolTip(tr("Pin screenshot to foreground in frameless window")); mPinAction->setShortcut(Qt::SHIFT + Qt::Key_P); mPinAction->setIcon(iconLoader->loadForTheme(QLatin1String("pin"))); connect(mPinAction, &QAction::triggered, this, &MainWindow::showPinWindow); mRemoveImageAction->setText(tr("Delete")); mRemoveImageAction->setIcon(iconLoader->loadForTheme(QLatin1String("delete"))); connect(mRemoveImageAction, &QAction::triggered, mCaptureHandler, &ICaptureHandler::removeImage); mModifyCanvasAction->setText(tr("Modify Canvas")); connect(mModifyCanvasAction, &QAction::triggered, mImageAnnotator, &IImageAnnotator::showCanvasModifier); mCutAction->setText(tr("Cut")); mCutAction->setShortcut(Qt::SHIFT + Qt::Key_T); connect(mCutAction, &QAction::triggered, mImageAnnotator, &IImageAnnotator::showCutter); mActionsMenu->setTitle(tr("Actions")); mActionsMenu->setIcon(iconLoader->loadForTheme(QLatin1String("action"))); connect(mActionsMenu, &ActionsMenu::triggered, this, &MainWindow::actionTriggered); mOcrAction->setText(tr("OCR")); connect(mOcrAction, &QAction::triggered, this, &MainWindow::showOcrWindow); auto menu = menuBar()->addMenu(tr("&File")); menu->addAction(mToolBar->newCaptureAction()); menu->addSeparator(); menu->addMenu(mActionsMenu); menu->addSeparator(); menu->addAction(mOpenImageAction); menu->addMenu(mRecentImagesMenu); menu->addAction(mToolBar->saveAction()); menu->addAction(mSaveAsAction); menu->addAction(mSaveAllAction); menu->addAction(mUploadAction); menu->addSeparator(); menu->addAction(mPrintAction); menu->addAction(mPrintPreviewAction); menu->addSeparator(); menu->addAction(mCloseWindowAction); menu->addAction(mQuitAction); menu = menuBar()->addMenu(tr("&Edit")); menu->addAction(mToolBar->undoAction()); menu->addAction(mToolBar->redoAction()); menu->addSeparator(); menu->addAction(mToolBar->copyToClipboardAction()); menu->addAction(mCopyAsDataUriAction); menu->addAction(mCopyPathAction); menu->addAction(mRenameAction); menu->addAction(mPasteAction); menu->addAction(mPasteEmbeddedAction); menu->addSeparator(); menu->addAction(mToolBar->cropAction()); menu->addAction(mScaleAction); menu->addAction(mRotateAction); menu->addAction(mCutAction); menu->addAction(mAddWatermarkAction); menu->addSeparator(); menu->addAction(mRemoveImageAction); menu = menuBar()->addMenu(tr("&View")); menu->addAction(mOpenDirectoryAction); menu->addAction(mToggleDocksAction); menu->addAction(mModifyCanvasAction); menu = menuBar()->addMenu(tr("&Options")); menu->addAction(mPinAction); menu->addAction(mOcrAction); menu->addAction(mSettingsAction); menu = menuBar()->addMenu(tr("&Help")); menu->addAction(mAboutAction); addToolBar(mToolBar); if(mConfig->useTrayIcon()) { connect(mTrayIcon, &TrayIcon::showEditorTriggered, [this](){ mVisibilityHandler->enforceVisible(); }); mTrayIcon->setCaptureActions(mToolBar->captureActions()); mTrayIcon->setOpenAction(mOpenImageAction); mTrayIcon->setSaveAction(mToolBar->saveAction()); mTrayIcon->setPasteAction(mPasteAction); mTrayIcon->setCopyAction(mToolBar->copyToClipboardAction()); mTrayIcon->setUploadAction(mUploadAction); mTrayIcon->setQuitAction(mQuitAction); mTrayIcon->setActionsMenu(mActionsMenu); mTrayIcon->setEnabled(true); } setCentralWidget(mImageAnnotator->widget()); } void MainWindow::copyCaptureToClipboard() { mCaptureHandler->copy(); } void MainWindow::upload() { auto image = mCaptureHandler->image(); UploadOperation operation(image, mUploadHandler, mConfig, mDependencyInjector->get()); operation.execute(); } void MainWindow::copyAsDataUri() { auto image = mCaptureHandler->image(); CopyAsDataUriOperation operation(image, mClipboard, mNotificationService, mConfig); operation.execute(); } void MainWindow::printClicked() { auto savePath = mSavePathProvider->savePathWithFormat(QLatin1String("pdf")); auto image = mCaptureHandler->image(); mCapturePrinter->print(image, savePath); } void MainWindow::printPreviewClicked() { auto savePath = mSavePathProvider->savePathWithFormat(QLatin1String("pdf")); auto image = mCaptureHandler->image(); mCapturePrinter->printPreview(image, savePath); } void MainWindow::showOpenImageDialog() { auto title = tr("Open Images"); auto directory = mSavePathProvider->saveDirectory(); auto filter = tr("Image Files") + FileDialogFilterHelper::ImageFilesImport(); auto pathList = mFileDialogService->getOpenFileNames(this, title, directory, filter); for (const auto &path : pathList) { loadImageFromFile(path); } } void MainWindow::setupImageAnnotator() { mImageAnnotator->setSaveToolSelection(mConfig->rememberToolSelection()); mImageAnnotator->setSmoothFactor(mConfig->smoothFactor()); mImageAnnotator->setSmoothPathEnabled(mConfig->smoothPathEnabled()); mImageAnnotator->setSwitchToSelectToolAfterDrawingItem(mConfig->switchToSelectToolAfterDrawingItem()); mImageAnnotator->setSelectItemAfterDrawing(mConfig->selectItemAfterDrawing()); mImageAnnotator->setNumberToolSeedChangeUpdatesAllItems(mConfig->numberToolSeedChangeUpdatesAllItems()); mImageAnnotator->setStickers(mConfig->stickerPaths(), mConfig->useDefaultSticker()); mImageAnnotator->setCanvasColor(mConfig->canvasColor()); mImageAnnotator->setControlsWidgetVisible(mConfig->isControlsWidgetVisible()); } void MainWindow::captureDelayChanged(int delay) { mConfig->setCaptureDelay(delay * 1000); } void MainWindow::addWatermark() { AddWatermarkOperation operation(mImageAnnotator, mConfig); operation.execute(); } void MainWindow::showDialog(const std::function& showDialogMethod) { mGlobalHotKeyHandler->setEnabled(false); showDialogMethod(); mGlobalHotKeyHandler->setEnabled(true); } void MainWindow::showSettingsDialog() { showDialog([&](){ SettingsDialog settingsDialog( mImageGrabber->supportedCaptureModes(), mConfig, mDependencyInjector->get(), mDependencyInjector->get(), mDependencyInjector->get(), mDependencyInjector->get(), mDependencyInjector->get(), this); settingsDialog.exec(); }); } void MainWindow::showAboutDialog() { showDialog([&](){ AboutDialog aboutDialog(this); aboutDialog.exec(); }); } void MainWindow::showScaleDialog() { showDialog([&](){ mImageAnnotator->showScaler(); }); } void MainWindow::showRotateDialog() { showDialog([&](){ mImageAnnotator->showRotator(); }); } void MainWindow::pasteFromClipboard() { auto pixmap = mClipboard->pixmap(); if (mClipboard->url().isNull()) { loadImageFromPixmap(pixmap); } else if (!pixmap.isNull()) { CaptureFromFileDto captureDto(pixmap, mClipboard->url()); processImage(captureDto); } } void MainWindow::pasteEmbeddedFromClipboard() { auto pixmap = mClipboard->pixmap(); mCaptureHandler->insertImageItem({}, pixmap); } void MainWindow::saveClicked() { mCaptureHandler->save(); } void MainWindow::saveAsClicked() { mCaptureHandler->saveAs(); } void MainWindow::saveAllClicked() { mCaptureHandler->saveAll(); } void MainWindow::loadImageFromFile(const QString &path) { LoadImageFromFileOperation operation( path, this, mNotificationService, mDependencyInjector->get(), mDependencyInjector->get(), mConfig); operation.execute(); } void MainWindow::loadImageFromPixmap(const QPixmap &pixmap) { if (!pixmap.isNull()) { CaptureDto captureDto(pixmap); processImage(captureDto); } else { qWarning("Provided pixmap is not valid."); } } void MainWindow::sessionFinished() { mSessionManagerRequestedQuit = true; } void MainWindow::captureCanceled() { mVisibilityHandler->restoreState(); } void MainWindow::uploadFinished(const UploadResult &result) { HandleUploadResultOperation handleUploadResponseOperation(result, mNotificationService, mClipboard, mDependencyInjector->get(), mConfig); handleUploadResponseOperation.execute(); } void MainWindow::captureEmpty() { setEnablements(false); mWindowResizer->resetAndResize(); if (isWindowMaximized()) { mResizeOnNormalize = true; } } void MainWindow::showPinWindow() { mPinWindowHandler->add(QPixmap::fromImage(mCaptureHandler->image())); } void MainWindow::actionTriggered(const Action &action) { if(action.isCaptureEnabled() && !mCaptureHandler->canTakeNew()){ return; } mActionProcessor->process(action); } void MainWindow::showAfterAction(bool minimized) { if (minimized && mTrayIcon->isVisible()) { mVisibilityHandler->hide(); } else if (minimized) { mVisibilityHandler->minimize(); mVisibilityHandler->restoreState(); } else { mVisibilityHandler->restoreState(); } mWindowResizer->resize(); } void MainWindow::showOcrWindow() { mOcrWindowHandler->add(QPixmap::fromImage(mCaptureHandler->image())); } ksnip-master/src/gui/MainWindow.h000066400000000000000000000152431457262621600173130ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_MAINWINDOW_H #define KSNIP_MAINWINDOW_H #include #include #include "src/gui/actions/ActionProcessor.h" #include "src/gui/actions/ActionsMenu.h" #include "src/gui/TrayIcon.h" #include "src/gui/IImageProcessor.h" #include "src/gui/imageAnnotator/KImageAnnotatorAdapter.h" #include "src/gui/aboutDialog/AboutDialog.h" #include "src/gui/settingsDialog/SettingsDialog.h" #include "src/gui/notificationService/NotificationServiceFactory.h" #include "src/gui/operations/AddWatermarkOperation.h" #include "src/gui/operations/CopyAsDataUriOperation.h" #include "src/gui/operations/UploadOperation.h" #include "src/gui/operations/HandleUploadResultOperation.h" #include "src/gui/operations/LoadImageFromFileOperation.h" #include "src/gui/globalHotKeys/GlobalHotKeyHandler.h" #include "src/gui/captureHandler/CaptureHandlerFactory.h" #include "src/gui/captureHandler/ICaptureChangeListener.h" #include "src/gui/widgetVisibilityHandler/WidgetVisibilityHandlerFactory.h" #include "src/gui/modelessWindows/pinWindow/IPinWindowHandler.h" #include "src/gui/modelessWindows/ocrWindow/IOcrWindowHandler.h" #include "src/gui/RecentImagesMenu.h" #include "src/gui/dragAndDrop/DragAndDropProcessor.h" #include "src/gui/dragAndDrop/IDragContentProvider.h" #include "src/gui/windowResizer/IResizableWindow.h" #include "src/gui/windowResizer/WindowResizer.h" #include "src/widgets/MainToolBar.h" #include "src/backend/uploader/UploadHandler.h" #include "src/backend/CapturePrinter.h" #include "src/backend/imageGrabber/IImageGrabber.h" #include "src/common/provider/ApplicationTitleProvider.h" #include "src/common/dtos/CaptureFromFileDto.h" #include "src/common/adapter/fileDialog/IFileDialogService.h" #include "src/common/helper/FileDialogFilterHelper.h" #include "src/common/handler/IDelayHandler.h" #include "src/dependencyInjector/DependencyInjector.h" #include "src/plugins/IPluginManager.h" class MainWindow : public QMainWindow, public ICaptureChangeListener, public IImageProcessor, public IResizableWindow, public IDragContentProvider { Q_OBJECT public: explicit MainWindow(DependencyInjector *dependencyInjector); ~MainWindow() override; void showEmpty(); void showHidden(); void showDefault(); void captureScreenshot(CaptureModes captureMode, bool captureCursor, int delay); void resizeToContent() override; bool isWindowMaximized() override; void processImage(const CaptureDto &capture) override; DragContent dragContent() const override; public slots: void processCapture(const CaptureDto &capture); void quit(); signals: void imageLoaded() const; protected: void moveEvent(QMoveEvent *event) override; void closeEvent(QCloseEvent *event) override; void changeEvent(QEvent *event) override; QMenu *createPopupMenu() override; QSize sizeHint() const override; private: DependencyInjector *mDependencyInjector; QSharedPointer mConfig; QSharedPointer mImageGrabber; QSharedPointer mPluginManager; TrayIcon *mTrayIcon; QSharedPointer mNotificationService; bool mSessionManagerRequestedQuit; bool mResizeOnNormalize; QAction *mSaveAsAction; QAction *mSaveAllAction; QAction *mUploadAction; QAction *mCopyAsDataUriAction; QAction *mPrintAction; QAction *mPrintPreviewAction; QAction *mQuitAction; QAction *mCopyPathAction; QAction *mRenameAction; QAction *mOpenDirectoryAction; QAction *mToggleDocksAction; QAction *mSettingsAction; QAction *mAboutAction; QAction *mOpenImageAction; QAction *mScaleAction; QAction *mRotateAction; QAction *mAddWatermarkAction; QAction *mPasteAction; QAction *mPasteEmbeddedAction; QAction *mPinAction; QAction *mRemoveImageAction; QAction *mModifyCanvasAction; QAction *mCloseWindowAction; QAction *mOcrAction; QAction *mCutAction; MainToolBar *mToolBar; QLayout *mMainLayout; ActionsMenu *mActionsMenu; RecentImagesMenu *mRecentImagesMenu; QSharedPointer mClipboard; CapturePrinter *mCapturePrinter; IImageAnnotator *mImageAnnotator; QSharedPointer mSavePathProvider; GlobalHotKeyHandler *mGlobalHotKeyHandler; DragAndDropProcessor *mDragAndDropProcessor; QSharedPointer mUploadHandler; ICaptureHandler *mCaptureHandler; QSharedPointer mPinWindowHandler; WidgetVisibilityHandler *mVisibilityHandler; QSharedPointer mFileDialogService; WindowResizer *mWindowResizer; ActionProcessor *mActionProcessor; QSharedPointer mOcrWindowHandler; QSharedPointer mDelayHandler; void setEnablements(bool enabled); void loadSettings(); void triggerCapture(CaptureModes captureMode); void capture(CaptureModes captureMode, bool captureCursor, int delay); void initGui(); void showDialog(const std::function& showDialogMethod); private slots: void captureChanged() override; void captureEmpty() override; void copyCaptureToClipboard(); void upload(); void uploadFinished(const UploadResult &result); void copyAsDataUri(); void printClicked(); void printPreviewClicked(); void showOpenImageDialog(); void pasteFromClipboard(); void pasteEmbeddedFromClipboard(); void setupImageAnnotator(); void captureDelayChanged(int delay); void addWatermark(); void showSettingsDialog(); void showAboutDialog(); void showScaleDialog(); void showRotateDialog(); void setPosition(); void handleGuiStartup(); void saveClicked(); void saveAsClicked(); void saveAllClicked(); void updateApplicationTitle(); void capturePostProcessing(); void loadImageFromFile(const QString &path); void loadImageFromPixmap(const QPixmap &pixmap); void sessionFinished(); void captureCanceled(); void showPinWindow(); void hideMainWindowIfRequired(); void toggleDocks(); void actionTriggered(const Action &action); void showAfterAction(bool minimized); void showOcrWindow(); }; #endif // KSNIP_MAINWINDOW_H ksnip-master/src/gui/RecentImagesMenu.cpp000066400000000000000000000032221457262621600207570ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "RecentImagesMenu.h" RecentImagesMenu::RecentImagesMenu(const QSharedPointer &recentImageService, QWidget *parent) : QMenu(parent), mRecentImageService(recentImageService) { connect(this, &QMenu::aboutToShow, this, &RecentImagesMenu::populateMenu); } void RecentImagesMenu::populateMenu() { clear(); const auto recentImages = mRecentImageService->getRecentImagesPath(); auto imageIndex = 0; for(const auto& path : recentImages) { auto action = createAction(path, imageIndex++); addAction(action); } setEnabled(!recentImages.isEmpty()); } QAction *RecentImagesMenu::createAction(const QString &path, int index) { auto action = new QAction(this); action->setText(path); action->setShortcut(Qt::CTRL + Qt::Key_0 + index); connect(action, &QAction::triggered, this, [this, path](){ emit openRecentSelected(path); }); return action; } ksnip-master/src/gui/RecentImagesMenu.h000066400000000000000000000025701457262621600204310ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RECENTIMAGESMENU_H #define KSNIP_RECENTIMAGESMENU_H #include #include "src/backend/recentImages/IRecentImageService.h" class RecentImagesMenu : public QMenu { Q_OBJECT public: explicit RecentImagesMenu(const QSharedPointer &recentImageService, QWidget *parent); ~RecentImagesMenu() override = default; signals: void openRecentSelected(const QString &path); private: void populateMenu(); QSharedPointer mRecentImageService; QAction *createAction(const QString &path, int index); }; #endif //KSNIP_RECENTIMAGESMENU_H ksnip-master/src/gui/TrayIcon.cpp000066400000000000000000000104521457262621600173170ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TrayIcon.h" TrayIcon::TrayIcon(const QSharedPointer &config, const QSharedPointer &iconLoader, QObject *parent) : QSystemTrayIcon(parent), mConfig(config), mOpenAction(nullptr), mSaveAction(nullptr), mPasteAction(nullptr), mCopyAction(nullptr), mUploadAction(nullptr), mShowEditorAction(nullptr), mQuitAction(nullptr), mActionsMenu(nullptr) { auto icon = iconLoader->loadForTheme(QLatin1String("ksnip")); setIcon(icon); mShowEditorAction = new QAction(tr("Show Editor"), this); mShowEditorAction->setIcon(icon); connect(mShowEditorAction, &QAction::triggered, this, &TrayIcon::showEditorTriggered); connect(this, &QSystemTrayIcon::activated, this, &TrayIcon::activatedDefaultAction); connect(this, &QSystemTrayIcon::messageClicked, this, &TrayIcon::openContentUrl); } void TrayIcon::setupMenu() { mMenu.addAction(mShowEditorAction); mMenu.addSeparator(); for(auto captureAction : mCaptureActions) { mMenu.addAction(captureAction); } mMenu.addSeparator(); mMenu.addMenu(mActionsMenu); mMenu.addSeparator(); mMenu.addAction(mOpenAction); mMenu.addAction(mSaveAction); mMenu.addAction(mPasteAction); mMenu.addAction(mCopyAction); mMenu.addAction(mUploadAction); mMenu.addSeparator(); mMenu.addAction(mQuitAction); setContextMenu(&mMenu); } TrayIcon::~TrayIcon() { delete mShowEditorAction; } void TrayIcon::setCaptureActions(const QList &captureActions) { mCaptureActions = captureActions; } void TrayIcon::setOpenAction(QAction *action) { mOpenAction = action; } void TrayIcon::setSaveAction(QAction *action) { mSaveAction = action; } void TrayIcon::setPasteAction(QAction *action) { mPasteAction = action; } void TrayIcon::setCopyAction(QAction *action) { mCopyAction = action; } void TrayIcon::setUploadAction(QAction *action) { mUploadAction = action; } void TrayIcon::setQuitAction(QAction *action) { mQuitAction = action; } void TrayIcon::setActionsMenu(QMenu *actionsMenu) { mActionsMenu = actionsMenu; } void TrayIcon::setEnabled(bool enabled) { if(enabled) { setupMenu(); show(); } else { hide(); } } void TrayIcon::showInfo(const QString &title, const QString &message, const QString &contentUrl) { showMessage(title, message, contentUrl, QSystemTrayIcon::Information); } void TrayIcon::showWarning(const QString &title, const QString &message, const QString &contentUrl) { showMessage(title, message, contentUrl, QSystemTrayIcon::Warning); } void TrayIcon::showCritical(const QString &title, const QString &message, const QString &contentUrl) { showMessage(title, message, contentUrl, QSystemTrayIcon::Critical); } void TrayIcon::showMessage(const QString &title, const QString &message, const QString &contentUrl, QSystemTrayIcon::MessageIcon messageIcon) { mToastContentUrl = PathHelper::extractParentDirectory(contentUrl); QSystemTrayIcon::showMessage(title, message, messageIcon); } void TrayIcon::activatedDefaultAction(ActivationReason reason) const { if(reason != ActivationReason::Context) { if (mConfig->defaultTrayIconActionMode() == TrayIconDefaultActionMode::ShowEditor) { mShowEditorAction->trigger(); } else { triggerDefaultCaptureMode(); } } } void TrayIcon::triggerDefaultCaptureMode() const { auto captureMode = mConfig->defaultTrayIconCaptureMode(); for(auto action : mCaptureActions) { if (action->data().value() == captureMode) { action->trigger(); return; } } } void TrayIcon::openContentUrl() { if(!mToastContentUrl.isEmpty() && !mToastContentUrl.isNull()) { QDesktopServices::openUrl(mToastContentUrl); } } ksnip-master/src/gui/TrayIcon.h000066400000000000000000000052401457262621600167630ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_TRAYICON_H #define KSNIP_TRAYICON_H #include #include #include #include #include "INotificationService.h" #include "src/backend/config/IConfig.h" #include "src/common/enum/CaptureModes.h" #include "src/common/loader/IIconLoader.h" #include "src/common/helper/PathHelper.h" class TrayIcon : public QSystemTrayIcon, public INotificationService { Q_OBJECT public: explicit TrayIcon(const QSharedPointer &config, const QSharedPointer &iconLoader, QObject *parent); ~TrayIcon() override; void setCaptureActions(const QList &captureActions); void setOpenAction(QAction *action); void setSaveAction(QAction *action); void setPasteAction(QAction *action); void setCopyAction(QAction *action); void setUploadAction(QAction *action); void setQuitAction(QAction *action); void setActionsMenu(QMenu *actionsMenu); void setEnabled(bool enabled); void showInfo(const QString &title, const QString &message, const QString &contentUrl) override; void showWarning(const QString &title, const QString &message, const QString &contentUrl) override; void showCritical(const QString &title, const QString &message, const QString &contentUrl) override; signals: void showEditorTriggered() const; private: QSharedPointer mConfig; QMenu mMenu; QList mCaptureActions; QAction *mOpenAction; QAction *mSaveAction; QAction *mPasteAction; QAction *mCopyAction; QAction *mUploadAction; QAction *mShowEditorAction; QAction *mQuitAction; QMenu *mActionsMenu; QString mToastContentUrl; void setupMenu(); void triggerDefaultCaptureMode() const; private slots: void activatedDefaultAction(ActivationReason reason) const; void openContentUrl(); void showMessage(const QString &title, const QString &message, const QString &contentUrl, QSystemTrayIcon::MessageIcon messageIcon); }; #endif //KSNIP_TRAYICON_H ksnip-master/src/gui/aboutDialog/000077500000000000000000000000001457262621600173135ustar00rootroot00000000000000ksnip-master/src/gui/aboutDialog/AboutDialog.cpp000066400000000000000000000052261457262621600222160ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "AboutDialog.h" AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), mMainLayout(new QVBoxLayout), mHeaderLayout(new QHBoxLayout), mTabWidget(new QTabWidget), mAboutTab(new AboutTab), mVersionTab(new VersionTab), mAuthorTab(new AuthorTab), mDonateTab(new DonateTab), mContactTab(new ContactTab), mCloseButton(new QPushButton) { setWindowTitle(tr("About ") + QApplication::applicationName()); createHeader(); mTabWidget->addTab(mAboutTab, tr("About")); mTabWidget->addTab(mVersionTab, tr("Version")); mTabWidget->addTab(mAuthorTab, tr("Author")); mTabWidget->addTab(mDonateTab, tr("Donate")); mTabWidget->addTab(mContactTab, tr("Contact")); mTabWidget->setMinimumSize(mTabWidget->sizeHint()); mCloseButton->setText(tr("Close")); connect(mCloseButton, &QPushButton::clicked, this, &AboutDialog::close); mMainLayout->addLayout(mHeaderLayout); mMainLayout->addWidget(mTabWidget); mMainLayout->addWidget(mCloseButton, 1, Qt::AlignRight); setLayout(mMainLayout); setFixedSize(sizeHint() + QSize(10, 0)); } AboutDialog::~AboutDialog() { delete mMainLayout; delete mCloseButton; delete mAboutTab; delete mVersionTab; delete mAuthorTab; delete mDonateTab; } void AboutDialog::createHeader() { auto pixmap = QPixmap(QLatin1String(":/icons/ksnip")); auto scaledPixmap = pixmap.scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation); auto label = new QLabel(); mHeaderLayout = new QHBoxLayout(); label->setPixmap(scaledPixmap); label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); mHeaderLayout->addWidget(label); label = new QLabel(QLatin1String("

") + QApplication::applicationName() + QLatin1String("

")); label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); mHeaderLayout->addWidget(label); mHeaderLayout->setAlignment(Qt::AlignLeft); } ksnip-master/src/gui/aboutDialog/AboutDialog.h000066400000000000000000000030041457262621600216530ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_ABOUTDIALOG_H #define KSNIP_ABOUTDIALOG_H #include #include #include #include "AboutTab.h" #include "VersionTab.h" #include "AuthorTab.h" #include "DonateTab.h" #include "ContactTab.h" class QLabel; class MainWindow; class AboutDialog : public QDialog { Q_OBJECT public: explicit AboutDialog(QWidget *parent = nullptr); ~AboutDialog() override; private: QVBoxLayout *mMainLayout; QHBoxLayout *mHeaderLayout; QTabWidget *mTabWidget; QPushButton *mCloseButton; AboutTab *mAboutTab; VersionTab *mVersionTab; AuthorTab *mAuthorTab; DonateTab *mDonateTab; ContactTab *mContactTab; void createHeader(); }; #endif // KSNIP_ABOUTDIALOG_H ksnip-master/src/gui/aboutDialog/AboutTab.cpp000066400000000000000000000030361457262621600215220ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AboutTab.h" AboutTab::AboutTab() : mLayout(new QVBoxLayout(this)), mContent(new QLabel(this)) { mContent->setText(QLatin1String("") + QApplication::applicationName() + QLatin1String(" - ") + tr("Screenshot and Annotation Tool") + QLatin1String("

") + QLatin1String("(C) 2021 Damir Porobic") + QLatin1String("

") + tr("License: ") + QLatin1String("GNU General Public License Version 2")); mContent->setTextFormat(Qt::RichText); mContent->setTextInteractionFlags(Qt::TextBrowserInteraction); mContent->setOpenExternalLinks(true); mLayout->addWidget(mContent); setLayout(mLayout); } AboutTab::~AboutTab() { delete mLayout; delete mContent; } ksnip-master/src/gui/aboutDialog/AboutTab.h000066400000000000000000000021131457262621600211620ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ABOUTTAB_H #define KSNIP_ABOUTTAB_H #include #include #include #include class AboutTab : public QWidget { Q_OBJECT public: AboutTab(); ~AboutTab() override; private: QLabel *mContent; QVBoxLayout *mLayout; }; #endif //KSNIP_ABOUTTAB_H ksnip-master/src/gui/aboutDialog/AuthorTab.cpp000066400000000000000000000054621457262621600217170ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AuthorTab.h" AuthorTab::AuthorTab() { mLayout = new QVBoxLayout(); mContent = new QLabel(); mContent->setText( QLatin1String("") + tr("The Authors:") + QLatin1String("
") + QLatin1String("Damir Porobic ") + createEmailEntry(QLatin1String("damir.porobic@gmx.com")) + QLatin1String("
") + QLatin1String("Stefan Comanescu") + createEmailEntry(QLatin1String("fnkabit@gmail.com")) + QLatin1String("

") + QLatin1String("") + tr("Contributors:") + QLatin1String("
") + createContributorEntry(QLatin1String("Galileo Sartor"), tr("Snap & Flatpak Support")) + createContributorEntry(QLatin1String("Luis Vásquez"), tr("Spanish Translation"), QLatin1String("lvaskz@protonmail.com")) + createContributorEntry(QLatin1String("Heimen Stoffels"), tr("Dutch Translation"), QLatin1String("vistausss@outlook.com")) + createContributorEntry(QLatin1String("Yury Martynov"), tr("Russian Translation"), QLatin1String("email@linxon.ru")) + createContributorEntry(QLatin1String("Allan Nordhøy"), tr("Norwegian Bokmål Translation"), QLatin1String("epost@anotheragency.no")) + createContributorEntry(QLatin1String("4goodapp"), tr("French Translation")) + createContributorEntry(QLatin1String("epsiloneridani"), tr("Polish Translation")) ); mContent->setTextFormat(Qt::RichText); mContent->setTextInteractionFlags(Qt::TextBrowserInteraction); mContent->setOpenExternalLinks(true); mLayout->addWidget(mContent); setLayout(mLayout); } AuthorTab::~AuthorTab() { delete mLayout; delete mContent; } QString AuthorTab::createContributorEntry(const QString &name, const QString &role, const QString &email) const { auto baseEntry = name + QLatin1String(" - ") + role; if(!email.isEmpty()) { baseEntry += QLatin1String(" ") + createEmailEntry(email); } return baseEntry + QLatin1String("
"); } QString AuthorTab::createEmailEntry(const QString &email) { return QLatin1String("(Email))"); } ksnip-master/src/gui/aboutDialog/AuthorTab.h000066400000000000000000000023461457262621600213620ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_AUTHORTAB_H #define KSNIP_AUTHORTAB_H #include #include #include class AuthorTab : public QWidget { Q_OBJECT public: AuthorTab(); ~AuthorTab() override; private: QLabel *mContent; QVBoxLayout *mLayout; QString createContributorEntry(const QString &name, const QString &role, const QString &email = QString()) const; static QString createEmailEntry(const QString &email) ; }; #endif //KSNIP_AUTHORTAB_H ksnip-master/src/gui/aboutDialog/ContactTab.cpp000066400000000000000000000034531457262621600220460ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ContactTab.h" ContactTab::ContactTab() : mLayout(new QVBoxLayout()), mContent(new QLabel()) { mContent->setText( QLatin1String("") + tr("Community") + QLatin1String("") + QLatin1String("
") + tr("If you have general questions, ideas or just want to talk about ksnip,
" "please join our %1 or our %2 server.") .arg(QLatin1String("Discord")) .arg(QLatin1String("IRC")) + QLatin1String("

") + QLatin1String("") + tr("Bug Reports") + QLatin1String("") + QLatin1String("
") + tr("Please use %1 to report bugs.") .arg(QLatin1String("GitHub"))); mContent->setTextFormat(Qt::RichText); mContent->setTextInteractionFlags(Qt::TextBrowserInteraction); mContent->setOpenExternalLinks(true); mLayout->addWidget(mContent); setLayout(mLayout); } ContactTab::~ContactTab() { delete mLayout; delete mContent; } ksnip-master/src/gui/aboutDialog/ContactTab.h000066400000000000000000000020771457262621600215140ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CONTACTTAB_H #define KSNIP_CONTACTTAB_H #include #include #include class ContactTab : public QWidget { Q_OBJECT public: ContactTab(); ~ContactTab() override; private: QLabel *mContent; QVBoxLayout *mLayout; }; #endif //KSNIP_CONTACTTAB_H ksnip-master/src/gui/aboutDialog/DonateTab.cpp000066400000000000000000000043241457262621600216630ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DonateTab.h" DonateTab::DonateTab() { mLayout = new QVBoxLayout(); mContent = new QLabel(); mContent->setText(QLatin1String("") + tr("Donation") + QLatin1String("") + QLatin1String("
") + tr("ksnip is a non-profitable copyleft libre software project, and
" "still has some costs that need to be covered,
" "like domain costs or hardware costs for cross-platform support.") + QLatin1String("
") + tr("If you want to help or just want to appreciate the work being done
" "by treating developers to a beer or coffee, you can do that %1here%2.").arg(QLatin1String("")).arg(QLatin1String("")) + QLatin1String("

") + tr("Donations are always welcome") + QLatin1String(" :)") + QLatin1String("

") + QLatin1String("") + tr("Become a GitHub Sponsor?") + QLatin1String("") + QLatin1String("
") + tr("Also possible, %1here%2.").arg(QLatin1String(" ")).arg(QLatin1String(""))); mContent->setTextFormat(Qt::RichText); mContent->setTextInteractionFlags(Qt::TextBrowserInteraction); mContent->setOpenExternalLinks(true); mLayout->addWidget(mContent); setLayout(mLayout); } DonateTab::~DonateTab() { delete mContent; delete mLayout; } ksnip-master/src/gui/aboutDialog/DonateTab.h000066400000000000000000000021521457262621600213250ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DONATETAB_H #define KSNIP_DONATETAB_H #include #include #include #include #include "BuildConfig.h" class DonateTab : public QWidget { Q_OBJECT public: DonateTab(); ~DonateTab() override; private: QLabel *mContent; QVBoxLayout *mLayout; }; #endif //KSNIP_DONATETAB_H ksnip-master/src/gui/aboutDialog/VersionTab.cpp000066400000000000000000000030611457262621600220730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "VersionTab.h" VersionTab::VersionTab() { mLayout = new QVBoxLayout(); mContent = new QLabel(); mContent->setText(QLatin1String("") + tr("Version") + QLatin1String(": ") + QApplication::applicationVersion() + QLatin1String("") + QLatin1String("
") + tr("Build") + QLatin1String(": ") + QLatin1String(KSNIP_BUILD_NUMBER) + QLatin1String("") + QLatin1String("

") + tr("Using:") + QLatin1String("
    " "
  • Qt5
  • " "
  • X11
  • " "
  • KDE Wayland
  • " "
  • Gnome Wayland
  • " "
")); mContent->setTextInteractionFlags(Qt::TextSelectableByMouse); mLayout->addWidget(mContent); setLayout(mLayout); } VersionTab::~VersionTab() { delete mContent; delete mLayout; } ksnip-master/src/gui/aboutDialog/VersionTab.h000066400000000000000000000021611457262621600215400ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_VERSIONTAB_H #define KSNIP_VERSIONTAB_H #include #include #include #include #include "BuildConfig.h" class VersionTab : public QWidget { Q_OBJECT public: VersionTab(); ~VersionTab() override; private: QLabel *mContent; QVBoxLayout *mLayout; }; #endif //KSNIP_VERSIONTAB_H ksnip-master/src/gui/actions/000077500000000000000000000000001457262621600165215ustar00rootroot00000000000000ksnip-master/src/gui/actions/Action.cpp000066400000000000000000000075431457262621600204530ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "Action.h" Action::Action() : mIsCaptureEnabled(false), mCaptureDelay(0), mCaptureMode(CaptureModes::RectArea), mIsPinImageEnabled(false), mIsUploadEnabled(false), mIsSaveEnabled(false), mIsCopyToClipboardEnabled(false), mIsOpenDirectoryEnabled(false), mIncludeCursor(false), mIsHideMainWindowEnabled(false), mIsGlobalShortcut(false) { } QString Action::name() const { return mName; } void Action::setName(const QString &name) { mName = name; } QKeySequence Action::shortcut() const { return mShortcut; } void Action::setShortcut(const QKeySequence &keySequence) { mShortcut = keySequence; } bool Action::isCaptureEnabled() const { return mIsCaptureEnabled; } void Action::setIsCaptureEnabled(bool enabled) { mIsCaptureEnabled = enabled; } int Action::captureDelay() const { return mCaptureDelay; } void Action::setCaptureDelay(int delayInMs) { mCaptureDelay = delayInMs; } bool Action::includeCursor() const { return mIncludeCursor; } void Action::setIncludeCursor(bool enabled) { mIncludeCursor = enabled; } CaptureModes Action::captureMode() const { return mCaptureMode; } void Action::setCaptureMode(CaptureModes mode) { mCaptureMode = mode; } bool Action::isPinImageEnabled() const { return mIsPinImageEnabled; } void Action::setIsPinImageEnabled(bool enabled) { mIsPinImageEnabled = enabled; } bool Action::isUploadEnabled() const { return mIsUploadEnabled; } void Action::setIsUploadEnabled(bool enabled) { mIsUploadEnabled = enabled; } bool Action::isSaveEnabled() const { return mIsSaveEnabled; } void Action::setIsSaveEnabled(bool enabled) { mIsSaveEnabled = enabled; } bool Action::isCopyToClipboardEnabled() const { return mIsCopyToClipboardEnabled; } void Action::setIsCopyToClipboardEnabled(bool enabled) { mIsCopyToClipboardEnabled = enabled; } bool Action::isOpenDirectoryEnabled() const { return mIsOpenDirectoryEnabled; } void Action::setIsOpenDirectoryEnabled(bool enabled) { mIsOpenDirectoryEnabled = enabled; } bool Action::isHideMainWindowEnabled() const { return mIsHideMainWindowEnabled; } void Action::setIsHideMainWindowEnabled(bool enabled) { mIsHideMainWindowEnabled = enabled; } bool Action::isGlobalShortcut() const { return mIsGlobalShortcut; } void Action::setIsGlobalShortcut(bool isGlobal) { mIsGlobalShortcut = isGlobal; } bool operator==(const Action &left, const Action &right) { return left.name() == right.name() && left.shortcut() == right.shortcut() && left.isGlobalShortcut() == right.isGlobalShortcut() && left.isCaptureEnabled() == right.isCaptureEnabled() && left.includeCursor() == right.includeCursor() && left.captureDelay() == right.captureDelay() && left.captureMode() == right.captureMode() && left.isSaveEnabled() == right.isSaveEnabled() && left.isCopyToClipboardEnabled() == right.isCopyToClipboardEnabled() && left.isPinImageEnabled() == right.isPinImageEnabled() && left.isOpenDirectoryEnabled() == right.isOpenDirectoryEnabled() && left.isUploadEnabled() == right.isUploadEnabled() && left.isHideMainWindowEnabled() == right.isHideMainWindowEnabled(); } ksnip-master/src/gui/actions/Action.h000066400000000000000000000046341457262621600201160ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTION_H #define KSNIP_ACTION_H #include #include #include "src/common/enum/CaptureModes.h" class Action { public: Action(); ~Action() = default; QString name() const; void setName(const QString &name); QKeySequence shortcut() const; void setShortcut(const QKeySequence &keySequence); bool isCaptureEnabled() const; void setIsCaptureEnabled(bool enabled); int captureDelay() const; void setCaptureDelay(int delayInMs); bool isPinImageEnabled() const; void setIsPinImageEnabled(bool enabled); CaptureModes captureMode() const; void setCaptureMode(CaptureModes mode); bool includeCursor() const; void setIncludeCursor(bool enabled); bool isUploadEnabled() const; void setIsUploadEnabled(bool enabled); bool isSaveEnabled() const; void setIsSaveEnabled(bool enabled); bool isCopyToClipboardEnabled() const; void setIsCopyToClipboardEnabled(bool enabled); bool isOpenDirectoryEnabled() const; void setIsOpenDirectoryEnabled(bool enabled); bool isHideMainWindowEnabled() const; void setIsHideMainWindowEnabled(bool enabled); bool isGlobalShortcut() const; void setIsGlobalShortcut(bool isGlobal); friend bool operator==(const Action& left, const Action& right); private: QString mName; bool mIsCaptureEnabled; int mCaptureDelay; bool mIncludeCursor; CaptureModes mCaptureMode; bool mIsPinImageEnabled; bool mIsUploadEnabled; bool mIsSaveEnabled; bool mIsCopyToClipboardEnabled; bool mIsOpenDirectoryEnabled; bool mIsHideMainWindowEnabled; QKeySequence mShortcut; bool mIsGlobalShortcut; }; bool operator==(const Action& left, const Action& right); #endif //KSNIP_ACTION_H ksnip-master/src/gui/actions/ActionProcessor.cpp000066400000000000000000000050131457262621600223410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ActionProcessor.h" ActionProcessor::ActionProcessor() : mIsCaptureInProgress(false), mIsPostProcessingEnabled(false), mIsActionInProgress(false) { } void ActionProcessor::process(const Action &action) { mCurrentAction = action; mIsActionInProgress = true; if (mCurrentAction.isCaptureEnabled()) { preCaptureProcessing(); } else { postCaptureProcessing(); } } void ActionProcessor::setPostProcessingEnabled(bool enabled) { mIsPostProcessingEnabled = enabled; } bool ActionProcessor::isActionInProgress() const { return mIsActionInProgress; } void ActionProcessor::captureFinished() { if(mIsCaptureInProgress) { mIsCaptureInProgress = false; postCaptureProcessing(); } } void ActionProcessor::captureCanceled() { mIsCaptureInProgress = false; mIsActionInProgress = false; } void ActionProcessor::preCaptureProcessing() { mIsCaptureInProgress = true; emit triggerCapture(mCurrentAction.captureMode(), mCurrentAction.includeCursor(), mCurrentAction.captureDelay()); } void ActionProcessor::postCaptureProcessing() { if (!mIsPostProcessingEnabled && !mCurrentAction.isCaptureEnabled()) { mIsActionInProgress = false; return; } if (mCurrentAction.isSaveEnabled()) { emit triggerSave(); } if (mCurrentAction.isCopyToClipboardEnabled()) { emit triggerCopyToClipboard(); } if (mCurrentAction.isOpenDirectoryEnabled()) { emit triggerOpenDirectory(); } if (mCurrentAction.isPinImageEnabled()) { emit triggerPinImage(); } if (mCurrentAction.isUploadEnabled()) { emit triggerUpload(); } if (mCurrentAction.isHideMainWindowEnabled()) { emit triggerShow(true); } if (!mCurrentAction.isHideMainWindowEnabled() && mCurrentAction.isCaptureEnabled()) { emit triggerShow(false); } mIsActionInProgress = false; } ksnip-master/src/gui/actions/ActionProcessor.h000066400000000000000000000032561457262621600220150ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTIONPROCESSOR_H #define KSNIP_ACTIONPROCESSOR_H #include #include "Action.h" class ActionProcessor : public QObject { Q_OBJECT public: ActionProcessor(); ~ActionProcessor() override = default; void process(const Action &action); void setPostProcessingEnabled(bool enabled); bool isActionInProgress() const; signals: void triggerCapture(CaptureModes mode, bool includeCursor, int delay) const; void triggerPinImage() const; void triggerCopyToClipboard() const; void triggerSave() const; void triggerUpload() const; void triggerOpenDirectory() const; void triggerShow(bool minimized) const; public slots: void captureFinished(); void captureCanceled(); private: bool mIsCaptureInProgress; bool mIsPostProcessingEnabled; bool mIsActionInProgress; Action mCurrentAction; void preCaptureProcessing(); void postCaptureProcessing(); }; #endif //KSNIP_ACTIONPROCESSOR_H ksnip-master/src/gui/actions/ActionsMenu.cpp000066400000000000000000000024241457262621600214540ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ActionsMenu.h" ActionsMenu::ActionsMenu(const QSharedPointer &config) : mConfig(config) { Q_ASSERT(mConfig != nullptr); connect(mConfig.data(), &IConfig::actionsChanged, this, &ActionsMenu::actionsChanged); actionsChanged(); } void ActionsMenu::actionsChanged() { clear(); auto actions = mConfig->actions(); for (const auto& action : actions) { addAction(action.name(), [this, action]() { emit triggered(action); }, action.shortcut()); } setEnabled(!actions.isEmpty()); } ksnip-master/src/gui/actions/ActionsMenu.h000066400000000000000000000023361457262621600211230ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTIONSMENU_H #define KSNIP_ACTIONSMENU_H #include #include "Action.h" #include "src/backend/config/IConfig.h" class ActionsMenu : public QMenu { Q_OBJECT public: explicit ActionsMenu(const QSharedPointer &config); ~ActionsMenu() override = default; signals: void triggered(const Action &action); private: QSharedPointer mConfig; private slots: void actionsChanged(); }; #endif //KSNIP_ACTIONSMENU_H ksnip-master/src/gui/captureHandler/000077500000000000000000000000001457262621600200225ustar00rootroot00000000000000ksnip-master/src/gui/captureHandler/CaptureHandlerFactory.cpp000066400000000000000000000042341457262621600247620ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CaptureHandlerFactory.h" ICaptureHandler* CaptureHandlerFactory::create( IImageAnnotator *imageAnnotator, QSharedPointer ¬ificationService, DependencyInjector *dependencyInjector, QWidget *parent) { auto config = dependencyInjector->get(); if(config->useTabs()) { return new MultiCaptureHandler( imageAnnotator, notificationService, dependencyInjector->get(), config, dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), parent); } else { return new SingleCaptureHandler( imageAnnotator, notificationService, dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), dependencyInjector->get(), config, parent); } } ksnip-master/src/gui/captureHandler/CaptureHandlerFactory.h000066400000000000000000000024751457262621600244340ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTUREHANDLERFACTORY_H #define KSNIP_CAPTUREHANDLERFACTORY_H #include "src/gui/captureHandler/SingleCaptureHandler.h" #include "src/gui/captureHandler/MultiCaptureHandler.h" class CaptureHandlerFactory { public: explicit CaptureHandlerFactory() = default; ~CaptureHandlerFactory() = default; static ICaptureHandler *create( IImageAnnotator *imageAnnotator, QSharedPointer ¬ificationService, DependencyInjector *dependencyInjector, QWidget *parent); }; #endif //KSNIP_CAPTUREHANDLERFACTORY_H ksnip-master/src/gui/captureHandler/CaptureTabState.h000066400000000000000000000022351457262621600232300ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTURETABSTATE_H #define KSNIP_CAPTURETABSTATE_H struct CaptureTabState { int index; QString path; QString filename; bool isSaved; explicit CaptureTabState(int index, const QString &filename, const QString &path, bool isSave) { this->index = index; this->filename = filename; this->path = path; this->isSaved = isSave; } }; #endif //KSNIP_CAPTURETABSTATE_H ksnip-master/src/gui/captureHandler/CaptureTabStateHandler.cpp000066400000000000000000000076541457262621600250730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CaptureTabStateHandler.h" CaptureTabStateHandler::CaptureTabStateHandler() : mCurrentTabIndex(-1) { } void CaptureTabStateHandler::add(int index, const QString &filename, const QString &path, bool isSaved) { auto newState = QSharedPointer(new CaptureTabState(index, filename, path, isSaved)); mCaptureTabStates.append(newState); refreshTabInfo(index); } bool CaptureTabStateHandler::isSaved(int index) { auto tabState = getTabState(index); return tabState.isNull() || tabState->isSaved; } bool CaptureTabStateHandler::isPathValid(int index) { return PathHelper::isPathValid(path(index)); } QString CaptureTabStateHandler::path(int index) { auto tabState = getTabState(index); return tabState.isNull() ? QString() : tabState->path; } QString CaptureTabStateHandler::filename(int index) { auto tabState = getTabState(index); return tabState.isNull() ? QString() : tabState->filename; } void CaptureTabStateHandler::setSaveState(int index, const SaveResultDto &saveResult) { auto tabState = getTabState(index); if (!tabState.isNull()) { tabState->isSaved = saveResult.isSuccessful; if (saveResult.isSuccessful) { tabState->path = saveResult.path; tabState->filename = PathHelper::extractFilename(saveResult.path); refreshTabInfo(index); } } } void CaptureTabStateHandler::renameFile(int index, const RenameResultDto &renameResult) { auto tabState = getTabState(index); if (!tabState.isNull() && renameResult.isSuccessful) { tabState->path = renameResult.path; tabState->filename = PathHelper::extractFilename(renameResult.path); refreshTabInfo(index); } } void CaptureTabStateHandler::tabMoved(int fromIndex, int toIndex) { for (auto& state : mCaptureTabStates) { if(state->index == fromIndex) { state->index = toIndex; } else if(state->index == toIndex) { state->index = fromIndex; } } } void CaptureTabStateHandler::currentTabChanged(int index) { mCurrentTabIndex = index; } void CaptureTabStateHandler::tabRemoved(int index) { auto iterator = mCaptureTabStates.begin(); while (iterator != mCaptureTabStates.end()) { if (iterator->data()->index == index) { iterator = mCaptureTabStates.erase(iterator); } else { if (iterator->data()->index > index) { iterator->data()->index--; } iterator++; } } } void CaptureTabStateHandler::currentTabContentChanged() { auto currentTabState = getTabState(mCurrentTabIndex); if (!currentTabState.isNull()) { currentTabState->isSaved = false; refreshTabInfo(mCurrentTabIndex); } } void CaptureTabStateHandler::refreshTabInfo(int index) { auto tabState = getTabState(index); if (!tabState.isNull()) { auto title = tabState->isSaved ? tabState->filename : tabState->filename + QLatin1String("*"); emit updateTabInfo(tabState->index, title, tabState->path); } } int CaptureTabStateHandler::count() const { return mCaptureTabStates.count(); } int CaptureTabStateHandler::currentTabIndex() const { return mCurrentTabIndex; } QSharedPointer CaptureTabStateHandler::getTabState(int index) { for (auto &state : mCaptureTabStates) { if (state->index == index) { return state; } } return QSharedPointer(nullptr); } ksnip-master/src/gui/captureHandler/CaptureTabStateHandler.h000066400000000000000000000041741457262621600245320ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTURETABSTATEHANDLER_H #define KSNIP_CAPTURETABSTATEHANDLER_H #include #include #include #include "ICaptureTabStateHandler.h" #include "CaptureTabState.h" #include "src/common/dtos/SaveResultDto.h" #include "src/common/dtos/RenameResultDto.h" #include "src/common/helper/PathHelper.h" class CaptureTabStateHandler : public ICaptureTabStateHandler { Q_OBJECT public: explicit CaptureTabStateHandler(); ~CaptureTabStateHandler() override = default; void add(int index, const QString &filename, const QString &path, bool isSaved) override; bool isSaved(int index) override; bool isPathValid(int index) override; QString path(int index) override; QString filename(int index) override; void setSaveState(int index, const SaveResultDto &saveResult) override; void renameFile(int index, const RenameResultDto &renameResult) override; int count() const override; int currentTabIndex() const override; public slots: void tabMoved(int fromIndex, int toIndex) override; void currentTabChanged(int index) override; void tabRemoved(int index) override; void currentTabContentChanged() override; private: int mCurrentTabIndex; QList> mCaptureTabStates; void refreshTabInfo(int index); QSharedPointer getTabState(int index); }; #endif //KSNIP_CAPTURETABSTATEHANDLER_H ksnip-master/src/gui/captureHandler/ICaptureChangeListener.h000066400000000000000000000020561457262621600245260ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICAPTURECHANGELISTENER_H #define KSNIP_ICAPTURECHANGELISTENER_H class ICaptureChangeListener { public: virtual ~ICaptureChangeListener() = default; virtual void captureChanged() = 0; virtual void captureEmpty() = 0; }; #endif //KSNIP_ICAPTURECHANGELISTENER_H ksnip-master/src/gui/captureHandler/ICaptureHandler.h000066400000000000000000000033521457262621600232100ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICAPTUREHANDLER_H #define KSNIP_ICAPTUREHANDLER_H #include "src/gui/captureHandler/ICaptureChangeListener.h" #include "src/common/dtos/CaptureDto.h" class ICaptureHandler : public QObject { public: explicit ICaptureHandler() = default; ~ICaptureHandler() override = default; virtual bool canClose() = 0; virtual bool canTakeNew() = 0; virtual bool isSaved() const = 0; virtual QString path() const = 0; virtual bool isPathValid() const = 0; virtual void saveAs() = 0; virtual void save() = 0; virtual void saveAll() = 0; virtual void rename() = 0; virtual void copy() = 0; virtual void copyPath() = 0; virtual void openDirectory() = 0; virtual void removeImage() = 0; virtual void load(const CaptureDto &capture) = 0; virtual QImage image() const = 0; virtual void insertImageItem(const QPointF &pos, const QPixmap &pixmap) = 0; virtual void addListener(ICaptureChangeListener *captureChangeListener) = 0; }; #endif //KSNIP_ICAPTUREHANDLER_H ksnip-master/src/gui/captureHandler/ICaptureTabStateHandler.h000066400000000000000000000036031457262621600246370ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICAPTURETABSTATEHANDLER_H #define KSNIP_ICAPTURETABSTATEHANDLER_H #include struct SaveResultDto; struct RenameResultDto; class ICaptureTabStateHandler : public QObject { Q_OBJECT public: explicit ICaptureTabStateHandler() = default; ~ICaptureTabStateHandler() override = default; virtual void add(int index, const QString &filename, const QString &path, bool isSaved) = 0; virtual bool isSaved(int index) = 0; virtual bool isPathValid(int index) = 0; virtual QString path(int index) = 0; virtual QString filename(int index) = 0; virtual void setSaveState(int index, const SaveResultDto &saveResult) = 0; virtual void renameFile(int index, const RenameResultDto &renameResult) = 0; virtual int count() const = 0; virtual int currentTabIndex() const = 0; signals: void updateTabInfo(int index, const QString &title, const QString &toolTip); public slots: virtual void tabMoved(int fromIndex, int toIndex) = 0; virtual void currentTabChanged(int index) = 0; virtual void tabRemoved(int index) = 0; virtual void currentTabContentChanged() = 0; }; #endif //KSNIP_ICAPTURETABSTATEHANDLER_H ksnip-master/src/gui/captureHandler/MultiCaptureHandler.cpp000066400000000000000000000272661457262621600244570ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MultiCaptureHandler.h" MultiCaptureHandler::MultiCaptureHandler( IImageAnnotator *imageAnnotator, const QSharedPointer ¬ificationService, const QSharedPointer &captureTabStateHandler, const QSharedPointer &config, const QSharedPointer &clipboard, const QSharedPointer &desktopService, const QSharedPointer &fileService, const QSharedPointer &messageBoxService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &iconLoader, const QSharedPointer &fileDialogService, QWidget *parent) : mImageAnnotator(imageAnnotator), mNotificationService(notificationService), mParent(parent), mCaptureChangeListener(nullptr), mTabStateHandler(captureTabStateHandler), mConfig(config), mClipboard(clipboard), mDesktopService(desktopService), mMessageBoxService(messageBoxService), mFileService(fileService), mRecentImageService(recentImageService), mImageSaver(imageSaver), mSavePathProvider(savePathProvider), mFileDialogService(fileDialogService), mSaveContextMenuAction(new TabContextMenuAction(this)), mSaveAsContextMenuAction(new TabContextMenuAction(this)), mSaveAllContextMenuAction(new TabContextMenuAction(this)), mRenameContextMenuAction(new TabContextMenuAction(this)), mOpenDirectoryContextMenuAction(new TabContextMenuAction(this)), mCopyPathToClipboardContextMenuAction(new TabContextMenuAction(this)), mCopyToClipboardContextMenuAction(new TabContextMenuAction(this)), mDeleteImageContextMenuAction(new TabContextMenuAction(this)), mContextMenuSeparatorAction(new QAction(this)) { connect(mImageAnnotator, &IImageAnnotator::currentTabChanged, mTabStateHandler.data(), &ICaptureTabStateHandler::currentTabChanged); connect(mImageAnnotator, &IImageAnnotator::tabMoved, mTabStateHandler.data(), &ICaptureTabStateHandler::tabMoved); connect(mImageAnnotator, &IImageAnnotator::imageChanged, mTabStateHandler.data(), &ICaptureTabStateHandler::currentTabContentChanged); connect(mTabStateHandler.data(), &ICaptureTabStateHandler::updateTabInfo, mImageAnnotator, &IImageAnnotator::updateTabInfo); connect(mImageAnnotator, &IImageAnnotator::imageChanged, this, &MultiCaptureHandler::captureChanged); connect(mImageAnnotator, &IImageAnnotator::currentTabChanged, this, &MultiCaptureHandler::captureChanged); connect(mImageAnnotator, &IImageAnnotator::tabCloseRequested, this, &MultiCaptureHandler::tabCloseRequested); connect(mImageAnnotator, &IImageAnnotator::tabContextMenuOpened, this, &MultiCaptureHandler::updateContextMenuActions); connect(mConfig.data(), &IConfig::annotatorConfigChanged, this, &MultiCaptureHandler::annotatorConfigChanged); addTabContextMenuActions(iconLoader); annotatorConfigChanged(); } bool MultiCaptureHandler::canClose() { while (mTabStateHandler->count() != 0) { int index = mTabStateHandler->currentTabIndex(); if (!discardChanges(index)) { return false; } removeTab(index); } return true; } bool MultiCaptureHandler::canTakeNew() { return true; } bool MultiCaptureHandler::discardChanges(int index) { auto image = mImageAnnotator->imageAt(index); auto isUnsaved = !mTabStateHandler->isSaved(index); auto pathToSource = mTabStateHandler->path(index); auto filename = mTabStateHandler->filename(index); CanDiscardOperation operation( image, isUnsaved, pathToSource, filename, mNotificationService, mRecentImageService, mMessageBoxService, mImageSaver, mSavePathProvider, mFileDialogService, mConfig, mParent); return operation.execute(); } void MultiCaptureHandler::removeTab(int currentTabIndex) { mImageAnnotator->removeTab(currentTabIndex); mTabStateHandler->tabRemoved(currentTabIndex); captureChanged(); if(mTabStateHandler->count() == 0) { mImageAnnotator->hide(); captureEmpty(); } } bool MultiCaptureHandler::isSaved() const { return mTabStateHandler->isSaved(mTabStateHandler->currentTabIndex()); } QString MultiCaptureHandler::path() const { return mTabStateHandler->path(mTabStateHandler->currentTabIndex()); } bool MultiCaptureHandler::isPathValid() const { return mTabStateHandler->isPathValid(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::saveAs() { saveAsTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::save() { saveTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::saveAll() { saveAllTabs(); } void MultiCaptureHandler::rename() { renameTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::copy() { copyToClipboardTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::copyPath() { copyPathToClipboardTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::openDirectory() { openDirectoryTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::removeImage() { deleteImageTab(mTabStateHandler->currentTabIndex()); } void MultiCaptureHandler::saveAt(int index, bool isInstant) { auto image = mImageAnnotator->imageAt(index); SaveOperation operation( image, isInstant, mTabStateHandler->path(index), mNotificationService, mRecentImageService, mImageSaver, mSavePathProvider, mFileDialogService, mConfig, mParent); auto saveResult = operation.execute(); mTabStateHandler->setSaveState(index, saveResult); captureChanged(); } void MultiCaptureHandler::load(const CaptureDto &capture) { auto path = mPathFromCaptureProvider.pathFrom(capture); auto isSaved = PathHelper::isPathValid(path); auto filename = mNewCaptureNameProvider.nextName(path); auto index = mImageAnnotator->addTab(capture.screenshot, filename, path); mTabStateHandler->add(index, filename, path, isSaved); if (capture.isCursorValid()) { mImageAnnotator->insertImageItem(capture.cursor.position, capture.cursor.image); } } void MultiCaptureHandler::tabCloseRequested(int index) { if (!discardChanges(index)) { return; } removeTab(index); } QImage MultiCaptureHandler::image() const { return mImageAnnotator->image(); } void MultiCaptureHandler::insertImageItem(const QPointF &pos, const QPixmap &pixmap) { mImageAnnotator->insertImageItem(pos, pixmap); } void MultiCaptureHandler::addListener(ICaptureChangeListener *captureChangeListener) { mCaptureChangeListener = captureChangeListener; } void MultiCaptureHandler::captureChanged() { if(mCaptureChangeListener != nullptr) { mCaptureChangeListener->captureChanged(); } } void MultiCaptureHandler::captureEmpty() { if(mCaptureChangeListener != nullptr) { mCaptureChangeListener->captureEmpty(); } } void MultiCaptureHandler::annotatorConfigChanged() { mImageAnnotator->setTabBarAutoHide(mConfig->autoHideTabs()); } void MultiCaptureHandler::addTabContextMenuActions(const QSharedPointer &iconLoader) { mSaveContextMenuAction->setText(tr("Save")); mSaveContextMenuAction->setIcon(iconLoader->loadForTheme(QLatin1String("save.svg"))); mSaveAsContextMenuAction->setText(tr("Save As")); mSaveAsContextMenuAction->setIcon(iconLoader->loadForTheme(QLatin1String("saveAs.svg"))); mSaveAllContextMenuAction->setText(tr("Save All")); mSaveAllContextMenuAction->setIcon(iconLoader->loadForTheme(QLatin1String("save.svg"))); mRenameContextMenuAction->setText(tr("Rename")); mOpenDirectoryContextMenuAction->setText(tr("Open Directory")); mCopyToClipboardContextMenuAction->setText(tr("Copy")); mCopyToClipboardContextMenuAction->setIcon(iconLoader->loadForTheme(QLatin1String("copy.svg"))); mCopyPathToClipboardContextMenuAction->setText(tr("Copy Path")); mContextMenuSeparatorAction->setSeparator(true); mDeleteImageContextMenuAction->setText(tr("Delete")); mDeleteImageContextMenuAction->setIcon(iconLoader->loadForTheme(QLatin1String("delete.svg"))); connect(mSaveContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::saveTab); connect(mSaveAsContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::saveAsTab); connect(mSaveAllContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::saveAllTabs); connect(mRenameContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::renameTab); connect(mOpenDirectoryContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::openDirectoryTab); connect(mCopyPathToClipboardContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::copyPathToClipboardTab); connect(mCopyToClipboardContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::copyToClipboardTab); connect(mDeleteImageContextMenuAction, &TabContextMenuAction::triggered, this, &MultiCaptureHandler::deleteImageTab); auto actions = QList{mSaveContextMenuAction, mSaveAsContextMenuAction, mSaveAllContextMenuAction, mRenameContextMenuAction, mOpenDirectoryContextMenuAction, mCopyToClipboardContextMenuAction, mCopyPathToClipboardContextMenuAction, mContextMenuSeparatorAction, mDeleteImageContextMenuAction }; mImageAnnotator->addTabContextMenuActions(actions); } void MultiCaptureHandler::saveAsTab(int index) { saveAt(index, false); } void MultiCaptureHandler::saveTab(int index) { saveAt(index, true); } void MultiCaptureHandler::saveAllTabs() { int tabIndex = 0; while (tabIndex < mTabStateHandler->count()) { if (!mTabStateHandler->isSaved(tabIndex)) { saveAt(tabIndex, true); } ++tabIndex; } } void MultiCaptureHandler::renameTab(int index) { RenameOperation operation(mTabStateHandler->path(index), mTabStateHandler->filename(index), mNotificationService, mConfig, mParent); auto renameResult = operation.execute(); if(renameResult.isSuccessful) { mTabStateHandler->renameFile(index, renameResult); captureChanged(); } } void MultiCaptureHandler::updateContextMenuActions(int index) { auto isPathValid = mTabStateHandler->isPathValid(index); mSaveContextMenuAction->setEnabled(!mTabStateHandler->isSaved(index)); mRenameContextMenuAction->setEnabled(isPathValid); mOpenDirectoryContextMenuAction->setEnabled(isPathValid); mCopyPathToClipboardContextMenuAction->setEnabled(isPathValid); mDeleteImageContextMenuAction->setEnabled(isPathValid); } void MultiCaptureHandler::openDirectoryTab(int index) { auto path = mTabStateHandler->path(index); mDesktopService->openFile(PathHelper::extractParentDirectory(path)); } void MultiCaptureHandler::copyToClipboardTab(int index) { auto image = mImageAnnotator->imageAt(index); mClipboard->setImage(image); } void MultiCaptureHandler::copyPathToClipboardTab(int index) { auto path = mTabStateHandler->path(index); mClipboard->setText(path); } void MultiCaptureHandler::deleteImageTab(int index) { auto path = mTabStateHandler->path(index); DeleteImageOperation operation(path, mFileService.data(), mMessageBoxService.data()); if(operation.execute()) { removeTab(index); } } ksnip-master/src/gui/captureHandler/MultiCaptureHandler.h000066400000000000000000000116271457262621600241160ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MULTICAPTUREHANDLER_H #define KSNIP_MULTICAPTUREHANDLER_H #include "src/gui/captureHandler/ICaptureHandler.h" #include "src/gui/captureHandler/ICaptureTabStateHandler.h" #include "src/gui/captureHandler/TabContextMenuAction.h" #include "src/gui/operations/CanDiscardOperation.h" #include "src/gui/operations/SaveOperation.h" #include "src/gui/operations/RenameOperation.h" #include "src/gui/operations/DeleteImageOperation.h" #include "src/gui/INotificationService.h" #include "src/gui/clipboard/IClipboard.h" #include "src/gui/desktopService/IDesktopService.h" #include "src/gui/imageAnnotator/IImageAnnotator.h" #include "src/common/provider/NewCaptureNameProvider.h" #include "src/common/provider/PathFromCaptureProvider.h" #include "src/common/loader/IIconLoader.h" #include "src/dependencyInjector/DependencyInjector.h" class MultiCaptureHandler : public ICaptureHandler { Q_OBJECT public: explicit MultiCaptureHandler( IImageAnnotator *imageAnnotator, const QSharedPointer ¬ificationService, const QSharedPointer &captureTabStateHandler, const QSharedPointer &config, const QSharedPointer &clipboard, const QSharedPointer &desktopService, const QSharedPointer &fileService, const QSharedPointer &messageBoxService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &iconLoader, const QSharedPointer &fileDialogService, QWidget *parent); ~MultiCaptureHandler() override = default; bool canClose() override; bool canTakeNew() override; bool isSaved() const override; QString path() const override; bool isPathValid() const override; void saveAs() override; void save() override; void saveAll() override; void rename() override; void copy() override; void copyPath() override; void openDirectory() override; void removeImage() override; void load(const CaptureDto &capture) override; QImage image() const override; void insertImageItem(const QPointF &pos, const QPixmap &pixmap) override; void addListener(ICaptureChangeListener *captureChangeListener) override; private: IImageAnnotator *mImageAnnotator; QSharedPointer mTabStateHandler; QSharedPointer mNotificationService; QWidget *mParent; ICaptureChangeListener *mCaptureChangeListener; NewCaptureNameProvider mNewCaptureNameProvider; PathFromCaptureProvider mPathFromCaptureProvider; QSharedPointer mConfig; QSharedPointer mClipboard; QSharedPointer mDesktopService; QSharedPointer mMessageBoxService; QSharedPointer mFileService; QSharedPointer mRecentImageService; QSharedPointer mImageSaver; QSharedPointer mSavePathProvider; QSharedPointer mFileDialogService; TabContextMenuAction *mSaveContextMenuAction; TabContextMenuAction *mSaveAsContextMenuAction; TabContextMenuAction *mSaveAllContextMenuAction; TabContextMenuAction *mRenameContextMenuAction; TabContextMenuAction *mOpenDirectoryContextMenuAction; TabContextMenuAction *mCopyPathToClipboardContextMenuAction; TabContextMenuAction *mCopyToClipboardContextMenuAction; TabContextMenuAction *mDeleteImageContextMenuAction; QAction *mContextMenuSeparatorAction; bool discardChanges(int index); void removeTab(int currentTabIndex); void saveAt(int index, bool isInstant); void addTabContextMenuActions(const QSharedPointer &iconLoader); private slots: void tabCloseRequested(int index); void captureChanged(); void captureEmpty(); void annotatorConfigChanged(); void saveAsTab(int index); void renameTab(int index); void saveTab(int index); void saveAllTabs(); void openDirectoryTab(int index); void updateContextMenuActions(int index); void copyToClipboardTab(int index); void copyPathToClipboardTab(int index); void deleteImageTab(int index); }; #endif //KSNIP_MULTICAPTUREHANDLER_H ksnip-master/src/gui/captureHandler/SingleCaptureHandler.cpp000066400000000000000000000124241457262621600245740ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SingleCaptureHandler.h" SingleCaptureHandler::SingleCaptureHandler( IImageAnnotator *imageAnnotator, const QSharedPointer ¬ificationService, const QSharedPointer &clipboard, const QSharedPointer &desktopService, const QSharedPointer &fileService, const QSharedPointer &messageBoxService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent) : mImageAnnotator(imageAnnotator), mNotificationService(notificationService), mClipboard(clipboard), mDesktopService(desktopService), mFileService(fileService), mMessageBoxService(messageBoxService), mRecentImageService(recentImageService), mImageSaver(imageSaver), mSavePathProvider(savePathProvider), mFileDialogService(fileDialogService), mConfig(config), mParent(parent), mCaptureChangeListener(nullptr), mIsSaved(true) { mImageAnnotator->setTabBarAutoHide(true); connect(mImageAnnotator, &IImageAnnotator::imageChanged, this, &SingleCaptureHandler::markUnsaved); } bool SingleCaptureHandler::canClose() { return discardChanges(); } bool SingleCaptureHandler::canTakeNew() { return discardChanges(); } bool SingleCaptureHandler::isSaved() const { return mIsSaved; } QString SingleCaptureHandler::path() const { return mPath; } bool SingleCaptureHandler::isPathValid() const { return PathHelper::isPathValid(mPath); } void SingleCaptureHandler::saveAs() { innerSave(false); } void SingleCaptureHandler::save() { innerSave(true); } void SingleCaptureHandler::saveAll() { innerSave(true); } void SingleCaptureHandler::rename() { RenameOperation operation(mPath, QFileInfo(mPath).fileName(), mNotificationService, mConfig, mParent); const auto renameResult = operation.execute(); if (renameResult.isSuccessful) { mPath = renameResult.path; captureChanged(); } } void SingleCaptureHandler::copy() { auto image = mImageAnnotator->image(); mClipboard->setImage(image); } void SingleCaptureHandler::copyPath() { mClipboard->setText(mPath); } void SingleCaptureHandler::openDirectory() { mDesktopService->openFile(PathHelper::extractParentDirectory(mPath)); } void SingleCaptureHandler::removeImage() { DeleteImageOperation operation(mPath, mFileService.data(), mMessageBoxService.data()); if(operation.execute()){ reset(); } } void SingleCaptureHandler::reset() { mImageAnnotator->hide(); mPath = QString(); mIsSaved = true; captureEmpty(); captureChanged(); } void SingleCaptureHandler::innerSave(bool isInstant) { auto image = mImageAnnotator->image(); SaveOperation operation( image, isInstant, mPath, mNotificationService, mRecentImageService, mImageSaver, mSavePathProvider, mFileDialogService, mConfig, mParent); auto saveResult = operation.execute(); mIsSaved = saveResult.isSuccessful; if (mIsSaved) { mPath = saveResult.path; captureChanged(); } } void SingleCaptureHandler::load(const CaptureDto &capture) { mPath = mPathFromCaptureProvider.pathFrom(capture); mIsSaved = PathHelper::isPathValid(mPath); mImageAnnotator->loadImage(capture.screenshot); if (capture.isCursorValid()) { mImageAnnotator->insertImageItem(capture.cursor.position, capture.cursor.image); } } QImage SingleCaptureHandler::image() const { return mImageAnnotator->image(); } void SingleCaptureHandler::insertImageItem(const QPointF &pos, const QPixmap &pixmap) { mImageAnnotator->insertImageItem(pos, pixmap); } void SingleCaptureHandler::addListener(ICaptureChangeListener *captureChangeListener) { mCaptureChangeListener = captureChangeListener; } bool SingleCaptureHandler::discardChanges() { auto image = mImageAnnotator->image(); auto filename = PathHelper::extractFilename(mPath); CanDiscardOperation operation( image, !mIsSaved, mPath, filename, mNotificationService, mRecentImageService, mMessageBoxService, mImageSaver, mSavePathProvider, mFileDialogService, mConfig, mParent); return operation.execute(); } void SingleCaptureHandler::captureChanged() { if(mCaptureChangeListener != nullptr) { mCaptureChangeListener->captureChanged(); } } void SingleCaptureHandler::captureEmpty() { if(mCaptureChangeListener != nullptr) { mCaptureChangeListener->captureEmpty(); } } void SingleCaptureHandler::markUnsaved() { mIsSaved = false; captureChanged(); } ksnip-master/src/gui/captureHandler/SingleCaptureHandler.h000066400000000000000000000070651457262621600242460ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLECAPTUREHANDLER_H #define KSNIP_SINGLECAPTUREHANDLER_H #include "src/gui/captureHandler/ICaptureHandler.h" #include "src/gui/operations/CanDiscardOperation.h" #include "src/gui/operations/DeleteImageOperation.h" #include "src/gui/operations/RenameOperation.h" #include "src/gui/INotificationService.h" #include "src/gui/clipboard/IClipboard.h" #include "src/gui/desktopService/IDesktopService.h" #include "src/gui/imageAnnotator/IImageAnnotator.h" #include "src/common/provider/PathFromCaptureProvider.h" #include "src/dependencyInjector/DependencyInjector.h" class SingleCaptureHandler : public ICaptureHandler { Q_OBJECT public: explicit SingleCaptureHandler( IImageAnnotator *imageAnnotator, const QSharedPointer ¬ificationService, const QSharedPointer &clipboard, const QSharedPointer &desktopService, const QSharedPointer &fileService, const QSharedPointer &messageBoxService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent); ~SingleCaptureHandler() override = default; bool canClose() override; bool canTakeNew() override; bool isSaved() const override; QString path() const override; bool isPathValid() const override; void saveAs() override; void save() override; void saveAll() override; void rename() override; void copy() override; void copyPath() override; void openDirectory() override; void removeImage() override; void load(const CaptureDto &capture) override; QImage image() const override; void insertImageItem(const QPointF &pos, const QPixmap &pixmap) override; void addListener(ICaptureChangeListener *captureChangeListener) override; private: IImageAnnotator *mImageAnnotator; QSharedPointer mNotificationService; QSharedPointer mClipboard; QSharedPointer mDesktopService; QSharedPointer mFileService; QSharedPointer mMessageBoxService; QSharedPointer mRecentImageService; QSharedPointer mImageSaver; QSharedPointer mSavePathProvider; QSharedPointer mFileDialogService; QSharedPointer mConfig; QWidget *mParent; ICaptureChangeListener *mCaptureChangeListener; bool mIsSaved; QString mPath; PathFromCaptureProvider mPathFromCaptureProvider; bool discardChanges(); private slots: void captureChanged(); void captureEmpty(); void innerSave(bool isInstant); void markUnsaved(); void reset(); }; #endif //KSNIP_SINGLECAPTUREHANDLER_H ksnip-master/src/gui/captureHandler/TabContextMenuAction.cpp000066400000000000000000000020631457262621600245650ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TabContextMenuAction.h" TabContextMenuAction::TabContextMenuAction(QObject *parent) : QAction(parent) { connect(this, &QAction::triggered, this, &TabContextMenuAction::actionTriggered); } void TabContextMenuAction::actionTriggered() { emit triggered(data().toInt()); } ksnip-master/src/gui/captureHandler/TabContextMenuAction.h000066400000000000000000000022271457262621600242340ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_TABCONTEXTMENUACTION_H #define KSNIP_TABCONTEXTMENUACTION_H #include class TabContextMenuAction : public QAction { Q_OBJECT public: explicit TabContextMenuAction(QObject *parent = nullptr); ~TabContextMenuAction() override = default; signals: void triggered(int index); private slots: void actionTriggered(); }; #endif //KSNIP_TABCONTEXTMENUACTION_H ksnip-master/src/gui/clipboard/000077500000000000000000000000001457262621600170205ustar00rootroot00000000000000ksnip-master/src/gui/clipboard/ClipboardAdapter.cpp000066400000000000000000000031441457262621600227260ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ClipboardAdapter.h" ClipboardAdapter::ClipboardAdapter() : mClipboard(QGuiApplication::clipboard()) { connect(mClipboard, &QClipboard::changed, this, &ClipboardAdapter::selectionChanged); } QPixmap ClipboardAdapter::pixmap() const { auto pixmap = mClipboard->pixmap(); if(pixmap.isNull()) { pixmap = QPixmap(url()); } return pixmap; } QString ClipboardAdapter::url() const { return FileUrlHelper::toPath(mClipboard->text()); } bool ClipboardAdapter::isPixmap() const { return !pixmap().isNull(); } void ClipboardAdapter::setImage(const QImage &image) { mClipboard->setImage(image); } void ClipboardAdapter::selectionChanged(QClipboard::Mode mode) const { if(mode == QClipboard::Mode::Clipboard) { emit changed(isPixmap()); } } void ClipboardAdapter::setText(const QString &text) { mClipboard->setText(text); } ksnip-master/src/gui/clipboard/ClipboardAdapter.h000066400000000000000000000027511457262621600223760ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CLIPBOARDADAPTER_H #define KSNIP_CLIPBOARDADAPTER_H #include #include #include #include "IClipboard.h" #include "src/common/dtos/CaptureFromFileDto.h" #include "src/common/helper/FileUrlHelper.h" class ClipboardAdapter : public IClipboard { Q_OBJECT public: explicit ClipboardAdapter(); ~ClipboardAdapter() override = default; QPixmap pixmap() const override; bool isPixmap() const override; void setImage(const QImage &image) override; void setText(const QString &text) override; QString url() const override; private: QClipboard *mClipboard{}; private slots: void selectionChanged(QClipboard::Mode mode) const; }; #endif //KSNIP_CLIPBOARDADAPTER_H ksnip-master/src/gui/clipboard/IClipboard.h000066400000000000000000000023701457262621600212030ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICLIPBOARD_H #define KSNIP_ICLIPBOARD_H #include class IClipboard : public QObject { Q_OBJECT public: explicit IClipboard() = default; ~IClipboard() override = default; virtual QPixmap pixmap() const = 0; virtual bool isPixmap() const = 0; virtual void setImage(const QImage &image) = 0; virtual void setText(const QString &text) = 0; virtual QString url() const = 0; signals: void changed(bool isPixmap) const; }; #endif //KSNIP_ICLIPBOARD_H ksnip-master/src/gui/desktopService/000077500000000000000000000000001457262621600200535ustar00rootroot00000000000000ksnip-master/src/gui/desktopService/DesktopServiceAdapter.cpp000066400000000000000000000020171457262621600250120ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DesktopServiceAdapter.h" void DesktopServiceAdapter::openFile(const QString &path) { QDesktopServices::openUrl(QUrl::fromLocalFile(path)); } void DesktopServiceAdapter::openUrl(const QString &url) { QDesktopServices::openUrl(url); } ksnip-master/src/gui/desktopService/DesktopServiceAdapter.h000066400000000000000000000023171457262621600244620ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DESKTOPSERVICEADAPTER_H #define KSNIP_DESKTOPSERVICEADAPTER_H #include #include #include "IDesktopService.h" class DesktopServiceAdapter : public IDesktopService { public: explicit DesktopServiceAdapter() = default; ~DesktopServiceAdapter() override = default; void openFile(const QString &path) override; void openUrl(const QString &url) override; }; #endif //KSNIP_DESKTOPSERVICEADAPTER_H ksnip-master/src/gui/desktopService/IDesktopService.h000066400000000000000000000021341457262621600232670ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IDESKTOPSERVICE_H #define KSNIP_IDESKTOPSERVICE_H class QString; class IDesktopService { public: explicit IDesktopService() = default; virtual ~IDesktopService() = default; virtual void openFile(const QString &path) = 0; virtual void openUrl(const QString &url) = 0; }; #endif //KSNIP_IDESKTOPSERVICE_H ksnip-master/src/gui/desktopService/SnapDesktopServiceAdapter.cpp000066400000000000000000000020151457262621600256320ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnapDesktopServiceAdapter.h" void SnapDesktopServiceAdapter::openFile(const QString &path) { // Workaround for issue #432, Qt unable to open file path in snap mXdgOpenProcess.start(QLatin1String("xdg-open"), QStringList{ path }); } ksnip-master/src/gui/desktopService/SnapDesktopServiceAdapter.h000066400000000000000000000023251457262621600253030ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNAPDESKTOPSERVICEADAPTER_H #define KSNIP_SNAPDESKTOPSERVICEADAPTER_H #include #include "DesktopServiceAdapter.h" class SnapDesktopServiceAdapter : public DesktopServiceAdapter { public: explicit SnapDesktopServiceAdapter() = default; ~SnapDesktopServiceAdapter() override = default; void openFile(const QString &path) override; private: QProcess mXdgOpenProcess; }; #endif //KSNIP_SNAPDESKTOPSERVICEADAPTER_H ksnip-master/src/gui/directoryService/000077500000000000000000000000001457262621600204065ustar00rootroot00000000000000ksnip-master/src/gui/directoryService/DirectoryService.cpp000066400000000000000000000023701457262621600244010ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DirectoryService.h" QList DirectoryService::childDirectories(const QString &path) const { return getChildrenOfType(path, QDir::Dirs | QDir::NoDotAndDotDot); } QList DirectoryService::childFiles(const QString &path) const { return getChildrenOfType(path, QDir::Files); } QList DirectoryService::getChildrenOfType(const QString &path, QFlags filters) const { QDir parent(path); return parent.entryInfoList(filters); } ksnip-master/src/gui/directoryService/DirectoryService.h000066400000000000000000000024371457262621600240520ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DIRECTORYSERVICE_H #define KSNIP_DIRECTORYSERVICE_H #include #include "IDirectoryService.h" class DirectoryService : public IDirectoryService { public: DirectoryService() = default; ~DirectoryService() = default; QList childDirectories(const QString &path) const override; QList childFiles(const QString &path) const override; private: QList getChildrenOfType(const QString &path, QFlags filters) const; }; #endif //KSNIP_DIRECTORYSERVICE_H ksnip-master/src/gui/directoryService/IDirectoryService.h000066400000000000000000000022331457262621600241550ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IDIRECTORYSERVICE_H #define KSNIP_IDIRECTORYSERVICE_H #include class QFileInfo; class IDirectoryService { public: IDirectoryService() = default; ~IDirectoryService() = default; virtual QList childDirectories(const QString &path) const = 0; virtual QList childFiles(const QString &path) const = 0; }; #endif //KSNIP_IDIRECTORYSERVICE_H ksnip-master/src/gui/dragAndDrop/000077500000000000000000000000001457262621600172465ustar00rootroot00000000000000ksnip-master/src/gui/dragAndDrop/DragAndDropProcessor.cpp000066400000000000000000000114151457262621600240010ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DragAndDropProcessor.h" DragAndDropProcessor::DragAndDropProcessor(IDragContentProvider *dragContentProvider, const QSharedPointer &tempFileProvider) : mDragContentProvider(dragContentProvider), mTempFileProvider(tempFileProvider) { } bool DragAndDropProcessor::eventFilter(QObject *object, QEvent *event) { if(event->type() == QEvent::DragEnter) { return handleDragEnter(dynamic_cast(event)); } else if(event->type() == QEvent::Drop) { return handleDrop(dynamic_cast(event)); } else if(event->type() == QEvent::GraphicsSceneDrop) { return handleDrop(dynamic_cast(event)); } else if (event->type() == QEvent::GraphicsSceneDragEnter) { return handleDragEnter(dynamic_cast(event)); } else if (event->type() == QEvent::MouseButtonPress) { return handleDragStart(dynamic_cast(event)); } else if (event->type() == QEvent::MouseMove) { return handleDragMove(dynamic_cast(event)); } return QObject::eventFilter(object, event); } bool DragAndDropProcessor::handleDragEnter(QDragEnterEvent *event) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); return true; } return false; } bool DragAndDropProcessor::handleDragEnter(QGraphicsSceneDragDropEvent *event) { if (event->mimeData()->hasUrls()) { event->acceptProposedAction(); return true; } return false; } bool DragAndDropProcessor::handleDrop(QDropEvent *event) { auto paths = getUrlsFromMimeData(event->mimeData()); processDroppedImagePaths(paths); event->acceptProposedAction(); return true; } bool DragAndDropProcessor::handleDrop(QGraphicsSceneDragDropEvent *event) { auto paths = getUrlsFromMimeData(event->mimeData()); processDroppedImagePaths(paths); event->acceptProposedAction(); return true; } bool DragAndDropProcessor::handleDragStart(QMouseEvent *event) { if (isDragStarting(event)) { mDragStartPosition = event->pos(); return true; } return false; } bool DragAndDropProcessor::handleDragMove(QMouseEvent *event) { if (isDragStarting(event) && isMinDragDistanceReached(event)) { auto dragContent = mDragContentProvider->dragContent(); if (dragContent.isValid()) { createDrag(dragContent); return true; } } return false; } QStringList DragAndDropProcessor::getUrlsFromMimeData(const QMimeData *mimeData) { QStringList urls; for (const auto &url : mimeData->urls()) { urls.push_back(FileUrlHelper::toPath(url.toString())); } return urls; } bool DragAndDropProcessor::isDragStarting(const QMouseEvent *event) { return event->buttons() & Qt::LeftButton && event->modifiers() & Qt::ShiftModifier; } bool DragAndDropProcessor::isMinDragDistanceReached(const QMouseEvent *event) const { return (event->pos() - mDragStartPosition).manhattanLength() >= QApplication::startDragDistance(); } void DragAndDropProcessor::createDrag(const DragContent &dragContent) { auto imagePath = getPathToDraggedImage(dragContent); auto mimeData = new QMimeData; mimeData->setUrls( { QUrl(FileUrlHelper::toFileUrl(imagePath)) }); mimeData->setData(QLatin1String("text/uri-list"), FileUrlHelper::toFileUrl(imagePath).toLatin1()); auto icon = QPixmap::fromImage(dragContent.image).scaled(256, 256, Qt::KeepAspectRatio, Qt::FastTransformation); auto drag = new QDrag(this); drag->setMimeData(mimeData); drag->setPixmap(icon); drag->exec(); } QString DragAndDropProcessor::getPathToDraggedImage(const DragContent &dragContent) { QString imagePath; if (dragContent.isSaved) { imagePath = dragContent.path; } else{ imagePath = mTempFileProvider->tempFile(); if(!dragContent.image.save(imagePath)){ qWarning("Failed to save temporary dragImage %s for drag and drop operation.", qPrintable(imagePath)); } } return imagePath; } void DragAndDropProcessor::processDroppedImagePaths(const QStringList &paths) { for(const auto& path: paths) { if (PathHelper::isTempDirectory(path)) { emit imageDropped(QPixmap(path)); } else { emit fileDropped(path); } } } ksnip-master/src/gui/dragAndDrop/DragAndDropProcessor.h000066400000000000000000000046721457262621600234550ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DRAGANDDROPPROCESSOR_H #define KSNIP_DRAGANDDROPPROCESSOR_H #include #include #include #include #include #include #include #include #include #include #include "IDragContentProvider.h" #include "src/common/helper/FileUrlHelper.h" #include "src/common/helper/PathHelper.h" #include "src/common/provider/ITempFileProvider.h" class DragAndDropProcessor : public QObject { Q_OBJECT public: explicit DragAndDropProcessor(IDragContentProvider *dragContentProvider, const QSharedPointer &tempFileProvider); ~DragAndDropProcessor() override = default; bool eventFilter(QObject *object, QEvent *event) override; signals: void fileDropped(const QString &path); void imageDropped(const QPixmap &pixmap); private: IDragContentProvider *mDragContentProvider; QSharedPointer mTempFileProvider; QPoint mDragStartPosition; static bool handleDragEnter(QDragEnterEvent *event); static bool handleDragEnter(QGraphicsSceneDragDropEvent *event); bool handleDrop(QDropEvent *event); bool handleDrop(QGraphicsSceneDragDropEvent *event); bool handleDragStart(QMouseEvent *event); bool handleDragMove(QMouseEvent *event); static QStringList getUrlsFromMimeData(const QMimeData *mimeData); static bool isDragStarting(const QMouseEvent *event); bool isMinDragDistanceReached(const QMouseEvent *event) const; void createDrag(const DragContent &dragContent); QString getPathToDraggedImage(const DragContent &dragContent); void processDroppedImagePaths(const QStringList &paths); }; #endif //KSNIP_DRAGANDDROPPROCESSOR_H ksnip-master/src/gui/dragAndDrop/DragContent.h000066400000000000000000000024001457262621600216230ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DRAGCONTENT_H #define KSNIP_DRAGCONTENT_H #include struct DragContent { QImage image; QString path; bool isSaved; explicit DragContent() { image = QImage(); path = QString(); isSaved = false; } explicit DragContent(const QImage &image, const QString &path, bool isSaved) { this->image = image.copy(); this->path = path; this->isSaved = isSaved; } virtual bool isValid() const { return !image.isNull(); } }; #endif //KSNIP_DRAGCONTENT_H ksnip-master/src/gui/dragAndDrop/IDragContentProvider.h000066400000000000000000000021011457262621600234450ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IDRAGCONTENTPROVIDER_H #define KSNIP_IDRAGCONTENTPROVIDER_H #include "DragContent.h" class IDragContentProvider { public: IDragContentProvider() = default; ~IDragContentProvider() = default; virtual DragContent dragContent() const = 0; }; #endif //KSNIP_IDRAGCONTENTPROVIDER_H ksnip-master/src/gui/fileService/000077500000000000000000000000001457262621600173215ustar00rootroot00000000000000ksnip-master/src/gui/fileService/FileService.cpp000066400000000000000000000017321457262621600222300ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "FileService.h" bool FileService::remove(const QString &path) { QFile file(path); return file.remove(); } QPixmap FileService::openPixmap(const QString &path) { return { path }; } ksnip-master/src/gui/fileService/FileService.h000066400000000000000000000022121457262621600216670ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FILESERVICE_H #define KSNIP_FILESERVICE_H #include #include #include "IFileService.h" class FileService : public IFileService { public: explicit FileService() = default; ~FileService() override = default; bool remove(const QString &path) override; QPixmap openPixmap(const QString &path) override; }; #endif //KSNIP_FILESERVICE_H ksnip-master/src/gui/fileService/IFileService.h000066400000000000000000000021361457262621600220050ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IFILESERVICE_H #define KSNIP_IFILESERVICE_H class QString; class QPixmap; class IFileService { public: explicit IFileService() = default; virtual ~IFileService() = default; virtual bool remove(const QString &path) = 0; virtual QPixmap openPixmap(const QString &path) = 0; }; #endif //KSNIP_IFILESERVICE_H ksnip-master/src/gui/globalHotKeys/000077500000000000000000000000001457262621600176305ustar00rootroot00000000000000ksnip-master/src/gui/globalHotKeys/GlobalHotKey.cpp000066400000000000000000000025661457262621600226710ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GlobalHotKey.h" GlobalHotKey::GlobalHotKey(QCoreApplication *app, const QKeySequence &keySequence, const QSharedPointer &platformChecker) { mApp = app; auto keyHandler = KeyHandlerFactory::create(platformChecker); keyHandler->registerKey(keySequence); mKeyEventFilter = new NativeKeyEventFilter(keyHandler); mApp->installNativeEventFilter(mKeyEventFilter); connect(mKeyEventFilter, &NativeKeyEventFilter::triggered, this, &GlobalHotKey::pressed); } GlobalHotKey::~GlobalHotKey() { mApp->removeNativeEventFilter(mKeyEventFilter); delete mKeyEventFilter; } ksnip-master/src/gui/globalHotKeys/GlobalHotKey.h000066400000000000000000000025461457262621600223340ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_GLOBALHOTKEY_H #define KSNIP_GLOBALHOTKEY_H #include #include #include "NativeKeyEventFilter.h" #include "src/gui/globalHotKeys/keyHandler/KeyHandlerFactory.h" class GlobalHotKey : public QObject { Q_OBJECT public: explicit GlobalHotKey(QCoreApplication *app, const QKeySequence &keySequence, const QSharedPointer &platformChecker); ~GlobalHotKey() override; signals: void pressed() const; private: QCoreApplication *mApp; NativeKeyEventFilter *mKeyEventFilter; }; #endif //KSNIP_GLOBALHOTKEY_H ksnip-master/src/gui/globalHotKeys/GlobalHotKeyHandler.cpp000066400000000000000000000064711457262621600241660ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GlobalHotKeyHandler.h" GlobalHotKeyHandler::GlobalHotKeyHandler( const QList &supportedCaptureModes, const QSharedPointer &platformChecker, const QSharedPointer &config) : mSupportedCaptureModes(supportedCaptureModes), mConfig(config), mPlatformChecker(platformChecker) { connect(mConfig.data(), &IConfig::hotKeysChanged, this, &GlobalHotKeyHandler::setupHotKeys); setupHotKeys(); } GlobalHotKeyHandler::~GlobalHotKeyHandler() { removeHotKeys(); } void GlobalHotKeyHandler::removeHotKeys() { mGlobalHotKeys.clear(); } void GlobalHotKeyHandler::setupHotKeys() { removeHotKeys(); if(mConfig->globalHotKeysEnabled()) { createHotKey(mConfig->rectAreaHotKey(), CaptureModes::RectArea); createHotKey(mConfig->lastRectAreaHotKey(), CaptureModes::LastRectArea); createHotKey(mConfig->fullScreenHotKey(), CaptureModes::FullScreen); createHotKey(mConfig->currentScreenHotKey(), CaptureModes::CurrentScreen); createHotKey(mConfig->activeWindowHotKey(), CaptureModes::ActiveWindow); createHotKey(mConfig->windowUnderCursorHotKey(), CaptureModes::WindowUnderCursor); createHotKey(mConfig->portalHotKey(), CaptureModes::Portal); auto actions = mConfig->actions(); for (const auto& action : actions) { createHotKey(action); } } } void GlobalHotKeyHandler::createHotKey(const QKeySequence &keySequence, CaptureModes captureMode) { if(mSupportedCaptureModes.contains(captureMode) && !keySequence.isEmpty()) { auto hotKey = QSharedPointer(new GlobalHotKey(QApplication::instance(), keySequence, mPlatformChecker)); connect(hotKey.data(), &GlobalHotKey::pressed, [this, captureMode](){ emit captureTriggered(captureMode); }); mGlobalHotKeys.append(hotKey); } } void GlobalHotKeyHandler::createHotKey(const Action &action) { auto isGlobal = action.isGlobalShortcut(); auto isShortcutSet = !action.shortcut().isEmpty(); auto isPostProcessingOnlyAction = !action.isCaptureEnabled(); auto isRequestedCaptureSupported = action.isCaptureEnabled() && mSupportedCaptureModes.contains(action.captureMode()); if(isShortcutSet && isGlobal && (isPostProcessingOnlyAction || isRequestedCaptureSupported)) { auto hotKey = QSharedPointer(new GlobalHotKey(QApplication::instance(), action.shortcut(), mPlatformChecker)); connect(hotKey.data(), &GlobalHotKey::pressed, [this, action](){ emit actionTriggered(action); }); mGlobalHotKeys.append(hotKey); } } void GlobalHotKeyHandler::setEnabled(bool enabled) { if(enabled) { setupHotKeys(); } else { removeHotKeys(); } } ksnip-master/src/gui/globalHotKeys/GlobalHotKeyHandler.h000066400000000000000000000036121457262621600236250ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_GLOBALHOTKEYHANDLER_H #define KSNIP_GLOBALHOTKEYHANDLER_H #include #include #include #include "GlobalHotKey.h" #include "src/backend/config/IConfig.h" #include "src/common/enum/CaptureModes.h" #include "src/gui/actions/Action.h" class GlobalHotKeyHandler : public QObject { Q_OBJECT public: explicit GlobalHotKeyHandler( const QList &supportedCaptureModes, const QSharedPointer &platformChecker, const QSharedPointer &config); ~GlobalHotKeyHandler() override; void setEnabled(bool enabled); signals: void captureTriggered(CaptureModes captureMode) const; void actionTriggered(const Action &action) const; private: QSharedPointer mConfig; QList> mGlobalHotKeys; QList mSupportedCaptureModes; QSharedPointer mPlatformChecker; void removeHotKeys(); void createHotKey(const QKeySequence &keySequence, CaptureModes captureMode); void createHotKey(const Action &action); private slots: void setupHotKeys(); }; #endif //KSNIP_GLOBALHOTKEYHANDLER_H ksnip-master/src/gui/globalHotKeys/HotKeyMap.cpp000066400000000000000000000114531457262621600222010ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "HotKeyMap.h" HotKeyMap *HotKeyMap::instance() { static HotKeyMap instance; return &instance; } HotKeyMap::HotKeyMap() { // Numbers mKeyToStringMap[Qt::Key_0] = QLatin1String("0"); mKeyToStringMap[Qt::Key_1] = QLatin1String("1"); mKeyToStringMap[Qt::Key_2] = QLatin1String("2"); mKeyToStringMap[Qt::Key_3] = QLatin1String("3"); mKeyToStringMap[Qt::Key_4] = QLatin1String("4"); mKeyToStringMap[Qt::Key_5] = QLatin1String("5"); mKeyToStringMap[Qt::Key_6] = QLatin1String("6"); mKeyToStringMap[Qt::Key_7] = QLatin1String("7"); mKeyToStringMap[Qt::Key_8] = QLatin1String("8"); mKeyToStringMap[Qt::Key_9] = QLatin1String("9"); // Misc mKeyToStringMap[Qt::Key_Escape] = QLatin1String("ESCAPE"); mKeyToStringMap[Qt::Key_Backspace] = QLatin1String("BACKSPACE"); mKeyToStringMap[Qt::Key_Return] = QLatin1String("RETURN"); mKeyToStringMap[Qt::Key_Enter] = QLatin1String("ENTER"); mKeyToStringMap[Qt::Key_Insert] = QLatin1String("INS"); mKeyToStringMap[Qt::Key_Delete] = QLatin1String("DEL"); mKeyToStringMap[Qt::Key_Pause] = QLatin1String("PAUSE"); mKeyToStringMap[Qt::Key_Print] = QLatin1String("PRINT"); mKeyToStringMap[Qt::Key_Home] = QLatin1String("HOME"); mKeyToStringMap[Qt::Key_End] = QLatin1String("END"); mKeyToStringMap[Qt::Key_Left] = QLatin1String("LEFT"); mKeyToStringMap[Qt::Key_Up] = QLatin1String("UP"); mKeyToStringMap[Qt::Key_Right] = QLatin1String("RIGHT"); mKeyToStringMap[Qt::Key_Down] = QLatin1String("DOWN"); mKeyToStringMap[Qt::Key_PageUp] = QLatin1String("PGUP"); mKeyToStringMap[Qt::Key_PageDown] = QLatin1String("PGDOWN"); mKeyToStringMap[Qt::Key_Comma] = QLatin1String(","); mKeyToStringMap[Qt::Key_Underscore] = QLatin1String("_"); mKeyToStringMap[Qt::Key_Minus] = QLatin1String("-"); mKeyToStringMap[Qt::Key_Period] = QLatin1String("."); mKeyToStringMap[Qt::Key_Slash] = QLatin1String("/"); mKeyToStringMap[Qt::Key_Colon] = QLatin1String(":"); mKeyToStringMap[Qt::Key_Semicolon] = QLatin1String(";"); // F-Keys mKeyToStringMap[Qt::Key_F1] = QLatin1String("F1"); mKeyToStringMap[Qt::Key_F2] = QLatin1String("F2"); mKeyToStringMap[Qt::Key_F3] = QLatin1String("F3"); mKeyToStringMap[Qt::Key_F4] = QLatin1String("F4"); mKeyToStringMap[Qt::Key_F5] = QLatin1String("F5"); mKeyToStringMap[Qt::Key_F6] = QLatin1String("F6"); mKeyToStringMap[Qt::Key_F7] = QLatin1String("F7"); mKeyToStringMap[Qt::Key_F8] = QLatin1String("F8"); mKeyToStringMap[Qt::Key_F9] = QLatin1String("F9"); mKeyToStringMap[Qt::Key_F10] = QLatin1String("F10"); mKeyToStringMap[Qt::Key_F11] = QLatin1String("F11"); mKeyToStringMap[Qt::Key_F12] = QLatin1String("F12"); // Letters mKeyToStringMap[Qt::Key_A] = QLatin1String("A"); mKeyToStringMap[Qt::Key_B] = QLatin1String("B"); mKeyToStringMap[Qt::Key_C] = QLatin1String("C"); mKeyToStringMap[Qt::Key_D] = QLatin1String("D"); mKeyToStringMap[Qt::Key_E] = QLatin1String("E"); mKeyToStringMap[Qt::Key_F] = QLatin1String("F"); mKeyToStringMap[Qt::Key_G] = QLatin1String("G"); mKeyToStringMap[Qt::Key_H] = QLatin1String("H"); mKeyToStringMap[Qt::Key_I] = QLatin1String("I"); mKeyToStringMap[Qt::Key_J] = QLatin1String("J"); mKeyToStringMap[Qt::Key_K] = QLatin1String("K"); mKeyToStringMap[Qt::Key_L] = QLatin1String("L"); mKeyToStringMap[Qt::Key_M] = QLatin1String("M"); mKeyToStringMap[Qt::Key_N] = QLatin1String("N"); mKeyToStringMap[Qt::Key_O] = QLatin1String("O"); mKeyToStringMap[Qt::Key_P] = QLatin1String("P"); mKeyToStringMap[Qt::Key_Q] = QLatin1String("Q"); mKeyToStringMap[Qt::Key_R] = QLatin1String("R"); mKeyToStringMap[Qt::Key_S] = QLatin1String("S"); mKeyToStringMap[Qt::Key_T] = QLatin1String("T"); mKeyToStringMap[Qt::Key_U] = QLatin1String("U"); mKeyToStringMap[Qt::Key_V] = QLatin1String("V"); mKeyToStringMap[Qt::Key_W] = QLatin1String("W"); mKeyToStringMap[Qt::Key_X] = QLatin1String("X"); mKeyToStringMap[Qt::Key_Y] = QLatin1String("Y"); mKeyToStringMap[Qt::Key_Z] = QLatin1String("Z"); } Qt::Key HotKeyMap::getKeyForString(const QString &string) const { return mKeyToStringMap.key(string); } QList HotKeyMap::getAllKeys() const { return mKeyToStringMap.keys(); } ksnip-master/src/gui/globalHotKeys/HotKeyMap.h000066400000000000000000000022531457262621600216440ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_HOTKEYMAP_H #define KSNIP_HOTKEYMAP_H #include #include #include #include class HotKeyMap { public: static HotKeyMap *instance(); Qt::Key getKeyForString(const QString &string) const; QList getAllKeys() const; private: QHash mKeyToStringMap; HotKeyMap(); ~HotKeyMap() = default; }; #endif //KSNIP_HOTKEYMAP_H ksnip-master/src/gui/globalHotKeys/KeyCodeCombo.h000066400000000000000000000021231457262621600223020ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYCODECOMBO_H #define KSNIP_KEYCODECOMBO_H struct KeyCodeCombo { unsigned int modifier; unsigned int key; explicit KeyCodeCombo(unsigned int modifier, unsigned int key) { this->modifier = modifier; this->key = key; } explicit KeyCodeCombo() = default; }; #endif //KSNIP_KEYCODECOMBO_H ksnip-master/src/gui/globalHotKeys/KeySequenceToMacKeyCodeTranslator.cpp000066400000000000000000000032061457262621600270200ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KeySequenceToMacKeyCodeTranslator.h" KeySequenceToMacKeyCodeTranslator::KeySequenceToMacKeyCodeTranslator() { mHotKeyMap = HotKeyMap::instance(); } KeyCodeCombo KeySequenceToMacKeyCodeTranslator::map(const QKeySequence &keySequence) const { auto sequenceString = keySequence.toString().toUpper(); auto modifierString = sequenceString.section(QLatin1String("+"), 0, -2); auto keyString = sequenceString.section(QLatin1String("+"), -1, -1); auto modifier = getModifier(modifierString); auto key = getKey(keyString); return KeyCodeCombo(modifier, key); } unsigned int KeySequenceToMacKeyCodeTranslator::getModifier(const QString &modifierString) const { unsigned int modifier = 0; return modifier; } unsigned int KeySequenceToMacKeyCodeTranslator::getKey(const QString &keyString) const { auto key = mHotKeyMap->getKeyForString(keyString); return key; } ksnip-master/src/gui/globalHotKeys/KeySequenceToMacKeyCodeTranslator.h000066400000000000000000000025021457262621600264630ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYSEQUENCETOMACKEYCODETRANSLATOR_H #define KSNIP_KEYSEQUENCETOMACKEYCODETRANSLATOR_H #include "KeyCodeCombo.h" #include "HotKeyMap.h" class KeySequenceToMacKeyCodeTranslator { public: KeySequenceToMacKeyCodeTranslator(); ~KeySequenceToMacKeyCodeTranslator() = default; KeyCodeCombo map(const QKeySequence &keySequence) const; private: HotKeyMap *mHotKeyMap; unsigned int getModifier(const QString &modifierString) const; unsigned int getKey(const QString &keyString) const; }; #endif //KSNIP_KEYSEQUENCETOMACKEYCODETRANSLATOR_H ksnip-master/src/gui/globalHotKeys/KeySequenceToWinKeyCodeTranslator.cpp000066400000000000000000000063051457262621600270600ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KeySequenceToWinKeyCodeTranslator.h" KeySequenceToWinKeyCodeTranslator::KeySequenceToWinKeyCodeTranslator() { mHotKeyMap = HotKeyMap::instance(); } KeyCodeCombo KeySequenceToWinKeyCodeTranslator::map(const QKeySequence &keySequence) const { auto sequenceString = keySequence.toString().toUpper(); auto modifierString = sequenceString.section(QLatin1String("+"), 0, -2); auto keyString = sequenceString.section(QLatin1String("+"), -1, -1); auto modifier = getModifier(modifierString); auto key = getKey(keyString); return KeyCodeCombo(modifier, key); } unsigned int KeySequenceToWinKeyCodeTranslator::getModifier(const QString &modifierString) const { unsigned int modifier = MOD_NOREPEAT; if (modifierString.contains(QLatin1String("SHIFT"))) { modifier |= MOD_SHIFT; } if (modifierString.contains(QLatin1String("ALT"))) { modifier |= MOD_ALT; } if (modifierString.contains(QLatin1String("CTRL"))) { modifier |= MOD_CONTROL; } return modifier; } unsigned int KeySequenceToWinKeyCodeTranslator::getKey(const QString &keyString) const { auto key = mHotKeyMap->getKeyForString(keyString); switch (key) { case Qt::Key_F1: return VK_F1; case Qt::Key_F2: return VK_F2; case Qt::Key_F3: return VK_F3; case Qt::Key_F4: return VK_F4; case Qt::Key_F5: return VK_F5; case Qt::Key_F6: return VK_F6; case Qt::Key_F7: return VK_F7; case Qt::Key_F8: return VK_F8; case Qt::Key_F9: return VK_F9; case Qt::Key_F10: return VK_F10; case Qt::Key_F11: return VK_F11; case Qt::Key_F12: return VK_F12; case Qt::Key_Escape: return VK_ESCAPE; case Qt::Key_Backspace: return VK_BACK; case Qt::Key_Return: case Qt::Key_Enter: return VK_RETURN; case Qt::Key_Insert: return VK_INSERT; case Qt::Key_Delete: return VK_DELETE; case Qt::Key_Pause: return VK_PAUSE; case Qt::Key_Print: return VK_SNAPSHOT; case Qt::Key_Home: return VK_HOME; case Qt::Key_End: return VK_END; case Qt::Key_Left: return VK_LEFT; case Qt::Key_Up: return VK_UP; case Qt::Key_Right: return VK_RIGHT; case Qt::Key_Down: return VK_DOWN; case Qt::Key_PageUp: return VK_PRIOR; case Qt::Key_PageDown: return VK_NEXT; case Qt::Key_Comma: case Qt::Key_Semicolon: return VK_OEM_COMMA; case Qt::Key_Minus: case Qt::Key_Underscore: return VK_OEM_MINUS; case Qt::Key_Period: case Qt::Key_Colon: return VK_OEM_PERIOD; default: return key; } } ksnip-master/src/gui/globalHotKeys/KeySequenceToWinKeyCodeTranslator.h000066400000000000000000000025621457262621600265260ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYSEQUENCETOWINKEYCODETRANSLATOR_H #define KSNIP_KEYSEQUENCETOWINKEYCODETRANSLATOR_H #include #include #include "KeyCodeCombo.h" #include "HotKeyMap.h" class KeySequenceToWinKeyCodeTranslator { public: KeySequenceToWinKeyCodeTranslator(); ~KeySequenceToWinKeyCodeTranslator() = default; KeyCodeCombo map(const QKeySequence &keySequence) const; private: HotKeyMap *mHotKeyMap; unsigned int getModifier(const QString &modifierString) const; unsigned int getKey(const QString &keyString) const; }; #endif //KSNIP_KEYSEQUENCETOWINKEYCODETRANSLATOR_H ksnip-master/src/gui/globalHotKeys/KeySequenceToX11KeyCodeTranslator.cpp000066400000000000000000000060271457262621600266750ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KeySequenceToX11KeyCodeTranslator.h" #include KeySequenceToX11KeyCodeTranslator::KeySequenceToX11KeyCodeTranslator() { mHotKeyMap = HotKeyMap::instance(); } KeyCodeCombo KeySequenceToX11KeyCodeTranslator::map(const QKeySequence &keySequence) const { auto sequenceString = keySequence.toString().toUpper(); auto modifierString = sequenceString.section(QLatin1String("+"), 0, -2); auto keyString = sequenceString.section(QLatin1String("+"), -1, -1); auto modifier = getModifier(modifierString); auto key = getKey(keyString); return KeyCodeCombo(modifier, key); } unsigned int KeySequenceToX11KeyCodeTranslator::getModifier(const QString &modifierString) const { unsigned int modifier = 0; if (modifierString.contains(QLatin1String("SHIFT"))) { modifier |= ShiftMask; } if (modifierString.contains(QLatin1String("ALT"))) { modifier |= Mod1Mask; } if (modifierString.contains(QLatin1String("CTRL"))) { modifier |= ControlMask; } if (modifierString.contains(QLatin1String("META"))) { modifier |= Mod4Mask; } return modifier; } unsigned int KeySequenceToX11KeyCodeTranslator::getKey(const QString &keyString) const { auto display = QX11Info::display(); auto keyCode = getKeyCode(keyString); return XKeysymToKeycode(display, keyCode); } unsigned int KeySequenceToX11KeyCodeTranslator::getKeyCode(const QString &keyString) const { auto key = mHotKeyMap->getKeyForString(keyString); switch (key) { case Qt::Key_F1: return XK_F1; case Qt::Key_F2: return XK_F2; case Qt::Key_F3: return XK_F3; case Qt::Key_F4: return XK_F4; case Qt::Key_F5: return XK_F5; case Qt::Key_F6: return XK_F6; case Qt::Key_F7: return XK_F7; case Qt::Key_F8: return XK_F8; case Qt::Key_F9: return XK_F9; case Qt::Key_F10: return XK_F10; case Qt::Key_F11: return XK_F11; case Qt::Key_F12: return XK_F12; case Qt::Key_Delete: return XK_Delete; case Qt::Key_Insert: return XK_Insert; case Qt::Key_Print: return XK_Print; case Qt::Key_Left: return XK_Left; case Qt::Key_Up: return XK_Up; case Qt::Key_Right: return XK_Right; case Qt::Key_Down: return XK_Down; case Qt::Key_PageDown: return XK_Page_Down; case Qt::Key_PageUp: return XK_Page_Up; default: return key; } } ksnip-master/src/gui/globalHotKeys/KeySequenceToX11KeyCodeTranslator.h000066400000000000000000000026511457262621600263410ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYSEQUENCETOX11KEYCODETRANSLATOR_H #define KSNIP_KEYSEQUENCETOX11KEYCODETRANSLATOR_H #include #include #include "KeyCodeCombo.h" #include "HotKeyMap.h" class KeySequenceToX11KeyCodeTranslator { public: KeySequenceToX11KeyCodeTranslator(); ~KeySequenceToX11KeyCodeTranslator() = default; KeyCodeCombo map(const QKeySequence &keySequence) const; private: HotKeyMap *mHotKeyMap; unsigned int getModifier(const QString &modifierString) const; unsigned int getKey(const QString &keyString) const; unsigned int getKeyCode(const QString &keyString) const; }; #endif //KSNIP_KEYSEQUENCETOX11KEYCODETRANSLATOR_H ksnip-master/src/gui/globalHotKeys/NativeKeyEventFilter.cpp000066400000000000000000000022611457262621600244040ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "NativeKeyEventFilter.h" NativeKeyEventFilter::NativeKeyEventFilter(const QSharedPointer &keyHandler) : mKeyHandler(keyHandler) { } bool NativeKeyEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result) { Q_UNUSED(eventType) Q_UNUSED(result) if(mKeyHandler->isKeyPressed(message)) { emit triggered(); } return false; } ksnip-master/src/gui/globalHotKeys/NativeKeyEventFilter.h000066400000000000000000000026471457262621600240610ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYEVENTFILTER_H #define KSNIP_KEYEVENTFILTER_H #include #include #include #include "src/gui/globalHotKeys/keyHandler/IKeyHandler.h" class NativeKeyEventFilter: public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: explicit NativeKeyEventFilter(const QSharedPointer &keyHandler); ~NativeKeyEventFilter() override = default; bool nativeEventFilter(const QByteArray&, void* message, long*) override; signals: void triggered() const; private: QSharedPointer mKeyHandler; }; #endif //KSNIP_KEYEVENTFILTER_H ksnip-master/src/gui/globalHotKeys/X11ErrorLogger.cpp000066400000000000000000000023511457262621600230600ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "X11ErrorLogger.h" X11ErrorLogger::X11ErrorLogger() { XSetErrorHandler(errorHandler); } int X11ErrorLogger::errorHandler(Display *d, XErrorEvent *e) { Q_UNUSED(d); switch (e->error_code) { case BadAccess: qCritical("Unable to assign Global Hotkey, key sequence already in use by other Application"); break; default: qCritical("Unknown Global Hotkey Error Code: %s", qPrintable(QString::number(e->error_code))); break; } return 1; } ksnip-master/src/gui/globalHotKeys/X11ErrorLogger.h000066400000000000000000000020671457262621600225310ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_X11ERRORLOGGER_H #define KSNIP_X11ERRORLOGGER_H #include #include class X11ErrorLogger { public: X11ErrorLogger(); ~X11ErrorLogger() = default; private: static int errorHandler(Display *d, XErrorEvent *e); }; #endif //KSNIP_X11ERRORLOGGER_H ksnip-master/src/gui/globalHotKeys/keyHandler/000077500000000000000000000000001457262621600217165ustar00rootroot00000000000000ksnip-master/src/gui/globalHotKeys/keyHandler/DummyKeyHandler.cpp000066400000000000000000000017411457262621600254670ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DummyKeyHandler.h" bool DummyKeyHandler::registerKey(const QKeySequence &keySequence) { return false; } bool DummyKeyHandler::isKeyPressed(void* message) { return false; }ksnip-master/src/gui/globalHotKeys/keyHandler/DummyKeyHandler.h000066400000000000000000000022231457262621600251300ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DUMMYKEYHANDLER_H #define KSNIP_DUMMYKEYHANDLER_H #include "IKeyHandler.h" class DummyKeyHandler : public IKeyHandler { public: DummyKeyHandler() = default; ~DummyKeyHandler() override = default; bool registerKey(const QKeySequence &keySequence) override; bool isKeyPressed(void* message) override; }; #endif //KSNIP_DUMMYKEYHANDLER_H ksnip-master/src/gui/globalHotKeys/keyHandler/IKeyHandler.h000066400000000000000000000021521457262621600242260ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IKEYHANDLER_H #define KSNIP_IKEYHANDLER_H #include class IKeyHandler { public: IKeyHandler() = default; virtual ~IKeyHandler() = default; virtual bool registerKey(const QKeySequence &keySequence) = 0; virtual bool isKeyPressed(void* message) = 0; }; #endif //KSNIP_IKEYHANDLER_H ksnip-master/src/gui/globalHotKeys/keyHandler/KeyHandlerFactory.cpp000066400000000000000000000024561457262621600260070ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KeyHandlerFactory.h" QSharedPointer KeyHandlerFactory::create(const QSharedPointer &platformChecker) { #if defined(__APPLE__) return QSharedPointer(new DummyKeyHandler); #endif #if defined(UNIX_X11) if(platformChecker->isWayland()) { return QSharedPointer(new DummyKeyHandler); } else { return QSharedPointer(new X11KeyHandler); } #endif #if defined(_WIN32) return QSharedPointer(new WinKeyHandler); #endif } ksnip-master/src/gui/globalHotKeys/keyHandler/KeyHandlerFactory.h000066400000000000000000000024601457262621600254470ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYHANDLERFACTORY_H #define KSNIP_KEYHANDLERFACTORY_H #include #include "src/common/platform/IPlatformChecker.h" #if defined(__APPLE__) #include "DummyKeyHandler.h" #endif #if defined(UNIX_X11) #include "X11KeyHandler.h" #include "DummyKeyHandler.h" #endif #if defined(_WIN32) #include "WinKeyHandler.h" #endif class KeyHandlerFactory { public: static QSharedPointer create(const QSharedPointer &platformChecker); }; #endif //KSNIP_KEYHANDLERFACTORY_H ksnip-master/src/gui/globalHotKeys/keyHandler/MacKeyHandler.cpp000066400000000000000000000020611457262621600250700ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MacKeyHandler.h" MacKeyHandler::~MacKeyHandler() { unregisterKey(); } bool MacKeyHandler::registerKey(const QKeySequence &keySequence) { return false; } bool MacKeyHandler::isKeyPressed(void *message) { return false; } void MacKeyHandler::unregisterKey() const { }ksnip-master/src/gui/globalHotKeys/keyHandler/MacKeyHandler.h000066400000000000000000000024071457262621600245410ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MACKEYHANDLER_H #define KSNIP_MACKEYHANDLER_H #include "IKeyHandler.h" #include "src/gui/globalHotKeys/KeySequenceToMacKeyCodeTranslator.h" class MacKeyHandler : public IKeyHandler { public: MacKeyHandler() = default; ~MacKeyHandler() override; bool registerKey(const QKeySequence &keySequence) override; bool isKeyPressed(void* message) override; private: KeySequenceToMacKeyCodeTranslator mKeyCodeMapper; void unregisterKey() const; }; #endif //KSNIP_MACKEYHANDLER_H ksnip-master/src/gui/globalHotKeys/keyHandler/WinKeyHandler.cpp000066400000000000000000000024621457262621600251320ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinKeyHandler.h" int WinKeyHandler::mNextId = 0; WinKeyHandler::~WinKeyHandler() { UnregisterHotKey(nullptr, mId); } bool WinKeyHandler::registerKey(const QKeySequence &keySequence) { mId = WinKeyHandler::mNextId++; auto keyCodeCombo = mKeyCodeMapper.map(keySequence); return RegisterHotKey(nullptr, mId, keyCodeCombo.modifier, keyCodeCombo.key); } bool WinKeyHandler::isKeyPressed(void* message) { auto msg = static_cast(message); return msg->message == WM_HOTKEY && msg->wParam == mId; } ksnip-master/src/gui/globalHotKeys/keyHandler/WinKeyHandler.h000066400000000000000000000024641457262621600246010ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINKEYHANDLER_H #define KSNIP_WINKEYHANDLER_H #include #include "IKeyHandler.h" #include "src/gui/globalHotKeys/KeySequenceToWinKeyCodeTranslator.h" class WinKeyHandler : public IKeyHandler { public: WinKeyHandler() = default; ~WinKeyHandler() override; bool registerKey(const QKeySequence &keySequence) override; bool isKeyPressed(void* message) override; private: int mId; static int mNextId; KeySequenceToWinKeyCodeTranslator mKeyCodeMapper; }; #endif //KSNIP_WINKEYHANDLER_H ksnip-master/src/gui/globalHotKeys/keyHandler/X11KeyHandler.cpp000066400000000000000000000053351457262621600247500ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * Inspired by Skycoder42`s QHotKey implementation https://github.com/Skycoder42/QHotkey/blob/master/QHotkey/qhotkey_x11.cpp */ #include "X11KeyHandler.h" #include "src/gui/globalHotKeys/X11ErrorLogger.h" X11KeyHandler::X11KeyHandler() : mFixedModifiers({ 0, Mod2Mask, LockMask, (Mod2Mask | LockMask)}) { } X11KeyHandler::~X11KeyHandler() { unregisterKey(); } bool X11KeyHandler::registerKey(const QKeySequence &keySequence) { auto display = QX11Info::display(); if(!display) { return false; } X11ErrorLogger x11ErrorLogger; mKeyCodeCombo = mKeyCodeMapper.map(keySequence); for(auto fixedModifier : mFixedModifiers) { GrabKey(display, fixedModifier); } XSync(display, False); return true; } bool X11KeyHandler::isKeyPressed(void *message) { auto genericEvent = static_cast(message); if (genericEvent->response_type == XCB_KEY_PRESS) { auto keyEvent = static_cast(message); for(auto fixedModifier : mFixedModifiers) { if(isMatching(keyEvent, fixedModifier)) { return true; } } } return false; } bool X11KeyHandler::isMatching(const xcb_key_press_event_t *keyEvent, unsigned int fixedModifier) const { return keyEvent->detail == mKeyCodeCombo.key && keyEvent->state == (mKeyCodeCombo.modifier | fixedModifier); } void X11KeyHandler::unregisterKey() const { auto display = QX11Info::display(); if(!display) { return; } X11ErrorLogger x11ErrorLogger; for(auto fixedModifier : mFixedModifiers) { UngrabKey(display, fixedModifier); } XSync(display, False); } void X11KeyHandler::GrabKey(Display *display, unsigned int fixedModifier) const { XGrabKey(display, mKeyCodeCombo.key, mKeyCodeCombo.modifier | fixedModifier, DefaultRootWindow(display), true, GrabModeAsync, GrabModeAsync); } void X11KeyHandler::UngrabKey(Display *display, unsigned int fixedModifier) const { XUngrabKey(display, mKeyCodeCombo.key, mKeyCodeCombo.modifier | fixedModifier, DefaultRootWindow(display)); } ksnip-master/src/gui/globalHotKeys/keyHandler/X11KeyHandler.h000066400000000000000000000032051457262621600244070ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_X11KEYHANDLER_H #define KSNIP_X11KEYHANDLER_H #include #include #include #include "src/gui/globalHotKeys/keyHandler/IKeyHandler.h" #include "src/gui/globalHotKeys/KeySequenceToX11KeyCodeTranslator.h" class X11KeyHandler : public IKeyHandler { public: X11KeyHandler(); ~X11KeyHandler() override; bool registerKey(const QKeySequence &keySequence) override; bool isKeyPressed(void* message) override; private: KeyCodeCombo mKeyCodeCombo; KeySequenceToX11KeyCodeTranslator mKeyCodeMapper; QVector mFixedModifiers; void unregisterKey() const; void GrabKey(Display *display, unsigned int fixedModifier) const; void UngrabKey(Display *display, unsigned int fixedModifier) const; bool isMatching(const xcb_key_press_event_t *keyEvent, unsigned int fixedModifier) const; }; #endif //KSNIP_X11KEYHANDLER_H ksnip-master/src/gui/imageAnnotator/000077500000000000000000000000001457262621600200315ustar00rootroot00000000000000ksnip-master/src/gui/imageAnnotator/IImageAnnotator.h000066400000000000000000000055441457262621600232330ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IIMAGEANNOTATOR_H #define KSNIP_IIMAGEANNOTATOR_H #include class QAction; class IImageAnnotator : public QObject { Q_OBJECT public: explicit IImageAnnotator() = default; ~IImageAnnotator() override = default; virtual QImage image() const = 0; virtual QImage imageAt(int index) const = 0; virtual QAction *undoAction() = 0; virtual QAction *redoAction() = 0; virtual QSize sizeHint() const = 0; virtual void showAnnotator() = 0; virtual void showCropper() = 0; virtual void showScaler() = 0; virtual void showCanvasModifier() = 0; virtual void showRotator() = 0; virtual void showCutter() = 0; virtual void setSettingsCollapsed(bool isCollapsed) = 0; virtual void hide() = 0; virtual void close() = 0; virtual bool isVisible() const = 0; virtual QWidget* widget() const = 0; public slots: virtual void loadImage(const QPixmap &pixmap) = 0; virtual int addTab(const QPixmap &pixmap, const QString &title, const QString &toolTip) = 0; virtual void updateTabInfo(int index, const QString &title, const QString &toolTip) = 0; virtual void insertImageItem(const QPointF &position, const QPixmap &pixmap) = 0; virtual void setSmoothPathEnabled(bool enabled) = 0; virtual void setSaveToolSelection(bool enabled) = 0; virtual void setSmoothFactor(int factor) = 0; virtual void setSwitchToSelectToolAfterDrawingItem(bool enabled) = 0; virtual void setSelectItemAfterDrawing(bool enabled) = 0; virtual void setNumberToolSeedChangeUpdatesAllItems(bool enabled) = 0; virtual void setTabBarAutoHide(bool enabled) = 0; virtual void removeTab(int index) = 0; virtual void setStickers(const QStringList &stickerPaths, bool keepDefault) = 0; virtual void addTabContextMenuActions(const QList & actions) = 0; virtual void setCanvasColor(const QColor &color) = 0; virtual void setControlsWidgetVisible(bool isVisible) = 0; signals: void imageChanged() const; void currentTabChanged(int index) const; void tabCloseRequested(int index) const; void tabMoved(int fromIndex, int toIndex); void tabContextMenuOpened(int index) const; }; #endif //KSNIP_IIMAGEANNOTATOR_H ksnip-master/src/gui/imageAnnotator/KImageAnnotatorAdapter.cpp000066400000000000000000000117231457262621600250650ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KImageAnnotatorAdapter.h" KImageAnnotatorAdapter::KImageAnnotatorAdapter() : mKImageAnnotator(new KImageAnnotator) { connect(mKImageAnnotator, &KImageAnnotator::imageChanged, this, &KImageAnnotatorAdapter::imageChanged); connect(mKImageAnnotator, &KImageAnnotator::currentTabChanged, this, &KImageAnnotatorAdapter::currentTabChanged); connect(mKImageAnnotator, &KImageAnnotator::tabCloseRequested, this, &KImageAnnotatorAdapter::tabCloseRequested); connect(mKImageAnnotator, &KImageAnnotator::tabMoved, this, &KImageAnnotatorAdapter::tabMoved); connect(mKImageAnnotator, &KImageAnnotator::tabContextMenuOpened, this, &KImageAnnotatorAdapter::tabContextMenuOpened); } KImageAnnotatorAdapter::~KImageAnnotatorAdapter() { delete mKImageAnnotator; } QImage KImageAnnotatorAdapter::image() const { return mKImageAnnotator->image(); } QImage KImageAnnotatorAdapter::imageAt(int index) const { return mKImageAnnotator->imageAt(index); } QAction *KImageAnnotatorAdapter::undoAction() { return mKImageAnnotator->undoAction(); } QAction *KImageAnnotatorAdapter::redoAction() { return mKImageAnnotator->redoAction(); } QSize KImageAnnotatorAdapter::sizeHint() const { return mKImageAnnotator->sizeHint(); } void KImageAnnotatorAdapter::showAnnotator() { mKImageAnnotator->showAnnotator(); } void KImageAnnotatorAdapter::showCropper() { mKImageAnnotator->showCropper(); } void KImageAnnotatorAdapter::showScaler() { mKImageAnnotator->showScaler(); } void KImageAnnotatorAdapter::setSettingsCollapsed(bool isCollapsed) { mKImageAnnotator->setSettingsCollapsed(isCollapsed); } void KImageAnnotatorAdapter::hide() { mKImageAnnotator->hide(); } void KImageAnnotatorAdapter::close() { mKImageAnnotator->close(); } bool KImageAnnotatorAdapter::isVisible() const { return mKImageAnnotator->isVisible(); } QWidget *KImageAnnotatorAdapter::widget() const { return mKImageAnnotator; } void KImageAnnotatorAdapter::loadImage(const QPixmap &pixmap) { mKImageAnnotator->loadImage(pixmap); } int KImageAnnotatorAdapter::addTab(const QPixmap &pixmap, const QString &title, const QString &toolTip) { return mKImageAnnotator->addTab(pixmap, title, toolTip); } void KImageAnnotatorAdapter::updateTabInfo(int index, const QString &title, const QString &toolTip) { mKImageAnnotator->updateTabInfo(index, title, toolTip); } void KImageAnnotatorAdapter::insertImageItem(const QPointF &position, const QPixmap &pixmap) { mKImageAnnotator->insertImageItem(position, pixmap); } void KImageAnnotatorAdapter::setSmoothPathEnabled(bool enabled) { mKImageAnnotator->setSmoothPathEnabled(enabled); } void KImageAnnotatorAdapter::setSaveToolSelection(bool enabled) { mKImageAnnotator->setSaveToolSelection(enabled); } void KImageAnnotatorAdapter::setSmoothFactor(int factor) { mKImageAnnotator->setSmoothFactor(factor); } void KImageAnnotatorAdapter::setSwitchToSelectToolAfterDrawingItem(bool enabled) { mKImageAnnotator->setSwitchToSelectToolAfterDrawingItem(enabled); } void KImageAnnotatorAdapter::setSelectItemAfterDrawing(bool enabled) { mKImageAnnotator->setSelectItemAfterDrawing(enabled); } void KImageAnnotatorAdapter::setNumberToolSeedChangeUpdatesAllItems(bool enabled) { mKImageAnnotator->setNumberToolSeedChangeUpdatesAllItems(enabled); } void KImageAnnotatorAdapter::setTabBarAutoHide(bool enabled) { mKImageAnnotator->setTabBarAutoHide(enabled); } void KImageAnnotatorAdapter::removeTab(int index) { mKImageAnnotator->removeTab(index); } void KImageAnnotatorAdapter::setStickers(const QStringList &stickerPaths, bool keepDefault) { mKImageAnnotator->setStickers(stickerPaths, keepDefault); } void KImageAnnotatorAdapter::addTabContextMenuActions(const QList &actions) { mKImageAnnotator->addTabContextMenuActions(actions); } void KImageAnnotatorAdapter::showCanvasModifier() { mKImageAnnotator->showCanvasModifier(); } void KImageAnnotatorAdapter::showRotator() { mKImageAnnotator->showRotator(); } void KImageAnnotatorAdapter::showCutter() { mKImageAnnotator->showCutter(); } void KImageAnnotatorAdapter::setCanvasColor(const QColor &color) { mKImageAnnotator->setCanvasColor(color); } void KImageAnnotatorAdapter::setControlsWidgetVisible(bool isVisible) { mKImageAnnotator->setControlsWidgetVisible(isVisible); } ksnip-master/src/gui/imageAnnotator/KImageAnnotatorAdapter.h000066400000000000000000000053161457262621600245330ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KIMAGEANNOTATORADAPTER_H #define KSNIP_KIMAGEANNOTATORADAPTER_H #include #include "IImageAnnotator.h" using kImageAnnotator::KImageAnnotator; class KImageAnnotatorAdapter : public IImageAnnotator { Q_OBJECT public: explicit KImageAnnotatorAdapter(); ~KImageAnnotatorAdapter() override; QImage image() const override; QImage imageAt(int index) const override; QAction *undoAction() override; QAction *redoAction() override; QSize sizeHint() const override; void showAnnotator() override; void showCropper() override; void showScaler() override; void showCanvasModifier() override; void showRotator() override; void showCutter() override; void setSettingsCollapsed(bool isCollapsed) override; void hide() override; void close() override; bool isVisible() const override; QWidget* widget() const override; public slots: void loadImage(const QPixmap &pixmap) override; int addTab(const QPixmap &pixmap, const QString &title, const QString &toolTip) override; void updateTabInfo(int index, const QString &title, const QString &toolTip) override; void insertImageItem(const QPointF &position, const QPixmap &pixmap) override; void setSmoothPathEnabled(bool enabled) override; void setSaveToolSelection(bool enabled) override; void setSmoothFactor(int factor) override; void setSwitchToSelectToolAfterDrawingItem(bool enabled) override; void setSelectItemAfterDrawing(bool enabled) override; void setNumberToolSeedChangeUpdatesAllItems(bool enabled) override; void setTabBarAutoHide(bool enabled) override; void removeTab(int index) override; void setStickers(const QStringList &stickerPaths, bool keepDefault) override; void addTabContextMenuActions(const QList & actions) override; void setCanvasColor(const QColor &color) override; void setControlsWidgetVisible(bool isVisible) override; private: KImageAnnotator *mKImageAnnotator; }; #endif //KSNIP_KIMAGEANNOTATORADAPTER_H ksnip-master/src/gui/messageBoxService/000077500000000000000000000000001457262621600204775ustar00rootroot00000000000000ksnip-master/src/gui/messageBoxService/IMessageBoxService.h000066400000000000000000000025531457262621600243440ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMESSAGEBOXSERVICE_H #define KSNIP_IMESSAGEBOXSERVICE_H #include "src/common/enum/MessageBoxResponse.h" class QString; class IMessageBoxService { public: explicit IMessageBoxService() = default; virtual ~IMessageBoxService() = default; virtual bool yesNo(const QString &title, const QString &question) = 0; virtual MessageBoxResponse yesNoCancel(const QString &title, const QString &question) = 0; virtual void ok(const QString &title, const QString &info) = 0; virtual bool okCancel(const QString &title, const QString &info) = 0; }; #endif //KSNIP_IMESSAGEBOXSERVICE_H ksnip-master/src/gui/messageBoxService/MessageBoxService.cpp000066400000000000000000000037121457262621600245640ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MessageBoxService.h" bool MessageBoxService::yesNo(const QString &title, const QString &question) { auto reply = QMessageBox::question(nullptr, title, question, QMessageBox::Yes | QMessageBox::No); return reply == QMessageBox::Yes; } MessageBoxResponse MessageBoxService::yesNoCancel(const QString &title, const QString &question) { auto reply = QMessageBox::question(nullptr, title, question, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); return mapReplyToMessageBoxResponse(reply); } void MessageBoxService::ok(const QString &title, const QString &info) { QMessageBox::question(nullptr, title, info, QMessageBox::Ok); } bool MessageBoxService::okCancel(const QString &title, const QString &info) { auto reply = QMessageBox::question(nullptr, title, info, QMessageBox::Ok | QMessageBox::Cancel); return reply == QMessageBox::Ok; } MessageBoxResponse MessageBoxService::mapReplyToMessageBoxResponse(int reply) { switch (reply) { case QMessageBox::Yes: return MessageBoxResponse::Yes; case QMessageBox::No: return MessageBoxResponse::No; case QMessageBox::Cancel: return MessageBoxResponse::Cancel; default: return MessageBoxResponse::No; } } ksnip-master/src/gui/messageBoxService/MessageBoxService.h000066400000000000000000000027621457262621600242350ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MESSAGEBOXSERVICE_H #define KSNIP_MESSAGEBOXSERVICE_H #include #include "IMessageBoxService.h" #include "src/common/enum/MessageBoxResponse.h" class MessageBoxService : public IMessageBoxService { public: explicit MessageBoxService() = default; ~MessageBoxService() override = default; bool yesNo(const QString &title, const QString &question) override; MessageBoxResponse yesNoCancel(const QString &title, const QString &question) override; void ok(const QString &title, const QString &info) override; bool okCancel(const QString &title, const QString &info) override; private: static MessageBoxResponse mapReplyToMessageBoxResponse(int reply); }; #endif //KSNIP_MESSAGEBOXSERVICE_H ksnip-master/src/gui/modelessWindows/000077500000000000000000000000001457262621600202475ustar00rootroot00000000000000ksnip-master/src/gui/modelessWindows/IModelessWindow.h000066400000000000000000000021571457262621600235010ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMODELESSWINDOW_H #define KSNIP_IMODELESSWINDOW_H #include class IModelessWindow : public QDialog { Q_OBJECT public: explicit IModelessWindow() = default; ~IModelessWindow() override = default; signals: void closeRequest(); void closeOtherRequest(); void closeAllRequest(); }; #endif //KSNIP_IMODELESSWINDOW_H ksnip-master/src/gui/modelessWindows/IModelessWindowCreator.h000066400000000000000000000022141457262621600250130ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMODELESSWINDOWCREATOR_H #define KSNIP_IMODELESSWINDOWCREATOR_H #include "IModelessWindow.h" class IModelessWindowCreator { public: explicit IModelessWindowCreator() = default; ~IModelessWindowCreator() = default; virtual QSharedPointer create(const QPixmap &pixmap, int windowId) const = 0; }; #endif //KSNIP_IMODELESSWINDOWCREATOR_H ksnip-master/src/gui/modelessWindows/ModelessWindowHandler.cpp000066400000000000000000000050641457262621600252210ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ModelessWindowHandler.h" ModelessWindowHandler::ModelessWindowHandler(const QSharedPointer &windowCreator) : QObject(nullptr), mWindowCreator(windowCreator) { } ModelessWindowHandler::~ModelessWindowHandler() { mModelessWindows.clear(); } void ModelessWindowHandler::add(const QPixmap &pixmap) { auto modelessWindow = CreateModelessWindow(pixmap); modelessWindow->show(); mModelessWindows.append(modelessWindow); } QSharedPointer ModelessWindowHandler::CreateModelessWindow(const QPixmap &pixmap) const { auto windowId = mModelessWindows.count() + 1; auto modelessWindow = mWindowCreator->create(pixmap, windowId); connect(modelessWindow.data(), &IModelessWindow::closeRequest, this, &ModelessWindowHandler::closeRequested); connect(modelessWindow.data(), &IModelessWindow::closeOtherRequest, this, &ModelessWindowHandler::closeOtherRequested); connect(modelessWindow.data(), &IModelessWindow::closeAllRequest, this, &ModelessWindowHandler::closeAllRequested); return modelessWindow; } void ModelessWindowHandler::closeRequested() { auto caller = dynamic_cast(sender()); caller->hide(); for(const auto& modelessWindow : mModelessWindows){ if (modelessWindow.data() == caller) { mModelessWindows.removeOne(modelessWindow); break; } } } void ModelessWindowHandler::closeAllRequested() { for(const auto& modelessWindow : mModelessWindows){ modelessWindow->hide(); } mModelessWindows.clear(); } void ModelessWindowHandler::closeOtherRequested() { auto caller = dynamic_cast(sender()); for (auto iterator = mModelessWindows.begin(); iterator != mModelessWindows.end(); ++iterator) { if(iterator->data() != caller) { iterator->data()->hide(); mModelessWindows.removeOne(*iterator); } } }ksnip-master/src/gui/modelessWindows/ModelessWindowHandler.h000066400000000000000000000027461457262621600246720ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MODELESSWINDOWHANDLER_H #define KSNIP_MODELESSWINDOWHANDLER_H #include #include "IModelessWindowCreator.h" class ModelessWindowHandler : public QObject { Q_OBJECT public: explicit ModelessWindowHandler(const QSharedPointer &windowCreator); ~ModelessWindowHandler() override; virtual void add(const QPixmap &pixmap); public slots: void closeRequested(); void closeAllRequested(); void closeOtherRequested(); private: QSharedPointer mWindowCreator; QList> mModelessWindows; QSharedPointer CreateModelessWindow(const QPixmap &pixmap) const; }; #endif //KSNIP_MODELESSWINDOWHANDLER_H ksnip-master/src/gui/modelessWindows/ocrWindow/000077500000000000000000000000001457262621600222225ustar00rootroot00000000000000ksnip-master/src/gui/modelessWindows/ocrWindow/IOcrWindowCreator.h000066400000000000000000000021151457262621600257360ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IOCRWINDOWCREATOR_H #define KSNIP_IOCRWINDOWCREATOR_H #include "src/gui/modelessWindows/IModelessWindowCreator.h" class IOcrWindowCreator : public IModelessWindowCreator { public: explicit IOcrWindowCreator() = default; ~IOcrWindowCreator() = default; }; #endif //KSNIP_IOCRWINDOWCREATOR_H ksnip-master/src/gui/modelessWindows/ocrWindow/IOcrWindowHandler.h000066400000000000000000000020561457262621600257200ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IOCRWINDOWHANDLER_H #define KSNIP_IOCRWINDOWHANDLER_H class QPixmap; class IOcrWindowHandler { public: explicit IOcrWindowHandler() = default; ~IOcrWindowHandler() = default; virtual void add(const QPixmap &pixmap) = 0; }; #endif //KSNIP_IOCRWINDOWHANDLER_H ksnip-master/src/gui/modelessWindows/ocrWindow/OcrWindow.cpp000066400000000000000000000043541457262621600246470ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "OcrWindow.h" OcrWindow::OcrWindow(const QPixmap &pixmap, const QString &title, const QSharedPointer &pluginManager) : mTextEdit(new QTextEdit(this)), mProcessIndicator(new ProcessIndicator(this)), mLayout(new QGridLayout(this)) { setWindowTitle(title); setGeometry(geometry().x(), geometry().y(), pixmap.size().width(), pixmap.size().height()); mLayout->addWidget(mTextEdit, 0, 0); mLayout->addWidget(mProcessIndicator, 0, 0, Qt::AlignCenter); setProcessingVisible(true); auto ocrProcessingFuture = QtConcurrent::run(this, &OcrWindow::process, pixmap, pluginManager); connect(&mOcrProcessFutureWatcher, &QFutureWatcher::finished, this, &OcrWindow::processingFinished); mOcrProcessFutureWatcher.setFuture(ocrProcessingFuture); } void OcrWindow::closeEvent(QCloseEvent *event) { emit closeRequest(); QDialog::closeEvent(event); } QString OcrWindow::process(const QPixmap &pixmap, const QSharedPointer &pluginManager) { auto ocrPlugin = pluginManager->get(PluginType::Ocr).objectCast(); return ocrPlugin->recognize(pixmap); } void OcrWindow::setProcessingVisible(bool isVisible) { if(isVisible) { mProcessIndicator->start(); } else { mProcessIndicator->stop(); } mTextEdit->setVisible(!isVisible); mProcessIndicator->setVisible(isVisible); } void OcrWindow::processingFinished() { setProcessingVisible(false); auto text = mOcrProcessFutureWatcher.future().result(); mTextEdit->setText(text); } ksnip-master/src/gui/modelessWindows/ocrWindow/OcrWindow.h000066400000000000000000000033141457262621600243070ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_OCRWINDOW_H #define KSNIP_OCRWINDOW_H #include #include #include #include "src/gui/modelessWindows/IModelessWindow.h" #include "src/widgets/ProcessIndicator.h" #include "src/plugins/IPluginManager.h" #include "src/plugins/interfaces/IPluginOcr.h" class OcrWindow : public IModelessWindow { public: explicit OcrWindow(const QPixmap &pixmap, const QString &title, const QSharedPointer &pluginManager); ~OcrWindow() override = default; protected: void closeEvent(QCloseEvent *event) override; private: QTextEdit *mTextEdit; ProcessIndicator *mProcessIndicator; QGridLayout *mLayout; QFutureWatcher mOcrProcessFutureWatcher; virtual QString process(const QPixmap &pixmap, const QSharedPointer &pluginManager); void setProcessingVisible(bool isVisible); private slots: void processingFinished(); }; #endif //KSNIP_OCRWINDOW_H ksnip-master/src/gui/modelessWindows/ocrWindow/OcrWindowCreator.cpp000066400000000000000000000026601457262621600261650ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "OcrWindowCreator.h" OcrWindowCreator::OcrWindowCreator(const QSharedPointer &pluginManager) : mPluginManager(pluginManager) { } QSharedPointer OcrWindowCreator::create(const QPixmap &pixmap, int windowId) const { auto title = tr("OCR Window %1").arg(windowId); return QSharedPointer(createWindow(pixmap, title), &QObject::deleteLater); } OcrWindow *OcrWindowCreator::createWindow(const QPixmap &pixmap, const QString &title) const { return new OcrWindow(pixmap, title, getPluginManager()); } const QSharedPointer &OcrWindowCreator::getPluginManager() const { return mPluginManager; } ksnip-master/src/gui/modelessWindows/ocrWindow/OcrWindowCreator.h000066400000000000000000000027371457262621600256370ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_OCRWINDOWCREATOR_H #define KSNIP_OCRWINDOWCREATOR_H #include "OcrWindow.h" #include "IOcrWindowCreator.h" #include "src/plugins/IPluginManager.h" class OcrWindowCreator : public IOcrWindowCreator, public QObject { public: explicit OcrWindowCreator(const QSharedPointer &pluginManager); ~OcrWindowCreator() override = default; QSharedPointer create(const QPixmap &pixmap, int windowId) const override; protected: virtual OcrWindow *createWindow(const QPixmap &pixmap, const QString &title) const; const QSharedPointer &getPluginManager() const; private: QSharedPointer mPluginManager; }; #endif //KSNIP_OCRWINDOWCREATOR_H ksnip-master/src/gui/modelessWindows/ocrWindow/OcrWindowHandler.cpp000066400000000000000000000020401457262621600261330ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "OcrWindowHandler.h" OcrWindowHandler::OcrWindowHandler(const QSharedPointer &windowCreator) : ModelessWindowHandler(windowCreator) { } void OcrWindowHandler::add(const QPixmap &pixmap) { ModelessWindowHandler::add(pixmap); } ksnip-master/src/gui/modelessWindows/ocrWindow/OcrWindowHandler.h000066400000000000000000000023431457262621600256060ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_OCRWINDOWHANDLER_H #define KSNIP_OCRWINDOWHANDLER_H #include "IOcrWindowHandler.h" #include "src/gui/modelessWindows/ModelessWindowHandler.h" class OcrWindowHandler : public IOcrWindowHandler, public ModelessWindowHandler { public: explicit OcrWindowHandler(const QSharedPointer &windowCreator); ~OcrWindowHandler() override = default; void add(const QPixmap &pixmap) override; }; #endif //KSNIP_OCRWINDOWHANDLER_H ksnip-master/src/gui/modelessWindows/ocrWindow/WinOcrWindow.cpp000066400000000000000000000025101457262621600253150ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinOcrWindow.h" WinOcrWindow::WinOcrWindow(const QPixmap &pixmap, const QString &title, const QSharedPointer &pluginManager) : OcrWindow(pixmap, title, pluginManager) { } QString WinOcrWindow::process(const QPixmap &pixmap, const QSharedPointer &pluginManager) { auto ocrPlugin = pluginManager->get(PluginType::Ocr).objectCast(); auto path = pluginManager->getPath(PluginType::Ocr); auto parentDir = QFileInfo(path).path(); return ocrPlugin->recognize(pixmap, parentDir.append("\\tessdata\\")); } ksnip-master/src/gui/modelessWindows/ocrWindow/WinOcrWindow.h000066400000000000000000000023151457262621600247650ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINOCRWINDOW_H #define KSNIP_WINOCRWINDOW_H #include "OcrWindow.h" class WinOcrWindow : public OcrWindow { public: explicit WinOcrWindow(const QPixmap &pixmap, const QString &title, const QSharedPointer &pluginManager); ~WinOcrWindow() override = default; private: QString process(const QPixmap &pixmap, const QSharedPointer &pluginManager) override; }; #endif //KSNIP_WINOCRWINDOW_H ksnip-master/src/gui/modelessWindows/ocrWindow/WinOcrWindowCreator.cpp000066400000000000000000000021421457262621600266360ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinOcrWindowCreator.h" WinOcrWindowCreator::WinOcrWindowCreator(const QSharedPointer &pluginManager) : OcrWindowCreator(pluginManager) { } OcrWindow *WinOcrWindowCreator::createWindow(const QPixmap &pixmap, const QString &title) const { return new WinOcrWindow(pixmap, title, getPluginManager()); } ksnip-master/src/gui/modelessWindows/ocrWindow/WinOcrWindowCreator.h000066400000000000000000000023421457262621600263050ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINOCRWINDOWCREATOR_H #define KSNIP_WINOCRWINDOWCREATOR_H #include "OcrWindowCreator.h" #include "WinOcrWindow.h" class WinOcrWindowCreator : public OcrWindowCreator { public: explicit WinOcrWindowCreator(const QSharedPointer &pluginManager); ~WinOcrWindowCreator() override = default; protected: virtual OcrWindow *createWindow(const QPixmap &pixmap, const QString &title) const; }; #endif //KSNIP_WINOCRWINDOWCREATOR_H ksnip-master/src/gui/modelessWindows/pinWindow/000077500000000000000000000000001457262621600222255ustar00rootroot00000000000000ksnip-master/src/gui/modelessWindows/pinWindow/IPinWindowCreator.h000066400000000000000000000021151457262621600257440ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPINWINDOWCREATOR_H #define KSNIP_IPINWINDOWCREATOR_H #include "src/gui/modelessWindows/IModelessWindowCreator.h" class IPinWindowCreator : public IModelessWindowCreator { public: explicit IPinWindowCreator() = default; ~IPinWindowCreator() = default; }; #endif //KSNIP_IPINWINDOWCREATOR_H ksnip-master/src/gui/modelessWindows/pinWindow/IPinWindowHandler.h000066400000000000000000000020561457262621600257260ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPINWINDOWHANDLER_H #define KSNIP_IPINWINDOWHANDLER_H class QPixmap; class IPinWindowHandler { public: explicit IPinWindowHandler() = default; ~IPinWindowHandler() = default; virtual void add(const QPixmap &pixmap) = 0; }; #endif //KSNIP_IPINWINDOWHANDLER_H ksnip-master/src/gui/modelessWindows/pinWindow/PinWindow.cpp000066400000000000000000000067631457262621600246630ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PinWindow.h" PinWindow::PinWindow(const QPixmap &pixmap, const QString &title) : mLayout(new QVBoxLayout(this)), mCentralWidget(new QLabel(this)), mDropShadowEffect(new QGraphicsDropShadowEffect(this)), mMargin(10), mMinSize(50), mImage(pixmap), mIsMoving(false) { setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::CoverWindow); setAttribute(Qt::WA_TranslucentBackground); setModal(false); setWindowTitle(title); setAttribute(Qt::WA_DeleteOnClose); setMouseTracking(true); setCursor(Qt::SizeAllCursor); mCentralWidget->setPixmap(mImage); mLayout->addWidget(mCentralWidget); setContentsMargins(mMargin, mMargin, mMargin, mMargin); addDropShadow(); } PinWindow::~PinWindow() { delete mLayout; delete mCentralWidget; delete mDropShadowEffect; } void PinWindow::addDropShadow() { mDropShadowEffect->setColor(QColor(160, 160, 160)); mDropShadowEffect->setBlurRadius(mMargin * 2); mDropShadowEffect->setOffset(0); setGraphicsEffect(mDropShadowEffect); } void PinWindow::mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event) emit close(); } void PinWindow::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { mIsMoving = true; mMoveOffset = event->globalPos() - pos(); } QWidget::mousePressEvent(event); } void PinWindow::mouseReleaseEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { mIsMoving = false; mMoveOffset = {}; } QWidget::mouseReleaseEvent(event); } void PinWindow::mouseMoveEvent(QMouseEvent *event) { if(mIsMoving) { move(event->globalPos() - mMoveOffset); } QWidget::mouseMoveEvent(event); } void PinWindow::keyPressEvent(QKeyEvent *event) { if(event->key() == Qt::Key_Escape) { emit close(); } } void PinWindow::contextMenuEvent(QContextMenuEvent *event) { QMenu menu; menu.addAction(tr("Close"), this, &PinWindow::closeRequest); menu.addAction(tr("Close Other"), this, &PinWindow::closeOtherRequest); menu.addAction(tr("Close All"), this, &PinWindow::closeAllRequest); menu.exec(event->globalPos()); } void PinWindow::enterEvent(QEvent *event) { mDropShadowEffect->setBlurRadius(mDropShadowEffect->blurRadius() + 4); QWidget::enterEvent(event); } void PinWindow::leaveEvent(QEvent *event) { mDropShadowEffect->setBlurRadius(mDropShadowEffect->blurRadius() - 4); QWidget::leaveEvent(event); } void PinWindow::wheelEvent(QWheelEvent *event) { auto delta = event->delta() / 10; auto scaledSize = QSize(mCentralWidget->width() + delta, mCentralWidget->height() + delta); if(scaledSize.width() > mMinSize && scaledSize.height() > mMinSize) { auto scaledImage = mImage.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); mCentralWidget->setPixmap(scaledImage); adjustSize(); } } ksnip-master/src/gui/modelessWindows/pinWindow/PinWindow.h000066400000000000000000000036441457262621600243230ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PINWINDOW_H #define KSNIP_PINWINDOW_H #include #include #include #include #include #include #include #include #include #include "src/gui/modelessWindows/IModelessWindow.h" class PinWindow : public IModelessWindow { public: explicit PinWindow(const QPixmap &pixmap, const QString &title); ~PinWindow() override; protected: void mouseDoubleClickEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void contextMenuEvent(QContextMenuEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void enterEvent(QEvent *event) override; void leaveEvent(QEvent *event) override; void wheelEvent(QWheelEvent *event) override; private: QLabel *mCentralWidget; QVBoxLayout *mLayout; QGraphicsDropShadowEffect *mDropShadowEffect; int mMargin; int mMinSize; QPixmap mImage; QPoint mMoveOffset; bool mIsMoving{}; void addDropShadow(); }; #endif //KSNIP_PINWINDOW_H ksnip-master/src/gui/modelessWindows/pinWindow/PinWindowCreator.cpp000066400000000000000000000020501457262621600261640ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PinWindowCreator.h" QSharedPointer PinWindowCreator::create(const QPixmap &pixmap, int windowId) const { auto title = tr("OCR Window %1").arg(windowId); return QSharedPointer(new PinWindow(pixmap, title), &QObject::deleteLater); } ksnip-master/src/gui/modelessWindows/pinWindow/PinWindowCreator.h000066400000000000000000000022621457262621600256360ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PINWINDOWCREATOR_H #define KSNIP_PINWINDOWCREATOR_H #include "PinWindow.h" #include "IPinWindowCreator.h" class PinWindowCreator : public IPinWindowCreator, public QObject { public: explicit PinWindowCreator() = default; ~PinWindowCreator() override = default; QSharedPointer create(const QPixmap &pixmap, int windowId) const override; }; #endif //KSNIP_PINWINDOWCREATOR_H ksnip-master/src/gui/modelessWindows/pinWindow/PinWindowHandler.cpp000066400000000000000000000020371457262621600261470ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PinWindowHandler.h" PinWindowHandler::PinWindowHandler(const QSharedPointer &windowCreator) : ModelessWindowHandler(windowCreator) { } void PinWindowHandler::add(const QPixmap &pixmap) { ModelessWindowHandler::add(pixmap); } ksnip-master/src/gui/modelessWindows/pinWindow/PinWindowHandler.h000066400000000000000000000023431457262621600256140ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PINWINDOWHANDLER_H #define KSNIP_PINWINDOWHANDLER_H #include "IPinWindowHandler.h" #include "src/gui/modelessWindows/ModelessWindowHandler.h" class PinWindowHandler : public IPinWindowHandler, public ModelessWindowHandler { public: explicit PinWindowHandler(const QSharedPointer &windowCreator); ~PinWindowHandler() override = default; void add(const QPixmap &pixmap) override; }; #endif //KSNIP_PINWINDOWHANDLER_H ksnip-master/src/gui/notificationService/000077500000000000000000000000001457262621600210705ustar00rootroot00000000000000ksnip-master/src/gui/notificationService/FreeDesktopNotificationService.cpp000066400000000000000000000053011457262621600276760ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include "FreeDesktopNotificationService.h" #include "src/common/helper/FileUrlHelper.h" FreeDesktopNotificationService::FreeDesktopNotificationService() : mNotificationTimeout(7000) { mDBusInterface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), QStringLiteral("org.freedesktop.Notifications"), QDBusConnection::sessionBus() ); } void FreeDesktopNotificationService::showInfo(const QString &title, const QString &message, const QString &contentUrl) { showToast(title, message, contentUrl, QStringLiteral("dialog-information")); } void FreeDesktopNotificationService::showWarning(const QString &title, const QString &message, const QString &contentUrl) { showToast(title, message, contentUrl, QStringLiteral("dialog-warning")); } void FreeDesktopNotificationService::showCritical(const QString &title, const QString &message, const QString &contentUrl) { showToast(title, message, contentUrl, QStringLiteral("dialog-error")); } void FreeDesktopNotificationService::showToast(const QString &title, const QString &message, const QString &contentUrl, const QString &appIcon) { QList args; args << qAppName() // app_name << static_cast(0) // replaces_id (0 = does not replace existing notification) << appIcon // app_icon << title // summary << message // body << QStringList() // actions << getHintsMap(contentUrl) // hints << mNotificationTimeout; // expire_timeout mDBusInterface->callWithArgumentList(QDBus::NoBlock, QStringLiteral("Notify"), args); } QVariantMap FreeDesktopNotificationService::getHintsMap(const QString &contentUrl) { QVariantMap hintsMap; if (!contentUrl.isEmpty()) { hintsMap[QLatin1String("image-path")] = FileUrlHelper::toFileUrl(contentUrl); } return hintsMap; } ksnip-master/src/gui/notificationService/FreeDesktopNotificationService.h000066400000000000000000000035611457262621600273510ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FREEDESKTOPNOTIFICATIONSERVICE_H #define KSNIP_FREEDESKTOPNOTIFICATIONSERVICE_H #include #include #include #include #include #include "src/gui/INotificationService.h" #include "src/common/platform/PlatformChecker.h" class FreeDesktopNotificationService : public QObject, public INotificationService { Q_OBJECT public: FreeDesktopNotificationService(); ~FreeDesktopNotificationService() override = default; void showInfo(const QString &title, const QString &message, const QString &contentUrl) override; void showWarning(const QString &title, const QString &message, const QString &contentUrl) override; void showCritical(const QString &title, const QString &message, const QString &contentUrl) override; protected: void showToast(const QString &title, const QString &message, const QString &contentUrl, const QString &appIcon); virtual QVariantMap getHintsMap(const QString &contentUrl); private: QDBusInterface *mDBusInterface; const int mNotificationTimeout; }; #endif //KSNIP_FREEDESKTOPNOTIFICATIONSERVICE_H ksnip-master/src/gui/notificationService/KdeDesktopNotificationService.cpp000066400000000000000000000020501457262621600275160ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KdeDesktopNotificationService.h" QVariantMap KdeDesktopNotificationService::getHintsMap(const QString &contentUrl) { QVariantMap hintsMap; if (!contentUrl.isEmpty()) { hintsMap[QLatin1String("x-kde-urls")] = QStringList(contentUrl); } return hintsMap; } ksnip-master/src/gui/notificationService/KdeDesktopNotificationService.h000066400000000000000000000023271457262621600271720ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KDEDESKTOPNOTIFICATIONSERVICE_H #define KSNIP_KDEDESKTOPNOTIFICATIONSERVICE_H #include "FreeDesktopNotificationService.h" class KdeDesktopNotificationService : public FreeDesktopNotificationService { public: KdeDesktopNotificationService() = default; ~KdeDesktopNotificationService() override = default; protected: QVariantMap getHintsMap(const QString &contentUrl) override; }; #endif //KSNIP_KDEDESKTOPNOTIFICATIONSERVICE_H ksnip-master/src/gui/notificationService/NotificationServiceFactory.cpp000066400000000000000000000031651457262621600271000ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "NotificationServiceFactory.h" #if defined(UNIX_X11) #include "FreeDesktopNotificationService.h" #include "KdeDesktopNotificationService.h" #endif QSharedPointer NotificationServiceFactory::create( INotificationService *defaultNotificationService, const QSharedPointer &platformChecker, const QSharedPointer &config) { #if defined(UNIX_X11) if (config->platformSpecificNotificationServiceEnabled()) { if(platformChecker->isKde()) { return QSharedPointer(new KdeDesktopNotificationService()); } else { return QSharedPointer(new FreeDesktopNotificationService()); } } else { return QSharedPointer(defaultNotificationService); } #else return QSharedPointer(defaultNotificationService); #endif } ksnip-master/src/gui/notificationService/NotificationServiceFactory.h000066400000000000000000000026301457262621600265410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NOTIFICATIONSERVICEFACTORY_H #define KSNIP_NOTIFICATIONSERVICEFACTORY_H #include #include "src/gui/INotificationService.h" #include "src/backend/config/IConfig.h" #include "src/common/platform/IPlatformChecker.h" class NotificationServiceFactory { public: explicit NotificationServiceFactory() = default; ~NotificationServiceFactory() = default; static QSharedPointer create( INotificationService *defaultNotificationService, const QSharedPointer &platformChecker, const QSharedPointer &config); }; #endif //KSNIP_NOTIFICATIONSERVICEFACTORY_H ksnip-master/src/gui/operations/000077500000000000000000000000001457262621600172445ustar00rootroot00000000000000ksnip-master/src/gui/operations/AddWatermarkOperation.cpp000066400000000000000000000043361457262621600242050ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AddWatermarkOperation.h" AddWatermarkOperation::AddWatermarkOperation(IImageAnnotator *imageAnnotator, const QSharedPointer &config) : mImageAnnotator(imageAnnotator), mConfig(config), mMessageBoxService(new MessageBoxService) { } AddWatermarkOperation::~AddWatermarkOperation() { delete mMessageBoxService; } void AddWatermarkOperation::execute() { auto watermarkImage = mWatermarkImageLoader.load(); if(watermarkImage.isNull()) { NotifyAboutMissingWatermarkImage(); return; } auto availableSpace = mImageAnnotator->image().size(); auto rotated = mConfig->rotateWatermarkEnabled(); auto finishedWatermarkImage = mImagePreparer.prepare(watermarkImage, availableSpace, rotated); auto position = getPositionForWatermark(finishedWatermarkImage, availableSpace); mImageAnnotator->insertImageItem(position, finishedWatermarkImage); } void AddWatermarkOperation::NotifyAboutMissingWatermarkImage() const { mMessageBoxService->ok(tr("Watermark Image Required"), tr("Please add a Watermark Image via Options > Settings > Annotator > Update")); } QPointF AddWatermarkOperation::getPositionForWatermark(const QPixmap &image, const QSize &availableSpace) { auto availableWidth = availableSpace.width() - image.rect().width(); auto availableHeight = availableSpace.height() - image.rect().height(); qreal x = availableWidth <= 0 ? 0 : rand() % availableWidth; qreal y = availableHeight <= 0 ? 0 : rand() % availableHeight; return {x, y}; } ksnip-master/src/gui/operations/AddWatermarkOperation.h000066400000000000000000000033421457262621600236460ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ADDWATERMARKOPERATION_H #define KSNIP_ADDWATERMARKOPERATION_H #include #include #include "WatermarkImagePreparer.h" #include "src/gui/messageBoxService/MessageBoxService.h" #include "src/backend/WatermarkImageLoader.h" #include "src/backend/config/IConfig.h" #include "src/gui/imageAnnotator/IImageAnnotator.h" class AddWatermarkOperation : public QObject { Q_OBJECT public: explicit AddWatermarkOperation(IImageAnnotator *imageAnnotator, const QSharedPointer &config); ~AddWatermarkOperation() override; void execute(); private: IImageAnnotator *mImageAnnotator; WatermarkImagePreparer mImagePreparer; WatermarkImageLoader mWatermarkImageLoader; QSharedPointer mConfig; IMessageBoxService *mMessageBoxService; static QPointF getPositionForWatermark(const QPixmap &image, const QSize &availableSpace) ; void NotifyAboutMissingWatermarkImage() const; }; #endif //KSNIP_ADDWATERMARKOPERATION_H ksnip-master/src/gui/operations/CanDiscardOperation.cpp000066400000000000000000000053331457262621600236300ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CanDiscardOperation.h" CanDiscardOperation::CanDiscardOperation( QImage image, bool isUnsaved, QString pathToImageSource, QString filename, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &messageBoxService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent) : mParent(parent), mImage(std::move(image)), mIsUnsaved(isUnsaved), mPathToImageSource(std::move(pathToImageSource)), mFilename(std::move(filename)), mConfig(config), mNotificationService(notificationService), mMessageBoxService(messageBoxService), mRecentImageService(recentImageService), mImageSaver(imageSaver), mSavePathProvider(savePathProvider), mFileDialogService(fileDialogService) { } bool CanDiscardOperation::execute() { if (mConfig->promptSaveBeforeExit() && mIsUnsaved) { auto saveBeforeDiscardResponse = getSaveBeforeDiscard(); if (saveBeforeDiscardResponse == MessageBoxResponse::Yes) { return saveImage(); } else if (saveBeforeDiscardResponse == MessageBoxResponse::Cancel) { return false; } } return true; } bool CanDiscardOperation::saveImage() const { SaveOperation operation( mImage, true, mPathToImageSource, mNotificationService, mRecentImageService, mImageSaver, mSavePathProvider, mFileDialogService, mConfig, mParent); return operation.execute().isSuccessful; } MessageBoxResponse CanDiscardOperation::getSaveBeforeDiscard() const { auto quote = mFilename.isEmpty() ? QString() : QLatin1String("\""); return mMessageBoxService->yesNoCancel(tr("Warning - ") + QApplication::applicationName(), tr("The capture %1%2%3 has been modified.\nDo you want to save it?").arg(quote, mFilename, quote)); } ksnip-master/src/gui/operations/CanDiscardOperation.h000066400000000000000000000045521457262621600232770ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CANDISCARDOPERATION_H #define KSNIP_CANDISCARDOPERATION_H #include #include #include "SaveOperation.h" #include "NotifyOperation.h" #include "src/backend/config/IConfig.h" #include "src/backend/recentImages/IRecentImageService.h" #include "src/gui/messageBoxService/MessageBoxService.h" class CanDiscardOperation : public QObject { Q_OBJECT public: CanDiscardOperation(QImage image, bool isUnsaved, QString pathToImageSource, QString filename, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &messageBoxService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent); ~CanDiscardOperation() override = default; bool execute(); private: QSharedPointer mConfig; bool mIsUnsaved; QWidget *mParent; QImage mImage; QString mPathToImageSource; QString mFilename; QSharedPointer mNotificationService; QSharedPointer mMessageBoxService; QSharedPointer mRecentImageService; QSharedPointer mImageSaver; QSharedPointer mSavePathProvider; QSharedPointer mFileDialogService; MessageBoxResponse getSaveBeforeDiscard() const; bool saveImage() const; }; #endif //KSNIP_CANDISCARDOPERATION_H ksnip-master/src/gui/operations/CopyAsDataUriOperation.cpp000066400000000000000000000044371457262621600243110ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CopyAsDataUriOperation.h" CopyAsDataUriOperation::CopyAsDataUriOperation( QImage image, const QSharedPointer &clipboardService, const QSharedPointer ¬ificationService, const QSharedPointer &config) : mImage(std::move(image)), mClipboardService(clipboardService), mNotificationService(notificationService), mConfig(config) { } bool CopyAsDataUriOperation::execute() { QByteArray byteArray; QBuffer buffer(&byteArray); buffer.open(QIODevice::WriteOnly); auto isSaved = mImage.save(&buffer, mConfig->saveFormat().toLatin1()); buffer.close(); if (isSaved) { QByteArray output = "data:image/" + mConfig->saveFormat().toLatin1() +";base64,"; output.append(byteArray.toBase64()); mClipboardService->setText(output); notifySuccess(); } else { notifyFailure(); } return isSaved; } void CopyAsDataUriOperation::notifyFailure() const { auto title = tr("Failed to copy to clipboard"); auto message = tr("Failed to copy to clipboard as base64 encoded image."); notify(title, message, NotificationTypes::Warning); } void CopyAsDataUriOperation::notifySuccess() const { auto title = tr("Copied to clipboard"); auto message = tr("Copied to clipboard as base64 encoded image."); notify(title, message, NotificationTypes::Information); } void CopyAsDataUriOperation::notify(const QString &title, const QString &message, NotificationTypes type) const { NotifyOperation operation(title, message, type, mNotificationService, mConfig); operation.execute(); } ksnip-master/src/gui/operations/CopyAsDataUriOperation.h000066400000000000000000000033631457262621600237530ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COPYASDATAURIOPERATION_H #define KSNIP_COPYASDATAURIOPERATION_H #include #include #include "src/gui/clipboard/IClipboard.h" #include "src/gui/INotificationService.h" #include "src/gui/operations/NotifyOperation.h" #include "src/backend/config/Config.h" class CopyAsDataUriOperation : public QObject { Q_OBJECT public: CopyAsDataUriOperation( QImage image, const QSharedPointer &clipboardService, const QSharedPointer ¬ificationService, const QSharedPointer &config); ~CopyAsDataUriOperation() override = default; bool execute(); private: QImage mImage; QSharedPointer mClipboardService; QSharedPointer mNotificationService; QSharedPointer mConfig; void notifySuccess() const; void notifyFailure() const; void notify(const QString &title, const QString &message, NotificationTypes type) const; }; #endif //KSNIP_COPYASDATAURIOPERATION_H ksnip-master/src/gui/operations/DeleteImageOperation.cpp000066400000000000000000000024601457262621600240000ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DeleteImageOperation.h" DeleteImageOperation::DeleteImageOperation(const QString &path, IFileService *fileService, IMessageBoxService *messageBoxService) : mPath(path), mFileService(fileService), mMessageBoxService(messageBoxService) { } bool DeleteImageOperation::execute() { auto title = tr("Delete Image"); auto question = tr("The item \'%1\' will be deleted.\nDo you want to continue?").arg(mPath); auto response = mMessageBoxService->okCancel(title, question); return response && mFileService->remove(mPath); } ksnip-master/src/gui/operations/DeleteImageOperation.h000066400000000000000000000025631457262621600234510ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DELETEIMAGEOPERATION_H #define KSNIP_DELETEIMAGEOPERATION_H #include #include #include "src/gui/fileService/IFileService.h" #include "src/gui/messageBoxService/IMessageBoxService.h" class DeleteImageOperation : public QObject { Q_OBJECT public: explicit DeleteImageOperation(const QString &path, IFileService *fileService, IMessageBoxService *messageBoxService); ~DeleteImageOperation() override = default; bool execute(); private: QString mPath; IFileService *mFileService; IMessageBoxService *mMessageBoxService; }; #endif //KSNIP_DELETEIMAGEOPERATION_H ksnip-master/src/gui/operations/HandleUploadResultOperation.cpp000066400000000000000000000116321457262621600253730ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "HandleUploadResultOperation.h" HandleUploadResultOperation::HandleUploadResultOperation( const UploadResult &result, const QSharedPointer ¬ificationService, const QSharedPointer &clipboard, const QSharedPointer &desktopService, const QSharedPointer &config) : mUploadResult(result), mNotificationService(notificationService), mConfig(config), mClipboardService(clipboard), mDesktopService(desktopService) { } bool HandleUploadResultOperation::execute() { switch (mUploadResult.type) { case UploaderType::Imgur: handleImgurResult(); break; case UploaderType::Script: handleScriptResult(); break; case UploaderType::Ftp: handleFtpResult(); break; } return mUploadResult.status == UploadStatus::NoError; } void HandleUploadResultOperation::handleImgurResult() { if(mUploadResult.status == UploadStatus::NoError) { if (mConfig->imgurOpenLinkInBrowser()) { OpenUrl(mUploadResult.content); } if (mConfig->imgurAlwaysCopyToClipboard()) { copyToClipboard(mUploadResult.content); } notifyImgurSuccessfulUpload(mUploadResult.content); } else { handleUploadError(); } } void HandleUploadResultOperation::handleScriptResult() { if(mUploadResult.status == UploadStatus::NoError) { if (mConfig->uploadScriptCopyOutputToClipboard()) { copyToClipboard(mUploadResult.content); } notifyScriptSuccessfulUpload(); } else { handleUploadError(); } } void HandleUploadResultOperation::handleFtpResult() { if(mUploadResult.status == UploadStatus::NoError) { notifyFtpSuccessfulUpload(); } else { handleUploadError(); } } void HandleUploadResultOperation::notifyFtpSuccessfulUpload() const { NotifyOperation operation(tr("Upload Successful"), tr("FTP Upload finished successfully."), NotificationTypes::Information, mNotificationService, mConfig); operation.execute(); } void HandleUploadResultOperation::notifyScriptSuccessfulUpload() const { NotifyOperation operation(tr("Upload Successful"), tr("Upload script %1 finished successfully.").arg(mConfig->uploadScriptPath()), NotificationTypes::Information, mNotificationService, mConfig); operation.execute(); } void HandleUploadResultOperation::notifyImgurSuccessfulUpload(const QString &url) const { NotifyOperation operation(tr("Upload Successful"), tr("Uploaded to %1").arg(url), url, NotificationTypes::Information, mNotificationService, mConfig); operation.execute(); } void HandleUploadResultOperation::copyToClipboard(const QString &url) const { mClipboardService->setText(url); } void HandleUploadResultOperation::OpenUrl(const QString &url) const { mDesktopService->openUrl(url); } void HandleUploadResultOperation::handleUploadError() { switch (mUploadResult.status) { case UploadStatus::NoError: // Nothing to report all good break; case UploadStatus::UnableToSaveTemporaryImage: notifyFailedUpload(tr("Unable to save temporary image for upload.")); break; case UploadStatus::FailedToStart: notifyFailedUpload(tr("Unable to start process, check path and permissions.")); break; case UploadStatus::Crashed: notifyFailedUpload(tr("Process crashed")); break; case UploadStatus::TimedOut: notifyFailedUpload(tr("Process timed out.")); break; case UploadStatus::ReadError: notifyFailedUpload(tr("Process read error.")); break; case UploadStatus::WriteError: notifyFailedUpload(tr("Process write error.")); break; case UploadStatus::WebError: notifyFailedUpload(tr("Web error, check console output.")); break; case UploadStatus::UnknownError: notifyFailedUpload(tr("Unknown error.")); break; case UploadStatus::ScriptWroteToStdErr: notifyFailedUpload(tr("Script wrote to StdErr.")); break; case UploadStatus::ConnectionError: notifyFailedUpload(tr("Connection Error.")); break; case UploadStatus::PermissionError: notifyFailedUpload(tr("Permission Error.")); break; } } void HandleUploadResultOperation::notifyFailedUpload(const QString &message) const { NotifyOperation operation(tr("Upload Failed"), message, NotificationTypes::Warning, mNotificationService, mConfig); operation.execute(); } ksnip-master/src/gui/operations/HandleUploadResultOperation.h000066400000000000000000000042721457262621600250420ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_HANDLEUPLOADRESULTOPERATION_H #define KSNIP_HANDLEUPLOADRESULTOPERATION_H #include #include "src/backend/config/IConfig.h" #include "src/backend/uploader/UploadResult.h" #include "src/gui/operations/NotifyOperation.h" #include "src/gui/clipboard/IClipboard.h" #include "src/gui/desktopService/IDesktopService.h" class HandleUploadResultOperation : public QObject { Q_OBJECT public: explicit HandleUploadResultOperation( const UploadResult &result, const QSharedPointer ¬ificationService, const QSharedPointer &clipboard, const QSharedPointer &desktopService, const QSharedPointer &config); ~HandleUploadResultOperation() override = default; bool execute(); private: UploadResult mUploadResult; QSharedPointer mNotificationService; QSharedPointer mConfig; QSharedPointer mClipboardService; QSharedPointer mDesktopService; void notifyImgurSuccessfulUpload(const QString &url) const; void handleImgurResult(); void handleScriptResult(); void handleFtpResult(); void copyToClipboard(const QString &url) const; void OpenUrl(const QString &url) const; void handleUploadError(); void notifyFtpSuccessfulUpload() const; void notifyScriptSuccessfulUpload() const; void notifyFailedUpload(const QString &message) const; }; #endif //KSNIP_HANDLEUPLOADRESULTOPERATION_H ksnip-master/src/gui/operations/LoadImageFromFileOperation.cpp000066400000000000000000000037071457262621600251060ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "LoadImageFromFileOperation.h" LoadImageFromFileOperation::LoadImageFromFileOperation( const QString &path, IImageProcessor *imageProcessor, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &fileService, const QSharedPointer &config) : mImageProcessor(imageProcessor), mPath(path), mNotificationService(notificationService), mRecentImageService(recentImageService), mFileService(fileService), mConfig(config) { } bool LoadImageFromFileOperation::execute() { auto pixmap = mFileService->openPixmap(mPath); if(pixmap.isNull()) { notifyAboutInvalidPath(); return false; } else { mRecentImageService->storeImagePath(mPath); CaptureFromFileDto captureDto(pixmap, mPath); mImageProcessor->processImage(captureDto); return true; } } void LoadImageFromFileOperation::notifyAboutInvalidPath() const { auto title = tr("Unable to open image"); auto message = tr("Unable to open image from path %1").arg(mPath); NotifyOperation operation(title, message, NotificationTypes::Warning, mNotificationService, mConfig); operation.execute(); } ksnip-master/src/gui/operations/LoadImageFromFileOperation.h000066400000000000000000000036721457262621600245540ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_LOADIMAGEFROMFILEOPERATION_H #define KSNIP_LOADIMAGEFROMFILEOPERATION_H #include #include "src/gui/INotificationService.h" #include "src/gui/IImageProcessor.h" #include "src/gui/operations/NotifyOperation.h" #include "src/gui/fileService/IFileService.h" #include "src/backend/recentImages/IRecentImageService.h" #include "src/common/dtos/CaptureFromFileDto.h" class LoadImageFromFileOperation : public QObject { Q_OBJECT public: LoadImageFromFileOperation( const QString &path, IImageProcessor *imageProcessor, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &fileService, const QSharedPointer &config); ~LoadImageFromFileOperation() override = default; bool execute(); private: QString mPath; IImageProcessor *mImageProcessor; QSharedPointer mNotificationService; QSharedPointer mRecentImageService; QSharedPointer mFileService; QSharedPointer mConfig; void notifyAboutInvalidPath() const; }; #endif //KSNIP_LOADIMAGEFROMFILEOPERATION_H ksnip-master/src/gui/operations/NotifyOperation.cpp000066400000000000000000000051051457262621600231020ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "NotifyOperation.h" NotifyOperation::NotifyOperation( const QString &title, const QString &message, const QString &contentUrl, NotificationTypes notificationType, const QSharedPointer ¬ificationService, const QSharedPointer &config) : NotifyOperation(title, message, notificationType, notificationService, config) { mContentUrl = contentUrl; } NotifyOperation::NotifyOperation( const QString &title, const QString &message, NotificationTypes notificationType, const QSharedPointer ¬ificationService, const QSharedPointer &config) : mNotificationService(notificationService), mTitle(title), mMessage(message), mNotificationType(notificationType), mConfig(config) { Q_ASSERT(mNotificationService != nullptr); } bool NotifyOperation::execute() { if(mConfig->trayIconNotificationsEnabled()) { notifyViaToastMessage(); } notifyViaConsoleMessage(); return true; } void NotifyOperation::notifyViaToastMessage() const { switch (mNotificationType) { case NotificationTypes::Information: mNotificationService->showInfo(mTitle, mMessage, mContentUrl); break; case NotificationTypes::Warning: mNotificationService->showWarning(mTitle, mMessage, mContentUrl); break; case NotificationTypes::Critical: mNotificationService->showCritical(mTitle, mMessage, mContentUrl); break; } } void NotifyOperation::notifyViaConsoleMessage() const { switch (mNotificationType) { case NotificationTypes::Information: qInfo("%s: %s", qPrintable(mTitle), qPrintable(mMessage)); break; case NotificationTypes::Warning: qWarning("%s: %s", qPrintable(mTitle), qPrintable(mMessage)); break; case NotificationTypes::Critical: qCritical("%s: %s", qPrintable(mTitle), qPrintable(mMessage)); break; } } ksnip-master/src/gui/operations/NotifyOperation.h000066400000000000000000000034571457262621600225570ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NOTIFYOPERATION_H #define KSNIP_NOTIFYOPERATION_H #include "src/gui/TrayIcon.h" #include "src/backend/config/IConfig.h" #include "src/common/enum/NotificationTypes.h" class NotifyOperation { public: NotifyOperation( const QString &title, const QString &message, const QString &contentUrl, NotificationTypes notificationType, const QSharedPointer ¬ificationService, const QSharedPointer &config); NotifyOperation( const QString &title, const QString &message, NotificationTypes notificationType, const QSharedPointer ¬ificationService, const QSharedPointer &config); ~NotifyOperation() = default; bool execute(); private: QSharedPointer mNotificationService; QString mTitle; QString mMessage; QString mContentUrl; NotificationTypes mNotificationType; QSharedPointer mConfig; void notifyViaToastMessage() const; void notifyViaConsoleMessage() const; }; #endif //KSNIP_NOTIFYOPERATION_H ksnip-master/src/gui/operations/RenameOperation.cpp000066400000000000000000000053761457262621600230530ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "RenameOperation.h" RenameOperation::RenameOperation( const QString &pathToImageSource, const QString &imageFilename, const QSharedPointer ¬ificationService, const QSharedPointer &config, QWidget *parent) : mParent(parent), mPathToImageSource(pathToImageSource), mImageFilename(imageFilename), mNotificationService(notificationService), mConfig(config) { } RenameResultDto RenameOperation::execute() { auto newFilename = getNewFilename(); if (newFilename.isNull() || newFilename.isEmpty()) { return RenameResultDto(false, mPathToImageSource); } auto renameSuccessful = rename(newFilename); if (renameSuccessful) { NotifyOperation operation( tr("Image Renamed"), tr("Successfully renamed image to %1").arg(newFilename), NotificationTypes::Information, mNotificationService, mConfig); operation.execute(); } else { NotifyOperation operation( tr("Image Rename Failed"), tr("Failed to rename image to %1").arg(newFilename), NotificationTypes::Warning, mNotificationService, mConfig); operation.execute(); } return RenameResultDto(renameSuccessful, mPathToImageSource); } QString RenameOperation::getNewFilename() const { QInputDialog dialog; dialog.setInputMode(QInputDialog::TextInput); dialog.setWindowTitle(tr("Rename image")); dialog.setLabelText(tr("New filename:")); dialog.setTextEchoMode(QLineEdit::Normal); dialog.setTextValue(mImageFilename); dialog.resize(270, 0); if (QDialog::Accepted == dialog.exec()) { return dialog.textValue(); } return {}; } bool RenameOperation::rename(const QString &newFilename) { auto oldFilename = PathHelper::extractFilename(mPathToImageSource); auto newPathToImageSource = mPathToImageSource; newPathToImageSource.replace(oldFilename, newFilename); QFile file(mPathToImageSource); auto renameSuccessful = file.rename(newPathToImageSource); if (renameSuccessful) { mPathToImageSource = newPathToImageSource; } return renameSuccessful; } ksnip-master/src/gui/operations/RenameOperation.h000066400000000000000000000033161457262621600225100ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RENAMEOPERATION_H #define KSNIP_RENAMEOPERATION_H #include #include #include #include #include "NotifyOperation.h" #include "src/common/dtos/RenameResultDto.h" #include "src/common/helper/PathHelper.h" #include "src/gui/INotificationService.h" class RenameOperation : public QObject { Q_OBJECT public: RenameOperation( const QString &pathToImageSource, const QString &imageFilename, const QSharedPointer ¬ificationService, const QSharedPointer &config, QWidget *parent); ~RenameOperation() override = default; RenameResultDto execute(); private: QWidget* mParent; QString mPathToImageSource; QString mImageFilename; QSharedPointer mNotificationService; QSharedPointer mConfig; QString getNewFilename() const; bool rename(const QString &newFilename); }; #endif //KSNIP_RENAMEOPERATION_H ksnip-master/src/gui/operations/SaveOperation.cpp000066400000000000000000000076721457262621600225430ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SaveOperation.h" #include SaveOperation::SaveOperation( QImage image, bool isInstantSave, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent) : mParent(parent), mImage(std::move(image)), mIsInstantSave(isInstantSave), mNotificationService(notificationService), mRecentImageService(recentImageService), mImageSaver(imageSaver), mSavePathProvider(savePathProvider), mFileDialogService(fileDialogService), mConfig(config) { Q_ASSERT(mParent != nullptr); } SaveOperation::SaveOperation( const QImage &image, bool isInstantSave, const QString &pathToImageSource, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent) : SaveOperation(image, isInstantSave, notificationService, recentImageService, imageSaver, savePathProvider, fileDialogService, config, parent) { mPathToImageSource = pathToImageSource; } SaveResultDto SaveOperation::execute() { auto path = getSavePath(); if(!mIsInstantSave){ auto title = tr("Save As"); auto filter = tr("Image Files") + FileDialogFilterHelper::ImageFilesExport() + tr("All Files") + FileDialogFilterHelper::AllFiles(); auto selectedSavePath = mFileDialogService->getSavePath(mParent, title, path, filter); if (selectedSavePath.isNull()) { return SaveResultDto(false, path); } path = selectedSavePath; } auto saveResult = save(path); updateSaveDirectoryIfRequired(path, saveResult); if (saveResult.isSuccessful) { mRecentImageService->storeImagePath(path); } return saveResult; } void SaveOperation::updateSaveDirectoryIfRequired(const QString &path, const SaveResultDto &saveResult) const { if(!mIsInstantSave && saveResult.isSuccessful && mConfig->rememberLastSaveDirectory()){ auto directory = PathHelper::extractParentDirectory(path); mConfig->setSaveDirectory(directory); } } QString SaveOperation::getSavePath() const { return PathHelper::isPathValid(mPathToImageSource) ? mPathToImageSource : mSavePathProvider->savePath(); } SaveResultDto SaveOperation::save(const QString &path) { auto successful = mImageSaver->save(mImage, path); if(successful) { notify(tr("Image Saved"), tr("Saved to %1").arg(path), path, NotificationTypes::Information); } else { notify(tr("Saving Image Failed"), tr("Failed to save image to %1").arg(path), path, NotificationTypes::Critical); } return SaveResultDto(successful, path); } void SaveOperation::notify(const QString &title, const QString &message, const QString &path, NotificationTypes notificationType) const { NotifyOperation operation(title, message, path, notificationType, mNotificationService, mConfig); operation.execute(); } ksnip-master/src/gui/operations/SaveOperation.h000066400000000000000000000057721457262621600222070ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SAVEOPERATION_H #define KSNIP_SAVEOPERATION_H #include #include "NotifyOperation.h" #include "src/common/dtos/SaveResultDto.h" #include "src/common/adapter/fileDialog/IFileDialogService.h" #include "src/common/helper/FileDialogFilterHelper.h" #include "src/backend/recentImages/IRecentImageService.h" #include "src/backend/config/IConfig.h" #include "src/backend/saver/ISavePathProvider.h" #include "src/backend/saver/IImageSaver.h" #include "src/gui/INotificationService.h" class SaveOperation : public QObject { Q_OBJECT public: SaveOperation( QImage image, bool isInstantSave, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent); SaveOperation( const QImage &image, bool isInstantSave, const QString &pathToImageSource, const QSharedPointer ¬ificationService, const QSharedPointer &recentImageService, const QSharedPointer &imageSaver, const QSharedPointer &savePathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &config, QWidget *parent); ~SaveOperation() override = default; SaveResultDto execute(); private: QWidget* mParent; QImage mImage; QString mPathToImageSource; bool mIsInstantSave; QSharedPointer mImageSaver; QSharedPointer mSavePathProvider; QSharedPointer mNotificationService; QSharedPointer mRecentImageService; QSharedPointer mFileDialogService; QSharedPointer mConfig; void notify(const QString &title, const QString &message, const QString &path, NotificationTypes notificationType) const; SaveResultDto save(const QString &path); QString getSavePath() const; void updateSaveDirectoryIfRequired(const QString &path, const SaveResultDto &saveResult) const; }; #endif //KSNIP_SAVEOPERATION_H ksnip-master/src/gui/operations/UpdateWatermarkOperation.cpp000066400000000000000000000025061457262621600247340ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "UpdateWatermarkOperation.h" UpdateWatermarkOperation::UpdateWatermarkOperation(QWidget *parent) { mParent = parent; } bool UpdateWatermarkOperation::execute() { auto title = tr("Select Image"); auto filter = tr("Image Files") + FileDialogFilterHelper::ImageFilesImport(); QFileDialog dialog(mParent, title, QString(), filter); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec() != QDialog::Accepted) { return false; } auto pathToImage = dialog.selectedFiles().first(); return mImageLoader.save(QPixmap(pathToImage)); } ksnip-master/src/gui/operations/UpdateWatermarkOperation.h000066400000000000000000000024571457262621600244060ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPDATEWATERMARKOPERATION_H #define KSNIP_UPDATEWATERMARKOPERATION_H #include #include #include "src/backend/WatermarkImageLoader.h" #include "src/common/helper/FileDialogFilterHelper.h" class UpdateWatermarkOperation : public QObject { Q_OBJECT public: explicit UpdateWatermarkOperation(QWidget *parent); ~UpdateWatermarkOperation() override = default; bool execute(); private: QWidget *mParent; WatermarkImageLoader mImageLoader; }; #endif //KSNIP_UPDATEWATERMARKOPERATION_H ksnip-master/src/gui/operations/UploadOperation.cpp000066400000000000000000000035671457262621600230700ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "UploadOperation.h" UploadOperation::UploadOperation( QImage image, const QSharedPointer &uploader, const QSharedPointer &config, const QSharedPointer &messageBoxService) : mImage(std::move(image)), mUploader(uploader), mConfig(config), mMessageBoxService(messageBoxService) { Q_ASSERT(mUploader != nullptr); } bool UploadOperation::execute() { if (mUploader->type() == UploaderType::Script && !PathHelper::isPathValid(mConfig->uploadScriptPath())) { mMessageBoxService->ok(tr("Upload Script Required"), tr("Please add an upload script via Options > Settings > Upload Script")); } else if (!mImage.isNull() && proceedWithUpload()) { mUploader->upload(mImage); return true; } return false; } bool UploadOperation::proceedWithUpload() const { return !mConfig->confirmBeforeUpload() || askIfCanProceedWithUpload(); } bool UploadOperation::askIfCanProceedWithUpload() const { return mMessageBoxService->yesNo(tr("Capture Upload"), tr("You are about to upload the image to an external destination, do you want to proceed?")); } ksnip-master/src/gui/operations/UploadOperation.h000066400000000000000000000032511457262621600225230ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADOPERATION_H #define KSNIP_UPLOADOPERATION_H #include #include #include #include #include "src/backend/uploader/IUploader.h" #include "src/backend/config/IConfig.h" #include "src/gui/messageBoxService/IMessageBoxService.h" #include "src/common/helper/PathHelper.h" class UploadOperation : public QObject { Q_OBJECT public: UploadOperation( QImage image, const QSharedPointer &uploader, const QSharedPointer &config, const QSharedPointer &messageBoxService); ~UploadOperation() override = default; bool execute(); private: QImage mImage; QSharedPointer mConfig; QSharedPointer mUploader; QSharedPointer mMessageBoxService; bool proceedWithUpload() const; bool askIfCanProceedWithUpload() const; }; #endif //KSNIP_UPLOADOPERATION_H ksnip-master/src/gui/operations/WatermarkImagePreparer.cpp000066400000000000000000000045451457262621600243610ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WatermarkImagePreparer.h" WatermarkImagePreparer::WatermarkImagePreparer() { mOpacity = 0.15; } QPixmap WatermarkImagePreparer::prepare(const QPixmap &image, const QSize &availableSpace, bool rotated) const { auto finishedWatermarkImage = getPreparedWatermarkImage(image, rotated); return fitWatermarkIntoCapture(finishedWatermarkImage, availableSpace); } QPixmap WatermarkImagePreparer::getPreparedWatermarkImage(const QPixmap &watermarkImage, bool rotated) const { auto preparedImage = watermarkImage; if(rotated) { preparedImage = getRotatedImage(watermarkImage); } QPixmap transparentWatermark(preparedImage.size()); transparentWatermark.fill(Qt::transparent); QPainter painter(&transparentWatermark); painter.setOpacity(mOpacity); painter.drawPixmap(0, 0, preparedImage); return transparentWatermark; } QPixmap WatermarkImagePreparer::getRotatedImage(const QPixmap &watermarkImage) const { QTransform transform; transform.rotate(45); return watermarkImage.transformed(transform); } QPixmap &WatermarkImagePreparer::fitWatermarkIntoCapture(QPixmap &finishedWatermarkImage, const QSize &availableSpace) const { auto widthRatio = (qreal) availableSpace.width() / (qreal) finishedWatermarkImage.size().width(); auto heightRatio = (qreal) availableSpace.height() / (qreal) finishedWatermarkImage.size().height(); if (widthRatio < 1 || heightRatio < 1) { auto minRatio = qMin(widthRatio, heightRatio); QTransform transform; transform.scale(minRatio, minRatio); finishedWatermarkImage = finishedWatermarkImage.transformed(transform); } return finishedWatermarkImage; } ksnip-master/src/gui/operations/WatermarkImagePreparer.h000066400000000000000000000026131457262621600240200ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WATERMARKIMAGEPREPARER_H #define KSNIP_WATERMARKIMAGEPREPARER_H #include class WatermarkImagePreparer { public: explicit WatermarkImagePreparer(); ~WatermarkImagePreparer() = default; QPixmap prepare(const QPixmap &image, const QSize &availableSpace, bool rotated) const; private: qreal mOpacity; QPixmap getPreparedWatermarkImage(const QPixmap &watermarkImage, bool rotated) const; QPixmap &fitWatermarkIntoCapture(QPixmap &finishedWatermarkImage, const QSize &availableSpace) const; QPixmap getRotatedImage(const QPixmap &watermarkImage) const; }; #endif //KSNIP_WATERMARKIMAGEPREPARER_H ksnip-master/src/gui/settingsDialog/000077500000000000000000000000001457262621600200415ustar00rootroot00000000000000ksnip-master/src/gui/settingsDialog/AnnotationSettings.cpp000066400000000000000000000153541457262621600244100ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AnnotationSettings.h" AnnotationSettings::AnnotationSettings(const QSharedPointer &config, const QSharedPointer &scaledSizeProvider) : mSmoothPathCheckbox(new QCheckBox(this)), mRememberToolSelectionCheckBox(new QCheckBox(this)), mSwitchToSelectToolAfterDrawingItemCheckBox(new QCheckBox(this)), mNumberToolSeedChangeUpdatesAllItemsCheckBox(new QCheckBox(this)), mSelectItemAfterDrawingCheckBox(new QCheckBox(this)), mIsControlsWidgetVisibleCheckBox(new QCheckBox(this)), mSmoothFactorLabel(new QLabel(this)), mCanvasColorLabel(new QLabel(this)), mSmoothFactorCombobox(new NumericComboBox(1, 1, 15)), mCanvasColorButton(new ColorButton(this)), mLayout(new QGridLayout(this)), mConfig(config), mScaledSizeProvider(scaledSizeProvider) { initGui(); loadConfig(); } AnnotationSettings::~AnnotationSettings() { delete mSmoothFactorCombobox; } void AnnotationSettings::saveSettings() { mConfig->setSmoothPathEnabled(mSmoothPathCheckbox->isChecked()); mConfig->setSmoothFactor(mSmoothFactorCombobox->value()); mConfig->setRememberToolSelection(mRememberToolSelectionCheckBox->isChecked()); mConfig->setSwitchToSelectToolAfterDrawingItem(mSwitchToSelectToolAfterDrawingItemCheckBox->isChecked()); mConfig->setNumberToolSeedChangeUpdatesAllItems(mNumberToolSeedChangeUpdatesAllItemsCheckBox->isChecked()); mConfig->setSelectItemAfterDrawing(mSelectItemAfterDrawingCheckBox->isChecked()); mConfig->setIsControlsWidgetVisible(mIsControlsWidgetVisibleCheckBox->isChecked()); mConfig->setCanvasColor(mCanvasColorButton->color()); } void AnnotationSettings::initGui() { auto const fixedButtonWidth = mScaledSizeProvider->scaledWidth(100); mRememberToolSelectionCheckBox->setText(tr("Remember annotation tool selection and load on startup")); mSwitchToSelectToolAfterDrawingItemCheckBox->setText(tr("Switch to Select Tool after drawing Item")); connect(mSwitchToSelectToolAfterDrawingItemCheckBox, &QCheckBox::clicked, this, &AnnotationSettings::switchToSelectToolAfterDrawingItemCheckBoxClicked); mSelectItemAfterDrawingCheckBox->setText(tr("Select Item after drawing")); mSelectItemAfterDrawingCheckBox->setToolTip(tr("With this option enabled the item gets selected after\n" "being created, allowing changing settings.")); mNumberToolSeedChangeUpdatesAllItemsCheckBox->setText(tr("Number Tool Seed change updates all Number Items")); mNumberToolSeedChangeUpdatesAllItemsCheckBox->setToolTip(tr("Disabling this option causes changes of the number tool\n" "seed to affect only new items but not existing items.\n" "Disabling this option allows having duplicate numbers.")); mIsControlsWidgetVisibleCheckBox->setText(tr("Show Controls Widget")); mIsControlsWidgetVisibleCheckBox->setToolTip(tr("The Controls Widget contains the Undo/Redo,\n" "Crop, Scale, Rotate and Modify Canvas buttons.")); mSmoothPathCheckbox->setText(tr("Smooth Painter Paths")); mSmoothPathCheckbox->setToolTip(tr("When enabled smooths out pen and\n" "marker paths after finished drawing.")); connect(mSmoothPathCheckbox, &QCheckBox::clicked, this, &AnnotationSettings::smoothPathCheckBoxClicked); mSmoothFactorLabel->setText(tr("Smooth Factor") + QLatin1String(":")); mSmoothFactorLabel->setToolTip(tr("Increasing the smooth factor will decrease\n" "precision for pen and marker but will\n" "make them more smooth.")); mSmoothFactorCombobox->setMinimumWidth(fixedButtonWidth); mSmoothFactorCombobox->setToolTip(mSmoothFactorLabel->toolTip()); mCanvasColorLabel->setText(tr("Canvas Color") + QLatin1String(":")); mCanvasColorLabel->setToolTip(tr("Default Canvas background color for annotation area.\n" "Changing color affects only new annotation areas.")); mCanvasColorButton->setMinimumWidth(fixedButtonWidth); mCanvasColorButton->setShowAlphaChannel(true); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mRememberToolSelectionCheckBox, 0, 0, 1, 6); mLayout->addWidget(mSwitchToSelectToolAfterDrawingItemCheckBox, 1, 0, 1, 6); mLayout->addWidget(mSelectItemAfterDrawingCheckBox, 2, 1, 1, 5); mLayout->addWidget(mNumberToolSeedChangeUpdatesAllItemsCheckBox, 3, 0, 1, 6); mLayout->addWidget(mIsControlsWidgetVisibleCheckBox, 4, 0, 1, 6); mLayout->addWidget(mSmoothPathCheckbox, 5, 0, 1, 6); mLayout->addWidget(mSmoothFactorLabel, 6, 1, 1, 3); mLayout->addWidget(mSmoothFactorCombobox, 7, 3, 1,3, Qt::AlignLeft); mLayout->setRowMinimumHeight(7, 15); mLayout->addWidget(mCanvasColorLabel, 8, 0, 1, 2); mLayout->addWidget(mCanvasColorButton, 8, 3, 1,3, Qt::AlignLeft); setTitle(tr("Annotator Settings")); setLayout(mLayout); } void AnnotationSettings::loadConfig() { mSmoothPathCheckbox->setChecked(mConfig->smoothPathEnabled()); mSmoothFactorCombobox->setValue(mConfig->smoothFactor()); mRememberToolSelectionCheckBox->setChecked(mConfig->rememberToolSelection()); mSwitchToSelectToolAfterDrawingItemCheckBox->setChecked(mConfig->switchToSelectToolAfterDrawingItem()); mNumberToolSeedChangeUpdatesAllItemsCheckBox->setChecked(mConfig->numberToolSeedChangeUpdatesAllItems()); mSelectItemAfterDrawingCheckBox->setChecked(mConfig->selectItemAfterDrawing()); mIsControlsWidgetVisibleCheckBox->setChecked(mConfig->isControlsWidgetVisible()); mCanvasColorButton->setColor(mConfig->canvasColor()); smoothPathCheckBoxClicked(mConfig->smoothPathEnabled()); switchToSelectToolAfterDrawingItemCheckBoxClicked(mConfig->switchToSelectToolAfterDrawingItem()); } void AnnotationSettings::smoothPathCheckBoxClicked(bool checked) { mSmoothFactorLabel->setEnabled(checked); mSmoothFactorCombobox->setEnabled(checked); } void AnnotationSettings::switchToSelectToolAfterDrawingItemCheckBoxClicked(bool checked) { mSelectItemAfterDrawingCheckBox->setEnabled(checked); } ksnip-master/src/gui/settingsDialog/AnnotationSettings.h000066400000000000000000000043331457262621600240500ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ANNOTATIONSETTINGS_H #define KSNIP_ANNOTATIONSETTINGS_H #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/backend/WatermarkImageLoader.h" #include "src/widgets/NumericComboBox.h" #include "src/widgets/ColorButton.h" #include "src/common/provider/scaledSizeProvider/IScaledSizeProvider.h" class AnnotationSettings : public QGroupBox { Q_OBJECT public: explicit AnnotationSettings(const QSharedPointer &config, const QSharedPointer &scaledSizeProvider); ~AnnotationSettings() override; void saveSettings(); private: QCheckBox *mSmoothPathCheckbox; QCheckBox *mRememberToolSelectionCheckBox; QCheckBox *mSwitchToSelectToolAfterDrawingItemCheckBox; QCheckBox *mNumberToolSeedChangeUpdatesAllItemsCheckBox; QCheckBox *mSelectItemAfterDrawingCheckBox; QCheckBox *mIsControlsWidgetVisibleCheckBox; QLabel *mSmoothFactorLabel; QLabel *mCanvasColorLabel; NumericComboBox *mSmoothFactorCombobox; ColorButton *mCanvasColorButton; QGridLayout *mLayout; QSharedPointer mConfig; QSharedPointer mScaledSizeProvider; void initGui(); void loadConfig(); private slots: void smoothPathCheckBoxClicked(bool checked); void switchToSelectToolAfterDrawingItemCheckBoxClicked(bool checked); }; #endif //KSNIP_ANNOTATIONSETTINGS_H ksnip-master/src/gui/settingsDialog/ApplicationSettings.cpp000066400000000000000000000203101457262621600245250ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ApplicationSettings.h" ApplicationSettings::ApplicationSettings(const QSharedPointer &config, const QSharedPointer &fileDialogService) : mConfig(config), mFileDialogService(fileDialogService), mAutoCopyToClipboardNewCapturesCheckbox(new QCheckBox(this)), mRememberPositionCheckbox(new QCheckBox(this)), mCaptureOnStartupCheckbox(new QCheckBox(this)), mUseTabsCheckbox(new QCheckBox(this)), mAutoHideTabsCheckbox(new QCheckBox(this)), mUseSingleInstanceCheckBox(new QCheckBox(this)), mAutoHideDocksCheckBox(new QCheckBox(this)), mAutoResizeToContentCheckBox(new QCheckBox(this)), mEnableDebugging(new QCheckBox(this)), mApplicationStyleLabel(new QLabel(this)), mResizeToContentDelayLabel(new QLabel(this)), mTempDirectoryLabel(new QLabel(this)), mTempDirectoryLineEdit(new QLineEdit(this)), mBrowseButton(new QPushButton(this)), mApplicationStyleCombobox(new QComboBox(this)), mResizeToContentDelaySpinBox(new CustomSpinBox(0, 1000, this)), mLayout(new QGridLayout) { Q_ASSERT(mConfig != nullptr); initGui(); loadConfig(); } void ApplicationSettings::initGui() { mAutoCopyToClipboardNewCapturesCheckbox->setText(tr("Automatically copy new captures to clipboard")); mRememberPositionCheckbox->setText(tr("Remember Main Window position on move and load on startup")); mCaptureOnStartupCheckbox->setText(tr("Capture screenshot at startup with default mode")); mUseTabsCheckbox->setText(tr("Use Tabs")); mUseTabsCheckbox->setToolTip(tr("Change requires restart.")); mAutoHideTabsCheckbox->setText(tr("Auto hide Tabs")); mAutoHideTabsCheckbox->setToolTip(tr("Hide Tabbar when only one Tab is used.")); mUseSingleInstanceCheckBox->setText(tr("Run ksnip as single instance")); mUseSingleInstanceCheckBox->setToolTip(tr("Enabling this option will allow only one ksnip instance to run,\n" "all other instances started after the first will pass its\n" "arguments to the first and close. Changing this option requires\n" "a new start of all instances.")); mAutoHideDocksCheckBox->setText(tr("Auto hide Docks")); mAutoHideDocksCheckBox->setToolTip(tr("On startup hide Toolbar and Annotation Settings.\n" "Docks visibility can be toggled with the Tab Key.")); mAutoResizeToContentCheckBox->setText(tr("Auto resize to content")); mAutoResizeToContentCheckBox->setToolTip(tr("Automatically resize Main Window to fit content image.")); mEnableDebugging->setText(tr("Enable Debugging")); mEnableDebugging->setToolTip(tr("Enables debug output written to the console.\n" "Change requires ksnip restart to take effect.")); mResizeToContentDelayLabel->setText(tr("Resize delay") + QLatin1String(":")); mResizeToContentDelayLabel->setToolTip(tr("Resizing to content is delay to allow the Window Manager to receive\n" "the new content. In case that the Main Windows is not adjusted correctly\n" "to the new content, increasing this delay might improve the behavior.")); mResizeToContentDelaySpinBox->setSuffix(QLatin1String("ms")); mResizeToContentDelaySpinBox->setToolTip(mResizeToContentDelayLabel->toolTip()); mResizeToContentDelaySpinBox->setSingleStep(10); connect(mUseTabsCheckbox, &QCheckBox::stateChanged, this, &ApplicationSettings::useTabsChanged); mApplicationStyleLabel->setText(tr("Application Style") + QLatin1String(":")); mApplicationStyleLabel->setToolTip(tr("Sets the application style which defines the look and feel of the GUI.\n" "Change requires ksnip restart to take effect.")); mTempDirectoryLabel->setText(tr("Temp Directory") + QLatin1String(":")); mTempDirectoryLineEdit->setToolTip(tr("Temp directory used for storing temporary images that are\n" "going to be deleted after ksnip closes.")); mBrowseButton->setText(tr("Browse")); connect(mBrowseButton, &QPushButton::clicked, this, &ApplicationSettings::chooseTempDirectory); mApplicationStyleCombobox->addItems(QStyleFactory::keys()); mApplicationStyleCombobox->setToolTip(mApplicationStyleLabel->toolTip()); mApplicationStyleCombobox->setFixedWidth(100); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mAutoCopyToClipboardNewCapturesCheckbox, 0, 0, 1, 4); mLayout->addWidget(mRememberPositionCheckbox, 1, 0, 1, 4); mLayout->addWidget(mCaptureOnStartupCheckbox, 2, 0, 1, 4); mLayout->addWidget(mUseTabsCheckbox, 3, 0, 1, 4); mLayout->addWidget(mAutoHideTabsCheckbox, 4, 1, 1, 3); mLayout->addWidget(mUseSingleInstanceCheckBox, 5, 0, 1, 4); mLayout->addWidget(mAutoHideDocksCheckBox, 6, 0, 1, 4); mLayout->addWidget(mAutoResizeToContentCheckBox, 7, 0, 1, 4); mLayout->addWidget(mEnableDebugging, 8, 0, 1, 4); mLayout->setRowMinimumHeight(9, 15); mLayout->addWidget(mResizeToContentDelayLabel, 10, 0, 1, 2); mLayout->addWidget(mResizeToContentDelaySpinBox, 10, 2, Qt::AlignLeft); mLayout->setRowMinimumHeight(11, 15); mLayout->addWidget(mApplicationStyleLabel, 12, 0, 1, 2); mLayout->addWidget(mApplicationStyleCombobox, 12, 2, Qt::AlignLeft); mLayout->setRowMinimumHeight(13, 15); mLayout->addWidget(mTempDirectoryLabel, 14, 0, 1, 2); mLayout->addWidget(mTempDirectoryLineEdit, 14, 2, 1, 2); mLayout->addWidget(mBrowseButton, 14, 4); setTitle(tr("Application Settings")); setLayout(mLayout); } void ApplicationSettings::loadConfig() { mAutoCopyToClipboardNewCapturesCheckbox->setChecked(mConfig->autoCopyToClipboardNewCaptures()); mRememberPositionCheckbox->setChecked(mConfig->rememberPosition()); mCaptureOnStartupCheckbox->setChecked(mConfig->captureOnStartup()); mUseTabsCheckbox->setChecked(mConfig->useTabs()); mAutoHideTabsCheckbox->setChecked(mConfig->autoHideTabs()); mUseSingleInstanceCheckBox->setChecked(mConfig->useSingleInstance()); mAutoHideDocksCheckBox->setChecked(mConfig->autoHideDocks()); mAutoResizeToContentCheckBox->setChecked(mConfig->autoResizeToContent()); mEnableDebugging->setChecked(mConfig->isDebugEnabled()); mResizeToContentDelaySpinBox->setValue(mConfig->resizeToContentDelay()); mApplicationStyleCombobox->setCurrentText(mConfig->applicationStyle()); mTempDirectoryLineEdit->setText(mConfig->tempDirectory()); useTabsChanged(); } void ApplicationSettings::saveSettings() { mConfig->setAutoCopyToClipboardNewCaptures(mAutoCopyToClipboardNewCapturesCheckbox->isChecked()); mConfig->setRememberPosition(mRememberPositionCheckbox->isChecked()); mConfig->setCaptureOnStartup(mCaptureOnStartupCheckbox->isChecked()); mConfig->setUseSingleInstance(mUseSingleInstanceCheckBox->isChecked()); mConfig->setUseTabs(mUseTabsCheckbox->isChecked()); mConfig->setAutoHideTabs(mAutoHideTabsCheckbox->isChecked()); mConfig->setAutoHideDocks(mAutoHideDocksCheckBox->isChecked()); mConfig->setAutoResizeToContent(mAutoResizeToContentCheckBox->isChecked()); mConfig->setIsDebugEnabled(mEnableDebugging->isChecked()); mConfig->setResizeToContentDelay(mResizeToContentDelaySpinBox->value()); mConfig->setApplicationStyle(mApplicationStyleCombobox->currentText()); mConfig->setTempDirectory(mTempDirectoryLineEdit->displayText()); } void ApplicationSettings::useTabsChanged() { mAutoHideTabsCheckbox->setEnabled(mUseTabsCheckbox->isChecked()); } void ApplicationSettings::chooseTempDirectory() { auto path = mFileDialogService->getExistingDirectory(this, tr("Temp Directory"), mTempDirectoryLineEdit->displayText()); mTempDirectoryLineEdit->setText(path); } ksnip-master/src/gui/settingsDialog/ApplicationSettings.h000066400000000000000000000045301457262621600242000ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_APPLICATIONSETTINGS_H #define KSNIP_APPLICATIONSETTINGS_H #include #include #include #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/helper/EnumTranslator.h" #include "src/widgets/CustomSpinBox.h" #include "src/common/adapter/fileDialog/IFileDialogService.h" class ApplicationSettings : public QGroupBox { Q_OBJECT public: explicit ApplicationSettings(const QSharedPointer &config, const QSharedPointer &fileDialogService); ~ApplicationSettings() override = default; void saveSettings(); private: QCheckBox *mAutoCopyToClipboardNewCapturesCheckbox; QCheckBox *mRememberPositionCheckbox; QCheckBox *mCaptureOnStartupCheckbox; QCheckBox *mUseTabsCheckbox; QCheckBox *mAutoHideTabsCheckbox; QCheckBox *mUseSingleInstanceCheckBox; QCheckBox *mAutoHideDocksCheckBox; QCheckBox *mAutoResizeToContentCheckBox; QCheckBox *mEnableDebugging; QLabel *mApplicationStyleLabel; QLabel *mResizeToContentDelayLabel; QLabel *mTempDirectoryLabel; QLineEdit *mTempDirectoryLineEdit; QPushButton *mBrowseButton; QComboBox *mApplicationStyleCombobox; CustomSpinBox *mResizeToContentDelaySpinBox; QGridLayout *mLayout; QSharedPointer mConfig; QSharedPointer mFileDialogService; void initGui(); void loadConfig(); private slots: void useTabsChanged(); void chooseTempDirectory(); }; #endif //KSNIP_APPLICATIONSETTINGS_H ksnip-master/src/gui/settingsDialog/HotKeySettings.cpp000066400000000000000000000254051457262621600234770ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "HotKeySettings.h" HotKeySettings::HotKeySettings(const QList &captureModes, const QSharedPointer &platformChecker, const QSharedPointer &config) : mConfig(config), mPlatformChecker(platformChecker), mCaptureModes(captureModes), mEnableGlobalHotKeysCheckBox(new QCheckBox(this)), mRectAreaLabel(new QLabel(this)), mLastRectAreaLabel(new QLabel(this)), mFullScreenLabel(new QLabel(this)), mCurrentScreenLabel(new QLabel(this)), mActiveWindowLabel(new QLabel(this)), mWindowUnderCursorLabel(new QLabel(this)), mPortalLabel(new QLabel(this)), mRectAreaClearPushButton(new QPushButton(this)), mLastRectAreaClearPushButton(new QPushButton(this)), mFullScreenClearPushButton(new QPushButton(this)), mCurrentScreenClearPushButton(new QPushButton(this)), mActiveWindowClearPushButton(new QPushButton(this)), mWindowUnderCursorClearPushButton(new QPushButton(this)), mPortalClearPushButton(new QPushButton(this)), mLayout(new QGridLayout(this)) { Q_ASSERT(mConfig != nullptr); initGui(); loadConfig(); } HotKeySettings::~HotKeySettings() { delete mEnableGlobalHotKeysCheckBox; delete mRectAreaLabel; delete mLastRectAreaLabel; delete mFullScreenLabel; delete mCurrentScreenLabel; delete mActiveWindowLabel; delete mWindowUnderCursorLabel; delete mPortalLabel; delete mRectAreaKeySequenceLineEdit; delete mLastRectAreaKeySequenceLineEdit; delete mFullScreenKeySequenceLineEdit; delete mCurrentScreenKeySequenceLineEdit; delete mActiveWindowKeySequenceLineEdit; delete mWindowUnderCursorKeySequenceLineEdit; delete mPortalKeySequenceLineEdit; delete mRectAreaClearPushButton; delete mLastRectAreaClearPushButton; delete mFullScreenClearPushButton; delete mCurrentScreenClearPushButton; delete mActiveWindowClearPushButton; delete mWindowUnderCursorClearPushButton; delete mPortalClearPushButton; delete mLayout; } void HotKeySettings::saveSettings() { mConfig->setGlobalHotKeysEnabled(mEnableGlobalHotKeysCheckBox->isChecked()); mConfig->setRectAreaHotKey(mRectAreaKeySequenceLineEdit->value()); mConfig->setLastRectAreaHotKey(mLastRectAreaKeySequenceLineEdit->value()); mConfig->setFullScreenHotKey(mFullScreenKeySequenceLineEdit->value()); mConfig->setCurrentScreenHotKey(mCurrentScreenKeySequenceLineEdit->value()); mConfig->setActiveWindowHotKey(mActiveWindowKeySequenceLineEdit->value()); mConfig->setWindowUnderCursorHotKey(mWindowUnderCursorKeySequenceLineEdit->value()); mConfig->setPortalHotKey(mPortalKeySequenceLineEdit->value()); } void HotKeySettings::initGui() { auto allowedKeys = HotKeyMap::instance()->getAllKeys(); mRectAreaKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mLastRectAreaKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mFullScreenKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mCurrentScreenKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mActiveWindowKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mWindowUnderCursorKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mPortalKeySequenceLineEdit = new KeySequenceLineEdit(this, allowedKeys, mPlatformChecker); mEnableGlobalHotKeysCheckBox->setText(tr("Enable Global HotKeys")); mEnableGlobalHotKeysCheckBox->setToolTip(tr("HotKeys are currently supported only for Windows and X11.\n" "Disabling this option makes also the action shortcuts ksnip only.")); connect(mEnableGlobalHotKeysCheckBox, &QCheckBox::stateChanged, this, &HotKeySettings::globalHotKeysStateChanged); mRectAreaLabel->setText(tr("Capture Rect Area") + QLatin1String(":")); mLastRectAreaLabel->setText(tr("Capture Last Rect Area") + QLatin1String(":")); mFullScreenLabel->setText(tr("Capture Full Screen") + QLatin1String(":")); mCurrentScreenLabel->setText(tr("Capture current Screen") + QLatin1String(":")); mActiveWindowLabel->setText(tr("Capture active Window") + QLatin1String(":")); mWindowUnderCursorLabel->setText(tr("Capture Window under Cursor") + QLatin1String(":")); mPortalLabel->setText(tr("Capture using Portal") + QLatin1String(":")); auto clearText = tr("Clear"); mRectAreaClearPushButton->setText(clearText); connect(mRectAreaClearPushButton, &QPushButton::clicked, mRectAreaKeySequenceLineEdit, &KeySequenceLineEdit::clear); mLastRectAreaClearPushButton->setText(clearText); connect(mLastRectAreaClearPushButton, &QPushButton::clicked, mLastRectAreaKeySequenceLineEdit, &KeySequenceLineEdit::clear); mFullScreenClearPushButton->setText(clearText); connect(mFullScreenClearPushButton, &QPushButton::clicked, mFullScreenKeySequenceLineEdit, &KeySequenceLineEdit::clear); mCurrentScreenClearPushButton->setText(clearText); connect(mCurrentScreenClearPushButton, &QPushButton::clicked, mCurrentScreenKeySequenceLineEdit, &KeySequenceLineEdit::clear); mActiveWindowClearPushButton->setText(clearText); connect(mActiveWindowClearPushButton, &QPushButton::clicked, mActiveWindowKeySequenceLineEdit, &KeySequenceLineEdit::clear); mWindowUnderCursorClearPushButton->setText(clearText); connect(mWindowUnderCursorClearPushButton, &QPushButton::clicked, mWindowUnderCursorKeySequenceLineEdit, &KeySequenceLineEdit::clear); mPortalClearPushButton->setText(clearText); connect(mPortalClearPushButton, &QPushButton::clicked, mPortalKeySequenceLineEdit, &KeySequenceLineEdit::clear); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnStretch(1, 1); mLayout->addWidget(mEnableGlobalHotKeysCheckBox, 0, 0, 1, 3); mLayout->addWidget(mRectAreaLabel, 1, 0, 1, 1); mLayout->addWidget(mRectAreaKeySequenceLineEdit, 1, 1, 1, 1); mLayout->addWidget(mRectAreaClearPushButton, 1, 2, 1, 1); mLayout->addWidget(mLastRectAreaLabel, 2, 0,1,1); mLayout->addWidget(mLastRectAreaKeySequenceLineEdit, 2, 1, 1, 1); mLayout->addWidget(mLastRectAreaClearPushButton, 2, 2, 1, 1); mLayout->addWidget(mFullScreenLabel, 3, 0, 1, 1); mLayout->addWidget(mFullScreenKeySequenceLineEdit, 3, 1, 1, 1); mLayout->addWidget(mFullScreenClearPushButton, 3, 2, 1, 1); mLayout->addWidget(mCurrentScreenLabel, 4, 0, 1, 1); mLayout->addWidget(mCurrentScreenKeySequenceLineEdit, 4, 1, 1, 1); mLayout->addWidget(mCurrentScreenClearPushButton, 4, 2, 1, 1); mLayout->addWidget(mActiveWindowLabel, 5, 0, 1, 1); mLayout->addWidget(mActiveWindowKeySequenceLineEdit, 5, 1, 1, 1); mLayout->addWidget(mActiveWindowClearPushButton, 5, 2, 1, 1); mLayout->addWidget(mWindowUnderCursorLabel, 6, 0, 1, 1); mLayout->addWidget(mWindowUnderCursorKeySequenceLineEdit, 6, 1, 1, 1); mLayout->addWidget(mWindowUnderCursorClearPushButton, 6, 2, 1, 1); mLayout->addWidget(mPortalLabel, 7, 0, 1, 1); mLayout->addWidget(mPortalKeySequenceLineEdit, 7, 1, 1, 1); mLayout->addWidget(mPortalClearPushButton, 7, 2, 1, 1); setTitle(tr("Global HotKeys")); setLayout(mLayout); } void HotKeySettings::loadConfig() { mEnableGlobalHotKeysCheckBox->setChecked(mConfig->globalHotKeysEnabled()); mEnableGlobalHotKeysCheckBox->setEnabled(!mConfig->isGlobalHotKeysEnabledReadOnly()); mRectAreaKeySequenceLineEdit->setValue(mConfig->rectAreaHotKey()); mLastRectAreaKeySequenceLineEdit->setValue(mConfig->lastRectAreaHotKey()); mFullScreenKeySequenceLineEdit->setValue(mConfig->fullScreenHotKey()); mCurrentScreenKeySequenceLineEdit->setValue(mConfig->currentScreenHotKey()); mActiveWindowKeySequenceLineEdit->setValue(mConfig->activeWindowHotKey()); mWindowUnderCursorKeySequenceLineEdit->setValue(mConfig->windowUnderCursorHotKey()); mPortalKeySequenceLineEdit->setValue(mConfig->portalHotKey()); globalHotKeysStateChanged(); } void HotKeySettings::globalHotKeysStateChanged() { auto hotKeysEnabled = mEnableGlobalHotKeysCheckBox->isChecked() && mEnableGlobalHotKeysCheckBox->isEnabled(); auto isRectAreaSupported = mCaptureModes.contains(CaptureModes::RectArea); auto isLastRectAreaSupported = mCaptureModes.contains(CaptureModes::LastRectArea); auto isFullScreenSupported = mCaptureModes.contains(CaptureModes::FullScreen); auto isCurrentScreenSupported = mCaptureModes.contains(CaptureModes::CurrentScreen); auto isActiveWindowSupported = mCaptureModes.contains(CaptureModes::ActiveWindow); auto isWindowUnderCursorSupported = mCaptureModes.contains(CaptureModes::WindowUnderCursor); auto isPortalSupported = mCaptureModes.contains(CaptureModes::Portal); mRectAreaLabel->setEnabled(hotKeysEnabled && isRectAreaSupported); mRectAreaKeySequenceLineEdit->setEnabled(hotKeysEnabled && isRectAreaSupported); mRectAreaClearPushButton->setEnabled(hotKeysEnabled && isRectAreaSupported); mLastRectAreaLabel->setEnabled(hotKeysEnabled && isLastRectAreaSupported); mLastRectAreaKeySequenceLineEdit->setEnabled(hotKeysEnabled && isLastRectAreaSupported); mLastRectAreaClearPushButton->setEnabled(hotKeysEnabled && isLastRectAreaSupported); mFullScreenLabel->setEnabled(hotKeysEnabled && isFullScreenSupported); mFullScreenKeySequenceLineEdit->setEnabled(hotKeysEnabled && isFullScreenSupported); mFullScreenClearPushButton->setEnabled(hotKeysEnabled && isFullScreenSupported); mCurrentScreenLabel->setEnabled(hotKeysEnabled && isCurrentScreenSupported); mCurrentScreenKeySequenceLineEdit->setEnabled(hotKeysEnabled && isCurrentScreenSupported); mCurrentScreenClearPushButton->setEnabled(hotKeysEnabled && isCurrentScreenSupported); mActiveWindowLabel->setEnabled(hotKeysEnabled && isActiveWindowSupported); mActiveWindowKeySequenceLineEdit->setEnabled(hotKeysEnabled && isActiveWindowSupported); mActiveWindowClearPushButton->setEnabled(hotKeysEnabled && isActiveWindowSupported); mWindowUnderCursorLabel->setEnabled(hotKeysEnabled && isWindowUnderCursorSupported); mWindowUnderCursorKeySequenceLineEdit->setEnabled(hotKeysEnabled && isWindowUnderCursorSupported); mWindowUnderCursorClearPushButton->setEnabled(hotKeysEnabled && isWindowUnderCursorSupported); mPortalLabel->setEnabled(hotKeysEnabled && isPortalSupported); mPortalKeySequenceLineEdit->setEnabled(hotKeysEnabled && isPortalSupported); mPortalClearPushButton->setEnabled(hotKeysEnabled && isPortalSupported); } ksnip-master/src/gui/settingsDialog/HotKeySettings.h000066400000000000000000000050171457262621600231410ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_HOTKEYSETTINGS_H #define KSNIP_HOTKEYSETTINGS_H #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/widgets/KeySequenceLineEdit.h" #include "src/gui/globalHotKeys/HotKeyMap.h" class HotKeySettings : public QGroupBox { Q_OBJECT public: explicit HotKeySettings(const QList &captureModes, const QSharedPointer &platformChecker, const QSharedPointer &config); ~HotKeySettings() override; void saveSettings(); private: QCheckBox *mEnableGlobalHotKeysCheckBox; QLabel *mRectAreaLabel; QLabel *mLastRectAreaLabel; QLabel *mFullScreenLabel; QLabel *mCurrentScreenLabel; QLabel *mActiveWindowLabel; QLabel *mWindowUnderCursorLabel; QLabel *mPortalLabel; KeySequenceLineEdit *mRectAreaKeySequenceLineEdit; KeySequenceLineEdit *mLastRectAreaKeySequenceLineEdit; KeySequenceLineEdit *mFullScreenKeySequenceLineEdit; KeySequenceLineEdit *mCurrentScreenKeySequenceLineEdit; KeySequenceLineEdit *mActiveWindowKeySequenceLineEdit; KeySequenceLineEdit *mWindowUnderCursorKeySequenceLineEdit; KeySequenceLineEdit *mPortalKeySequenceLineEdit; QPushButton *mRectAreaClearPushButton; QPushButton *mLastRectAreaClearPushButton; QPushButton *mFullScreenClearPushButton; QPushButton *mCurrentScreenClearPushButton; QPushButton *mActiveWindowClearPushButton; QPushButton *mWindowUnderCursorClearPushButton; QPushButton *mPortalClearPushButton; QGridLayout *mLayout; QList mCaptureModes; QSharedPointer mConfig; QSharedPointer mPlatformChecker; void initGui(); void loadConfig(); private slots: void globalHotKeysStateChanged(); }; #endif //KSNIP_HOTKEYSETTINGS_H ksnip-master/src/gui/settingsDialog/ISettingsFilter.h000066400000000000000000000023651457262621600232770ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ISETTINGSFILTER_H #define KSNIP_ISETTINGSFILTER_H #include #include #include #include #include class ISettingsFilter { public: explicit ISettingsFilter() = default; ~ISettingsFilter() = default; virtual void filterSettings(const QString &filterString, QTreeWidget *treeWidget, std::function getSettingsPageFunc) const = 0; }; #endif //KSNIP_ISETTINGSFILTER_H ksnip-master/src/gui/settingsDialog/ImageGrabberSettings.cpp000066400000000000000000000140161457262621600245770ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImageGrabberSettings.h" ImageGrabberSettings::ImageGrabberSettings(const QSharedPointer &config) : mCaptureCursorCheckbox(new QCheckBox(this)), mHideMainWindowDuringScreenshotCheckbox(new QCheckBox(this)), mShowMainWindowAfterTakingScreenshotCheckbox(new QCheckBox(this)), mForceGenericWaylandCheckbox(new QCheckBox(this)), mScaleGenericWaylandScreenshotsCheckbox(new QCheckBox(this)), mImplicitCaptureDelayLabel(new QLabel(this)), mImplicitCaptureDelaySpinBox(new CustomSpinBox(0, 2000, this)), mLayout(new QGridLayout(this)), mConfig(config) { Q_ASSERT(mConfig != nullptr); initGui(); loadConfig(); } void ImageGrabberSettings::saveSettings() { mConfig->setHideMainWindowDuringScreenshot(mHideMainWindowDuringScreenshotCheckbox->isChecked()); mConfig->setCaptureCursor(mCaptureCursorCheckbox->isChecked()); mConfig->setShowMainWindowAfterTakingScreenshotEnabled(mShowMainWindowAfterTakingScreenshotCheckbox->isChecked()); mConfig->setForceGenericWaylandEnabled(mForceGenericWaylandCheckbox->isChecked()); mConfig->setScaleGenericWaylandScreenshots(mScaleGenericWaylandScreenshotsCheckbox->isChecked()); mConfig->setImplicitCaptureDelay(mImplicitCaptureDelaySpinBox->value()); } void ImageGrabberSettings::initGui() { mCaptureCursorCheckbox->setText(tr("Capture mouse cursor on screenshot")); mCaptureCursorCheckbox->setToolTip(tr("Should mouse cursor be visible on\n" "screenshots.")); mShowMainWindowAfterTakingScreenshotCheckbox->setText(tr("Show Main Window after capturing screenshot")); mShowMainWindowAfterTakingScreenshotCheckbox->setToolTip(tr("Show Main Window after capturing a new screenshot\n" "when the Main Window was hidden or minimize.")); mForceGenericWaylandCheckbox->setText(tr("Force Generic Wayland (xdg-desktop-portal) Screenshot")); mForceGenericWaylandCheckbox->setToolTip(tr("GNOME and KDE Plasma support their own Wayland\n" "and the Generic XDG-DESKTOP-PORTAL screenshots.\n" "Enabling this option will force KDE Plasma and\n" "GNOME to use the XDG-DESKTOP-PORTAL screenshots.\n" "Change in this option require a ksnip restart.")); mScaleGenericWaylandScreenshotsCheckbox->setText(tr("Scale Generic Wayland (xdg-desktop-portal) Screenshots")); mScaleGenericWaylandScreenshotsCheckbox->setToolTip(tr("Generic Wayland implementations that use\n" "XDG-DESKTOP-PORTAL handle screen scaling\n" "differently. Enabling this option will\n" "determine the current screen scaling and\n" "apply that to the screenshot in ksnip.")); mHideMainWindowDuringScreenshotCheckbox->setText(tr("Hide Main Window during screenshot")); mHideMainWindowDuringScreenshotCheckbox->setToolTip(tr("Hide Main Window when capturing a new screenshot.")); mImplicitCaptureDelayLabel->setText(tr("Implicit capture delay") + QLatin1String(":")); mImplicitCaptureDelayLabel->setToolTip(tr("This delay is used when no delay was selected in\n" "the UI, it allows ksnip to hide before taking\n" "a screenshot. This value is not applied when\n" "ksnip was already minimized. Reducing this value\n" "can have the effect that ksnip's main window is\n" "visible on the screenshot.")); mImplicitCaptureDelaySpinBox->setSuffix(QLatin1String("ms")); mImplicitCaptureDelaySpinBox->setToolTip(mImplicitCaptureDelayLabel->toolTip()); mImplicitCaptureDelaySpinBox->setSingleStep(10); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mCaptureCursorCheckbox, 0, 0, 1, 3); mLayout->addWidget(mShowMainWindowAfterTakingScreenshotCheckbox, 1, 0, 1, 3); mLayout->addWidget(mHideMainWindowDuringScreenshotCheckbox, 2, 0, 1, 3); mLayout->addWidget(mForceGenericWaylandCheckbox, 3, 0, 1, 3); mLayout->addWidget(mScaleGenericWaylandScreenshotsCheckbox, 4, 0, 1, 3); mLayout->setRowMinimumHeight(5, 15); mLayout->addWidget(mImplicitCaptureDelayLabel, 6, 0, 1, 1); mLayout->addWidget(mImplicitCaptureDelaySpinBox, 6, 1, Qt::AlignLeft); setTitle(tr("Image Grabber")); setLayout(mLayout); } void ImageGrabberSettings::loadConfig() { mHideMainWindowDuringScreenshotCheckbox->setChecked(mConfig->hideMainWindowDuringScreenshot()); mCaptureCursorCheckbox->setChecked(mConfig->captureCursor()); mShowMainWindowAfterTakingScreenshotCheckbox->setChecked(mConfig->showMainWindowAfterTakingScreenshotEnabled()); mForceGenericWaylandCheckbox->setChecked(mConfig->forceGenericWaylandEnabled()); mForceGenericWaylandCheckbox->setEnabled(!mConfig->isForceGenericWaylandEnabledReadOnly()); mScaleGenericWaylandScreenshotsCheckbox->setChecked(mConfig->scaleGenericWaylandScreenshotsEnabled()); mScaleGenericWaylandScreenshotsCheckbox->setEnabled(!mConfig->isScaleGenericWaylandScreenshotEnabledReadOnly()); mImplicitCaptureDelaySpinBox->setValue(mConfig->implicitCaptureDelay()); } ksnip-master/src/gui/settingsDialog/ImageGrabberSettings.h000066400000000000000000000032531457262621600242450ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEGRABBERSETTINGS_H #define KSNIP_IMAGEGRABBERSETTINGS_H #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/widgets/CustomSpinBox.h" class ImageGrabberSettings : public QGroupBox { Q_OBJECT public: explicit ImageGrabberSettings(const QSharedPointer &config); ~ImageGrabberSettings() override = default; void saveSettings(); private: QCheckBox *mCaptureCursorCheckbox; QCheckBox *mHideMainWindowDuringScreenshotCheckbox; QCheckBox *mShowMainWindowAfterTakingScreenshotCheckbox; QCheckBox *mForceGenericWaylandCheckbox; QCheckBox *mScaleGenericWaylandScreenshotsCheckbox; QLabel *mImplicitCaptureDelayLabel; CustomSpinBox *mImplicitCaptureDelaySpinBox; QGridLayout *mLayout; QSharedPointer mConfig; void initGui(); void loadConfig(); }; #endif //KSNIP_IMAGEGRABBERSETTINGS_H ksnip-master/src/gui/settingsDialog/SaverSettings.cpp000066400000000000000000000144701457262621600233540ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SaverSettings.h" SaverSettings::SaverSettings(const QSharedPointer &config, const QSharedPointer &fileDialogService) : mConfig(config), mAutoSaveNewCapturesCheckbox(new QCheckBox(this)), mPromptToSaveBeforeExitCheckbox(new QCheckBox(this)), mRememberSaveDirectoryCheckbox(new QCheckBox(this)), mSaveQualityDefaultRadioButton(new QRadioButton(this)), mSaveQualityFactorRadioButton(new QRadioButton(this)), mSaveLocationLabel(new QLabel(this)), mSaveLocationLineEdit(new QLineEdit(this)), mBrowseButton(new QPushButton(this)), mOverwriteFileCheckbox(new QCheckBox(this)), mSaveQualityFactorSpinBox(new CustomSpinBox(0, 100, this)), mLayout(new QGridLayout), mSaveQualityLayout(new QGridLayout), mSaveQualityGroupBox(new QGroupBox(this)), mFileDialogService(fileDialogService) { initGui(); loadConfig(); } void SaverSettings::initGui() { mAutoSaveNewCapturesCheckbox->setText(tr("Automatically save new captures to default location")); mPromptToSaveBeforeExitCheckbox->setText(tr("Prompt to save before discarding unsaved changes")); mSaveQualityDefaultRadioButton->setText(tr("Default")); mSaveQualityFactorRadioButton->setText(tr("Factor")); mSaveQualityFactorRadioButton->setToolTip(tr("Specify 0 to obtain small compressed files, 100 for large uncompressed files.\n" "Not all image formats support the full range, JPEG does.")); mSaveQualityFactorSpinBox->setToolTip(mSaveQualityFactorRadioButton->toolTip()); mSaveQualityGroupBox->setTitle(tr("Save Quality")); mRememberSaveDirectoryCheckbox->setText(tr("Remember last Save Directory")); mRememberSaveDirectoryCheckbox->setToolTip(tr("When enabled will overwrite the save directory stored in settings\n" "with the latest save directory, for every save.")); mSaveLocationLabel->setText(tr("Capture save location and filename") + QLatin1String(":")); mSaveLocationLineEdit->setToolTip(tr("Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default.\n" "Filename can contain following wildcards:\n" "- $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format.\n" "- Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002.")); mBrowseButton->setText(tr("Browse")); connect(mBrowseButton, &QPushButton::clicked, this, &SaverSettings::chooseSaveDirectory); mOverwriteFileCheckbox->setText(tr("Overwrite file with same name")); mSaveQualityLayout->addWidget(mSaveQualityDefaultRadioButton, 0, 0, 1, 1); mSaveQualityLayout->addWidget(mSaveQualityFactorRadioButton, 1, 0, 1, 1); mSaveQualityLayout->addWidget(mSaveQualityFactorSpinBox, 1, 1, 1, 1); mSaveQualityLayout->setColumnStretch(2, 1); mSaveQualityGroupBox->setLayout(mSaveQualityLayout); mLayout->setAlignment(Qt::AlignTop); mLayout->addWidget(mAutoSaveNewCapturesCheckbox, 0, 0, 1, 4); mLayout->addWidget(mPromptToSaveBeforeExitCheckbox, 1, 0, 1, 4); mLayout->addWidget(mRememberSaveDirectoryCheckbox, 2, 0, 1, 4); mLayout->setRowMinimumHeight(3, 15); mLayout->addWidget(mSaveQualityGroupBox, 4, 0, 1, 4); mLayout->setRowMinimumHeight(5, 15); mLayout->addWidget(mSaveLocationLabel, 6, 0, 1, 4); mLayout->addWidget(mSaveLocationLineEdit, 7, 0, 1, 3); mLayout->addWidget(mBrowseButton, 7, 3); mLayout->addWidget(mOverwriteFileCheckbox, 8, 0, 1, 4); setTitle(tr("Saver Settings")); setLayout(mLayout); } void SaverSettings::loadConfig() { mAutoSaveNewCapturesCheckbox->setChecked(mConfig->autoSaveNewCaptures()); mPromptToSaveBeforeExitCheckbox->setChecked(mConfig->promptSaveBeforeExit()); mRememberSaveDirectoryCheckbox->setChecked(mConfig->rememberLastSaveDirectory()); mSaveQualityFactorSpinBox->setValue(mConfig->saveQualityFactor()); mSaveQualityDefaultRadioButton->setChecked(mConfig->saveQualityMode() == SaveQualityMode::Default); mSaveQualityFactorRadioButton->setChecked(mConfig->saveQualityMode() == SaveQualityMode::Factor); mSaveLocationLineEdit->setText(mConfig->saveDirectory() + mConfig->saveFilename() + QLatin1String(".") + mConfig->saveFormat()); mOverwriteFileCheckbox->setChecked(mConfig->overwriteFile()); } void SaverSettings::saveSettings() { mConfig->setAutoSaveNewCaptures(mAutoSaveNewCapturesCheckbox->isChecked()); mConfig->setPromptSaveBeforeExit(mPromptToSaveBeforeExitCheckbox->isChecked()); mConfig->setRememberLastSaveDirectory(mRememberSaveDirectoryCheckbox->isChecked()); mConfig->setSaveQualityMode(getSaveQualityMode()); mConfig->setSaveQualityFactor(mSaveQualityFactorSpinBox->value()); mConfig->setSaveDirectory(PathHelper::extractParentDirectory(mSaveLocationLineEdit->displayText())); mConfig->setSaveFilename(PathHelper::extractFilename(mSaveLocationLineEdit->displayText())); mConfig->setSaveFormat(PathHelper::extractFormat(mSaveLocationLineEdit->displayText())); mConfig->setOverwriteFile(mOverwriteFileCheckbox->isChecked()); } void SaverSettings::chooseSaveDirectory() { auto path = mFileDialogService->getExistingDirectory(this, tr("Capture save location"), mConfig->saveDirectory()); if(!path.isEmpty()) { auto filename = PathHelper::extractFilename(mSaveLocationLineEdit->text()); auto format = PathHelper::extractFormat(mSaveLocationLineEdit->text()); if(!filename.isEmpty()) { path.append(QLatin1Char('/')).append(filename); } if(!format.isEmpty()) { path.append(QLatin1Char('.')).append(format); } mSaveLocationLineEdit->setText(path); } } SaveQualityMode SaverSettings::getSaveQualityMode() { return mSaveQualityDefaultRadioButton->isChecked() ? SaveQualityMode::Default : SaveQualityMode::Factor; } ksnip-master/src/gui/settingsDialog/SaverSettings.h000066400000000000000000000042461457262621600230210ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SAVERSETTINGS_H #define KSNIP_SAVERSETTINGS_H #include #include #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/adapter/fileDialog/IFileDialogService.h" #include "src/common/helper/PathHelper.h" #include "src/widgets/CustomSpinBox.h" class SaverSettings : public QGroupBox { Q_OBJECT public: explicit SaverSettings(const QSharedPointer &config, const QSharedPointer &fileDialogService); ~SaverSettings() override = default; void saveSettings(); private: QCheckBox *mAutoSaveNewCapturesCheckbox; QCheckBox *mPromptToSaveBeforeExitCheckbox; QCheckBox *mRememberSaveDirectoryCheckbox; QRadioButton *mSaveQualityDefaultRadioButton; QRadioButton *mSaveQualityFactorRadioButton; QLabel *mSaveLocationLabel; QLineEdit *mSaveLocationLineEdit; QPushButton *mBrowseButton; QCheckBox *mOverwriteFileCheckbox; CustomSpinBox *mSaveQualityFactorSpinBox; QGridLayout *mLayout; QGridLayout *mSaveQualityLayout; QGroupBox *mSaveQualityGroupBox; QSharedPointer mConfig; QSharedPointer mFileDialogService; void initGui(); void loadConfig(); private slots: void chooseSaveDirectory(); SaveQualityMode getSaveQualityMode(); }; #endif //KSNIP_SAVERSETTINGS_H ksnip-master/src/gui/settingsDialog/SettingsDialog.cpp000066400000000000000000000211311457262621600234630ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "SettingsDialog.h" SettingsDialog::SettingsDialog( const QList &captureModes, const QSharedPointer &config, const QSharedPointer &scaledSizeProvider, const QSharedPointer &directoryPathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &platformChecker, const QSharedPointer &pluginFinder, QWidget *parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint), mOkButton(new QPushButton), mCancelButton(new QPushButton), mTreeWidget(new QTreeWidget), mStackedLayout(new QStackedLayout), mConfig(config), mScaledSizeProvider(scaledSizeProvider), mSettingsFilter(new SettingsFilter()), mEmptyWidget(new QWidget()), mApplicationSettings(new ApplicationSettings(mConfig, fileDialogService)), mImageGrabberSettings(new ImageGrabberSettings(mConfig)), mImgurUploaderSettings(new ImgurUploaderSettings(mConfig)), mScriptUploaderSettings(new ScriptUploaderSettings(mConfig, fileDialogService)), mAnnotationSettings(new AnnotationSettings(mConfig, mScaledSizeProvider)), mHotKeySettings(new HotKeySettings(captureModes, platformChecker, mConfig)), mUploaderSettings(new UploaderSettings(mConfig)), mSaverSettings(new SaverSettings(mConfig, fileDialogService)), mStickerSettings(new StickerSettings(mConfig, directoryPathProvider)), mTrayIconSettings(new TrayIconSettings(captureModes, mConfig)), mSnippingAreaSettings(new SnippingAreaSettings(mConfig, mScaledSizeProvider)), mWatermarkSettings(new WatermarkSettings(mConfig, mScaledSizeProvider)), mActionsSettings(new ActionsSettings(captureModes, platformChecker, mConfig)), mPluginsSettings(new PluginsSettings(mConfig, fileDialogService, pluginFinder)), mSearchSettingsLineEdit(new QLineEdit(this)), mFtpUploaderSettings(new FtpUploaderSettings(mConfig)) { setWindowTitle(QApplication::applicationName() + QLatin1String(" - ") + tr("Settings")); initGui(); connect(mTreeWidget, &QTreeWidget::itemSelectionChanged, this, &SettingsDialog::switchTab); connect(mSearchSettingsLineEdit, &QLineEdit::textChanged, this, &SettingsDialog::filterSettings); } SettingsDialog::~SettingsDialog() { delete mOkButton; delete mCancelButton; delete mTreeWidget; delete mStackedLayout; delete mEmptyWidget; delete mApplicationSettings; delete mImageGrabberSettings; delete mImgurUploaderSettings; delete mAnnotationSettings; delete mHotKeySettings; delete mUploaderSettings; delete mSaverSettings; delete mStickerSettings; delete mTrayIconSettings; delete mSnippingAreaSettings; delete mWatermarkSettings; delete mActionsSettings; delete mFtpUploaderSettings; delete mPluginsSettings; } void SettingsDialog::saveSettings() { mApplicationSettings->saveSettings(); mImageGrabberSettings->saveSettings(); mUploaderSettings->saveSettings(); mImgurUploaderSettings->saveSettings(); mScriptUploaderSettings->saveSettings(); mAnnotationSettings->saveSettings(); mHotKeySettings->saveSettings(); mSaverSettings->saveSettings(); mStickerSettings->saveSettings(); mTrayIconSettings->saveSettings(); mSnippingAreaSettings->saveSettings(); mWatermarkSettings->saveSettings(); mActionsSettings->saveSettings(); mFtpUploaderSettings->saveSettings(); mPluginsSettings->saveSettings(); } void SettingsDialog::initGui() { mOkButton->setText(tr("OK")); connect(mOkButton, &QPushButton::clicked, this, &SettingsDialog::okClicked); mCancelButton->setText(tr("Cancel")); connect(mCancelButton, &QPushButton::clicked, this, &SettingsDialog::cancelClicked); auto buttonLayout = new QHBoxLayout; buttonLayout->addWidget(mOkButton); buttonLayout->addWidget(mCancelButton); buttonLayout->setAlignment(Qt::AlignRight); mStackedLayout->addWidget(mApplicationSettings); mStackedLayout->addWidget(mSaverSettings); mStackedLayout->addWidget(mTrayIconSettings); mStackedLayout->addWidget(mImageGrabberSettings); mStackedLayout->addWidget(mSnippingAreaSettings); mStackedLayout->addWidget(mUploaderSettings); mStackedLayout->addWidget(mImgurUploaderSettings); mStackedLayout->addWidget(mFtpUploaderSettings); mStackedLayout->addWidget(mScriptUploaderSettings); mStackedLayout->addWidget(mAnnotationSettings); mStackedLayout->addWidget(mStickerSettings); mStackedLayout->addWidget(mWatermarkSettings); mStackedLayout->addWidget(mHotKeySettings); mStackedLayout->addWidget(mActionsSettings); mStackedLayout->addWidget(mPluginsSettings); mStackedLayout->addWidget(mEmptyWidget); auto application = new QTreeWidgetItem(mTreeWidget, { tr("Application") }); auto saver = new QTreeWidgetItem(application, { tr("Saver") }); auto trayIcon = new QTreeWidgetItem(application, { tr("Tray Icon") }); auto imageGrabber = new QTreeWidgetItem(mTreeWidget, { tr("Image Grabber") }); auto snippingArea = new QTreeWidgetItem(imageGrabber, { tr("Snipping Area") }); auto uploader = new QTreeWidgetItem(mTreeWidget, { tr("Uploader") }); auto imgurUploader = new QTreeWidgetItem(uploader, { tr("Imgur Uploader") }); auto ftpUploader = new QTreeWidgetItem(uploader, { tr("FTP Uploader") }); auto scriptUploader = new QTreeWidgetItem(uploader, { tr("Script Uploader") }); auto annotator = new QTreeWidgetItem(mTreeWidget, { tr("Annotator") }); auto stickers = new QTreeWidgetItem(annotator, { tr("Stickers") }); auto watermark = new QTreeWidgetItem(annotator, { tr("Watermark") }); auto hotkeys = new QTreeWidgetItem(mTreeWidget, { tr("HotKeys") }); auto actions = new QTreeWidgetItem(mTreeWidget, { tr("Actions") }); auto plugins = new QTreeWidgetItem(mTreeWidget, { tr("Plugins") }); mNavigatorItems.append(application); mNavigatorItems.append(saver); mNavigatorItems.append(trayIcon); mNavigatorItems.append(imageGrabber); mNavigatorItems.append(snippingArea); mNavigatorItems.append(uploader); mNavigatorItems.append(imgurUploader); mNavigatorItems.append(ftpUploader); mNavigatorItems.append(scriptUploader); mNavigatorItems.append(annotator); mNavigatorItems.append(stickers); mNavigatorItems.append(watermark); mNavigatorItems.append(hotkeys); mNavigatorItems.append(actions); mNavigatorItems.append(plugins); mTreeWidget->addTopLevelItem(application); mTreeWidget->addTopLevelItem(imageGrabber); mTreeWidget->addTopLevelItem(uploader); mTreeWidget->addTopLevelItem(annotator); mTreeWidget->addTopLevelItem(hotkeys); mTreeWidget->addTopLevelItem(actions); mTreeWidget->addTopLevelItem(plugins); mTreeWidget->setHeaderHidden(true); mTreeWidget->setItemSelected(mNavigatorItems[0], true); mTreeWidget->setFixedWidth(mTreeWidget->minimumSizeHint().width() + mScaledSizeProvider->scaledWidth(100)); mTreeWidget->expandAll(); mSearchSettingsLineEdit->setPlaceholderText(tr("Search Settings...")); mSearchSettingsLineEdit->setFixedWidth(mTreeWidget->width()); mSearchSettingsLineEdit->setClearButtonEnabled(true); auto settingsNavigationLayout = new QVBoxLayout(); settingsNavigationLayout->addWidget(mSearchSettingsLineEdit); settingsNavigationLayout->addWidget(mTreeWidget); auto listAndStackLayout = new QHBoxLayout; listAndStackLayout->addLayout(settingsNavigationLayout); listAndStackLayout->addLayout(mStackedLayout); auto mainLayout = new QVBoxLayout(); mainLayout->addLayout(listAndStackLayout); mainLayout->addLayout(buttonLayout); setLayout(mainLayout); } void SettingsDialog::switchTab() { if (mTreeWidget->selectedItems().empty()) { mStackedLayout->setCurrentIndex(mNavigatorItems.size()); } else { mStackedLayout->setCurrentIndex(mNavigatorItems.indexOf(mTreeWidget->currentItem())); } } void SettingsDialog::filterSettings(const QString &filterString) { mSettingsFilter->filterSettings(filterString, mTreeWidget, [this](QTreeWidgetItem *treeWidgetItem) { return mStackedLayout->itemAt(mNavigatorItems.indexOf(treeWidgetItem))->widget(); }); } void SettingsDialog::okClicked() { saveSettings(); close(); } void SettingsDialog::cancelClicked() { close(); } ksnip-master/src/gui/settingsDialog/SettingsDialog.h000066400000000000000000000066211457262621600231370ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_SETTINGSDIALOG_H #define KSNIP_SETTINGSDIALOG_H #include #include #include #include #include "AnnotationSettings.h" #include "ApplicationSettings.h" #include "ImageGrabberSettings.h" #include "SettingsFilter.h" #include "HotKeySettings.h" #include "SaverSettings.h" #include "StickerSettings.h" #include "TrayIconSettings.h" #include "SnippingAreaSettings.h" #include "WatermarkSettings.h" #include "src/gui/settingsDialog/uploader/UploaderSettings.h" #include "src/gui/settingsDialog/uploader/ImgurUploaderSettings.h" #include "src/gui/settingsDialog/uploader/ScriptUploaderSettings.h" #include "src/gui/settingsDialog/uploader/FtpUploaderSettings.h" #include "src/gui/settingsDialog/actions/ActionsSettings.h" #include "src/gui/settingsDialog/plugins/PluginsSettings.h" #include "src/backend/config/IConfig.h" #include "src/common/provider/scaledSizeProvider/IScaledSizeProvider.h" class SettingsDialog : public QDialog { Q_OBJECT public: explicit SettingsDialog( const QList &captureModes, const QSharedPointer &config, const QSharedPointer &scaledSizeProvider, const QSharedPointer &directoryPathProvider, const QSharedPointer &fileDialogService, const QSharedPointer &platformChecker, const QSharedPointer &pluginFinder, QWidget *parent); ~SettingsDialog() override; private: QSharedPointer mConfig; QSharedPointer mScaledSizeProvider; QSharedPointer mSettingsFilter; QPushButton *mOkButton; QPushButton *mCancelButton; QWidget *mEmptyWidget; ApplicationSettings *mApplicationSettings; ImageGrabberSettings *mImageGrabberSettings; ImgurUploaderSettings *mImgurUploaderSettings; ScriptUploaderSettings *mScriptUploaderSettings; HotKeySettings *mHotKeySettings; AnnotationSettings *mAnnotationSettings; UploaderSettings *mUploaderSettings; SaverSettings *mSaverSettings; StickerSettings *mStickerSettings; TrayIconSettings *mTrayIconSettings; SnippingAreaSettings *mSnippingAreaSettings; WatermarkSettings *mWatermarkSettings; ActionsSettings *mActionsSettings; FtpUploaderSettings *mFtpUploaderSettings; PluginsSettings *mPluginsSettings; QLineEdit *mSearchSettingsLineEdit; QTreeWidget *mTreeWidget; QStackedLayout *mStackedLayout; QList mNavigatorItems; void saveSettings(); void initGui(); private slots: void switchTab(); void filterSettings(const QString &filterString); void cancelClicked(); void okClicked(); }; #endif // KSNIP_SETTINGSDIALOG_H ksnip-master/src/gui/settingsDialog/SettingsFilter.cpp000066400000000000000000000073201457262621600235150ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include "SettingsFilter.h" void SettingsFilter::filterSettings( const QString &filterString, QTreeWidget *treeWidget, std::function getSettingsPageFunc) const { if (filterString.isEmpty()) { for (auto topLevelItemIndex = 0; topLevelItemIndex < treeWidget->topLevelItemCount(); ++topLevelItemIndex) { auto topLevelItem = treeWidget->topLevelItem(topLevelItemIndex); for (auto childIndex = 0; childIndex < topLevelItem->childCount(); ++childIndex) { topLevelItem->child(childIndex)->setHidden(false); } topLevelItem->setHidden(false); } return; } for (auto index = 0; index < treeWidget->topLevelItemCount(); ++index) { filterNavigatorItem(treeWidget->topLevelItem(index), filterString, getSettingsPageFunc); } for (auto topLevelItemIndex = 0; topLevelItemIndex < treeWidget->topLevelItemCount(); ++topLevelItemIndex) { if (!treeWidget->topLevelItem(topLevelItemIndex)->isHidden()) { treeWidget->setCurrentItem(treeWidget->topLevelItem(topLevelItemIndex)); return; } } treeWidget->clearSelection(); } bool SettingsFilter::filterNavigatorItem( QTreeWidgetItem *navigatorItem, const QString &filterString, std::function getSettingsPageFunc) const { bool isFiltered{true}; if (navigatorItem->text(0).contains(filterString, Qt::CaseInsensitive)) { navigatorItem->setDisabled(false); for (auto index = 0; index < navigatorItem->childCount(); ++index) { filterNavigatorItem(navigatorItem->child(index), filterString, getSettingsPageFunc); } isFiltered = false; } else { isFiltered = !settingsPageContainsFilterString(getSettingsPageFunc(navigatorItem), filterString); for (auto index = 0; index < navigatorItem->childCount(); ++index) { isFiltered &= filterNavigatorItem(navigatorItem->child(index), filterString, getSettingsPageFunc); } } navigatorItem->setHidden(isFiltered); return isFiltered; } bool SettingsFilter::settingsPageContainsFilterString(QWidget *settingsPage, const QString &filterString) const { foreach (auto button, settingsPage->findChildren()) { if (button->text().contains(filterString, Qt::CaseInsensitive)) { return true; } } foreach (auto label, settingsPage->findChildren()) { if (label->text().contains(filterString, Qt::CaseInsensitive)) { return true; } } foreach (auto lineEdit, settingsPage->findChildren()) { if (lineEdit->text().contains(filterString, Qt::CaseInsensitive)) { return true; } if (lineEdit->placeholderText().contains(filterString, Qt::CaseInsensitive)) { return true; } } foreach (auto comboBox, settingsPage->findChildren()) { for (int index = 0; index < comboBox->count(); ++index) { if (comboBox->itemText(index).contains(filterString, Qt::CaseInsensitive)) { return true; } } } return false; } ksnip-master/src/gui/settingsDialog/SettingsFilter.h000066400000000000000000000027221457262621600231630ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SETTINGSFILTER_H #define KSNIP_SETTINGSFILTER_H #include "ISettingsFilter.h" class SettingsFilter : public ISettingsFilter { public: explicit SettingsFilter() = default; ~SettingsFilter() = default; void filterSettings( const QString &filterString, QTreeWidget *treeWidget, std::function getSettingsPageFunc) const override; private: bool filterNavigatorItem( QTreeWidgetItem *navigatorItem, const QString &filterString, std::function getSettingsPageFunc) const; bool settingsPageContainsFilterString(QWidget *settingsPage, const QString &filterString) const; }; #endif //KSNIP_SETTINGSFILTER_H ksnip-master/src/gui/settingsDialog/SnippingAreaSettings.cpp000066400000000000000000000270711457262621600246550ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnippingAreaSettings.h" SnippingAreaSettings::SnippingAreaSettings(const QSharedPointer &config, const QSharedPointer &scaledSizeProvider) : mConfig(config), mScaledSizeProvider(scaledSizeProvider), mFreezeImageWhileSnippingCheckbox(new QCheckBox(this)), mSnippingAreaRulersCheckbox(new QCheckBox(this)), mSnippingAreaPositionAndSizeInfoCheckbox(new QCheckBox(this)), mSnippingAreaMagnifyingGlassCheckbox(new QCheckBox(this)), mAllowResizingRectSelectionCheckbox(new QCheckBox(this)), mShowSnippingAreaInfoTextCheckbox(new QCheckBox(this)), mSnippingAreaOffsetEnabledCheckbox(new QCheckBox(this)), mSnippingCursorSizeLabel(new QLabel(this)), mSnippingCursorColorLabel(new QLabel(this)), mSnippingAdornerColorLabel(new QLabel(this)), mSnippingAreaTransparencyLabel(new QLabel(this)), mSnippingAreaOffsetXLabel(new QLabel(this)), mSnippingAreaOffsetYLabel(new QLabel(this)), mSnippingCursorSizeCombobox(new NumericComboBox(1, 2, 3)), mSnippingCursorColorButton(new ColorButton(this)), mSnippingAdornerColorButton(new ColorButton(this)), mSnippingAreaTransparencySpinBox(new QSpinBox(this)), mSnippingAreaOffsetXSpinBox(new QDoubleSpinBox(this)), mSnippingAreaOffsetYSpinBox(new QDoubleSpinBox(this)), mLayout(new QGridLayout(this)) { initGui(); loadConfig(); } SnippingAreaSettings::~SnippingAreaSettings() { delete mSnippingCursorSizeCombobox; } void SnippingAreaSettings::saveSettings() { mConfig->setFreezeImageWhileSnippingEnabled(mFreezeImageWhileSnippingCheckbox->isChecked()); mConfig->setSnippingAreaMagnifyingGlassEnabled(mSnippingAreaMagnifyingGlassCheckbox->isChecked()); mConfig->setSnippingAreaRulersEnabled(mSnippingAreaRulersCheckbox->isChecked()); mConfig->setSnippingAreaPositionAndSizeInfoEnabled(mSnippingAreaPositionAndSizeInfoCheckbox->isChecked()); mConfig->setAllowResizingRectSelection(mAllowResizingRectSelectionCheckbox->isChecked()); mConfig->setShowSnippingAreaInfoText(mShowSnippingAreaInfoTextCheckbox->isChecked()); mConfig->setSnippingCursorColor(mSnippingCursorColorButton->color()); mConfig->setSnippingAdornerColor(mSnippingAdornerColorButton->color()); mConfig->setSnippingCursorSize(mSnippingCursorSizeCombobox->value()); mConfig->setSnippingAreaTransparency(mSnippingAreaTransparencySpinBox->value()); mConfig->setSnippingAreaOffsetEnable(mSnippingAreaOffsetEnabledCheckbox->isChecked()); mConfig->setSnippingAreaOffset({mSnippingAreaOffsetXSpinBox->value(), mSnippingAreaOffsetYSpinBox->value()}); } void SnippingAreaSettings::initGui() { auto const fixedButtonWidth = mScaledSizeProvider->scaledWidth(70); mFreezeImageWhileSnippingCheckbox->setText(tr("Freeze Image while snipping")); mFreezeImageWhileSnippingCheckbox->setToolTip(tr("When enabled will freeze the background while\n" "selecting a rectangular region. It also changes\n" "the behavior of delayed screenshots, with this\n" "option enabled the delay happens before the\n" "snipping area is shown and with the option disabled\n" "the delay happens after the snipping area is shown.\n" "This feature is always disabled for Wayland and always\n" "enabled for MacOs.")); connect(mFreezeImageWhileSnippingCheckbox, &QCheckBox::stateChanged, this, &SnippingAreaSettings::freezeImageWhileSnippingStateChanged); mSnippingAreaMagnifyingGlassCheckbox->setText(tr("Show magnifying glass on snipping area")); mSnippingAreaMagnifyingGlassCheckbox->setToolTip(tr("Show a magnifying glass which zooms into\n" "the background image. This option only works\n" "with 'Freeze Image while snipping' enabled.")); mSnippingAreaRulersCheckbox->setText(tr("Show Snipping Area rulers")); mSnippingAreaRulersCheckbox->setToolTip(tr("Horizontal and vertical lines going from\n" "desktop edges to cursor on snipping area.")); mSnippingAreaPositionAndSizeInfoCheckbox->setText(tr("Show Snipping Area position and size info")); mSnippingAreaPositionAndSizeInfoCheckbox->setToolTip(tr("When left mouse button is not pressed the position\n" "is shown, when the mouse button is pressed,\n" "the size of the select area is shown left\n" "and above from the captured area.")); mAllowResizingRectSelectionCheckbox->setText(tr("Allow resizing rect area selection by default")); mAllowResizingRectSelectionCheckbox->setToolTip(tr("When enabled will, after selecting a rect\n" "area, allow resizing the selection. When\n" "done resizing the selection can be confirmed\n" "by pressing return.")); mShowSnippingAreaInfoTextCheckbox->setText(tr("Show Snipping Area info text")); mSnippingCursorColorLabel->setText(tr("Snipping Area cursor color") + QLatin1String(":")); mSnippingCursorColorLabel->setToolTip(tr("Sets the color of the snipping area cursor.")); mSnippingCursorColorButton->setMinimumWidth(fixedButtonWidth); mSnippingCursorColorButton->setToolTip(mSnippingCursorColorLabel->toolTip()); mSnippingAdornerColorLabel->setText(tr("Snipping Area adorner color") + QLatin1String(":")); mSnippingAdornerColorLabel->setToolTip(tr("Sets the color of all adorner elements\n" "on the snipping area.")); mSnippingAdornerColorButton->setMinimumWidth(fixedButtonWidth); mSnippingAdornerColorButton->setToolTip(mSnippingAdornerColorLabel->toolTip()); mSnippingCursorSizeLabel->setText(tr("Snipping Area cursor thickness") + QLatin1String(":")); mSnippingCursorSizeLabel->setToolTip(tr("Sets the thickness of the snipping area cursor.")); mSnippingCursorSizeCombobox->setMinimumWidth(fixedButtonWidth); mSnippingCursorSizeCombobox->setToolTip(mSnippingCursorSizeLabel->toolTip()); mSnippingAreaTransparencyLabel->setText(tr("Snipping Area Transparency")); mSnippingAreaTransparencyLabel->setToolTip(tr("Alpha for not selected region on snipping area.\n" "Smaller number is more transparent.")); mSnippingAreaTransparencySpinBox->setMinimum(0); mSnippingAreaTransparencySpinBox->setMaximum(200); mSnippingAreaTransparencySpinBox->setToolTip(mSnippingAreaTransparencyLabel->toolTip()); mSnippingAreaTransparencySpinBox->setMinimumWidth(fixedButtonWidth); mSnippingAreaOffsetEnabledCheckbox->setText(tr("Enable Snipping Area offset")); mSnippingAreaOffsetEnabledCheckbox->setToolTip(tr("When enabled will apply the configured\n" "offset to the Snipping Area position which\n" "is required when the position is not\n" "correctly calculated. This is sometimes\n" "required with screen scaling enabled.")); connect(mSnippingAreaOffsetEnabledCheckbox, &QCheckBox::stateChanged, this, &SnippingAreaSettings::snippingAreaOffsetEnableStateChanged); mSnippingAreaOffsetXLabel->setText(tr("X") + QLatin1String(":")); mSnippingAreaOffsetYLabel->setText(tr("Y") + QLatin1String(":")); mSnippingAreaOffsetXSpinBox->setMinimum(-9999); mSnippingAreaOffsetXSpinBox->setMaximum(9999); mSnippingAreaOffsetXSpinBox->setDecimals(2); mSnippingAreaOffsetYSpinBox->setMinimum(-9999); mSnippingAreaOffsetYSpinBox->setMaximum(9999); mSnippingAreaOffsetYSpinBox->setDecimals(2); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, mScaledSizeProvider->scaledWidth(10)); mLayout->setColumnMinimumWidth(1, mScaledSizeProvider->scaledWidth(30)); mLayout->addWidget(mFreezeImageWhileSnippingCheckbox, 0, 0, 1, 5); mLayout->addWidget(mSnippingAreaMagnifyingGlassCheckbox, 1, 1, 1, 4); mLayout->addWidget(mSnippingAreaRulersCheckbox, 2, 0, 1, 5); mLayout->addWidget(mSnippingAreaPositionAndSizeInfoCheckbox, 3, 0, 1, 5); mLayout->addWidget(mAllowResizingRectSelectionCheckbox, 4, 0, 1, 5); mLayout->addWidget(mShowSnippingAreaInfoTextCheckbox, 5, 0, 1, 5); mLayout->setRowMinimumHeight(6, 15); mLayout->addWidget(mSnippingAdornerColorLabel, 7, 0, 1, 3); mLayout->addWidget(mSnippingAdornerColorButton, 7, 3, Qt::AlignLeft); mLayout->addWidget(mSnippingCursorColorLabel, 8, 0, 1, 3); mLayout->addWidget(mSnippingCursorColorButton, 8, 3, Qt::AlignLeft); mLayout->addWidget(mSnippingCursorSizeLabel, 9, 0, 1, 3); mLayout->addWidget(mSnippingCursorSizeCombobox, 9, 3, Qt::AlignLeft); mLayout->addWidget(mSnippingAreaTransparencyLabel, 10, 0, 1, 3); mLayout->addWidget(mSnippingAreaTransparencySpinBox, 10, 3, Qt::AlignLeft); mLayout->setRowMinimumHeight(11, 15); mLayout->addWidget(mSnippingAreaOffsetEnabledCheckbox, 12, 0, 1, 5); mLayout->addWidget(mSnippingAreaOffsetXLabel, 13, 1, 1, 1); mLayout->addWidget(mSnippingAreaOffsetXSpinBox, 13, 2, Qt::AlignLeft); mLayout->addWidget(mSnippingAreaOffsetYLabel, 14, 1, 1, 1); mLayout->addWidget(mSnippingAreaOffsetYSpinBox, 14, 2, Qt::AlignLeft); setTitle(tr("Snipping Area")); setLayout(mLayout); } void SnippingAreaSettings::loadConfig() { mFreezeImageWhileSnippingCheckbox->setChecked(mConfig->freezeImageWhileSnippingEnabled()); mFreezeImageWhileSnippingCheckbox->setEnabled(!mConfig->isFreezeImageWhileSnippingEnabledReadOnly()); mSnippingAreaMagnifyingGlassCheckbox->setChecked(mConfig->snippingAreaMagnifyingGlassEnabled()); mSnippingAreaMagnifyingGlassCheckbox->setEnabled(!mConfig->isSnippingAreaMagnifyingGlassEnabledReadOnly()); mSnippingAreaRulersCheckbox->setChecked(mConfig->snippingAreaRulersEnabled()); mSnippingAreaPositionAndSizeInfoCheckbox->setChecked(mConfig->snippingAreaPositionAndSizeInfoEnabled()); mAllowResizingRectSelectionCheckbox->setChecked(mConfig->allowResizingRectSelection()); mShowSnippingAreaInfoTextCheckbox->setChecked(mConfig->showSnippingAreaInfoText()); mSnippingCursorColorButton->setColor(mConfig->snippingCursorColor()); mSnippingAdornerColorButton->setColor(mConfig->snippingAdornerColor()); mSnippingCursorSizeCombobox->setValue(mConfig->snippingCursorSize()); mSnippingAreaTransparencySpinBox->setValue(mConfig->snippingAreaTransparency()); mSnippingAreaOffsetEnabledCheckbox->setChecked(mConfig->snippingAreaOffsetEnable()); mSnippingAreaOffsetXSpinBox->setValue(mConfig->snippingAreaOffset().x()); mSnippingAreaOffsetYSpinBox->setValue(mConfig->snippingAreaOffset().y()); freezeImageWhileSnippingStateChanged(); snippingAreaOffsetEnableStateChanged(); } void SnippingAreaSettings::freezeImageWhileSnippingStateChanged() { mSnippingAreaMagnifyingGlassCheckbox->setEnabled(mFreezeImageWhileSnippingCheckbox->isChecked()); } void SnippingAreaSettings::snippingAreaOffsetEnableStateChanged() { auto isEnabled = mSnippingAreaOffsetEnabledCheckbox->isChecked(); mSnippingAreaOffsetXLabel->setEnabled(isEnabled); mSnippingAreaOffsetYLabel->setEnabled(isEnabled); mSnippingAreaOffsetXSpinBox->setEnabled(isEnabled); mSnippingAreaOffsetYSpinBox->setEnabled(isEnabled); } ksnip-master/src/gui/settingsDialog/SnippingAreaSettings.h000066400000000000000000000050031457262621600243110ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNIPPINGAREASETTINGS_H #define KSNIP_SNIPPINGAREASETTINGS_H #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/widgets/ColorButton.h" #include "src/widgets/NumericComboBox.h" #include "src/common/provider/scaledSizeProvider/IScaledSizeProvider.h" class SnippingAreaSettings : public QGroupBox { Q_OBJECT public: explicit SnippingAreaSettings(const QSharedPointer &config, const QSharedPointer &scaledSizeProvider); ~SnippingAreaSettings() override; void saveSettings(); private: QCheckBox *mFreezeImageWhileSnippingCheckbox; QCheckBox *mSnippingAreaRulersCheckbox; QCheckBox *mSnippingAreaPositionAndSizeInfoCheckbox; QCheckBox *mSnippingAreaMagnifyingGlassCheckbox; QCheckBox *mAllowResizingRectSelectionCheckbox; QCheckBox *mShowSnippingAreaInfoTextCheckbox; QCheckBox *mSnippingAreaOffsetEnabledCheckbox; QLabel *mSnippingCursorSizeLabel; QLabel *mSnippingCursorColorLabel; QLabel *mSnippingAdornerColorLabel; QLabel *mSnippingAreaTransparencyLabel; QLabel *mSnippingAreaOffsetXLabel; QLabel *mSnippingAreaOffsetYLabel; ColorButton *mSnippingCursorColorButton; ColorButton *mSnippingAdornerColorButton; NumericComboBox *mSnippingCursorSizeCombobox; QSpinBox *mSnippingAreaTransparencySpinBox; QDoubleSpinBox *mSnippingAreaOffsetXSpinBox; QDoubleSpinBox *mSnippingAreaOffsetYSpinBox; QGridLayout *mLayout; QSharedPointer mConfig; QSharedPointer mScaledSizeProvider; void initGui(); void loadConfig(); private slots: void freezeImageWhileSnippingStateChanged(); void snippingAreaOffsetEnableStateChanged(); }; #endif //KSNIP_SNIPPINGAREASETTINGS_H ksnip-master/src/gui/settingsDialog/StickerSettings.cpp000066400000000000000000000130351457262621600236740ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "StickerSettings.h" StickerSettings::StickerSettings(const QSharedPointer &config, const QSharedPointer &directoryPathProvider) : mConfig(config), mDirectoryPathProvider(directoryPathProvider), mListWidget(new QListWidget(this)), mAddButton(new QPushButton(this)), mRemoveButton(new QPushButton(this)), mUpButton(new QPushButton(this)), mDownButton(new QPushButton(this)), mUseDefaultStickerCheckBox(new QCheckBox(this)), mLayout(new QGridLayout), mPathDataKey(1001), mIsSavedDataKey(1002), mIsRemovedDataKey(1003) { initGui(); loadConfig(); } StickerSettings::~StickerSettings() { delete mListWidget; delete mAddButton; delete mRemoveButton; delete mUpButton; delete mDownButton; delete mUseDefaultStickerCheckBox; delete mLayout; } void StickerSettings::saveSettings() { auto selectedSticker = processSticker(); mConfig->setUseDefaultSticker(mUseDefaultStickerCheckBox->isChecked()); mConfig->setStickerPaths(selectedSticker); } QStringList StickerSettings::processSticker() const { QStringList paths; for (int i = 0; i < mListWidget->count(); i++) { auto path = mListWidget->item(i)->data(mPathDataKey).toString(); auto isSaved = mListWidget->item(i)->data(mIsSavedDataKey).toBool(); auto isRemovedSaved = mListWidget->item(i)->data(mIsRemovedDataKey).toBool(); if(isSaved && isRemovedSaved) { QFile::remove(path); } else if (isSaved) { paths.append(path); } else { auto directory = stickerDirectory(); auto filename = PathHelper::extractFilenameWithFormat(path); auto newPath = directory + QLatin1String("/") + filename; QFile::copy(path, newPath); paths.append(newPath); } } return paths; } QString StickerSettings::stickerDirectory() const { auto directory = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QDir qdir; qdir.mkpath(directory); return directory; } void StickerSettings::initGui() { connect(mListWidget, &QListWidget::currentRowChanged, this, &StickerSettings::currentRowChanged); mAddButton->setText(tr("Add")); connect(mAddButton, &QPushButton::clicked, this, &StickerSettings::addTriggered); mRemoveButton->setText(tr("Remove")); connect(mRemoveButton, &QPushButton::clicked, this, &StickerSettings::removeTriggered); mUpButton->setText(tr("Up")); connect(mUpButton, &QPushButton::clicked, this, &StickerSettings::upTriggered); mDownButton->setText(tr("Down")); connect(mDownButton, &QPushButton::clicked, this, &StickerSettings::downTriggered); mUseDefaultStickerCheckBox->setText(tr("Use Default Stickers")); mLayout->setAlignment(Qt::AlignTop); mLayout->addWidget(mListWidget, 0, 0, 5,1); mLayout->addWidget(mAddButton, 0, 1, 1,1), mLayout->addWidget(mRemoveButton, 1, 1, 1,1), mLayout->addWidget(mUpButton, 2, 1, 1,1), mLayout->addWidget(mDownButton, 3, 1, 1,1), mLayout->addWidget(mUseDefaultStickerCheckBox, 6, 0, 1,1), mLayout->setRowStretch(0,1); setTitle(tr("Sticker Settings")); setLayout(mLayout); } void StickerSettings::loadConfig() { auto list = mConfig->stickerPaths(); for(const auto& path : list) { addSticker(path, true); } currentRowChanged(mListWidget->currentRow()); mUseDefaultStickerCheckBox->setChecked(mConfig->useDefaultSticker()); } void StickerSettings::addTriggered() { auto title = tr("Add Stickers"); auto filter = tr("Vector Image Files (*.svg)"); auto paths = QFileDialog::getOpenFileNames(this, title, mDirectoryPathProvider->home(), filter); for(const auto& path : paths) { addSticker(path, false); } } void StickerSettings::addSticker(const QString &path, bool isSaved) const { auto filename = PathHelper::extractFilename(path); auto item = new QListWidgetItem(QIcon(path), filename); item->setData(mPathDataKey, path); item->setData(mIsSavedDataKey, isSaved); item->setData(mIsRemovedDataKey, false); mListWidget->addItem(item); } void StickerSettings::removeTriggered() { auto selectedItem = mListWidget->currentItem(); if(selectedItem != nullptr) { selectedItem->setData(mIsRemovedDataKey, true); selectedItem->setHidden(true); } } void StickerSettings::upTriggered() { auto row = mListWidget->currentRow(); if(row > 0) { auto item = mListWidget->takeItem(row); auto newRow = row - 1; mListWidget->insertItem(newRow, item); mListWidget->setCurrentRow(newRow); mListWidget->setFocus(); } } void StickerSettings::downTriggered() { auto row = mListWidget->currentRow(); if(row < mListWidget->count() - 1) { auto item = mListWidget->takeItem(row); auto newRow = row + 1; mListWidget->insertItem(newRow, item); mListWidget->setCurrentRow(newRow); mListWidget->setFocus(); } } void StickerSettings::currentRowChanged(int row) { mRemoveButton->setEnabled(row != -1); mUpButton->setEnabled(row > 0); mDownButton->setEnabled(row >= 0 && row < mListWidget->count() - 1); } ksnip-master/src/gui/settingsDialog/StickerSettings.h000066400000000000000000000042201457262621600233350ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_STICKERSETTINGS_H #define KSNIP_STICKERSETTINGS_H #include #include #include #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/helper/PathHelper.h" #include "src/common/provider/directoryPathProvider/IDirectoryPathProvider.h" class StickerSettings : public QGroupBox { Q_OBJECT public: explicit StickerSettings(const QSharedPointer &config, const QSharedPointer &directoryPathProvider); ~StickerSettings() override; void saveSettings(); private: QListWidget *mListWidget; QPushButton *mAddButton; QPushButton *mRemoveButton; QPushButton *mUpButton; QPushButton *mDownButton; QCheckBox *mUseDefaultStickerCheckBox; QGridLayout *mLayout; QSharedPointer mConfig; QSharedPointer mDirectoryPathProvider; int mPathDataKey; int mIsSavedDataKey; int mIsRemovedDataKey; void initGui(); void loadConfig(); private slots: void addTriggered(); void removeTriggered(); void upTriggered(); void downTriggered(); void currentRowChanged(int row); void addSticker(const QString &path, bool isSaved) const; QString stickerDirectory() const; QStringList processSticker() const; }; #endif //KSNIP_STICKERSETTINGS_H ksnip-master/src/gui/settingsDialog/TrayIconSettings.cpp000066400000000000000000000153021457262621600240170ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "TrayIconSettings.h" TrayIconSettings::TrayIconSettings(const QList &captureModes, const QSharedPointer &config) : mConfig(config), mUseTrayIconCheckBox(new QCheckBox(this)), mMinimizeToTrayCheckBox(new QCheckBox(this)), mCloseToTrayCheckBox(new QCheckBox(this)), mTrayIconNotificationsCheckBox(new QCheckBox(this)), mUsePlatformSpecificNotificationServiceCheckBox(new QCheckBox(this)), mDefaultActionCaptureModeCombobox(new QComboBox(this)), mStartMinimizedToTrayCheckBox(new QCheckBox(this)), mDefaultActionShowEditorRadioButton(new QRadioButton(this)), mDefaultActionCaptureRadioButton(new QRadioButton(this)), mDefaultActionGroupBox(new QGroupBox(this)), mDefaultActionLayout(new QGridLayout), mLayout(new QGridLayout) { Q_ASSERT(mConfig != nullptr); initGui(); populateDefaultActionCaptureModeCombobox(captureModes); loadConfig(); } void TrayIconSettings::saveSettings() { mConfig->setUseTrayIcon(mUseTrayIconCheckBox->isChecked()); mConfig->setMinimizeToTray(mMinimizeToTrayCheckBox->isChecked()); mConfig->setStartMinimizedToTray(mStartMinimizedToTrayCheckBox->isChecked()); mConfig->setCloseToTray(mCloseToTrayCheckBox->isChecked()); mConfig->setTrayIconNotificationsEnabled(mTrayIconNotificationsCheckBox->isChecked()); mConfig->setPlatformSpecificNotificationServiceEnabled(mUsePlatformSpecificNotificationServiceCheckBox->isChecked()); mConfig->setDefaultTrayIconActionMode(selectedTrayIconDefaultActionMode()); mConfig->setDefaultTrayIconCaptureMode(mDefaultActionCaptureModeCombobox->currentData().value()); } void TrayIconSettings::initGui() { mUseTrayIconCheckBox->setText(tr("Use Tray Icon")); mUseTrayIconCheckBox->setToolTip(tr("When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it.\n" "Change requires restart.")); mMinimizeToTrayCheckBox->setText(tr("Minimize to Tray")); mStartMinimizedToTrayCheckBox->setText(tr("Start Minimized to Tray")); mCloseToTrayCheckBox->setText(tr("Close to Tray")); mTrayIconNotificationsCheckBox->setText(tr("Display Tray Icon notifications")); mUsePlatformSpecificNotificationServiceCheckBox->setText(tr("Use platform specific notification service")); mUsePlatformSpecificNotificationServiceCheckBox->setToolTip(tr("When enabled will use try to use platform specific notification\n" "service when such exists. Change requires restart to take effect.")); connect(mUseTrayIconCheckBox, &QCheckBox::stateChanged, this, &TrayIconSettings::useTrayIconChanged); mDefaultActionShowEditorRadioButton->setText(tr("Show Editor")); mDefaultActionCaptureRadioButton->setText(tr("Capture") + QLatin1String(":")); mDefaultActionLayout->addWidget(mDefaultActionShowEditorRadioButton, 0, 0, 1, 1); mDefaultActionLayout->addWidget(mDefaultActionCaptureRadioButton, 1, 0, 1, 1); mDefaultActionLayout->addWidget(mDefaultActionCaptureModeCombobox, 1, 1, 1, 1); mDefaultActionLayout->setColumnStretch(2, 1); mDefaultActionGroupBox->setTitle(tr("Default Tray Icon action")); mDefaultActionGroupBox->setToolTip(tr("Default Action that is triggered by left clicking the tray icon.")); mDefaultActionGroupBox->setLayout(mDefaultActionLayout); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mUseTrayIconCheckBox, 0, 0, 1, 4); mLayout->setRowMinimumHeight(1, 5); mLayout->addWidget(mStartMinimizedToTrayCheckBox, 2, 0, 1, 4); mLayout->addWidget(mMinimizeToTrayCheckBox, 3, 0, 1, 4); mLayout->addWidget(mCloseToTrayCheckBox, 4, 0, 1, 4); mLayout->addWidget(mTrayIconNotificationsCheckBox, 5, 0, 1, 4); mLayout->addWidget(mUsePlatformSpecificNotificationServiceCheckBox, 6, 0, 1, 4); mLayout->addWidget(mDefaultActionGroupBox, 7, 0, 1, 4); setTitle(tr("Tray Icon Settings")); setLayout(mLayout); } void TrayIconSettings::loadConfig() { mUseTrayIconCheckBox->setChecked(mConfig->useTrayIcon()); mMinimizeToTrayCheckBox->setChecked(mConfig->minimizeToTray()); mStartMinimizedToTrayCheckBox->setChecked(mConfig->startMinimizedToTray()); mCloseToTrayCheckBox->setChecked(mConfig->closeToTray()); mTrayIconNotificationsCheckBox->setChecked(mConfig->trayIconNotificationsEnabled()); mUsePlatformSpecificNotificationServiceCheckBox->setChecked(mConfig->platformSpecificNotificationServiceEnabled()); mDefaultActionShowEditorRadioButton->setChecked(mConfig->defaultTrayIconActionMode() == TrayIconDefaultActionMode::ShowEditor); mDefaultActionCaptureRadioButton->setChecked(mConfig->defaultTrayIconActionMode() == TrayIconDefaultActionMode::Capture); mDefaultActionCaptureModeCombobox->setCurrentIndex(indexOfSelectedCaptureMode()); useTrayIconChanged(); } int TrayIconSettings::indexOfSelectedCaptureMode() const { return mDefaultActionCaptureModeCombobox->findData(QVariant::fromValue(mConfig->defaultTrayIconCaptureMode())); } TrayIconDefaultActionMode TrayIconSettings::selectedTrayIconDefaultActionMode() const { return mDefaultActionShowEditorRadioButton->isChecked() ? TrayIconDefaultActionMode::ShowEditor : TrayIconDefaultActionMode::Capture; } void TrayIconSettings::populateDefaultActionCaptureModeCombobox(const QList &captureModes) { for (auto captureMode: captureModes) { const auto label = EnumTranslator::instance()->toTranslatedString(captureMode); mDefaultActionCaptureModeCombobox->addItem(label, static_cast(captureMode)); } } void TrayIconSettings::useTrayIconChanged() { const auto trayIconEnabled = mUseTrayIconCheckBox->isChecked(); mMinimizeToTrayCheckBox->setEnabled(trayIconEnabled); mCloseToTrayCheckBox->setEnabled(trayIconEnabled); mTrayIconNotificationsCheckBox->setEnabled(trayIconEnabled); mUsePlatformSpecificNotificationServiceCheckBox->setEnabled(trayIconEnabled); mStartMinimizedToTrayCheckBox->setEnabled(trayIconEnabled); mDefaultActionCaptureModeCombobox->setEnabled(trayIconEnabled); mDefaultActionShowEditorRadioButton->setEnabled(trayIconEnabled); mDefaultActionCaptureRadioButton->setEnabled(trayIconEnabled); } ksnip-master/src/gui/settingsDialog/TrayIconSettings.h000066400000000000000000000042061457262621600234650ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_TRAYICONSETTINGS_H #define KSNIP_TRAYICONSETTINGS_H #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/helper/EnumTranslator.h" class TrayIconSettings : public QGroupBox { Q_OBJECT public: explicit TrayIconSettings(const QList &captureModes, const QSharedPointer &config); ~TrayIconSettings() override = default; void saveSettings(); private: QCheckBox *mUseTrayIconCheckBox; QCheckBox *mMinimizeToTrayCheckBox; QCheckBox *mCloseToTrayCheckBox; QCheckBox *mTrayIconNotificationsCheckBox; QCheckBox *mUsePlatformSpecificNotificationServiceCheckBox; QComboBox *mDefaultActionCaptureModeCombobox; QCheckBox *mStartMinimizedToTrayCheckBox; QRadioButton *mDefaultActionShowEditorRadioButton; QRadioButton *mDefaultActionCaptureRadioButton; QGridLayout *mLayout; QGridLayout *mDefaultActionLayout; QGroupBox *mDefaultActionGroupBox; QSharedPointer mConfig; void initGui(); void loadConfig(); void populateDefaultActionCaptureModeCombobox(const QList &captureModes); TrayIconDefaultActionMode selectedTrayIconDefaultActionMode() const; int indexOfSelectedCaptureMode() const; private slots: void useTrayIconChanged(); }; #endif //KSNIP_TRAYICONSETTINGS_H ksnip-master/src/gui/settingsDialog/WatermarkSettings.cpp000066400000000000000000000055621457262621600242330ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WatermarkSettings.h" WatermarkSettings::WatermarkSettings(const QSharedPointer &config, const QSharedPointer &scaledSizeProvider) : mConfig(config), mScaledSizeProvider(scaledSizeProvider), mLayout(new QGridLayout(this)), mRotateWatermarkCheckbox(new QCheckBox(this)), mWatermarkImageLabel(new QLabel(this)), mUpdateWatermarkImageButton(new QPushButton(this)) { initGui(); loadConfig(); } WatermarkSettings::~WatermarkSettings() { delete mRotateWatermarkCheckbox; delete mWatermarkImageLabel; delete mUpdateWatermarkImageButton; } void WatermarkSettings::saveSettings() { mConfig->setRotateWatermarkEnabled(mRotateWatermarkCheckbox->isChecked()); } void WatermarkSettings::initGui() { mWatermarkImageLabel->setPixmap(mWatermarkImageLoader.load()); mWatermarkImageLabel->setToolTip(tr("Watermark Image")); mWatermarkImageLabel->setAutoFillBackground(true); mWatermarkImageLabel->setFixedSize(mScaledSizeProvider->scaledSize(QSize(100, 100))); mWatermarkImageLabel->setScaledContents(true); mWatermarkImageLabel->setStyleSheet(QLatin1String("QLabel { background-color : white; }")); mUpdateWatermarkImageButton->setText(tr("Update")); connect(mUpdateWatermarkImageButton, &QPushButton::clicked, this, &WatermarkSettings::updateWatermarkImageClicked); mRotateWatermarkCheckbox->setText(tr("Rotate Watermark")); mRotateWatermarkCheckbox->setToolTip(tr("When enabled, Watermark will be added with a rotation of 45°")); mLayout->setAlignment(Qt::AlignTop); mLayout->addWidget(mWatermarkImageLabel, 0, 0); mLayout->addWidget(mUpdateWatermarkImageButton, 0, 1, Qt::AlignLeft); mLayout->setRowMinimumHeight(1, 15); mLayout->addWidget(mRotateWatermarkCheckbox, 2, 0); setTitle(tr("Watermark Settings")); setLayout(mLayout); } void WatermarkSettings::loadConfig() { mRotateWatermarkCheckbox->setChecked(mConfig->rotateWatermarkEnabled()); } void WatermarkSettings::updateWatermarkImageClicked() { UpdateWatermarkOperation operation(this); auto successful = operation.execute(); if(successful) { mWatermarkImageLabel->setPixmap(mWatermarkImageLoader.load()); } } ksnip-master/src/gui/settingsDialog/WatermarkSettings.h000066400000000000000000000034061457262621600236730ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WATERMARKSETTINGS_H #define KSNIP_WATERMARKSETTINGS_H #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/gui/operations/UpdateWatermarkOperation.h" #include "src/common/provider/scaledSizeProvider/IScaledSizeProvider.h" class WatermarkSettings : public QGroupBox { Q_OBJECT public: explicit WatermarkSettings(const QSharedPointer &config, const QSharedPointer &scaledSizeProvider); ~WatermarkSettings() override; void saveSettings(); private: QGridLayout *mLayout; QSharedPointer mConfig; QSharedPointer mScaledSizeProvider; QCheckBox *mRotateWatermarkCheckbox; QLabel *mWatermarkImageLabel; QPushButton *mUpdateWatermarkImageButton; WatermarkImageLoader mWatermarkImageLoader; void initGui(); void loadConfig(); private slots: void updateWatermarkImageClicked(); }; #endif //KSNIP_WATERMARKSETTINGS_H ksnip-master/src/gui/settingsDialog/actions/000077500000000000000000000000001457262621600215015ustar00rootroot00000000000000ksnip-master/src/gui/settingsDialog/actions/ActionSettingTab.cpp000066400000000000000000000205131457262621600254100ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ActionSettingTab.h" ActionSettingTab::ActionSettingTab(const QString &name, const QList &captureModes, const QSharedPointer &platformChecker) : ActionSettingTab(captureModes, platformChecker) { mNameLineEdit->setTextAndPlaceholderText(name); } ActionSettingTab::ActionSettingTab(const Action &action, const QList &captureModes, const QSharedPointer &platformChecker) : ActionSettingTab(captureModes, platformChecker) { setAction(action); } ActionSettingTab::~ActionSettingTab() { delete mCaptureModeComboBox; delete mDelaySpinBox; delete mShortcutLineEdit; } void ActionSettingTab::initGui(const QList &captureModes) { mNameLabel->setText(tr("Name") + QLatin1String(":")); mNameLineEdit->setMaxLength(50); connect(mNameLineEdit, &QLineEdit::editingFinished, this, &ActionSettingTab::nameEditingFinished); mShortcutLabel->setText(tr("Shortcut") + QLatin1String(":")); mShortcutLabel->setToolTip("When global hotkeys are enabled and supported then\n" "this shortcut will also work as a global hotkey\n" "when the 'Global' option is enabled."); mIsGlobalShortcutCheckBox->setText(tr("Global")); mIsGlobalShortcutCheckBox->setToolTip(tr("When enabled will make the shortcut\n" "available even when ksnip has no focus.")); mShortcutLineEdit->setToolTip(mShortcutLabel->toolTip()); mShortcutClearButton->setText(tr("Clear")); connect(mShortcutClearButton, &QPushButton::clicked, mShortcutLineEdit, &KeySequenceLineEdit::clear); mCaptureEnabledCheckBox->setText(tr("Take Capture")); connect(mCaptureEnabledCheckBox, &QCheckBox::toggled, this, &ActionSettingTab::captureEnabledChanged); mIncludeCursorCheckBox->setText(tr("Include Cursor")); mDelayLabel->setText(tr("Delay") + QLatin1String(":")); //: The small letter s stands for seconds. mDelaySpinBox->setSuffix(tr("s")); mCaptureModeLabel->setText(tr("Capture Mode") + QLatin1String(":")); populateCaptureModeCombobox(captureModes); mShowPinWindowCheckBox->setText(tr("Show image in Pin Window")); mCopyToClipboardCheckBox->setText(tr("Copy image to Clipboard")); mUploadCheckBox->setText(tr("Upload image")); mOpenDirectoryCheckBox->setText(tr("Open image parent directory")); mSaveCheckBox->setText(tr("Save image")); mHideMainWindowCheckBox->setText(tr("Hide Main Window")); mLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mNameLabel, 0, 0, 1, 2); mLayout->addWidget(mNameLineEdit, 0, 2, 1, 3); mLayout->addWidget(mShortcutLabel, 1, 0, 1, 2); mLayout->addWidget(mShortcutLineEdit, 1, 2, 1, 3); mLayout->addWidget(mIsGlobalShortcutCheckBox, 1, 7, 1, 1); mLayout->addWidget(mShortcutClearButton, 1, 6, 1, 1); mLayout->setRowMinimumHeight(2, 10); mLayout->addWidget(mCaptureEnabledCheckBox, 3, 0, 1, 5); mLayout->addWidget(mIncludeCursorCheckBox, 4, 1, 1, 4); mLayout->addWidget(mDelayLabel, 5, 1, 1, 2); mLayout->addWidget(mDelaySpinBox, 5, 3, 1, 2); mLayout->addWidget(mCaptureModeLabel, 6, 1, 1, 2); mLayout->addWidget(mCaptureModeComboBox, 6, 3, 1, 2); mLayout->setRowMinimumHeight(7, 10); mLayout->addWidget(mShowPinWindowCheckBox, 8, 0, 1, 5); mLayout->addWidget(mCopyToClipboardCheckBox, 9, 0, 1, 5); mLayout->addWidget(mUploadCheckBox, 10, 0, 1, 5); mLayout->addWidget(mSaveCheckBox, 11, 0, 1, 5); mLayout->addWidget(mOpenDirectoryCheckBox, 12, 0, 1, 5); mLayout->addWidget(mHideMainWindowCheckBox, 13, 0, 1, 5); setLayout(mLayout); } void ActionSettingTab::populateCaptureModeCombobox(const QList &captureModes) { for (auto captureMode: captureModes) { const auto label = EnumTranslator::instance()->toTranslatedString(captureMode); mCaptureModeComboBox->addItem(label, static_cast(captureMode)); } } void ActionSettingTab::captureEnabledChanged() { auto isEnabled = mCaptureEnabledCheckBox->isChecked(); mIncludeCursorCheckBox->setEnabled(isEnabled); mDelayLabel->setEnabled(isEnabled); mDelaySpinBox->setEnabled(isEnabled); mCaptureModeLabel->setEnabled(isEnabled); mCaptureModeComboBox->setEnabled(isEnabled); } Action ActionSettingTab::action() const { Action action; action.setName(getTextWithEscapedAmpersand(mNameLineEdit->textOrPlaceholderText())); action.setShortcut(mShortcutLineEdit->value()); action.setIsGlobalShortcut(mIsGlobalShortcutCheckBox->isChecked()); action.setIsCaptureEnabled(mCaptureEnabledCheckBox->isChecked()); action.setCaptureDelay(mDelaySpinBox->value() * 1000); action.setIncludeCursor(mIncludeCursorCheckBox->isChecked()); action.setCaptureMode(mCaptureModeComboBox->currentData().value()); action.setIsPinImageEnabled(mShowPinWindowCheckBox->isChecked()); action.setIsSaveEnabled(mSaveCheckBox->isChecked()); action.setIsCopyToClipboardEnabled(mCopyToClipboardCheckBox->isChecked()); action.setIsOpenDirectoryEnabled(mOpenDirectoryCheckBox->isChecked()); action.setIsUploadEnabled(mUploadCheckBox->isChecked()); action.setIsHideMainWindowEnabled(mHideMainWindowCheckBox->isChecked()); return action; } void ActionSettingTab::setAction(const Action &action) const { mNameLineEdit->setTextAndPlaceholderText(getTextWithoutEscapedAmpersand(action.name())); mShortcutLineEdit->setValue(action.shortcut()); mIsGlobalShortcutCheckBox->setChecked(action.isGlobalShortcut()); mCaptureEnabledCheckBox->setChecked(action.isCaptureEnabled()); mDelaySpinBox->setValue(action.captureDelay() / 1000); mIncludeCursorCheckBox->setChecked(action.includeCursor()); mCaptureModeComboBox->setCurrentIndex(indexOfSelectedCaptureMode(action.captureMode())); mShowPinWindowCheckBox->setChecked(action.isPinImageEnabled()); mSaveCheckBox->setChecked(action.isSaveEnabled()); mCopyToClipboardCheckBox->setChecked(action.isCopyToClipboardEnabled()); mOpenDirectoryCheckBox->setChecked(action.isOpenDirectoryEnabled()); mUploadCheckBox->setChecked(action.isUploadEnabled()); mHideMainWindowCheckBox->setChecked(action.isHideMainWindowEnabled()); } int ActionSettingTab::indexOfSelectedCaptureMode(CaptureModes modes) const { return mCaptureModeComboBox->findData(QVariant::fromValue(modes)); } QString ActionSettingTab::getTextWithEscapedAmpersand(const QString &text) { auto copiedText = text; return copiedText.replace(QLatin1String("&"), QLatin1String("&&")); } QString ActionSettingTab::getTextWithoutEscapedAmpersand(const QString &text) { auto copiedText = text; return copiedText.replace(QLatin1String("&&"), QLatin1String("&")); } void ActionSettingTab::nameEditingFinished() { emit nameChanged(getTextWithEscapedAmpersand(mNameLineEdit->textOrPlaceholderText())); } ActionSettingTab::ActionSettingTab(const QList &captureModes, const QSharedPointer &platformChecker) : mCaptureModeComboBox(new QComboBox(nullptr)), mCaptureEnabledCheckBox(new QCheckBox(this)), mIncludeCursorCheckBox(new QCheckBox(this)), mShowPinWindowCheckBox(new QCheckBox(this)), mCopyToClipboardCheckBox(new QCheckBox(this)), mUploadCheckBox(new QCheckBox(this)), mOpenDirectoryCheckBox(new QCheckBox(this)), mHideMainWindowCheckBox(new QCheckBox(this)), mSaveCheckBox(new QCheckBox(this)), mIsGlobalShortcutCheckBox(new QCheckBox(this)), mCaptureModeLabel(new QLabel(this)), mDelayLabel(new QLabel(this)), mNameLabel(new QLabel(this)), mShortcutLabel(new QLabel(this)), mDelaySpinBox(new CustomSpinBox(0, 100)), mNameLineEdit(new CustomLineEdit(this)), mShortcutLineEdit(new KeySequenceLineEdit(this, HotKeyMap::instance()->getAllKeys(), platformChecker)), mShortcutClearButton(new QPushButton(this)), mLayout(new QGridLayout(this)) { initGui(captureModes); captureEnabledChanged(); } ksnip-master/src/gui/settingsDialog/actions/ActionSettingTab.h000066400000000000000000000056201457262621600250570ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTIONSETTINGTAB_H #define KSNIP_ACTIONSETTINGTAB_H #include #include #include #include #include #include #include #include "src/common/helper/EnumTranslator.h" #include "src/widgets/CustomSpinBox.h" #include "src/widgets/CustomLineEdit.h" #include "src/widgets/KeySequenceLineEdit.h" #include "src/gui/actions/Action.h" #include "src/gui/globalHotKeys/HotKeyMap.h" class ActionSettingTab : public QWidget { Q_OBJECT public: explicit ActionSettingTab(const QString &name, const QList &captureModes, const QSharedPointer &platformChecker); explicit ActionSettingTab(const Action &action, const QList &captureModes, const QSharedPointer &platformChecker); ~ActionSettingTab() override; Action action() const; signals: void nameChanged(const QString &name); protected: explicit ActionSettingTab(const QList &captureModes, const QSharedPointer &platformChecker); void setAction(const Action &action) const; private: QComboBox *mCaptureModeComboBox; QCheckBox *mCaptureEnabledCheckBox; QCheckBox *mIncludeCursorCheckBox; QCheckBox *mShowPinWindowCheckBox; QCheckBox *mUploadCheckBox; QCheckBox *mSaveCheckBox; QCheckBox *mCopyToClipboardCheckBox; QCheckBox *mOpenDirectoryCheckBox; QCheckBox *mHideMainWindowCheckBox; QCheckBox *mIsGlobalShortcutCheckBox; QLabel *mCaptureModeLabel; QLabel *mDelayLabel; QLabel *mNameLabel; QLabel *mShortcutLabel; CustomSpinBox *mDelaySpinBox; CustomLineEdit *mNameLineEdit; KeySequenceLineEdit *mShortcutLineEdit; QPushButton *mShortcutClearButton; QGridLayout *mLayout; void initGui(const QList &captureModes); void populateCaptureModeCombobox(const QList &captureModes); int indexOfSelectedCaptureMode(CaptureModes modes) const; static QString getTextWithEscapedAmpersand(const QString &text); static QString getTextWithoutEscapedAmpersand(const QString &text); private slots: void captureEnabledChanged(); void nameEditingFinished(); }; #endif //KSNIP_ACTIONSETTINGTAB_H ksnip-master/src/gui/settingsDialog/actions/ActionsSettings.cpp000066400000000000000000000061571457262621600253370ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ActionsSettings.h" ActionsSettings::ActionsSettings(const QList &captureModes, const QSharedPointer &platformChecker, const QSharedPointer &config) : mConfig(config), mPlatformChecker(platformChecker), mLayout(new QVBoxLayout(this)), mTabWidget(new QTabWidget(this)), mCaptureModes(captureModes) { Q_ASSERT(mConfig != nullptr); initGui(); loadConfig(); mTabWidget->setCurrentIndex(0); } ActionsSettings::~ActionsSettings() { delete mTabWidget; delete mLayout; } void ActionsSettings::saveSettings() { QList actions; auto count = mTabWidget->count(); for (int index = 0; index < count; ++index) { auto tabContent = dynamic_cast(mTabWidget->widget(index)); if(tabContent != nullptr) { actions.append(tabContent->action()); } } mConfig->setActions(actions); } void ActionsSettings::initGui() { auto addButton = new QPushButton(); addButton->setText(tr("Add")); connect(addButton, &QPushButton::clicked, this, &ActionsSettings::addEmptyTab); auto addTabIndex = mTabWidget->addTab(new EmptyActionSettingTab, QString()); mTabWidget->setTabEnabled(addTabIndex, false); mTabWidget->tabBar()->setTabButton(addTabIndex, QTabBar::RightSide, addButton); mTabWidget->setTabsClosable(true); connect(mTabWidget, &QTabWidget::tabCloseRequested, this, &ActionsSettings::closeTab); mLayout->addWidget(mTabWidget); setTitle(tr("Actions Settings")); setLayout(mLayout); } void ActionsSettings::loadConfig() { auto actions = mConfig->actions(); for(const auto& action : actions) { auto tabContent = new ActionSettingTab(action, mCaptureModes, mPlatformChecker); insertActionTab(tabContent, action.name()); } } void ActionsSettings::insertActionTab(ActionSettingTab *tabContent, const QString &name) { auto index = mTabWidget->insertTab(mTabWidget->count() - 1, tabContent, name); connect(tabContent, &ActionSettingTab::nameChanged, [this, index](const QString &name) { mTabWidget->setTabText(index, name); }); mTabWidget->setCurrentIndex(index); } void ActionsSettings::addEmptyTab() { auto name = tr("Action") + QLatin1String(" ") + QString::number(mTabWidget->count()); auto tabContent = new ActionSettingTab(name, mCaptureModes, mPlatformChecker); insertActionTab(tabContent, name); } void ActionsSettings::closeTab(int index) { mTabWidget->removeTab(index); } ksnip-master/src/gui/settingsDialog/actions/ActionsSettings.h000066400000000000000000000032731457262621600250000ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTIONSSETTINGS_H #define KSNIP_ACTIONSSETTINGS_H #include #include #include #include #include "ActionSettingTab.h" #include "EmptyActionSettingTab.h" #include "src/backend/config/IConfig.h" class ActionsSettings : public QGroupBox { Q_OBJECT public: explicit ActionsSettings(const QList &captureModes, const QSharedPointer &platformChecker, const QSharedPointer &config); ~ActionsSettings() override; void saveSettings(); private: QVBoxLayout *mLayout; QSharedPointer mConfig; QSharedPointer mPlatformChecker; QTabWidget *mTabWidget; QList mCaptureModes; void initGui(); void loadConfig(); void insertActionTab(ActionSettingTab *tabContent, const QString &name); private slots: void addEmptyTab(); void closeTab(int index); }; #endif //KSNIP_ACTIONSSETTINGS_H ksnip-master/src/gui/settingsDialog/actions/EmptyActionSettingTab.cpp000066400000000000000000000022611457262621600264270ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "EmptyActionSettingTab.h" EmptyActionSettingTab::EmptyActionSettingTab() : mContent(new QLabel(this)), mLayout(new QVBoxLayout(this)) { mContent->setText(tr("Add new actions by pressing the 'Add' tab button.")); mLayout->addWidget(mContent); mLayout->setAlignment(Qt::AlignCenter); setLayout(mLayout); } EmptyActionSettingTab::~EmptyActionSettingTab() { delete mContent; delete mLayout; } ksnip-master/src/gui/settingsDialog/actions/EmptyActionSettingTab.h000066400000000000000000000022001457262621600260650ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_EMPTYACTIONSETTINGTAB_H #define KSNIP_EMPTYACTIONSETTINGTAB_H #include #include #include class EmptyActionSettingTab : public QWidget { Q_OBJECT public: EmptyActionSettingTab(); ~EmptyActionSettingTab() override; private: QLabel *mContent; QVBoxLayout *mLayout; }; #endif //KSNIP_EMPTYACTIONSETTINGTAB_H ksnip-master/src/gui/settingsDialog/plugins/000077500000000000000000000000001457262621600215225ustar00rootroot00000000000000ksnip-master/src/gui/settingsDialog/plugins/PluginsSettings.cpp000066400000000000000000000111501457262621600253660ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PluginsSettings.h" PluginsSettings::PluginsSettings( const QSharedPointer &config, const QSharedPointer &fileDialogService, const QSharedPointer &pluginFinder) : mConfig(config), mFileDialogService(fileDialogService), mPluginFinder(pluginFinder), mLayout(new QGridLayout), mPluginPathLabel(new QLabel(this)), mPluginPathLineEdit(new QLineEdit(this)), mBrowseButton(new QPushButton(this)), mDetectButton(new QPushButton(this)), mTableWidget(new QTableWidget(5, 2, this)), mDefaultSearchPathRadioButton(new QRadioButton(this)), mCustomSearchPathRadioButton(new QRadioButton(this)) { initGui(); loadConfig(); } void PluginsSettings::saveSettings() { mConfig->setPluginInfos(mDetectedPlugins); mConfig->setPluginPath(mPluginPathLineEdit->text()); mConfig->setCustomPluginSearchPathEnabled(mCustomSearchPathRadioButton->isChecked()); } void PluginsSettings::initGui() { mPluginPathLabel->setText(tr("Search Path") + QLatin1String(":")); mDefaultSearchPathRadioButton->setText(tr("Default")); connect(mDefaultSearchPathRadioButton, &QRadioButton::clicked, this, &PluginsSettings::searchPathSelectionChanged); mDefaultSearchPathRadioButton->setChecked(true); connect(mCustomSearchPathRadioButton, &QRadioButton::clicked, this, &PluginsSettings::searchPathSelectionChanged); mPluginPathLineEdit->setToolTip(tr("The directory where the plugins are located.")); mBrowseButton->setText(tr("Browse")); connect(mBrowseButton, &QPushButton::clicked, this, &PluginsSettings::choosePluginDirectory); mTableWidget->setHorizontalHeaderLabels(QStringList{ tr("Name"), tr("Version") }); mTableWidget->horizontalHeader()->setStretchLastSection(true); mTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); mTableWidget->verticalHeader()->setVisible(false); mDetectButton->setText(tr("Detect")); connect(mDetectButton, &QPushButton::clicked, this, &PluginsSettings::detectPlugins); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 18); mLayout->addWidget(mPluginPathLabel, 0, 0, 1, 4); mLayout->addWidget(mDefaultSearchPathRadioButton, 1, 0, 1, 4); mLayout->addWidget(mCustomSearchPathRadioButton, 2, 0, 1, 4); mLayout->addWidget(mPluginPathLineEdit, 2, 1, 1, 3); mLayout->addWidget(mBrowseButton, 2, 4); mLayout->addWidget(mTableWidget, 4, 0, 2, 4); mLayout->addWidget(mDetectButton, 4, 4); setTitle(tr("Plugin Settings")); setLayout(mLayout); } void PluginsSettings::loadConfig() { mPluginPathLineEdit->setText(mConfig->pluginPath()); mCustomSearchPathRadioButton->setChecked(mConfig->customPluginSearchPathEnabled()); mDetectedPlugins = mConfig->pluginInfos(); updatePluginTable(); searchPathSelectionChanged(); } void PluginsSettings::choosePluginDirectory() { auto path = mFileDialogService->getExistingDirectory(this, tr("Plugin location"), mConfig->saveDirectory()); if(!path.isEmpty()) { mPluginPathLineEdit->setText(path); } } void PluginsSettings::detectPlugins() { if(mDefaultSearchPathRadioButton->isChecked()) { mDetectedPlugins = mPluginFinder->find(); } else { auto pluginPath = mPluginPathLineEdit->text(); if (!pluginPath.isEmpty()) { mDetectedPlugins = mPluginFinder->find(pluginPath); } } updatePluginTable(); } void PluginsSettings::updatePluginTable() { auto pluginCount = mDetectedPlugins.count(); for (auto i = 0; i < pluginCount; i++) { auto pluginInfo = mDetectedPlugins[i]; auto name = new QTableWidgetItem(PathHelper::extractFilename(pluginInfo.path())); auto version = new QTableWidgetItem(pluginInfo.version()); mTableWidget->setItem(i, 0, name); mTableWidget->setItem(i, 1, version); } } void PluginsSettings::searchPathSelectionChanged() { auto isCustomSelected = mCustomSearchPathRadioButton->isChecked(); mPluginPathLineEdit->setEnabled(isCustomSelected); mBrowseButton->setEnabled(isCustomSelected); } ksnip-master/src/gui/settingsDialog/plugins/PluginsSettings.h000066400000000000000000000042531457262621600250410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLUGINSSETTINGS_H #define KSNIP_PLUGINSSETTINGS_H #include #include #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/adapter/fileDialog/IFileDialogService.h" #include "src/common/helper/PathHelper.h" #include "src/plugins/PluginInfo.h" #include "src/plugins/IPluginFinder.h" class PluginsSettings : public QGroupBox { Q_OBJECT public: explicit PluginsSettings( const QSharedPointer &config, const QSharedPointer &fileDialogService, const QSharedPointer &pluginFinder); ~PluginsSettings() override = default; void saveSettings(); private: QGridLayout *mLayout; QLabel *mPluginPathLabel; QLineEdit *mPluginPathLineEdit; QPushButton *mBrowseButton; QPushButton *mDetectButton; QTableWidget *mTableWidget; QRadioButton *mDefaultSearchPathRadioButton; QRadioButton *mCustomSearchPathRadioButton; QSharedPointer mConfig; QSharedPointer mFileDialogService; QSharedPointer mPluginFinder; QList mDetectedPlugins; void initGui(); void loadConfig(); void updatePluginTable(); private slots: void choosePluginDirectory(); void detectPlugins(); void searchPathSelectionChanged(); }; #endif //KSNIP_PLUGINSSETTINGS_H ksnip-master/src/gui/settingsDialog/uploader/000077500000000000000000000000001457262621600216545ustar00rootroot00000000000000ksnip-master/src/gui/settingsDialog/uploader/FtpUploaderSettings.cpp000066400000000000000000000052401457262621600263270ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "FtpUploaderSettings.h" FtpUploaderSettings::FtpUploaderSettings(const QSharedPointer &config) : mConfig(config), mLayout(new QGridLayout(this)), mForceAnonymousUploadCheckBox(new QCheckBox(this)), mUrlLabel(new QLabel(this)), mUsernameLabel(new QLabel(this)), mPasswordLabel(new QLabel(this)), mUrlLineEdit(new QLineEdit(this)), mUsernameLineEdit(new QLineEdit(this)), mPasswordLineEdit(new QLineEdit(this)) { initGui(); loadConfig(); } void FtpUploaderSettings::saveSettings() { mConfig->setFtpUploadForceAnonymous(mForceAnonymousUploadCheckBox->isChecked()); mConfig->setFtpUploadUrl(mUrlLineEdit->text()); mConfig->setFtpUploadUsername(mUsernameLineEdit->text()); mConfig->setFtpUploadPassword(mPasswordLineEdit->text()); } void FtpUploaderSettings::initGui() { mForceAnonymousUploadCheckBox->setText(tr("Force anonymous upload.")); mUrlLabel->setText(tr("Url") + QLatin1String(":")); mUsernameLabel->setText(tr("Username") + QLatin1String(":")); mPasswordLabel->setText(tr("Password") + QLatin1String(":")); mPasswordLineEdit->setEchoMode(QLineEdit::Password); mLayout->setAlignment(Qt::AlignTop); mLayout->addWidget(mForceAnonymousUploadCheckBox, 0, 0, 1, 3); mLayout->setRowMinimumHeight(1, 15); mLayout->addWidget(mUrlLabel, 2, 0, 1, 1); mLayout->addWidget(mUrlLineEdit, 2, 1, 1, 2); mLayout->setRowMinimumHeight(3, 15); mLayout->addWidget(mUsernameLabel, 4, 0, 1, 1); mLayout->addWidget(mUsernameLineEdit, 4, 1, 1, 1); mLayout->addWidget(mPasswordLabel, 5, 0, 1, 1); mLayout->addWidget(mPasswordLineEdit, 5, 1, 1, 1); setTitle(tr("FTP Uploader")); setLayout(mLayout); } void FtpUploaderSettings::loadConfig() { mForceAnonymousUploadCheckBox->setChecked(mConfig->ftpUploadForceAnonymous()); mUrlLineEdit->setText(mConfig->ftpUploadUrl()); mUsernameLineEdit->setText(mConfig->ftpUploadUsername()); mPasswordLineEdit->setText(mConfig->ftpUploadPassword()); } ksnip-master/src/gui/settingsDialog/uploader/FtpUploaderSettings.h000066400000000000000000000030271457262621600257750ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FTPUPLOADERSETTINGS_H #define KSNIP_FTPUPLOADERSETTINGS_H #include #include #include #include #include #include "src/backend/config/IConfig.h" class FtpUploaderSettings : public QGroupBox { Q_OBJECT public: explicit FtpUploaderSettings(const QSharedPointer &config); ~FtpUploaderSettings() override = default; void saveSettings(); private: QGridLayout *mLayout; QSharedPointer mConfig; QCheckBox *mForceAnonymousUploadCheckBox; QLabel *mUrlLabel; QLabel *mUsernameLabel; QLabel *mPasswordLabel; QLineEdit *mUrlLineEdit; QLineEdit *mUsernameLineEdit; QLineEdit *mPasswordLineEdit; void initGui(); void loadConfig(); }; #endif //KSNIP_FTPUPLOADERSETTINGS_H ksnip-master/src/gui/settingsDialog/uploader/ImgurUploaderSettings.cpp000066400000000000000000000225261457262621600266670ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ImgurUploaderSettings.h" ImgurUploaderSettings::ImgurUploaderSettings(const QSharedPointer &config) : mConfig(config), mForceAnonymousCheckbox(new QCheckBox(this)), mDirectLinkToImageCheckbox(new QCheckBox(this)), mAlwaysCopyToClipboardCheckBox(new QCheckBox(this)), mOpenLinkInBrowserCheckbox(new QCheckBox(this)), mClientIdLineEdit(new QLineEdit(this)), mClientSecretLineEdit(new QLineEdit(this)), mPinLineEdit(new QLineEdit(this)), mUsernameLineEdit(new QLineEdit(this)), mBaseUrlLineEdit(new CustomLineEdit(this)), mUploadTitleEdit(new CustomLineEdit(this)), mUploadDescriptionEdit(new CustomLineEdit(this)), mUsernameLabel(new QLabel(this)), mBaseUrlLabel(new QLabel(this)), mUploadTitleLabel(new QLabel(this)), mUploadDescriptionLabel(new QLabel(this)), mGetPinButton(new QPushButton(this)), mGetTokenButton(new QPushButton(this)), mClearTokenButton(new QPushButton(this)), mHistoryButton(new QPushButton(this)), mImgurWrapper(new ImgurWrapper(mConfig->imgurBaseUrl(), this)), mLayout(new QGridLayout(this)) { Q_ASSERT(mConfig != nullptr); initGui(); loadConfig(); } void ImgurUploaderSettings::saveSettings() { mConfig->setImgurForceAnonymous(mForceAnonymousCheckbox->isChecked()); mConfig->setImgurLinkDirectlyToImage(mDirectLinkToImageCheckbox->isChecked()); mConfig->setImgurAlwaysCopyToClipboard(mAlwaysCopyToClipboardCheckBox->isChecked()); mConfig->setImgurOpenLinkInBrowser(mOpenLinkInBrowserCheckbox->isChecked()); mConfig->setImgurUploadTitle(mUploadTitleEdit->textOrPlaceholderText()); mConfig->setImgurUploadDescription(mUploadDescriptionEdit->textOrPlaceholderText()); mConfig->setImgurBaseUrl(mBaseUrlLineEdit->textOrPlaceholderText()); } void ImgurUploaderSettings::initGui() { connect(mImgurWrapper, &ImgurWrapper::tokenUpdated, this, &ImgurUploaderSettings::imgurTokenUpdated); connect(mImgurWrapper, &ImgurWrapper::error, this, &ImgurUploaderSettings::imgurTokenError); mForceAnonymousCheckbox->setText(tr("Force anonymous upload")); mOpenLinkInBrowserCheckbox->setText(tr("After uploading open Imgur link in default browser")); mDirectLinkToImageCheckbox->setText(tr("Link directly to image")); mAlwaysCopyToClipboardCheckBox->setText(tr("Always copy Imgur link to clipboard")); mUploadTitleLabel->setText(tr("Upload title:")); mUploadDescriptionLabel->setText(tr("Upload description:")); mBaseUrlLabel->setText(tr("Base Url:")); mBaseUrlLabel->setToolTip(tr("Base url that will be used for communication with Imgur.\n" "Changing requires restart.")); mClientIdLineEdit->setPlaceholderText(tr("Client ID")); connect(mClientIdLineEdit, &QLineEdit::textChanged, this, &ImgurUploaderSettings::imgurClientEntered); mClientSecretLineEdit->setPlaceholderText(tr("Client Secret")); connect(mClientSecretLineEdit, &QLineEdit::textChanged, this, &ImgurUploaderSettings::imgurClientEntered); mPinLineEdit->setPlaceholderText(tr("PIN")); mPinLineEdit->setToolTip(tr("Enter imgur Pin which will be exchanged for a token.")); connect(mPinLineEdit, &QLineEdit::textChanged, [this](const QString & text) { mGetTokenButton->setEnabled(text.length() > 8); }); mUploadTitleEdit->setPlaceholderText(DefaultValues::ImgurUploadTitle); mUploadDescriptionEdit->setPlaceholderText(DefaultValues::ImgurUploadDescription); mBaseUrlLineEdit->setPlaceholderText(DefaultValues::ImgurBaseUrl); mBaseUrlLineEdit->setToolTip(mBaseUrlLabel->toolTip()); mUsernameLabel->setText(tr("Username") + QLatin1String(":")); mUsernameLineEdit->setReadOnly(true); connect(mUsernameLineEdit, &QLineEdit::textChanged, this, &ImgurUploaderSettings::usernameChanged); mGetPinButton->setText(tr("Get PIN")); connect(mGetPinButton, &QPushButton::clicked, this, &ImgurUploaderSettings::requestImgurPin); mGetPinButton->setEnabled(false); mGetTokenButton->setText(tr("Get Token")); connect(mGetTokenButton, &QPushButton::clicked, this, &ImgurUploaderSettings::getImgurToken); mGetTokenButton->setEnabled(false); mClearTokenButton->setText(tr("Clear Token")); connect(mClearTokenButton, &QPushButton::clicked, this, &ImgurUploaderSettings::clearImgurToken); mHistoryButton->setText(tr("Imgur History")); connect(mHistoryButton, &QPushButton::clicked, this, &ImgurUploaderSettings::showImgurHistoryDialog); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mForceAnonymousCheckbox, 0, 0, 1, 3); mLayout->addWidget(mOpenLinkInBrowserCheckbox, 1, 0, 1, 3); mLayout->addWidget(mDirectLinkToImageCheckbox, 2, 0, 1, 3); mLayout->addWidget(mAlwaysCopyToClipboardCheckBox, 3, 0, 1, 3); mLayout->setRowMinimumHeight(4, 15); mLayout->addWidget(mUploadTitleLabel, 5, 0, 1, 1); mLayout->addWidget(mUploadTitleEdit, 5, 1, 1, 2); mLayout->addWidget(mUploadDescriptionLabel, 6, 0, 1, 1); mLayout->addWidget(mUploadDescriptionEdit, 6, 1, 1, 2); mLayout->addWidget(mBaseUrlLabel, 7, 0, 1, 1); mLayout->addWidget(mBaseUrlLineEdit, 7, 1, 1, 2); mLayout->setRowMinimumHeight(8, 15); mLayout->addWidget(mUsernameLabel, 9, 0, 1, 1); mLayout->addWidget(mUsernameLineEdit, 9, 1, 1, 2); mLayout->addWidget(mClearTokenButton, 9, 3, 1, 1); mLayout->addWidget(mClientIdLineEdit, 10, 0, 1, 3); mLayout->addWidget(mClientSecretLineEdit, 11, 0, 1, 3); mLayout->addWidget(mGetPinButton, 11, 3, 1, 1); mLayout->addWidget(mPinLineEdit, 12, 0, 1, 3); mLayout->addWidget(mGetTokenButton, 12, 3, 1, 1); mLayout->addWidget(mHistoryButton, 13, 3, 1, 1); setTitle(tr("Imgur Uploader")); setLayout(mLayout); } void ImgurUploaderSettings::loadConfig() { mForceAnonymousCheckbox->setChecked(mConfig->imgurForceAnonymous()); mOpenLinkInBrowserCheckbox->setChecked(mConfig->imgurOpenLinkInBrowser()); mDirectLinkToImageCheckbox->setChecked(mConfig->imgurLinkDirectlyToImage()); mAlwaysCopyToClipboardCheckBox->setChecked(mConfig->imgurAlwaysCopyToClipboard()); mUploadTitleEdit->setText(mConfig->imgurUploadTitle()); mUploadDescriptionEdit->setText(mConfig->imgurUploadDescription()); mUsernameLineEdit->setText(mConfig->imgurUsername()); mBaseUrlLineEdit->setText(mConfig->imgurBaseUrl()); if(!mConfig->imgurClientId().isEmpty()) { mClientIdLineEdit->setPlaceholderText(mConfig->imgurClientId()); } usernameChanged(); } /* * Based on the entered client id and client secret we create a pin request and open it up in the * default browser. */ void ImgurUploaderSettings::requestImgurPin() { // Save client ID and Secret to config file mConfig->setImgurClientId(mClientIdLineEdit->text().toUtf8()); mConfig->setImgurClientSecret(mClientSecretLineEdit->text().toUtf8()); // Open the pin request in the default browser QDesktopServices::openUrl(mImgurWrapper->pinRequestUrl(mClientIdLineEdit->text())); // Cleanup line edits mClientIdLineEdit->setPlaceholderText(mClientIdLineEdit->text()); mClientIdLineEdit->clear(); mClientSecretLineEdit->clear(); } /* * Request a new token from imgur.com when clicked. */ void ImgurUploaderSettings::getImgurToken() { mImgurWrapper->getAccessToken(mPinLineEdit->text().toUtf8(), mConfig->imgurClientId(), mConfig->imgurClientSecret()); mPinLineEdit->clear(); qInfo("%s", qPrintable(tr("Waiting for imgur.com…"))); } void ImgurUploaderSettings::clearImgurToken() { mConfig->setImgurAccessToken({}); mConfig->setImgurRefreshToken({}); mConfig->setImgurUsername({}); mUsernameLineEdit->setText({}); } void ImgurUploaderSettings::imgurClientEntered(const QString&) { mGetPinButton->setEnabled(!mClientIdLineEdit->text().isEmpty() && !mClientSecretLineEdit->text().isEmpty()); } /* * We have received a new token from imgur.com, now we save it to config for * later use and inform the user about it. */ void ImgurUploaderSettings::imgurTokenUpdated(const QString& accessToken, const QString& refreshToken, const QString& username) { mConfig->setImgurAccessToken(accessToken.toUtf8()); mConfig->setImgurRefreshToken(refreshToken.toUtf8()); mConfig->setImgurUsername(username); mUsernameLineEdit->setText(username); qInfo("%s", qPrintable(tr("Imgur.com token successfully updated."))); } /* * Something went wrong while requesting a new token, we write the message to * shell. */ void ImgurUploaderSettings::imgurTokenError(QNetworkReply::NetworkError networkError, const QString& message) { Q_UNUSED(networkError); qCritical("SettingsDialog returned error: '%s'", qPrintable(message)); qInfo("%s", qPrintable(tr("Imgur.com token update error."))); } void ImgurUploaderSettings::showImgurHistoryDialog() { ImgurHistoryDialog dialog; dialog.exec(); } void ImgurUploaderSettings::usernameChanged() { mClearTokenButton->setEnabled(!mUsernameLineEdit->text().isEmpty()); } ksnip-master/src/gui/settingsDialog/uploader/ImgurUploaderSettings.h000066400000000000000000000051321457262621600263260ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMGURUPLOADERSETTINGS_H #define KSNIP_IMGURUPLOADERSETTINGS_H #include #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/backend/uploader/imgur/ImgurWrapper.h" #include "src/gui/ImgurHistoryDialog.h" #include "src/widgets/CustomLineEdit.h" #include "src/common/constants/DefaultValues.h" class ImgurUploaderSettings : public QGroupBox { Q_OBJECT public: explicit ImgurUploaderSettings(const QSharedPointer &config); ~ImgurUploaderSettings() override = default; void saveSettings(); private: QSharedPointer mConfig; QCheckBox *mForceAnonymousCheckbox; QCheckBox *mDirectLinkToImageCheckbox; QCheckBox *mAlwaysCopyToClipboardCheckBox; QCheckBox *mOpenLinkInBrowserCheckbox; QLineEdit *mClientIdLineEdit; QLineEdit *mClientSecretLineEdit; QLineEdit *mPinLineEdit; QLineEdit *mUsernameLineEdit; CustomLineEdit *mBaseUrlLineEdit; CustomLineEdit *mUploadTitleEdit; CustomLineEdit *mUploadDescriptionEdit; QLabel *mUsernameLabel; QLabel *mBaseUrlLabel; QLabel *mUploadTitleLabel; QLabel *mUploadDescriptionLabel; QPushButton *mGetPinButton; QPushButton *mGetTokenButton; QPushButton *mClearTokenButton; QPushButton *mHistoryButton; ImgurWrapper *mImgurWrapper; QGridLayout *mLayout; void initGui(); void loadConfig(); private slots: void requestImgurPin(); void getImgurToken(); void clearImgurToken(); void imgurClientEntered(const QString &text); void imgurTokenUpdated(const QString &accessToken, const QString &refreshToken, const QString &username); void imgurTokenError(QNetworkReply::NetworkError networkError, const QString &message); void showImgurHistoryDialog(); void usernameChanged(); }; #endif //KSNIP_IMGURUPLOADERSETTINGS_H ksnip-master/src/gui/settingsDialog/uploader/ScriptUploaderSettings.cpp000066400000000000000000000111571457262621600270460ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ScriptUploaderSettings.h" ScriptUploaderSettings::ScriptUploaderSettings(const QSharedPointer &config, const QSharedPointer &fileDialogService) : mConfig(config), mLayout(new QGridLayout(this)), mCopyOutputToClipboardCheckbox(new QCheckBox(this)), mStopOnStdErrCheckbox(new QCheckBox(this)), mCopyOutputFilterLabel(new QLabel(this)), mScriptPathLabel(new QLabel(this)), mCopyOutputFilterLineEdit(new QLineEdit(this)), mUploadScriptPathLineEdit(new QLineEdit(this)), mBrowseButton(new QPushButton(this)), mFileDialogService(fileDialogService) { initGui(); loadConfig(); } ScriptUploaderSettings::~ScriptUploaderSettings() { delete mCopyOutputToClipboardCheckbox; delete mStopOnStdErrCheckbox; delete mCopyOutputFilterLabel; delete mScriptPathLabel; delete mCopyOutputFilterLineEdit; delete mUploadScriptPathLineEdit; delete mBrowseButton; } void ScriptUploaderSettings::saveSettings() { mConfig->setUploadScriptStopOnStdErr(mStopOnStdErrCheckbox->isChecked()); mConfig->setUploadScriptCopyOutputToClipboard(mCopyOutputToClipboardCheckbox->isChecked()); mConfig->setUploadScriptCopyOutputFilter(mCopyOutputFilterLineEdit->text()); mConfig->setUploadScriptPath(mUploadScriptPathLineEdit->text()); } void ScriptUploaderSettings::initGui() { mStopOnStdErrCheckbox->setText(tr("Stop when upload script writes to StdErr")); mStopOnStdErrCheckbox->setToolTip(tr("Marks the upload as failed when script writes to StdErr.\n" "Without this setting errors in the script will be unnoticed.")); mCopyOutputToClipboardCheckbox->setText(tr("Copy script output to clipboard")); connect(mCopyOutputToClipboardCheckbox, &QCheckBox::stateChanged, this, &ScriptUploaderSettings::copyToClipboardChanged); mCopyOutputFilterLabel->setText(tr("Filter:")); mCopyOutputFilterLabel->setToolTip(tr("RegEx Expression. Only copy to clipboard what matches the RegEx Expression.\n" "When omitted, everything is copied.")); mCopyOutputFilterLineEdit->setToolTip(mCopyOutputFilterLabel->toolTip()); mScriptPathLabel->setText(tr("Script:")); mScriptPathLabel->setToolTip(tr("Path to script that will be called for uploading. During upload the script will be called\n" "with the path to a temporary png file as a single argument.")); mUploadScriptPathLineEdit->setToolTip(mScriptPathLabel->toolTip()); mBrowseButton->setText(tr("Browse")); connect(mBrowseButton, &QPushButton::clicked, this, &ScriptUploaderSettings::ShowScriptSelectionDialog); mLayout->setAlignment(Qt::AlignTop); mLayout->setColumnMinimumWidth(0, 10); mLayout->addWidget(mStopOnStdErrCheckbox, 0, 0, 1, 3); mLayout->addWidget(mCopyOutputToClipboardCheckbox, 1, 0, 1, 3); mLayout->addWidget(mCopyOutputFilterLabel, 2, 1, 1, 1); mLayout->addWidget(mCopyOutputFilterLineEdit, 2, 2, 1, 1); mLayout->addWidget(mScriptPathLabel, 3, 0, 1, 1); mLayout->addWidget(mUploadScriptPathLineEdit, 3, 1, 1, 2); mLayout->addWidget(mBrowseButton, 3, 3, 1, 1); setTitle(tr("Script Uploader")); setLayout(mLayout); } void ScriptUploaderSettings::loadConfig() { mStopOnStdErrCheckbox->setChecked(mConfig->uploadScriptStopOnStdErr()); mCopyOutputToClipboardCheckbox->setChecked(mConfig->uploadScriptCopyOutputToClipboard()); mCopyOutputFilterLineEdit->setText(mConfig->uploadScriptCopyOutputFilter()); mUploadScriptPathLineEdit->setText(mConfig->uploadScriptPath()); copyToClipboardChanged(); } void ScriptUploaderSettings::ShowScriptSelectionDialog() { auto path = mFileDialogService->getOpenFileName(this, tr("Select Upload Script"), mConfig->uploadScriptPath()); if(PathHelper::isPathValid(path)) { mUploadScriptPathLineEdit->setText(path); } } void ScriptUploaderSettings::copyToClipboardChanged() { auto enabled = mCopyOutputToClipboardCheckbox->isChecked(); mCopyOutputFilterLabel->setEnabled(enabled); mCopyOutputFilterLineEdit->setEnabled(enabled); } ksnip-master/src/gui/settingsDialog/uploader/ScriptUploaderSettings.h000066400000000000000000000036521457262621600265140ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SCRIPTUPLOADERSETTINGS_H #define KSNIP_SCRIPTUPLOADERSETTINGS_H #include #include #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/adapter/fileDialog/IFileDialogService.h" #include "src/common/helper/PathHelper.h" class ScriptUploaderSettings : public QGroupBox { Q_OBJECT public: explicit ScriptUploaderSettings(const QSharedPointer &config, const QSharedPointer &fileDialogService); ~ScriptUploaderSettings() override; void saveSettings(); private: QGridLayout *mLayout; QSharedPointer mConfig; QCheckBox *mCopyOutputToClipboardCheckbox; QCheckBox *mStopOnStdErrCheckbox; QLineEdit *mCopyOutputFilterLineEdit; QLineEdit *mUploadScriptPathLineEdit; QLabel *mCopyOutputFilterLabel; QLabel *mScriptPathLabel; QPushButton *mBrowseButton; QSharedPointer mFileDialogService; void initGui(); void loadConfig(); private slots: void ShowScriptSelectionDialog(); void copyToClipboardChanged(); }; #endif //KSNIP_SCRIPTUPLOADERSETTINGS_H ksnip-master/src/gui/settingsDialog/uploader/UploaderSettings.cpp000066400000000000000000000046051457262621600256610ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "UploaderSettings.h" UploaderSettings::UploaderSettings(const QSharedPointer &config) : mConfig(config), mConfirmBeforeUploadCheckbox(new QCheckBox(this)), mUploaderTypeComboBox(new QComboBox(this)), mUploaderTypeLabel(new QLabel(this)), mLayout(new QGridLayout(this)) { initGui(); loadConfig(); } UploaderSettings::~UploaderSettings() { delete mConfirmBeforeUploadCheckbox; delete mUploaderTypeComboBox; delete mUploaderTypeLabel; } void UploaderSettings::saveSettings() { mConfig->setConfirmBeforeUpload(mConfirmBeforeUploadCheckbox->isChecked()); mConfig->setUploaderType(static_cast(mUploaderTypeComboBox->currentData().toInt())); } void UploaderSettings::initGui() { mConfirmBeforeUploadCheckbox->setText(tr("Ask for confirmation before uploading")); mUploaderTypeLabel->setText(tr("Uploader Type:")); mUploaderTypeComboBox->addItem(tr("Imgur"), static_cast(UploaderType::Imgur)); mUploaderTypeComboBox->addItem(tr("FTP"), static_cast(UploaderType::Ftp)); mUploaderTypeComboBox->addItem(tr("Script"), static_cast(UploaderType::Script)); mLayout->setAlignment(Qt::AlignTop); mLayout->addWidget(mConfirmBeforeUploadCheckbox, 0, 0, 1, 3); mLayout->setRowMinimumHeight(1, 15); mLayout->addWidget(mUploaderTypeLabel, 2, 0, 1, 1); mLayout->addWidget(mUploaderTypeComboBox, 2, 1, 1, 1); setTitle(tr("Uploader")); setLayout(mLayout); } void UploaderSettings::loadConfig() { mConfirmBeforeUploadCheckbox->setChecked(mConfig->confirmBeforeUpload()); mUploaderTypeComboBox->setCurrentIndex(mUploaderTypeComboBox->findData(static_cast(mConfig->uploaderType()))); } ksnip-master/src/gui/settingsDialog/uploader/UploaderSettings.h000066400000000000000000000027061457262621600253260ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADERSETTINGS_H #define KSNIP_UPLOADERSETTINGS_H #include #include #include #include #include #include "src/backend/config/IConfig.h" #include "src/common/enum/UploaderType.h" class UploaderSettings : public QGroupBox { Q_OBJECT public: explicit UploaderSettings(const QSharedPointer &config); ~UploaderSettings() override; void saveSettings(); private: QGridLayout *mLayout; QSharedPointer mConfig; QCheckBox *mConfirmBeforeUploadCheckbox; QComboBox *mUploaderTypeComboBox; QLabel *mUploaderTypeLabel; void initGui(); void loadConfig(); }; #endif //KSNIP_UPLOADERSETTINGS_H ksnip-master/src/gui/snippingArea/000077500000000000000000000000001457262621600175015ustar00rootroot00000000000000ksnip-master/src/gui/snippingArea/AbstractSnippingArea.cpp000066400000000000000000000176271457262621600242660ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AbstractSnippingArea.h" AbstractSnippingArea::AbstractSnippingArea(const QSharedPointer &config) : mConfig(config), mBackground(nullptr), mResizer(new SnippingAreaResizer(mConfig, this)), mSelector(new SnippingAreaSelector(mConfig, this)), mSelectorInfoText(new SnippingAreaSelectorInfoText(this)), mResizerInfoText(new SnippingAreaResizerInfoText(this)), mIsSwitchPressed(false), mTimer(new QTimer(this)), mUnselectedRegionAlpha(150) { // Make the frame span across the screen and show above any other widget setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); setMouseTracking(true); connect(mResizer, &SnippingAreaResizer::rectChanged, this, &AbstractSnippingArea::updateCapturedArea); connect(mResizer, &SnippingAreaResizer::cursorChanged, this, &AbstractSnippingArea::updateCursor); connect(mSelector, &SnippingAreaSelector::rectChanged, this, &AbstractSnippingArea::updateCapturedArea); connect(mSelector, &SnippingAreaSelector::cursorChanged, this, &AbstractSnippingArea::updateCursor); connect(mTimer, &QTimer::timeout, this, &AbstractSnippingArea::cancelSelection); connect(mConfig.data(), &IConfig::snippingAreaChangedChanged, this, &AbstractSnippingArea::updatePosition); updatePosition(); } AbstractSnippingArea::~AbstractSnippingArea() { delete mBackground; delete mResizer; delete mSelector; delete mSelectorInfoText; delete mResizerInfoText; delete mTimer; } void AbstractSnippingArea::showWithoutBackground() { setAttribute(Qt::WA_TranslucentBackground, true); clearBackgroundImage(); showSnippingArea(); } void AbstractSnippingArea::showWithBackground(const QPixmap &background) { setAttribute(Qt::WA_TranslucentBackground, false); setBackgroundImage(background); showSnippingArea(); } QRect AbstractSnippingArea::getCaptureArea() const { auto offset = getPosition().toPoint(); const QRect &anAuto = mCaptureArea.translated(-offset.x(), -offset.y()); return anAuto; } void AbstractSnippingArea::showSnippingArea() { startTimeout(); mIsSwitchPressed = false; setFullScreen(); mSelector->activate(getGeometry(), getGlobalCursorPosition()); mUnselectedRegionAlpha = mConfig->snippingAreaTransparency(); if(mConfig->showSnippingAreaInfoText()) { mSelectorInfoText->activate(getGeometry(), mConfig->allowResizingRectSelection()); } grabKeyboardFocus(); } void AbstractSnippingArea::setBackgroundImage(const QPixmap &background) { clearBackgroundImage(); mBackground = new QPixmap(background); mSelector->setBackgroundImage(mBackground); } void AbstractSnippingArea::clearBackgroundImage() { delete mBackground; mBackground = nullptr; mSelector->setBackgroundImage(nullptr); } void AbstractSnippingArea::mousePressEvent(QMouseEvent *event) { if (event->button() != Qt::LeftButton) { return; } auto pos = event->pos(); mResizer->handleMousePress(pos); mSelector->handleMousePress(pos); } void AbstractSnippingArea::mouseReleaseEvent(QMouseEvent *event) { if (event->button() != Qt::LeftButton) { return; } mResizer->handleMouseRelease(); mSelector->handleMouseRelease(); if(isResizerSwitchRequired() && !mResizer->isActive()) { switchToResizer(event->pos()); } else if(mSelector->isActive()){ finishSelection(); } } void AbstractSnippingArea::mouseMoveEvent(QMouseEvent *event) { auto pos = event->pos(); mResizer->handleMouseMove(pos); mSelector->handleMouseMove(pos); mSelectorInfoText->handleMouseMove(pos); mResizerInfoText->handleMouseMove(pos); update(); QWidget::mouseMoveEvent(event); } void AbstractSnippingArea::mouseDoubleClickEvent(QMouseEvent *event) { if (mResizer->isActive()) { finishSelection(); } QWidget::mouseDoubleClickEvent(event); } bool AbstractSnippingArea::isResizerSwitchRequired() const { bool allowResizingRectSelection = mConfig->allowResizingRectSelection(); return (allowResizingRectSelection && !mIsSwitchPressed) || (!allowResizingRectSelection && mIsSwitchPressed); } void AbstractSnippingArea::switchToResizer(const QPointF &pos) { mSelector->deactivate(); mSelectorInfoText->deactivate(); if(mConfig->showSnippingAreaInfoText()) { mResizerInfoText->activate(getGeometry()); } mResizer->activate(mCaptureArea, pos); update(); } QPixmap AbstractSnippingArea::background() const { Q_ASSERT(!isBackgroundTransparent()); return *mBackground; } bool AbstractSnippingArea::closeSnippingArea() { mSelector->deactivate(); mResizer->deactivate(); mSelectorInfoText->deactivate(); mResizerInfoText->deactivate(); releaseKeyboard(); // Issue #57 return QWidget::close(); } void AbstractSnippingArea::paintEvent(QPaintEvent *event) { QPainter painter(this); auto geometry = getGeometry(); if (!isBackgroundTransparent()) { painter.drawPixmap(geometry, *mBackground, mBackground->rect()); } painter.setClipRegion(mClippingRegion); painter.setBrush(QColor(0, 0, 0, mUnselectedRegionAlpha)); painter.drawRect(geometry); mResizer->paint(&painter); mSelector->paint(&painter); painter.setClipRect(geometry); mSelectorInfoText->paint(&painter); mResizerInfoText->paint(&painter); QWidget::paintEvent(event); } bool AbstractSnippingArea::isBackgroundTransparent() const { return mBackground == nullptr; } QPoint AbstractSnippingArea::getGlobalCursorPosition() const { return QCursor::pos(); } void AbstractSnippingArea::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Escape) { cancelSelection(); } else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { finishSelection(); } else if (event->key() == Qt::Key_Control){ mIsSwitchPressed = true; } mResizer->handleKeyPress(event); update(); QWidget::keyPressEvent(event); } void AbstractSnippingArea::keyReleaseEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Control) { mIsSwitchPressed = false; } mResizer->handleKeyRelease(event); QWidget::keyReleaseEvent(event); } void AbstractSnippingArea::cancelSelection() { stopTimeout(); closeSnippingArea(); emit canceled(); } void AbstractSnippingArea::updateCapturedArea(const QRectF &rect) { mCaptureArea = rect.toRect(); mClippingRegion = QRegion(getGeometry().toRect()).subtracted(QRegion(mCaptureArea)); } void AbstractSnippingArea::finishSelection() { stopTimeout(); closeSnippingArea(); mConfig->setLastRectArea(selectedRectArea()); emit finished(); } void AbstractSnippingArea::grabKeyboardFocus() { QApplication::setActiveWindow(this); activateWindow(); setFocus(); grabKeyboard(); } QPointF AbstractSnippingArea::getPosition() const { return mPosition; } QRectF AbstractSnippingArea::getGeometry() const { return { getPosition(), getSize() }; } void AbstractSnippingArea::updateCursor(const QCursor &cursor) { setCursor(cursor); } void AbstractSnippingArea::startTimeout() { mTimer->start(60000); } void AbstractSnippingArea::stopTimeout() { mTimer->stop(); } void AbstractSnippingArea::updatePosition() { if(mConfig->snippingAreaOffsetEnable()) { mPosition = mConfig->snippingAreaOffset(); } else { mPosition = {}; } } ksnip-master/src/gui/snippingArea/AbstractSnippingArea.h000066400000000000000000000062551457262621600237260ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ABSTRACTSNIPPINGAREA_H #define KSNIP_ABSTRACTSNIPPINGAREA_H #include #include #include #include #include #include "SnippingAreaAdorner.h" #include "SnippingAreaResizer.h" #include "SnippingAreaSelector.h" #include "SnippingAreaSelectorInfoText.h" #include "SnippingAreaResizerInfoText.h" #include "src/common/helper/MathHelper.h" #include "src/backend/config/IConfig.h" class AbstractSnippingArea : public QWidget { Q_OBJECT public: explicit AbstractSnippingArea(const QSharedPointer &config); ~AbstractSnippingArea() override; void showWithoutBackground(); void showWithBackground(const QPixmap& background); virtual QRect selectedRectArea() const = 0; virtual QPixmap background() const; bool closeSnippingArea(); signals: void finished(); void canceled(); protected: QRegion mClippingRegion; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override; void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; void paintEvent(QPaintEvent *event) override; virtual bool isBackgroundTransparent() const; virtual void setFullScreen() = 0; virtual QSizeF getSize() const = 0; virtual QPoint getGlobalCursorPosition() const; virtual void grabKeyboardFocus(); virtual QPointF getPosition() const; virtual QRectF getGeometry() const; virtual void showSnippingArea(); QRect getCaptureArea() const; private: QRect mCaptureArea; QSharedPointer mConfig; QPixmap *mBackground; SnippingAreaResizer *mResizer; SnippingAreaSelector *mSelector; SnippingAreaSelectorInfoText *mSelectorInfoText; SnippingAreaResizerInfoText *mResizerInfoText; bool mIsSwitchPressed; QTimer *mTimer; int mUnselectedRegionAlpha; QPointF mPosition; void setBackgroundImage(const QPixmap &background); void clearBackgroundImage(); void finishSelection(); private slots: void updateCapturedArea(const QRectF &rect); void updateCursor(const QCursor &cursor); void switchToResizer(const QPointF &pos); void cancelSelection(); bool isResizerSwitchRequired() const; void startTimeout(); void stopTimeout(); void updatePosition(); }; #endif // KSNIP_ABSTRACTSNIPPINGAREA_H ksnip-master/src/gui/snippingArea/AbstractSnippingAreaInfoText.cpp000066400000000000000000000052451457262621600257400ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AbstractSnippingAreaInfoText.h" AbstractSnippingAreaInfoText::AbstractSnippingAreaInfoText(QObject *parent): QObject(parent), mRectPen(new QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)), mRectBrush(new QBrush(QColor(255, 255, 255, 160))), mBaseInfoTextRectSize(new QSize(500, 100)), mRectOffset(30, 30), mIsActive(false) { } AbstractSnippingAreaInfoText::~AbstractSnippingAreaInfoText() { delete mRectPen; delete mRectBrush; delete mBaseInfoTextRectSize; } void AbstractSnippingAreaInfoText::paint(QPainter *painter) { if(mIsActive) { auto fontMetric = painter->fontMetrics(); auto textRect = fontMetric.boundingRect(QRect(mSnippingAreaGeometry.topLeft().toPoint() + mRectOffset, *mBaseInfoTextRectSize), Qt::TextWordWrap, mInfoText); auto boundingRect = textRect.adjusted(-10, -10, 10, 10); if(boundingRect.contains(mCurrentMousePos.toPoint())) { auto bottomPosition = mSnippingAreaGeometry.bottomRight().toPoint(); textRect.moveBottomRight(bottomPosition - QPoint(40, 40)); boundingRect.moveBottomRight(bottomPosition - mRectOffset); } painter->setBrush(*mRectBrush); painter->setPen(*mRectPen); painter->drawRect(boundingRect); painter->drawText(textRect, mInfoText); } } void AbstractSnippingAreaInfoText::handleMouseMove(const QPointF &pos) { mCurrentMousePos = pos; } void AbstractSnippingAreaInfoText::activate(const QRectF &snippingAreaGeometry) { mIsActive = true; mSnippingAreaGeometry = snippingAreaGeometry; updateInfoText(); } void AbstractSnippingAreaInfoText::deactivate() { mIsActive = false; } void AbstractSnippingAreaInfoText::setInfoText(const QStringList &infoTextLines) { auto newLine = QLatin1String("\n"); mInfoText = QString(); for (int i = 0; i < infoTextLines.length(); ++i) { mInfoText += infoTextLines[i]; if(i < infoTextLines.length() - 1){ mInfoText += newLine; } } } ksnip-master/src/gui/snippingArea/AbstractSnippingAreaInfoText.h000066400000000000000000000031011457262621600253720ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ABSTRACTSNIPPINGAREAINFOTEXT_H #define KSNIP_ABSTRACTSNIPPINGAREAINFOTEXT_H #include class AbstractSnippingAreaInfoText : public QObject { Q_OBJECT public: explicit AbstractSnippingAreaInfoText(QObject *parent); ~AbstractSnippingAreaInfoText() override; virtual void paint(QPainter *painter); virtual void handleMouseMove(const QPointF &pos); virtual void activate(const QRectF &snippingAreaGeometry); virtual void deactivate(); protected: virtual void updateInfoText() = 0; void setInfoText(const QStringList &infoTextLines); private: QPen *mRectPen; QBrush *mRectBrush; QString mInfoText; QSize *mBaseInfoTextRectSize; QPointF mCurrentMousePos; bool mIsActive; QRectF mSnippingAreaGeometry; QPoint mRectOffset; }; #endif //KSNIP_ABSTRACTSNIPPINGAREAINFOTEXT_H ksnip-master/src/gui/snippingArea/AdornerMagnifyingGlass.cpp000066400000000000000000000116331457262621600246060ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AdornerMagnifyingGlass.h" AdornerMagnifyingGlass::AdornerMagnifyingGlass() : mOffsetToMouse(QPoint(20, 20)), mScaleFactor(QSize(600, 600)), mZoomInAreaSize(QSize(100, 100)), mBackgroundOffset(QPoint(50,50)), mCrossHairPen(new QPen(Qt::red, 6)) { mVisibleRect.setWidth(200); mVisibleRect.setHeight(200); } AdornerMagnifyingGlass::~AdornerMagnifyingGlass() { delete mCrossHairPen; } void AdornerMagnifyingGlass::update(const QPoint &mousePosition, const QRect &screenRect) { if (mBackgroundWithMargine.isNull()) { return; } updatePosition(mousePosition, screenRect); updateImage(mousePosition - screenRect.topLeft()); updateCrossHair(); } void AdornerMagnifyingGlass::paint(QPainter *painter, const QColor &color) { if (mBackgroundWithMargine.isNull()) { return; } painter->setBrush(Qt::NoBrush); painter->setRenderHint(QPainter::Antialiasing); painter->setClipRegion(QRegion(mVisibleRect, QRegion::Ellipse)); painter->drawPixmap(mVisibleRect, mImage); mCrossHairPen->setColor(color); painter->setPen(*mCrossHairPen); painter->drawLine(mCrossHairTop); painter->drawLine(mCrossHairBottom); painter->drawLine(mCrossHairLeft); painter->drawLine(mCrossHairRight); } void AdornerMagnifyingGlass::setBackgroundImage(const QPixmap *background) { if (background == nullptr) { mBackgroundWithMargine = QPixmap(); } else { mBackgroundWithMargine = createBackgroundWithMagine(background); } } void AdornerMagnifyingGlass::updatePosition(const QPoint &mousePosition, const QRect &screenRect) { if (isPositionTopLeftFromMouse(mousePosition, screenRect)) { mVisibleRect.moveBottomRight(mousePosition); } else if (isPositionBottomLeftFromMouse(mousePosition, screenRect)) { mVisibleRect.moveTopRight(mousePosition); } else if (isPositionTopRightFromMouse(mousePosition, screenRect)) { mVisibleRect.moveBottomLeft(mousePosition); } else { mVisibleRect.moveTopLeft(mousePosition + mOffsetToMouse); } } void AdornerMagnifyingGlass::updateImage(const QPoint &mousePosition) { QRect positionAroundMouse(QPoint(), mZoomInAreaSize); positionAroundMouse.moveCenter(mousePosition + mBackgroundOffset); auto zoomedInImage = mBackgroundWithMargine.copy(positionAroundMouse).scaled(mScaleFactor); QRect rectForFinalCut(mVisibleRect); rectForFinalCut.moveCenter(zoomedInImage.rect().center()); mImage = zoomedInImage.copy(rectForFinalCut); } QPixmap AdornerMagnifyingGlass::createBackgroundWithMagine(const QPixmap *background) const { QPixmap backgroundWithMargine(background->size() + mZoomInAreaSize); backgroundWithMargine.fill(Qt::black); QPainter painter(&backgroundWithMargine); painter.drawPixmap(mBackgroundOffset, *background); return backgroundWithMargine; } void AdornerMagnifyingGlass::updateCrossHair() { auto outerOffset = 20; auto innerOffset = 15; mCrossHairTop.setLine(mVisibleRect.center().x(), mVisibleRect.top() + outerOffset, mVisibleRect.center().x(), mVisibleRect.center().y() - innerOffset); mCrossHairBottom.setLine(mVisibleRect.center().x(), mVisibleRect.bottom() - outerOffset, mVisibleRect.center().x(), mVisibleRect.center().y() + innerOffset); mCrossHairLeft.setLine(mVisibleRect.left() + outerOffset, mVisibleRect.center().y(), mVisibleRect.center().x() - innerOffset, mVisibleRect.center().y()); mCrossHairRight.setLine(mVisibleRect.right() - outerOffset, mVisibleRect.center().y(), mVisibleRect.center().x() + innerOffset, mVisibleRect.center().y()); } bool AdornerMagnifyingGlass::isPositionTopRightFromMouse(const QPoint &mousePosition, const QRect &screenRect) const { return mousePosition.x() + mVisibleRect.width() < screenRect.width() && mousePosition.y() + mVisibleRect.height() > screenRect.height(); } bool AdornerMagnifyingGlass::isPositionBottomLeftFromMouse(const QPoint &mousePosition, const QRect &screenRect) const { return mousePosition.x() + mVisibleRect.width() > screenRect.width() && mousePosition.y() + mVisibleRect.height() < screenRect.height(); } bool AdornerMagnifyingGlass::isPositionTopLeftFromMouse(const QPoint &mousePosition, const QRect &screenRect) const { return mousePosition.x() + mVisibleRect.width() > screenRect.width() && mousePosition.y() + mVisibleRect.height() > screenRect.height(); } ksnip-master/src/gui/snippingArea/AdornerMagnifyingGlass.h000066400000000000000000000037341457262621600242560ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ADORNERMAGNIFYINGGLASS_H #define KSNIP_ADORNERMAGNIFYINGGLASS_H #include class AdornerMagnifyingGlass { public: explicit AdornerMagnifyingGlass(); ~AdornerMagnifyingGlass(); void update(const QPoint &mousePosition, const QRect &screenRect); void paint(QPainter *painter, const QColor &color); void setBackgroundImage(const QPixmap *background); private: QPixmap mBackgroundWithMargine; QPixmap mImage; QRect mVisibleRect; QPoint mOffsetToMouse; QSize mScaleFactor; QSize mZoomInAreaSize; QPoint mBackgroundOffset; QLine mCrossHairTop; QLine mCrossHairBottom; QLine mCrossHairLeft; QLine mCrossHairRight; QPen *mCrossHairPen; void updateImage(const QPoint &mousePosition); void updateCrossHair(); bool isPositionTopLeftFromMouse(const QPoint &mousePosition, const QRect &screenRect) const; bool isPositionBottomLeftFromMouse(const QPoint &mousePosition, const QRect &screenRect) const; bool isPositionTopRightFromMouse(const QPoint &mousePosition, const QRect &screenRect) const; void updatePosition(const QPoint &mousePosition, const QRect &screenRect); QPixmap createBackgroundWithMagine(const QPixmap *background) const; }; #endif //KSNIP_ADORNERMAGNIFYINGGLASS_H ksnip-master/src/gui/snippingArea/AdornerPositionInfo.cpp000066400000000000000000000032771457262621600241510ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AdornerPositionInfo.h" AdornerPositionInfo::AdornerPositionInfo() : mFontMetric(new QFontMetrics(mFont)), mPen(new QPen(Qt::red, 1)) { } AdornerPositionInfo::~AdornerPositionInfo() { delete mFontMetric; delete mPen; } void AdornerPositionInfo::update(const QPoint &mousePosition, const QRect &screenRect) { QPoint textOffset(10, 8); auto offset = screenRect.topLeft(); mText = QString::number(mousePosition.x() - offset.x()) + QLatin1String(", ") + QString::number(mousePosition.y() - offset.y()); mBox = mFontMetric->boundingRect(mText); mBox.moveTopLeft(mousePosition + textOffset); mTextRect = mBox; mBox.adjust(0, 0, 7, 4); mTextRect.adjust(-3, 0, 5, 0); } void AdornerPositionInfo::paint(QPainter *painter, const QColor &color) { mPen->setColor(color); painter->setPen(*mPen); painter->setBrush(QColor(0, 0, 0, 200)); painter->drawRoundedRect(mTextRect, 2, 2); painter->drawText(mBox, mText); } ksnip-master/src/gui/snippingArea/AdornerPositionInfo.h000066400000000000000000000023461457262621600236120ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ADORNERPOSITIONINFO_H #define KSNIP_ADORNERPOSITIONINFO_H #include class AdornerPositionInfo { public: explicit AdornerPositionInfo(); ~AdornerPositionInfo(); void update(const QPoint &mousePosition, const QRect &screenRect); void paint(QPainter *painter, const QColor &color); private: QFont mFont; QFontMetrics *mFontMetric; QPen *mPen; QRect mBox; QRect mTextRect; QString mText; }; #endif //KSNIP_ADORNERPOSITIONINFO_H ksnip-master/src/gui/snippingArea/AdornerRulers.cpp000066400000000000000000000033301457262621600227730ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AdornerRulers.h" AdornerRulers::AdornerRulers() : mPen(new QPen(Qt::red, 1, Qt::DotLine, Qt::SquareCap, Qt::MiterJoin)) { } AdornerRulers::~AdornerRulers() { delete mPen; } void AdornerRulers::update(const QPoint &mousePosition, const QRect &screenRect) { int offset = 4; mTopLine.setLine(mousePosition.x(), mousePosition.y() - offset, mousePosition.x(), screenRect.top()); mRightLine.setLine(mousePosition.x() + offset, mousePosition.y(), screenRect.right(), mousePosition.y()); mBottomLine.setLine(mousePosition.x(), mousePosition.y() + offset, mousePosition.x(), screenRect.bottom()); mLeftLine.setLine(mousePosition.x() - offset, mousePosition.y(), screenRect.left(), mousePosition.y()); } void AdornerRulers::paint(QPainter *painter, const QColor &color) { mPen->setColor(color); painter->setPen(*mPen); painter->drawLine(mTopLine); painter->drawLine(mRightLine); painter->drawLine(mBottomLine); painter->drawLine(mLeftLine); } ksnip-master/src/gui/snippingArea/AdornerRulers.h000066400000000000000000000022631457262621600224440ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ADORNERRULERS_H #define KSNIP_ADORNERRULERS_H #include class AdornerRulers { public: explicit AdornerRulers(); ~AdornerRulers(); void update(const QPoint &mousePosition, const QRect &screenRect); void paint(QPainter *painter, const QColor &color); private: QPen *mPen; QLine mBottomLine; QLine mTopLine; QLine mLeftLine; QLine mRightLine; }; #endif //KSNIP_ADORNERRULERS_H ksnip-master/src/gui/snippingArea/AdornerSizeInfo.cpp000066400000000000000000000064241457262621600232540ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "AdornerSizeInfo.h" AdornerSizeInfo::AdornerSizeInfo() : mFontMetric(new QFontMetrics(mFont)), mSizeInfoPen(new QPen(Qt::red, 1)) { } AdornerSizeInfo::~AdornerSizeInfo() { delete mFontMetric; delete mSizeInfoPen; } void AdornerSizeInfo::update(const QRect &captureRect) { updateWidthInfo(captureRect); updateHeightInfo(captureRect); updateSizeInfoText(captureRect); } void AdornerSizeInfo::paint(QPainter *painter, const QColor &color) { mSizeInfoPen->setColor(color); painter->setBrush(Qt::NoBrush); painter->setPen(*mSizeInfoPen); painter->drawPath(mWidthInfo); painter->drawPath(mHeightInfo); painter->drawText(mWidthTextPosition, mWidthInfoText); painter->drawText(mHeightTextPosition, mHeightInfoText); } void AdornerSizeInfo::updateWidthInfo(const QRect &captureRect) { auto topLeft = captureRect.topLeft(); auto topRight = captureRect.topRight(); auto offsetLine = QPoint(0, 10); auto offsetBorderBottom = QPoint(0, 7); auto offsetBorderTop = QPoint(0, 13); QPainterPath newPath(topLeft - offsetBorderBottom); newPath.lineTo(topLeft - offsetBorderTop); newPath.lineTo(topLeft - offsetLine); newPath.lineTo(topRight - offsetLine); newPath.lineTo(topRight - offsetBorderTop); newPath.lineTo(topRight - offsetBorderBottom); mWidthInfo.swap(newPath); } void AdornerSizeInfo::updateHeightInfo(const QRect &captureRect) { auto topLeft = captureRect.topLeft(); auto bottomLeft = captureRect.bottomLeft(); auto offsetLine = QPoint(10, 0); auto offsetBorderLeft = QPoint(7, 0); auto offsetBorderRight = QPoint(13, 0); QPainterPath newPath(topLeft - offsetBorderLeft); newPath.lineTo(topLeft - offsetBorderRight); newPath.lineTo(topLeft - offsetLine); newPath.lineTo(bottomLeft - offsetLine); newPath.lineTo(bottomLeft - offsetBorderRight); newPath.lineTo(bottomLeft - offsetBorderLeft); mHeightInfo.swap(newPath); } void AdornerSizeInfo::updateSizeInfoText(const QRect &captureRect) { auto textOffset = 13; mWidthInfoText = QString::number(captureRect.width()); mHeightInfoText = QString::number(captureRect.height()); auto widthTextBoundingRect = mFontMetric->boundingRect(mWidthInfoText); auto heightTextBoundingRect = mFontMetric->boundingRect(mHeightInfoText); mWidthTextPosition.setX(captureRect.center().x() - widthTextBoundingRect.width() / 2); mWidthTextPosition.setY(captureRect.top() - textOffset); mHeightTextPosition.setX(captureRect.left() - textOffset - heightTextBoundingRect.width()); mHeightTextPosition.setY(captureRect.center().y() + heightTextBoundingRect.height() / 2); } ksnip-master/src/gui/snippingArea/AdornerSizeInfo.h000066400000000000000000000027341457262621600227210ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ADORNERSIZEINFO_H #define KSNIP_ADORNERSIZEINFO_H #include #include class AdornerSizeInfo { public: explicit AdornerSizeInfo(); ~AdornerSizeInfo(); void update(const QRect &captureRect); void paint(QPainter *painter, const QColor &color); private: QFont mFont; QFontMetrics *mFontMetric; QPen *mSizeInfoPen; QPainterPath mWidthInfo; QPainterPath mHeightInfo; QPoint mWidthTextPosition; QPoint mHeightTextPosition; QString mWidthInfoText; QString mHeightInfoText; void updateWidthInfo(const QRect &captureRect); void updateHeightInfo(const QRect &captureRect); void updateSizeInfoText(const QRect &captureRect); }; #endif //KSNIP_ADORNERSIZEINFO_H ksnip-master/src/gui/snippingArea/MacSnippingArea.cpp000066400000000000000000000024331457262621600232100ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MacSnippingArea.h" MacSnippingArea::MacSnippingArea(const QSharedPointer &config) : AbstractSnippingArea(config) { setWindowFlags(windowFlags() | Qt::WindowFullscreenButtonHint); } QRect MacSnippingArea::selectedRectArea() const { return mHdpiScaler.scale(getCaptureArea()); } void MacSnippingArea::setFullScreen() { setFixedSize(QDesktopWidget().size()); QWidget::showFullScreen(); } QSizeF MacSnippingArea::getSize() const { return QSizeF(geometry().size()); }ksnip-master/src/gui/snippingArea/MacSnippingArea.h000066400000000000000000000024541457262621600226600ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MACSNIPPINGAREA_H #define KSNIP_MACSNIPPINGAREA_H #include "AbstractSnippingArea.h" #include "src/common/platform/HdpiScaler.h" class MacSnippingArea : public AbstractSnippingArea { public: explicit MacSnippingArea(const QSharedPointer &config); ~MacSnippingArea() override = default; QRect selectedRectArea() const override; protected: void setFullScreen() override; QSizeF getSize() const override; private: HdpiScaler mHdpiScaler; }; #endif //KSNIP_MACSNIPPINGAREA_H ksnip-master/src/gui/snippingArea/SnippingAreaAdorner.cpp000066400000000000000000000045721457262621600241100ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnippingAreaAdorner.h" SnippingAreaAdorner::SnippingAreaAdorner() : mMouseIsDown(false), mRulerEnabled(false), mPositionAndSizeInfoEnabled(false), mMagnifyingGlassEnabled(false) { } void SnippingAreaAdorner::setRulersEnabled(bool enabled) { mRulerEnabled = enabled; } void SnippingAreaAdorner::setPositionAndSizeInfoEnabled(bool enabled) { mPositionAndSizeInfoEnabled = enabled; } void SnippingAreaAdorner::setMagnifyingGlassEnabled(bool enabled) { mMagnifyingGlassEnabled = enabled; } void SnippingAreaAdorner::setIsMouseDown(bool isDown) { mMouseIsDown = isDown; } void SnippingAreaAdorner::setBackgroundImage(const QPixmap *background) { mMagnifyingGlass.setBackgroundImage(background); } void SnippingAreaAdorner::update(const QPoint &mousePosition, const QRect &screenRect, const QRect &captureRect) { if (mRulerEnabled && !mMouseIsDown) { mRulers.update(mousePosition, screenRect); } if (mPositionAndSizeInfoEnabled) { if (mMouseIsDown) { mSizeInfo.update(captureRect); } else { mPositionInfo.update(mousePosition, screenRect); } } if (mMagnifyingGlassEnabled) { mMagnifyingGlass.update(mousePosition, screenRect); } } void SnippingAreaAdorner::paint(QPainter *painter, const QColor &adornerColor, const QColor &cursorColor) { if (mRulerEnabled && !mMouseIsDown) { mRulers.paint(painter, adornerColor); } if (mPositionAndSizeInfoEnabled) { if (mMouseIsDown) { mSizeInfo.paint(painter, adornerColor); } else { mPositionInfo.paint(painter, adornerColor); } } if (mMagnifyingGlassEnabled) { mMagnifyingGlass.paint(painter, cursorColor); } } ksnip-master/src/gui/snippingArea/SnippingAreaAdorner.h000066400000000000000000000034731457262621600235540ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNIPPINGAREAADORNER_H #define KSNIP_SNIPPINGAREAADORNER_H #include #include "AdornerMagnifyingGlass.h" #include "AdornerRulers.h" #include "AdornerPositionInfo.h" #include "AdornerSizeInfo.h" #include "src/common/helper/MathHelper.h" class SnippingAreaAdorner { public: explicit SnippingAreaAdorner(); ~SnippingAreaAdorner() = default; void setRulersEnabled(bool enabled); void setPositionAndSizeInfoEnabled(bool enabled); void setMagnifyingGlassEnabled(bool enabled); void setIsMouseDown(bool isDown); void setBackgroundImage(const QPixmap *background); void update(const QPoint &mousePosition, const QRect &screenRect, const QRect &captureRect); void paint(QPainter *painter, const QColor &adornerColor, const QColor &cursorColor); private: bool mRulerEnabled; bool mPositionAndSizeInfoEnabled; bool mMagnifyingGlassEnabled; bool mMouseIsDown; AdornerSizeInfo mSizeInfo; AdornerPositionInfo mPositionInfo; AdornerRulers mRulers; AdornerMagnifyingGlass mMagnifyingGlass; }; #endif //KSNIP_SNIPPINGAREAADORNER_H ksnip-master/src/gui/snippingArea/SnippingAreaResizer.cpp000066400000000000000000000154051457262621600241360ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnippingAreaResizer.h" SnippingAreaResizer::SnippingAreaResizer(const QSharedPointer &config, QObject *parent) : QObject(parent), mConfig(config), mIsActive(false), mIsGrabbed(false), mGrabbedHandleIndex(-1), mControlPressed(false), mAltPressed(false) { const auto width = 15; mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); mHandles.append(QRectF(0, 0, width, width)); } void SnippingAreaResizer::activate(const QRectF &rect, const QPointF &pos) { mIsActive = true; mCurrentRect = rect; mColor = mConfig->snippingAdornerColor(); updateHandlePositions(); updateCursor(pos.toPoint()); } void SnippingAreaResizer::deactivate() { mIsActive = false; mIsGrabbed = false; mGrabbedHandleIndex = -1; } void SnippingAreaResizer::paint(QPainter *painter) { if(mIsActive) { painter->setRenderHint(QPainter::Antialiasing); painter->setBrush(Qt::NoBrush); painter->setPen(QPen(mColor, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin)); painter->drawRect(mCurrentRect); painter->setBrush(mColor); for(const auto handle : mHandles) { painter->drawEllipse(handle); } } } bool SnippingAreaResizer::isActive() const { return mIsActive; } void SnippingAreaResizer::handleMousePress(const QPointF &pos) { if(mIsActive) { for(const auto handle : mHandles) { if(handle.contains(pos)) { mIsGrabbed = true; mGrabOffset = pos - handle.center(); mGrabbedHandleIndex = mHandles.indexOf(handle); break; } } if(!mIsGrabbed && mCurrentRect.contains(pos)) { mIsGrabbed = true; mGrabOffset = pos - mCurrentRect.topLeft(); } } } void SnippingAreaResizer::handleMouseRelease() { if(mIsActive && mIsGrabbed) { mIsGrabbed = false; mGrabOffset = {}; mGrabbedHandleIndex = -1; } } void SnippingAreaResizer::handleMouseMove(const QPointF &pos) { if (mIsActive) { if (mIsGrabbed) { updateCurrentRect(pos); } else { updateCursor(pos); } } } void SnippingAreaResizer::handleKeyPress(QKeyEvent *event) { if (event->key() == Qt::Key_Control) { mControlPressed = true; } else if (event->key() == Qt::Key_Alt) { mAltPressed = true; } if (mIsActive) { arrowKeyPressed(event); notifyRectChanged(); } } void SnippingAreaResizer::arrowKeyPressed(const QKeyEvent *event) { if (event->key() == Qt::Key_Up) { arrowUpPressed(); } else if (event->key() == Qt::Key_Down) { arrowDownPressed(); } else if (event->key() == Qt::Key_Left) { arrowLeftPressed(); } else if (event->key() == Qt::Key_Right) { arrowRightPressed(); } } void SnippingAreaResizer::handleKeyRelease(QKeyEvent *event) { if(event->key() == Qt::Key_Control) { mControlPressed = false; } else if(event->key() == Qt::Key_Alt) { mAltPressed = false; } } void SnippingAreaResizer::updateCursor(const QPointF &pos) { if (mHandles[1].contains(pos) || mHandles[5].contains(pos)) { emit cursorChanged(Qt::SizeVerCursor); } else if (mHandles[3].contains(pos) || mHandles[7].contains(pos)) { emit cursorChanged(Qt::SizeHorCursor); } else if (mHandles[0].contains(pos) || mHandles[2].contains(pos) || mHandles[4].contains(pos) || mHandles[6].contains(pos) || mCurrentRect.contains(pos)) { emit cursorChanged(Qt::SizeAllCursor); } else { emit cursorChanged(Qt::ArrowCursor); } } void SnippingAreaResizer::updateCurrentRect(const QPointF &point) { if(mGrabbedHandleIndex == -1){ mCurrentRect.moveTo(point - mGrabOffset); } else if(mGrabbedHandleIndex == 0){ mCurrentRect.setTopLeft(point - mGrabOffset); } else if(mGrabbedHandleIndex == 1){ mCurrentRect.setTop((point - mGrabOffset).y()); } else if(mGrabbedHandleIndex == 2){ mCurrentRect.setTopRight(point - mGrabOffset); } else if(mGrabbedHandleIndex == 3){ mCurrentRect.setRight((point - mGrabOffset).x()); } else if(mGrabbedHandleIndex == 4){ mCurrentRect.setBottomRight(point - mGrabOffset); } else if(mGrabbedHandleIndex == 5){ mCurrentRect.setBottom((point - mGrabOffset).y()); } else if(mGrabbedHandleIndex == 6){ mCurrentRect.setBottomLeft(point - mGrabOffset); } else if(mGrabbedHandleIndex == 7){ mCurrentRect.setLeft((point - mGrabOffset).x()); } notifyRectChanged(); } void SnippingAreaResizer::notifyRectChanged() { updateHandlePositions(); emit rectChanged(mCurrentRect.normalized()); } void SnippingAreaResizer::updateHandlePositions() { mHandles[0].moveCenter(RectHelper::topLeft(mCurrentRect)); mHandles[1].moveCenter(RectHelper::top(mCurrentRect)); mHandles[2].moveCenter(RectHelper::topRight(mCurrentRect)); mHandles[3].moveCenter(RectHelper::right(mCurrentRect)); mHandles[4].moveCenter(RectHelper::bottomRight(mCurrentRect)); mHandles[5].moveCenter(RectHelper::bottom(mCurrentRect)); mHandles[6].moveCenter(RectHelper::bottomLeft(mCurrentRect)); mHandles[7].moveCenter(RectHelper::left(mCurrentRect)); } void SnippingAreaResizer::arrowRightPressed() { if (mControlPressed) { mCurrentRect.setLeft(mCurrentRect.left() + 1); } else if (mAltPressed) { mCurrentRect.setRight(mCurrentRect.right() + 1); } else { mCurrentRect.moveRight(mCurrentRect.right() + 1); } } void SnippingAreaResizer::arrowLeftPressed() { if (mControlPressed) { mCurrentRect.setLeft(mCurrentRect.left() - 1); } else if (mAltPressed) { mCurrentRect.setRight(mCurrentRect.right() - 1); } else { mCurrentRect.moveLeft(mCurrentRect.left() - 1); } } void SnippingAreaResizer::arrowDownPressed() { if (mControlPressed) { mCurrentRect.setTop(mCurrentRect.top() + 1); } else if (mAltPressed) { mCurrentRect.setBottom(mCurrentRect.bottom() + 1); } else { mCurrentRect.moveBottom(mCurrentRect.bottom() + 1); } } void SnippingAreaResizer::arrowUpPressed() { if (mControlPressed) { mCurrentRect.setTop(mCurrentRect.top() - 1); } else if (mAltPressed) { mCurrentRect.setBottom(mCurrentRect.bottom() - 1); } else { mCurrentRect.moveTop(mCurrentRect.top() - 1); } } ksnip-master/src/gui/snippingArea/SnippingAreaResizer.h000066400000000000000000000042461457262621600236040ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNIPPINGAREARESIZER_H #define KSNIP_SNIPPINGAREARESIZER_H #include #include #include #include #include "src/common/helper/RectHelper.h" #include "src/backend/config/IConfig.h" class SnippingAreaResizer : public QObject { Q_OBJECT public: explicit SnippingAreaResizer(const QSharedPointer &config, QObject *parent); ~SnippingAreaResizer() override = default; void activate(const QRectF &rect, const QPointF &pos); void deactivate(); void paint(QPainter *painter); bool isActive() const; void handleMousePress(const QPointF &pos); void handleMouseRelease(); void handleMouseMove(const QPointF &pos); void handleKeyPress(QKeyEvent *event); void handleKeyRelease(QKeyEvent *event); signals: void rectChanged(const QRectF &rect); void cursorChanged(const QCursor &cursor); private: QRectF mCurrentRect; bool mIsActive; QPointF mGrabOffset; bool mIsGrabbed; int mGrabbedHandleIndex; QVector mHandles; QSharedPointer mConfig; QColor mColor; bool mControlPressed; bool mAltPressed; void updateHandlePositions(); void updateCurrentRect(const QPointF &point); void updateCursor(const QPointF &pos); void notifyRectChanged(); void arrowUpPressed(); void arrowDownPressed(); void arrowLeftPressed(); void arrowRightPressed(); void arrowKeyPressed(const QKeyEvent *event); }; #endif //KSNIP_SNIPPINGAREARESIZER_H ksnip-master/src/gui/snippingArea/SnippingAreaResizerInfoText.cpp000066400000000000000000000027611457262621600256200ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnippingAreaResizerInfoText.h" SnippingAreaResizerInfoText::SnippingAreaResizerInfoText(QObject *parent) : AbstractSnippingAreaInfoText(parent) { } void SnippingAreaResizerInfoText::updateInfoText() { QStringList infoTextLines = { tr("Resize selected rect using the handles or move it by dragging the selection."), tr("Use arrow keys to move the selection."), tr("Use arrow keys while pressing CTRL to move top left handle."), tr("Use arrow keys while pressing ALT to move bottom right handle."), tr("Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere."), tr("Abort by pressing ESC."), tr("This message can be disabled via settings.") }; setInfoText(infoTextLines); } ksnip-master/src/gui/snippingArea/SnippingAreaResizerInfoText.h000066400000000000000000000023011457262621600252530ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNIPPINGAREARESIZERINFOTEXT_H #define KSNIP_SNIPPINGAREARESIZERINFOTEXT_H #include "AbstractSnippingAreaInfoText.h" class SnippingAreaResizerInfoText : public AbstractSnippingAreaInfoText { Q_OBJECT public: explicit SnippingAreaResizerInfoText(QObject *parent); ~SnippingAreaResizerInfoText() override = default; protected: void updateInfoText() override; }; #endif //KSNIP_SNIPPINGAREARESIZERINFOTEXT_H ksnip-master/src/gui/snippingArea/SnippingAreaSelector.cpp000066400000000000000000000065451457262621600243000ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnippingAreaSelector.h" SnippingAreaSelector::SnippingAreaSelector(const QSharedPointer &config, QObject *parent) : QObject(parent), mIsActive(false), mConfig(config), mIsMouseDown(false) { } void SnippingAreaSelector::activate(const QRectF &snippingAreaGeometry, const QPointF &pos) { setupAdorner(); mIsActive = true; mSnippingAreaGeometry = snippingAreaGeometry; mAdornerColor = mConfig->snippingAdornerColor(); mCursorColor = mConfig->snippingCursorColor(); updateCurrentRect({}, pos); updateAdorner(pos); emit cursorChanged(CustomCursor(mConfig->snippingCursorColor(), mConfig->snippingCursorSize())); } void SnippingAreaSelector::deactivate() { mIsActive = false; mIsMouseDown = false; mMouseDownPos = {}; } void SnippingAreaSelector::paint(QPainter *painter) { if(mIsActive) { mAdorner.paint(painter, mAdornerColor, mCursorColor); painter->setClipping(false); painter->setRenderHint(QPainter::Antialiasing, false); painter->setPen(mAdornerColor); painter->drawRect(mCurrentRect); } } void SnippingAreaSelector::setBackgroundImage(const QPixmap *background) { mAdorner.setBackgroundImage(background); } bool SnippingAreaSelector::isActive() const { return mIsActive; } void SnippingAreaSelector::handleMousePress(const QPointF &pos) { if(mIsActive) { mMouseDownPos = pos; setIsMouseDown(true); rectChanged(QRectF(mMouseDownPos, mMouseDownPos)); } } void SnippingAreaSelector::handleMouseRelease() { if(mIsActive) { setIsMouseDown(false); } } void SnippingAreaSelector::handleMouseMove(const QPointF &pos) { if(mIsActive) { if(mIsMouseDown) { const auto rect = QRectF(mMouseDownPos, pos).normalized(); updateCurrentRect(rect, pos); } updateAdorner(pos); } } void SnippingAreaSelector::updateAdorner(const QPointF &pos) { mAdorner.update(pos.toPoint(), mSnippingAreaGeometry.toRect(), mCurrentRect.toRect()); } void SnippingAreaSelector::updateCurrentRect(const QRectF &rect, const QPointF &pos) { mCurrentRect = rect; emit rectChanged(rect); } void SnippingAreaSelector::setupAdorner() { auto magnifyingGlassEnabled = mConfig->snippingAreaMagnifyingGlassEnabled(); auto freezeImageWhileSnippingEnabled = mConfig->freezeImageWhileSnippingEnabled(); mAdorner.setRulersEnabled(mConfig->snippingAreaRulersEnabled()); mAdorner.setPositionAndSizeInfoEnabled(mConfig->snippingAreaPositionAndSizeInfoEnabled()); mAdorner.setMagnifyingGlassEnabled(magnifyingGlassEnabled && freezeImageWhileSnippingEnabled); } void SnippingAreaSelector::setIsMouseDown(bool isMouseDown) { mIsMouseDown = isMouseDown; mAdorner.setIsMouseDown(isMouseDown); } ksnip-master/src/gui/snippingArea/SnippingAreaSelector.h000066400000000000000000000040031457262621600237300ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNIPPINGAREASELECTOR_H #define KSNIP_SNIPPINGAREASELECTOR_H #include #include "SnippingAreaAdorner.h" #include "src/backend/config/Config.h" #include "src/widgets/CustomCursor.h" class SnippingAreaSelector : public QObject { Q_OBJECT public: explicit SnippingAreaSelector(const QSharedPointer &config, QObject *parent); ~SnippingAreaSelector() override = default; void activate(const QRectF &snippingAreaGeometry, const QPointF &pos); void deactivate(); void paint(QPainter *painter); bool isActive() const; void handleMousePress(const QPointF &pos); void handleMouseRelease(); void handleMouseMove(const QPointF &pos); void setBackgroundImage(const QPixmap *background); signals: void rectChanged(const QRectF &rect); void cursorChanged(const QCursor &cursor); private: QRectF mCurrentRect; bool mIsActive; QSharedPointer mConfig; SnippingAreaAdorner mAdorner; QPointF mMouseDownPos; bool mIsMouseDown; QRectF mSnippingAreaGeometry; QColor mAdornerColor; QColor mCursorColor; void setupAdorner(); void setIsMouseDown(bool isMouseDown); void updateCurrentRect(const QRectF &rect, const QPointF &pos); void updateAdorner(const QPointF &pos); }; #endif //KSNIP_SNIPPINGAREASELECTOR_H ksnip-master/src/gui/snippingArea/SnippingAreaSelectorInfoText.cpp000066400000000000000000000033641457262621600257550ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SnippingAreaSelectorInfoText.h" SnippingAreaSelectorInfoText::SnippingAreaSelectorInfoText(QObject *parent) : AbstractSnippingAreaInfoText(parent), mIsResizingDefault(false) { } void SnippingAreaSelectorInfoText::updateInfoText() { auto resizeAfterSelection = tr("Hold CTRL pressed to resize selection after selecting."); auto dontResizeAfterSelection = tr("Hold CTRL pressed to prevent resizing after selecting."); QStringList infoTextLines = { tr("Click and Drag to select a rectangular area or press ESC to quit."), mIsResizingDefault ? dontResizeAfterSelection : resizeAfterSelection, tr("Operation will be canceled after 60 sec when no selection made."), tr("This message can be disabled via settings.") }; setInfoText(infoTextLines); } void SnippingAreaSelectorInfoText::activate(const QRectF &snippingAreaGeometry, bool isResizingDefault) { mIsResizingDefault = isResizingDefault; AbstractSnippingAreaInfoText::activate(snippingAreaGeometry); } ksnip-master/src/gui/snippingArea/SnippingAreaSelectorInfoText.h000066400000000000000000000024701457262621600254170ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SNIPPINGAREASELECTORINFOTEXT_H #define KSNIP_SNIPPINGAREASELECTORINFOTEXT_H #include "AbstractSnippingAreaInfoText.h" class SnippingAreaSelectorInfoText : public AbstractSnippingAreaInfoText { Q_OBJECT public: explicit SnippingAreaSelectorInfoText(QObject *parent); ~SnippingAreaSelectorInfoText() override = default; void activate(const QRectF &snippingAreaGeometry, bool isResizingDefault); protected: void updateInfoText() override; private: bool mIsResizingDefault; }; #endif //KSNIP_SNIPPINGAREASELECTORINFOTEXT_H ksnip-master/src/gui/snippingArea/WaylandSnippingArea.cpp000066400000000000000000000022051457262621600241040ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WaylandSnippingArea.h" WaylandSnippingArea::WaylandSnippingArea(const QSharedPointer &config) : X11SnippingArea(config) { } QRect WaylandSnippingArea::selectedRectArea() const { return mHdpiScaler.scale(getCaptureArea()); } void WaylandSnippingArea::grabKeyboardFocus() { QApplication::setActiveWindow(this); setFocus(); grabKeyboard(); } ksnip-master/src/gui/snippingArea/WaylandSnippingArea.h000066400000000000000000000023321457262621600235520ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WAYLANDSNIPPINGAREA_H #define KSNIP_WAYLANDSNIPPINGAREA_H #include "X11SnippingArea.h" class WaylandSnippingArea : public X11SnippingArea { public: explicit WaylandSnippingArea(const QSharedPointer &config); ~WaylandSnippingArea() override = default; QRect selectedRectArea() const override; protected: void grabKeyboardFocus() override; private: HdpiScaler mHdpiScaler; }; #endif //KSNIP_WAYLANDSNIPPINGAREA_H ksnip-master/src/gui/snippingArea/WinSnippingArea.cpp000066400000000000000000000077121457262621600232520ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinSnippingArea.h" WinSnippingArea::WinSnippingArea(const QSharedPointer &config) : AbstractSnippingArea(config), mIsFullScreenSizeSet(false), mIsMultipleScaledScreens(false) { setWindowFlags(windowFlags() | Qt::Tool); connect(qGuiApp, &QGuiApplication::screenRemoved, this, &WinSnippingArea::init); connect(qGuiApp, &QGuiApplication::screenAdded, this, &WinSnippingArea::init); init(); } QRect WinSnippingArea::selectedRectArea() const { auto captureArea = getCaptureArea(); if(isBackgroundTransparent()) { auto topLeft = mapToGlobal(captureArea.topLeft()); auto bottomRight = mapToGlobal(captureArea.bottomRight()); return {topLeft, bottomRight}; } else { return mHdpiScaler.scale(captureArea); } } void WinSnippingArea::setFullScreen() { /* * Workaround for Qt HiDPI issue, setting geometry more then once * enlarges the widget outside the size of the visible desktop. See #668. * Qt behaves differently in case of one or multiple scaled screens so * we utilise here different 'hacks' to fix the different use cases. * This part just be checked after upgrading to newer Qt version if it * can be simplified again in case the issue was fixed from Qt side. * See bug https://bugreports.qt.io/browse/QTBUG-94638 */ if (mIsMultipleScaledScreens) { setGeometry(QApplication::desktop()->geometry()); QWidget::show(); setGeometry(QApplication::desktop()->geometry()); } else if (!mIsFullScreenSizeSet) { setGeometry(mFullScreenRect); mIsFullScreenSizeSet = true; } QWidget::show(); } QSizeF WinSnippingArea::getSize() const { if (mIsMultipleScaledScreens) { return { static_cast(mFullScreenRect.width()) / 2, static_cast(mFullScreenRect.height()) / 2 }; } else { return { static_cast(geometry().width()), static_cast(geometry().height()) }; } } QPoint WinSnippingArea::getGlobalCursorPosition() const { return mapFromGlobal(AbstractSnippingArea::getGlobalCursorPosition()); } void WinSnippingArea::setupScalingVariables() { auto scaledScreens = 0; auto screens = QApplication::screens(); for (auto screen : screens) { auto screenGeometry = screen->geometry(); if(screen->devicePixelRatio() > 1) { scaledScreens++; } if (screenGeometry.x() != 0) { mScalePosition.setX(screenGeometry.x()); } if (screenGeometry.y() != 0) { mScalePosition.setY(screenGeometry.y()); } } mScalePosition.setX((mScalePosition.x() - mFullScreenRect.x()) / mHdpiScaler.scaleFactor()); mScalePosition.setY((mScalePosition.y() - mFullScreenRect.y()) / mHdpiScaler.scaleFactor()); mIsMultipleScaledScreens = scaledScreens > 1; } void WinSnippingArea::init() { mIsFullScreenSizeSet = false; mFullScreenRect = mWinWrapper.getFullScreenRect(); setupScalingVariables(); } QPointF WinSnippingArea::getPosition() const { if (mIsMultipleScaledScreens) { return mScalePosition; } else { return AbstractSnippingArea::getPosition(); } } ksnip-master/src/gui/snippingArea/WinSnippingArea.h000066400000000000000000000032251457262621600227120ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINSNIPPINGAREA_H #define KSNIP_WINSNIPPINGAREA_H #include "AbstractSnippingArea.h" #include "src/common/platform/HdpiScaler.h" #include "src/backend/imageGrabber/WinWrapper.h" class WinSnippingArea : public AbstractSnippingArea { public: explicit WinSnippingArea(const QSharedPointer &config); ~WinSnippingArea() override = default; QRect selectedRectArea() const override; protected: void setFullScreen() override; QSizeF getSize() const override; QPoint getGlobalCursorPosition() const override; QPointF getPosition() const override; private: QPointF mScalePosition; QRect mFullScreenRect; HdpiScaler mHdpiScaler; WinWrapper mWinWrapper; bool mIsFullScreenSizeSet; bool mIsMultipleScaledScreens; void setupScalingVariables(); private slots: void init(); }; #endif //KSNIP_WINSNIPPINGAREA_H ksnip-master/src/gui/snippingArea/X11SnippingArea.cpp000066400000000000000000000056661457262621600230740ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "X11SnippingArea.h" X11SnippingArea::X11SnippingArea(const QSharedPointer &config) : AbstractSnippingArea(config), mIsDesktopGeometryCalculated(false) { setWindowFlags(windowFlags() | Qt::Tool | Qt::X11BypassWindowManagerHint); connect(qGuiApp, &QGuiApplication::screenRemoved, this, &X11SnippingArea::screenCountChanged); connect(qGuiApp, &QGuiApplication::screenAdded, this, &X11SnippingArea::screenCountChanged); screenCountChanged(); } QRect X11SnippingArea::selectedRectArea() const { auto captureArea = getCaptureArea(); if(isBackgroundTransparent()) { return captureArea; } else { return mHdpiScaler.scale(captureArea); } } void X11SnippingArea::setFullScreen() { setFixedSize(QDesktopWidget().size()); QWidget::showFullScreen(); } QSizeF X11SnippingArea::getSize() const { return mDesktopGeometry.size(); } void X11SnippingArea::showSnippingArea() { // Just after the screen count is changed the new screen is not positioned // correctly so our calculation is wrong. As a workaround we mark that we // need to recalculate the screen and calculate just before we show the // snipping area. if (!mIsDesktopGeometryCalculated) { calculateDesktopGeometry(); mIsDesktopGeometryCalculated = true; } AbstractSnippingArea::showSnippingArea(); } void X11SnippingArea::calculateDesktopGeometry() { mDesktopGeometry = QRectF(); auto screens = QGuiApplication::screens(); for(auto screen : screens) { auto scaleFactor = screen->devicePixelRatio(); auto screenGeometry = screen->geometry(); auto x = screenGeometry.x() / scaleFactor; auto y = screenGeometry.y() / scaleFactor; auto width = (qreal)screenGeometry.width(); auto height = (qreal)screenGeometry.height(); mDesktopGeometry = mDesktopGeometry.united({x, y, width, height}); } } void X11SnippingArea::screenCountChanged() { desktopGeometryChanged(); auto screens = QGuiApplication::screens(); for(auto screen : screens) { connect(screen, &QScreen::availableGeometryChanged, this, &X11SnippingArea::desktopGeometryChanged, Qt::UniqueConnection); } } void X11SnippingArea::desktopGeometryChanged() { mIsDesktopGeometryCalculated = false; } ksnip-master/src/gui/snippingArea/X11SnippingArea.h000066400000000000000000000027511457262621600225310ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_X11SNIPPINGAREA_H #define KSNIP_X11SNIPPINGAREA_H #include "AbstractSnippingArea.h" #include "src/common/platform/HdpiScaler.h" class X11SnippingArea : public AbstractSnippingArea { public: explicit X11SnippingArea(const QSharedPointer &config); ~X11SnippingArea() override = default; QRect selectedRectArea() const override; protected: void setFullScreen() override; QSizeF getSize() const override; void showSnippingArea() override; private: QRectF mDesktopGeometry; HdpiScaler mHdpiScaler; bool mIsDesktopGeometryCalculated; void calculateDesktopGeometry(); private slots: void screenCountChanged(); void desktopGeometryChanged(); }; #endif //KSNIP_X11SNIPPINGAREA_H ksnip-master/src/gui/widgetVisibilityHandler/000077500000000000000000000000001457262621600217125ustar00rootroot00000000000000ksnip-master/src/gui/widgetVisibilityHandler/GnomeWaylandWidgetVisibilityHandler.cpp000066400000000000000000000023141457262621600315150ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "GnomeWaylandWidgetVisibilityHandler.h" GnomeWaylandWidgetVisibilityHandler::GnomeWaylandWidgetVisibilityHandler(QWidget *widget) : WidgetVisibilityHandler(widget) { } void GnomeWaylandWidgetVisibilityHandler::setVisible(bool isVisible) { mWidget->setVisible(isVisible); } void GnomeWaylandWidgetVisibilityHandler::showWidget() { mWidget->setWindowState(getSelectedWindowState()); mWidget->raise(); mWidget->show(); } ksnip-master/src/gui/widgetVisibilityHandler/GnomeWaylandWidgetVisibilityHandler.h000066400000000000000000000023601457262621600311630ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_GNOMEWAYLANDWIDGETVISIBILITYHANDLER_H #define KSNIP_GNOMEWAYLANDWIDGETVISIBILITYHANDLER_H #include "WidgetVisibilityHandler.h" class GnomeWaylandWidgetVisibilityHandler : public WidgetVisibilityHandler { public: explicit GnomeWaylandWidgetVisibilityHandler(QWidget *widget); ~GnomeWaylandWidgetVisibilityHandler() = default; void setVisible(bool isVisible) override; void showWidget() override; }; #endif //KSNIP_GNOMEWAYLANDWIDGETVISIBILITYHANDLER_H ksnip-master/src/gui/widgetVisibilityHandler/WidgetVisibilityHandler.cpp000066400000000000000000000052571457262621600272200ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WidgetVisibilityHandler.h" WidgetVisibilityHandler::WidgetVisibilityHandler(QWidget *widget) : mWidget(widget), mSelectedWindowState(Qt::WindowActive), mWindowStateChangeLock(false), mIsMinimized(false), mIsHidden(false) { } void WidgetVisibilityHandler::hide() { mWidget->hide(); if(!mWindowStateChangeLock) { mIsHidden = true; } } void WidgetVisibilityHandler::makeInvisible() { mWindowStateChangeLock = true; setVisible(false); mWidget->showMinimized(); } void WidgetVisibilityHandler::show() { showWidget(); } void WidgetVisibilityHandler::minimize() { mWindowStateChangeLock = true; mIsMinimized = true; mWidget->showMinimized(); } void WidgetVisibilityHandler::restoreState() { setVisible(true); if(!mIsMinimized && !mIsHidden) { showWidget(); mIsHidden = false; } else if(!mIsMinimized && mIsHidden){ hide(); } else { mWidget->setWindowState(Qt::WindowMinimized); mIsHidden = false; } mWindowStateChangeLock = false; } void WidgetVisibilityHandler::enforceVisible() { setVisible(true); showWidget(); mIsHidden = false; mWindowStateChangeLock = false; } bool WidgetVisibilityHandler::isMaximized() { return mSelectedWindowState == Qt::WindowMaximized; } void WidgetVisibilityHandler::updateState() { if(!mWindowStateChangeLock) { if(mWidget->isMaximized()) { mSelectedWindowState = Qt::WindowMaximized; } else if(mWidget->isActiveWindow()){ mSelectedWindowState = Qt::WindowActive; } mIsMinimized = mWidget->isMinimized(); } } void WidgetVisibilityHandler::setVisible(bool isVisible) { if(isVisible) { mWidget->setWindowOpacity(1.0); } else { mWidget->setWindowOpacity(0.0); } } void WidgetVisibilityHandler::showWidget() { mWidget->setWindowState(getSelectedWindowState()); mWidget->activateWindow(); mWidget->raise(); mWidget->show(); } Qt::WindowState WidgetVisibilityHandler::getSelectedWindowState() const { return mSelectedWindowState; } ksnip-master/src/gui/widgetVisibilityHandler/WidgetVisibilityHandler.h000066400000000000000000000030751457262621600266610ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WIDGETVISIBILITYHANDLER_H #define KSNIP_WIDGETVISIBILITYHANDLER_H #include #include "src/backend/config/Config.h" class WidgetVisibilityHandler { public: explicit WidgetVisibilityHandler(QWidget *widget); ~WidgetVisibilityHandler() = default; virtual void hide(); virtual void makeInvisible(); virtual void show(); virtual void minimize(); virtual void restoreState(); virtual void enforceVisible(); virtual bool isMaximized(); virtual void updateState(); protected: QWidget *mWidget; virtual void setVisible(bool isVisible); virtual void showWidget(); Qt::WindowState getSelectedWindowState() const; private: bool mWindowStateChangeLock; bool mIsMinimized; bool mIsHidden; Qt::WindowState mSelectedWindowState; }; #endif //KSNIP_WIDGETVISIBILITYHANDLER_H ksnip-master/src/gui/widgetVisibilityHandler/WidgetVisibilityHandlerFactory.cpp000066400000000000000000000023331457262621600305400ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WidgetVisibilityHandlerFactory.h" WidgetVisibilityHandler *WidgetVisibilityHandlerFactory::create(QWidget *widget, const QSharedPointer &platformChecker) { #if defined(UNIX_X11) if (platformChecker->isWayland() && platformChecker->isGnome()) { return new GnomeWaylandWidgetVisibilityHandler(widget); } else { return new WidgetVisibilityHandler(widget); } #else return new WidgetVisibilityHandler(widget); #endif } ksnip-master/src/gui/widgetVisibilityHandler/WidgetVisibilityHandlerFactory.h000066400000000000000000000024511457262621600302060ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WIDGETVISIBILITYHANDLERRFACTORY_H #define KSNIP_WIDGETVISIBILITYHANDLERRFACTORY_H #include "src/common/platform/IPlatformChecker.h" #if defined(__APPLE__) || defined(_WIN32) #include "WidgetVisibilityHandler.h" #endif #if defined(UNIX_X11) #include "GnomeWaylandWidgetVisibilityHandler.h" #endif class WidgetVisibilityHandlerFactory { public: static WidgetVisibilityHandler *create(QWidget *widget, const QSharedPointer &platformChecker); }; #endif //KSNIP_WIDGETVISIBILITYHANDLERRFACTORY_H ksnip-master/src/gui/windowResizer/000077500000000000000000000000001457262621600177345ustar00rootroot00000000000000ksnip-master/src/gui/windowResizer/IResizableWindow.h000066400000000000000000000020551457262621600233300ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IRESIZABLEWINDOW_H #define KSNIP_IRESIZABLEWINDOW_H class IResizableWindow { public: IResizableWindow() = default; ~IResizableWindow() = default; virtual void resizeToContent() = 0; virtual bool isWindowMaximized() = 0; }; #endif //KSNIP_IRESIZABLEWINDOW_H ksnip-master/src/gui/windowResizer/WindowResizer.cpp000066400000000000000000000031351457262621600232550ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WindowResizer.h" WindowResizer::WindowResizer(IResizableWindow *resizableWindow, const QSharedPointer &config, QObject *parent) : QObject(parent), mResizableWindow(resizableWindow), mConfig(config), mPerformedAutoResize(false), mResizeDelayInMs(50) { Q_ASSERT(mResizableWindow != nullptr); Q_ASSERT(mConfig != nullptr); } void WindowResizer::resize() { if(mResizableWindow->isWindowMaximized()) { return; } auto enforceAutoResize = mConfig->autoResizeToContent() || !mPerformedAutoResize; if (enforceAutoResize) { QTimer::singleShot(mConfig->resizeToContentDelay(), this, &WindowResizer::resizeWindow); } } void WindowResizer::resetAndResize() { mPerformedAutoResize = false; resize(); } void WindowResizer::resizeWindow() { mPerformedAutoResize = true; mResizableWindow->resizeToContent(); } ksnip-master/src/gui/windowResizer/WindowResizer.h000066400000000000000000000026211457262621600227210ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINDOWRESIZER_H #define KSNIP_WINDOWRESIZER_H #include #include #include #include "IResizableWindow.h" #include "src/backend/config/IConfig.h" class WindowResizer : public QObject { public: WindowResizer(IResizableWindow *resizableWindow, const QSharedPointer &config, QObject *parent); ~WindowResizer() override = default; void resize(); void resetAndResize(); private: IResizableWindow *mResizableWindow; QSharedPointer mConfig; bool mPerformedAutoResize; int mResizeDelayInMs; private slots: void resizeWindow(); }; #endif //KSNIP_WINDOWRESIZER_H ksnip-master/src/logging/000077500000000000000000000000001457262621600157235ustar00rootroot00000000000000ksnip-master/src/logging/ConsoleLogger.cpp000066400000000000000000000025631457262621600211770ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ConsoleLogger.h" void ConsoleLogger::log(const QString &message) const { qDebug("%s.", qPrintable(message)); } void ConsoleLogger::log(const QString &message, bool isSuccess) const { qDebug("%s, %s.", qPrintable(message), qPrintable(boolToString(isSuccess))); } QString ConsoleLogger::boolToString(bool isSuccess) { return isSuccess ? QString("success") : QString("failed"); } void ConsoleLogger::log(const QString &message, QNetworkReply::NetworkError value) const { auto metaEnum = QMetaEnum::fromType(); log(message.arg(metaEnum.valueToKey(value))); } ksnip-master/src/logging/ConsoleLogger.h000066400000000000000000000024171457262621600206420ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CONSOLELOGGER_H #define KSNIP_CONSOLELOGGER_H #include #include "ILogger.h" class ConsoleLogger : public ILogger { public: ConsoleLogger() = default; ~ConsoleLogger() = default; void log(const QString &message) const override; void log(const QString &message, bool isSuccess) const override; void log(const QString &message, QNetworkReply::NetworkError value) const override; private: static QString boolToString(bool isSuccess); }; #endif //KSNIP_CONSOLELOGGER_H ksnip-master/src/logging/ILogger.h000066400000000000000000000021751457262621600174310ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ILOGGER_H #define KSNIP_ILOGGER_H #include #include class ILogger { public: virtual void log(const QString &message) const = 0; virtual void log(const QString &message, bool isSuccess) const = 0; virtual void log(const QString &message, QNetworkReply::NetworkError value) const = 0; }; #endif //KSNIP_ILOGGER_H ksnip-master/src/logging/LogOutputHandler.cpp000066400000000000000000000026231457262621600216720ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "LogOutputHandler.h" void LogOutputHandler::handleOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { auto localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: fprintf(stdout, "Debug: %s\n", localMsg.constData()); break; case QtInfoMsg: fprintf(stdout, "Info: %s\n", localMsg.constData()); break; case QtWarningMsg: fprintf(stderr, "Warning: %s\n", localMsg.constData()); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s\n", localMsg.constData()); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s\n", localMsg.constData()); break; } }ksnip-master/src/logging/LogOutputHandler.h000066400000000000000000000022161457262621600213350ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_LOGOUTPUTHANDLER_H #define KSNIP_LOGOUTPUTHANDLER_H #include #include #include class LogOutputHandler { public: static void handleOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg); private: LogOutputHandler() = default; ~LogOutputHandler() = default; }; #endif //KSNIP_LOGOUTPUTHANDLER_H ksnip-master/src/logging/NoneLogger.cpp000066400000000000000000000022431457262621600204670ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "NoneLogger.h" void NoneLogger::log(const QString &message) const { Q_UNUSED(message) // doing nothing } void NoneLogger::log(const QString &message, bool isSuccess) const { Q_UNUSED(message) Q_UNUSED(isSuccess) // doing nothing } void NoneLogger::log(const QString &message, QNetworkReply::NetworkError value) const { Q_UNUSED(message) Q_UNUSED(value) // doing nothing } ksnip-master/src/logging/NoneLogger.h000066400000000000000000000022561457262621600201400ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NONELOGGER_H #define KSNIP_NONELOGGER_H #include "ILogger.h" class NoneLogger : public ILogger { public: NoneLogger() = default; ~NoneLogger() = default; void log(const QString &message) const override; void log(const QString &message, bool isSuccess) const override; void log(const QString &message, QNetworkReply::NetworkError value) const override; }; #endif //KSNIP_NONELOGGER_H ksnip-master/src/main.cpp000066400000000000000000000036261457262621600157340ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #if defined(_WIN32) && defined(QT_NO_DEBUG) // Prevent starting console in background under windows #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") #endif #include "BuildConfig.h" #include "src/bootstrapper/BootstrapperFactory.h" #include "src/logging/LogOutputHandler.h" int main(int argc, char** argv) { qInstallMessageHandler(LogOutputHandler::handleOutput); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps); app.setOrganizationName(QLatin1String("ksnip")); app.setOrganizationDomain(QLatin1String("ksnip.ksnip.org")); app.setApplicationName(QLatin1String("ksnip")); app.setApplicationVersion(QLatin1String(KSNIP_VERSION)); app.setDesktopFileName(QLatin1String("org.ksnip.ksnip.desktop")); auto dependencyInjector = new DependencyInjector; DependencyInjectorBootstrapper::BootstrapCore(dependencyInjector); app.setStyle(dependencyInjector->get()->applicationStyle()); BootstrapperFactory bootstrapperFactory; return bootstrapperFactory.create(dependencyInjector)->start(app); } ksnip-master/src/plugins/000077500000000000000000000000001457262621600157565ustar00rootroot00000000000000ksnip-master/src/plugins/IPluginFinder.h000066400000000000000000000021761457262621600206340ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLUGINFINDER_H #define KSNIP_IPLUGINFINDER_H #include class QString; class PluginInfo; class IPluginFinder { public: IPluginFinder() = default; ~IPluginFinder() = default; virtual QList find(const QString &path) const = 0; virtual QList find() const = 0; }; #endif //KSNIP_IPLUGINFINDER_H ksnip-master/src/plugins/IPluginLoader.h000066400000000000000000000020631457262621600206260ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLUGINLOADER_H #define KSNIP_IPLUGINLOADER_H class QObject; class QString; class IPluginLoader { public: IPluginLoader() = default; ~IPluginLoader() = default; virtual QObject* load(const QString &path) const = 0; }; #endif //KSNIP_IPLUGINLOADER_H ksnip-master/src/plugins/IPluginManager.h000066400000000000000000000023341457262621600207730ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLUGINMANAGER_H #define KSNIP_IPLUGINMANAGER_H #include "src/common/enum/PluginType.h" class IPluginManager : public QObject { Q_OBJECT public: IPluginManager() = default; ~IPluginManager() override = default; virtual bool isAvailable(PluginType type) const = 0; virtual QSharedPointer get(PluginType type) const = 0; virtual QString getPath(PluginType type) const = 0; }; #endif //KSNIP_IPLUGINMANAGER_H ksnip-master/src/plugins/PluginFinder.cpp000066400000000000000000000045341457262621600210560ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PluginFinder.h" PluginFinder::PluginFinder( const QSharedPointer &loader, const QSharedPointer &directoryService, const QSharedPointer &searchPathProvider) : mLoader(loader), mDirectoryService(directoryService), mSearchPathProvider(searchPathProvider) { } QList PluginFinder::find(const QString &path) const { auto plugins = QList(); auto pluginsInDirectory = findPluginsInDirectory(path); plugins.append(pluginsInDirectory); auto childDirectoryInfos = mDirectoryService->childDirectories(path); for (const auto& childDirectoryInfo : childDirectoryInfos) { auto pluginsInChildDirectory = findPluginsInDirectory(childDirectoryInfo.filePath()); plugins.append(pluginsInChildDirectory); } return plugins; } QList PluginFinder::find() const { auto plugins = QList(); for (const auto& path : mSearchPathProvider->searchPaths()) { plugins.append(find(path)); } return plugins; } QList PluginFinder::findPluginsInDirectory(const QString &path) const { auto plugins = QList(); auto childFileInfos = mDirectoryService->childFiles(path); for (const auto& childFileInfo : childFileInfos) { auto plugin = mLoader->load(childFileInfo.filePath()); if (plugin != nullptr) { auto ocrPlugin = qobject_cast(plugin); if (ocrPlugin != nullptr) { PluginInfo pluginInfo(PluginType::Ocr, ocrPlugin->version(), childFileInfo.filePath()); plugins.append(pluginInfo); } } } return plugins; } ksnip-master/src/plugins/PluginFinder.h000066400000000000000000000034561457262621600205250ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLUGINFINDER_H #define KSNIP_PLUGINFINDER_H #include #include #include #include "IPluginFinder.h" #include "IPluginLoader.h" #include "PluginInfo.h" #include "src/plugins/interfaces/IPluginOcr.h" #include "src/plugins/searchPathProvider/IPluginSearchPathProvider.h" #include "src/gui/directoryService/IDirectoryService.h" class PluginFinder : public IPluginFinder { public: PluginFinder( const QSharedPointer &loader, const QSharedPointer &directoryService, const QSharedPointer &searchPathProvider); ~PluginFinder() = default; QList find(const QString &path) const override; QList find() const override; private: QSharedPointer mLoader; QSharedPointer mDirectoryService; QSharedPointer mSearchPathProvider; QList findPluginsInDirectory(const QString &path) const; }; #endif //KSNIP_PLUGINFINDER_H ksnip-master/src/plugins/PluginInfo.cpp000066400000000000000000000024221457262621600205340ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PluginInfo.h" PluginInfo::PluginInfo(PluginType type, const QString &version, const QString &path) : mType(type), mVersion(version), mPath(path) { } QString PluginInfo::path() const { return mPath; } PluginType PluginInfo::type() const { return mType; } QString PluginInfo::version() const { return mVersion; } bool operator==(const PluginInfo& left, const PluginInfo& right) { return left.path() == right.path() && left.type() == right.type() && left.version() == right.version(); } ksnip-master/src/plugins/PluginInfo.h000066400000000000000000000023721457262621600202050ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLUGININFO_H #define KSNIP_PLUGININFO_H #include #include "src/common/enum/PluginType.h" class PluginInfo { public: PluginInfo(PluginType type, const QString &version, const QString &path); ~PluginInfo() = default; QString path() const; PluginType type() const; QString version() const; private: QString mPath; PluginType mType; QString mVersion; }; bool operator==(const PluginInfo& left, const PluginInfo& right); #endif //KSNIP_PLUGININFO_H ksnip-master/src/plugins/PluginLoader.cpp000066400000000000000000000023551457262621600210540ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PluginLoader.h" PluginLoader::PluginLoader(const QSharedPointer &logger) : mLogger(logger) { } QObject* PluginLoader::load(const QString &path) const { QPluginLoader pluginLoader(path); pluginLoader.load(); if (pluginLoader.isLoaded()) { mLogger->log(QString("Loading plugin %1").arg(path)); } else if (!pluginLoader.metaData().isEmpty()) { mLogger->log(pluginLoader.errorString()); } return pluginLoader.instance(); } ksnip-master/src/plugins/PluginLoader.h000066400000000000000000000023111457262621600205110ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLUGINLOADER_H #define KSNIP_PLUGINLOADER_H #include #include "IPluginLoader.h" #include "src/logging/ILogger.h" class PluginLoader : public IPluginLoader { public: explicit PluginLoader(const QSharedPointer &logger); ~PluginLoader() = default; QObject* load(const QString &path) const override; private: QSharedPointer mLogger; }; #endif //KSNIP_PLUGINLOADER_H ksnip-master/src/plugins/PluginManager.cpp000066400000000000000000000043131457262621600212140ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PluginManager.h" PluginManager::PluginManager(const QSharedPointer &config, const QSharedPointer &loader, const QSharedPointer &logger) : mConfig(config), mLoader(loader), mLogger(logger) { loadPlugins(); connect(mConfig.data(), &IConfig::pluginsChanged, this, &PluginManager::loadPlugins); } bool PluginManager::isAvailable(PluginType type) const { return mPluginMap.contains(type); } void PluginManager::loadPlugins() { auto pluginInfos = mConfig->pluginInfos(); for (const auto& pluginInfo : pluginInfos) { auto plugin = QSharedPointer(mLoader->load(pluginInfo.path())); if(plugin.isNull()) { mLogger->log(QString("Unable to load plugin %1 of type %2").arg(pluginInfo.path(), EnumTranslator::instance()->toString(pluginInfo.type()))); } else { mPluginMap[pluginInfo.type()] = plugin; mPluginPathMap[pluginInfo.type()] = pluginInfo.path(); } } } QSharedPointer PluginManager::get(PluginType type) const { if(isAvailable(type)) { return mPluginMap[type]; } else { mLogger->log(QString("Unavailable plugin requested %1").arg(EnumTranslator::instance()->toString(type))); return {}; } } QString PluginManager::getPath(PluginType type) const { if(isAvailable(type)) { return mPluginPathMap[type]; } else { mLogger->log(QString("Unavailable plugin path requested %1").arg(EnumTranslator::instance()->toString(type))); return {}; } } ksnip-master/src/plugins/PluginManager.h000066400000000000000000000033701457262621600206630ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLUGINMANAGER_H #define KSNIP_PLUGINMANAGER_H #include #include "IPluginManager.h" #include "IPluginLoader.h" #include "PluginInfo.h" #include "src/backend/config/IConfig.h" #include "src/logging/ILogger.h" #include "src/common/helper/EnumTranslator.h" class PluginManager : public IPluginManager { public: explicit PluginManager(const QSharedPointer &config, const QSharedPointer &loader, const QSharedPointer &logger); ~PluginManager() override = default; bool isAvailable(PluginType type) const override; QSharedPointer get(PluginType type) const override; QString getPath(PluginType type) const override; private: QSharedPointer mConfig; QSharedPointer mLoader; QSharedPointer mLogger; QMap> mPluginMap; QMap mPluginPathMap; private slots: void loadPlugins(); }; #endif //KSNIP_PLUGINMANAGER_H ksnip-master/src/plugins/WinPluginLoader.cpp000066400000000000000000000030431457262621600215250ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinPluginLoader.h" WinPluginLoader::WinPluginLoader(const QSharedPointer &logger) : PluginLoader(logger), mLogger(logger) { } QObject *WinPluginLoader::load(const QString &path) const { // Under Windows the 3rd Party Dlls are next to the plugin in the same directory // in order to find them we set the current directory to the plugin directory auto currentDir = QDir::current(); auto pluginDir = QFileInfo(path).path(); auto isDirectoryChanged = QDir::setCurrent(pluginDir); if(!isDirectoryChanged) { mLogger->log(QString("Unable to change to plugin directory %1").arg(pluginDir)); } auto plugin = PluginLoader::load(path); // Return previous current directory QDir::setCurrent(currentDir.absolutePath()); return plugin; } ksnip-master/src/plugins/WinPluginLoader.h000066400000000000000000000023051457262621600211720ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINPLUGINLOADER_H #define KSNIP_WINPLUGINLOADER_H #include #include #include "PluginLoader.h" class WinPluginLoader : public PluginLoader { public: explicit WinPluginLoader(const QSharedPointer &logger); ~WinPluginLoader() = default; QObject* load(const QString &path) const override; private: QSharedPointer mLogger; }; #endif //KSNIP_WINPLUGINLOADER_H ksnip-master/src/plugins/interfaces/000077500000000000000000000000001457262621600201015ustar00rootroot00000000000000ksnip-master/src/plugins/interfaces/IPlugin.h000066400000000000000000000017671457262621600216340ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLUGIN_H #define KSNIP_IPLUGIN_H class QString; class IPlugin { public: IPlugin() = default; virtual ~IPlugin() = default; virtual QString version() const = 0; }; #endif //KSNIP_IPLUGIN_H ksnip-master/src/plugins/interfaces/IPluginOcr.h000066400000000000000000000024271457262621600222720ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLUGINOCR_H #define KSNIP_IPLUGINOCR_H #include #include "IPlugin.h" class IPluginOcr { public: IPluginOcr() = default; virtual ~IPluginOcr() = default; virtual QString recognize(const QPixmap &pixmap) const = 0; virtual QString recognize(const QPixmap &pixmap, const QString &dataPath) const = 0; virtual QString version() const = 0; }; #define IPluginOcr_iid "org.ksnip.plugin.ocr" Q_DECLARE_INTERFACE(IPluginOcr, IPluginOcr_iid) #endif //KSNIP_IPLUGINOCR_H ksnip-master/src/plugins/searchPathProvider/000077500000000000000000000000001457262621600215535ustar00rootroot00000000000000ksnip-master/src/plugins/searchPathProvider/IPluginSearchPathProvider.h000066400000000000000000000021471457262621600267550ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IPLUGINSEARCHPATHPROVIDER_H #define KSNIP_IPLUGINSEARCHPATHPROVIDER_H class QStringList; class IPluginSearchPathProvider { public: IPluginSearchPathProvider() = default; ~IPluginSearchPathProvider() = default; virtual QStringList searchPaths() const = 0; }; #endif //KSNIP_IPLUGINSEARCHPATHPROVIDER_H ksnip-master/src/plugins/searchPathProvider/LinuxPluginSearchPathProvider.cpp000066400000000000000000000020171457262621600302130ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "LinuxPluginSearchPathProvider.h" QStringList LinuxPluginSearchPathProvider::searchPaths() const { return { QString("/usr/local/lib"), QString("/usr/local/lib64"), QString("/usr/lib"), QString("/usr/lib64"), }; } ksnip-master/src/plugins/searchPathProvider/LinuxPluginSearchPathProvider.h000066400000000000000000000023131457262621600276570ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_LINUXPLUGINSEARCHPATHPROVIDER_H #define KSNIP_LINUXPLUGINSEARCHPATHPROVIDER_H #include #include "IPluginSearchPathProvider.h" class LinuxPluginSearchPathProvider : public IPluginSearchPathProvider { public: LinuxPluginSearchPathProvider() = default; ~LinuxPluginSearchPathProvider() = default; QStringList searchPaths() const override; }; #endif //KSNIP_LINUXPLUGINSEARCHPATHPROVIDER_H ksnip-master/src/plugins/searchPathProvider/MacPluginSearchPathProvider.cpp000066400000000000000000000016351457262621600276210ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MacPluginSearchPathProvider.h" QStringList MacPluginSearchPathProvider::searchPaths() const { return {}; } ksnip-master/src/plugins/searchPathProvider/MacPluginSearchPathProvider.h000066400000000000000000000022771457262621600272710ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MACPLUGINSEARCHPATHPROVIDER_H #define KSNIP_MACPLUGINSEARCHPATHPROVIDER_H #include #include "IPluginSearchPathProvider.h" class MacPluginSearchPathProvider : public IPluginSearchPathProvider { public: MacPluginSearchPathProvider() = default; ~MacPluginSearchPathProvider() = default; QStringList searchPaths() const override; }; #endif //KSNIP_MACPLUGINSEARCHPATHPROVIDER_H ksnip-master/src/plugins/searchPathProvider/WinPluginSearchPathProvider.cpp000066400000000000000000000017261457262621600276570ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "WinPluginSearchPathProvider.h" QStringList WinPluginSearchPathProvider::searchPaths() const { return { QDir::current().absolutePath() + QString("/plugins") }; }ksnip-master/src/plugins/searchPathProvider/WinPluginSearchPathProvider.h000066400000000000000000000023171457262621600273210ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_WINPLUGINSEARCHPATHPROVIDER_H #define KSNIP_WINPLUGINSEARCHPATHPROVIDER_H #include #include #include "IPluginSearchPathProvider.h" class WinPluginSearchPathProvider : public IPluginSearchPathProvider { public: WinPluginSearchPathProvider() = default; ~WinPluginSearchPathProvider() = default; QStringList searchPaths() const override; }; #endif //KSNIP_WINPLUGINSEARCHPATHPROVIDER_H ksnip-master/src/widgets/000077500000000000000000000000001457262621600157435ustar00rootroot00000000000000ksnip-master/src/widgets/CaptureModePicker.cpp000066400000000000000000000127301457262621600220200ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CaptureModePicker.h" CaptureModePicker::CaptureModePicker(const QList &captureModes, const QSharedPointer &iconLoader) { init(captureModes, iconLoader); setToolButtonStyle(Qt::ToolButtonTextBesideIcon); setButtonText(tr("New")); } void CaptureModePicker::setCaptureMode(CaptureModes mode) { for(auto action : mCaptureActions) { if (action->data().value() == mode) { setDefaultAction(action); mSelectedCaptureMode = mode; return; } } } CaptureModes CaptureModePicker::captureMode() const { return mSelectedCaptureMode; } void CaptureModePicker::init(const QList &captureModes, const QSharedPointer &iconLoader) { auto menu = new CustomMenu(); if (isCaptureModeSupported(captureModes, CaptureModes::RectArea)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::RectArea), tr("Draw a rectangular area with your mouse"), iconLoader->loadForTheme(QLatin1String("drawRect.svg")), CaptureModes::RectArea, QKeySequence(Qt::SHIFT + Qt::Key_R)); menu->addAction(action); } if (isCaptureModeSupported(captureModes, CaptureModes::LastRectArea)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::LastRectArea), tr("Capture a screenshot of the last selected rectangular area"), iconLoader->loadForTheme(QLatin1String("lastRect.svg")), CaptureModes::LastRectArea, QKeySequence(Qt::SHIFT + Qt::Key_L)); menu->addAction(action); } if (isCaptureModeSupported(captureModes, CaptureModes::FullScreen)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::FullScreen), tr("Capture full screen including all monitors"), iconLoader->loadForTheme(QLatin1String("fullScreen.svg")), CaptureModes::FullScreen, QKeySequence(Qt::SHIFT + Qt::Key_F)); menu->addAction(action); } if (isCaptureModeSupported(captureModes, CaptureModes::CurrentScreen)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::CurrentScreen), tr("Capture screen where the mouse is located"), iconLoader->loadForTheme(QLatin1String("currentScreen.svg")), CaptureModes::CurrentScreen, QKeySequence(Qt::SHIFT + Qt::Key_M)); menu->addAction(action); } if (isCaptureModeSupported(captureModes, CaptureModes::ActiveWindow)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::ActiveWindow), tr("Capture window that currently has focus"), iconLoader->loadForTheme(QLatin1String("activeWindow.svg")), CaptureModes::ActiveWindow, QKeySequence(Qt::SHIFT + Qt::Key_A)); menu->addAction(action); } if (isCaptureModeSupported(captureModes, CaptureModes::WindowUnderCursor)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::WindowUnderCursor), tr("Capture that is currently under the mouse cursor"), iconLoader->loadForTheme(QLatin1String("windowUnderCursor.svg")), CaptureModes::WindowUnderCursor, QKeySequence(Qt::SHIFT + Qt::Key_U)); menu->addAction(action); } if (isCaptureModeSupported(captureModes, CaptureModes::Portal)) { auto action = createAction( EnumTranslator::instance()->toTranslatedString(CaptureModes::Portal), tr("Uses the screenshot Portal for taking screenshot"), iconLoader->loadForTheme(QLatin1String("wayland.svg")), CaptureModes::Portal, QKeySequence(Qt::SHIFT + Qt::Key_T)); menu->addAction(action); } if (!mCaptureActions.isEmpty()) { setDefaultAction(mCaptureActions.first()); } setMenu(menu); } bool CaptureModePicker::isCaptureModeSupported(const QList &captureModes, CaptureModes captureMode) { return captureModes.contains(captureMode); } QAction *CaptureModePicker::createAction(const QString &text, const QString &tooltip, const QIcon &icon, CaptureModes captureMode, const QKeySequence &shortcut) { auto action = new QAction(this); action->setIconText(text); action->setToolTip(tooltip); action->setIcon(icon); action->setShortcut(shortcut); action->setData(static_cast(captureMode)); connect(action, &QAction::triggered, [this, captureMode]() { selectCaptureMode(captureMode); } ); mCaptureActions.append(action); return action; } void CaptureModePicker::selectCaptureMode(CaptureModes mode) { mSelectedCaptureMode = mode; emit captureModeSelected(mode); } QList CaptureModePicker::captureActions() const { return mCaptureActions; } ksnip-master/src/widgets/CaptureModePicker.h000066400000000000000000000037261457262621600214720ustar00rootroot00000000000000/* * Copyright (C) 2018 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTUREMODEPICKER_H #define KSNIP_CAPTUREMODEPICKER_H #include #include "src/widgets/CustomToolButton.h" #include "src/common/loader/IIconLoader.h" #include "src/common/enum/CaptureModes.h" #include "src/common/helper/EnumTranslator.h" class CaptureModePicker : public CustomToolButton { Q_OBJECT public: explicit CaptureModePicker(const QList &captureModes, const QSharedPointer &iconLoader); ~CaptureModePicker() override = default; void setCaptureMode(CaptureModes mode); CaptureModes captureMode() const; QList captureActions() const; signals: void captureModeSelected(CaptureModes mode) const; private: CaptureModes mSelectedCaptureMode; QList mCaptureActions; void init(const QList &captureModes, const QSharedPointer &iconLoader); void selectCaptureMode(CaptureModes mode); QAction *createAction(const QString &text, const QString &tooltip, const QIcon &icon, CaptureModes captureMode, const QKeySequence &shortcut); static bool isCaptureModeSupported(const QList &captureModes, CaptureModes captureMode) ; }; #endif //KSNIP_CAPTUREMODEPICKER_H ksnip-master/src/widgets/ColorButton.cpp000066400000000000000000000046711457262621600207310ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ColorButton.h" ColorButton::ColorButton(QWidget* parent) : QPushButton(parent), mShowAlphaChannel(false) { connect(this, &ColorButton::clicked, this, &ColorButton::openDialog); setIconSize(QSize(48, iconSize().height())); } QColor ColorButton::color() const { return mColor; } void ColorButton::setColor(const QColor& color) { mColor = color; auto pixmapIcon = createPixmapFromColor(mColor); setIcon(pixmapIcon); setToolTip(mShowAlphaChannel ? mColor.name(QColor::HexArgb) : mColor.name()); } void ColorButton::setShowAlphaChannel(bool enabled) { mShowAlphaChannel = enabled; } QPixmap ColorButton::createPixmapFromColor(const QColor& color) { QImage tiledBackground(QSize(10, 10), QImage::Format_ARGB32_Premultiplied); tiledBackground.fill(Qt::white); QPainter tiledBackgroundPainter(&tiledBackground); tiledBackgroundPainter.setPen(Qt::NoPen); tiledBackgroundPainter.setBrush(Qt::gray); tiledBackgroundPainter.drawRect(0, 0, 5, 5); tiledBackgroundPainter.drawRect(5, 5, 10, 10); QPixmap pixmap(iconSize()); QPainter pixmapPainter(&pixmap); pixmapPainter.setPen(Qt::gray); pixmapPainter.setBrush(tiledBackground); pixmapPainter.drawRect(0,0, iconSize().width() - 1, iconSize().height() - 1); pixmapPainter.setBrush(color); pixmapPainter.drawRect(0,0, iconSize().width() - 1, iconSize().height() - 1); return pixmap; } void ColorButton::openDialog() { QFlags options; if(mShowAlphaChannel) { options |= QColorDialog::ShowAlphaChannel; } auto color = QColorDialog::getColor(mColor, parentWidget(), QString(), options); if (color.isValid() && color != mColor) { setColor(color); } } ksnip-master/src/widgets/ColorButton.h000066400000000000000000000024551457262621600203740ustar00rootroot00000000000000/* * Copyright (C) 2017 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COLORBUTTON_H #define KSNIP_COLORBUTTON_H #include #include #include class ColorButton : public QPushButton { Q_OBJECT public: explicit ColorButton(QWidget *parent); void setColor(const QColor &color); QColor color() const; void setShowAlphaChannel(bool enabled); private: QColor mColor; bool mShowAlphaChannel; QPixmap createPixmapFromColor(const QColor &color); private slots: void openDialog(); }; #endif // KSNIP_COLORBUTTON_H ksnip-master/src/widgets/CustomCursor.cpp000066400000000000000000000030431457262621600211170ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "CustomCursor.h" CustomCursor::CustomCursor() : QCursor() { } CustomCursor::CustomCursor(const QColor &color, int size) : QCursor(createCrossPixmap(color, size)) { } QPixmap CustomCursor::createCrossPixmap(const QColor& color, int size) { auto pixmap = createEmptyPixmap(); QPainter painter(&pixmap); painter.setPen(QPen(Qt::red, 1, Qt::SolidLine)); painter.drawPoint(16, 16); painter.setPen(QPen(color, size, Qt::SolidLine)); painter.drawLine(16, 12, 16, 0); painter.drawLine(16, 20, 16, 32); painter.drawLine(12, 16, 0, 16); painter.drawLine(20, 16, 32, 16); return pixmap; } QPixmap CustomCursor::createEmptyPixmap() { QPixmap pixmap(QSize(32, 32)); pixmap.fill(Qt::transparent); return pixmap; } ksnip-master/src/widgets/CustomCursor.h000066400000000000000000000022361457262621600205670ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef CUSTOMCURSOR_H #define CUSTOMCURSOR_H #include #include class CustomCursor : public QCursor { public: CustomCursor(); explicit CustomCursor(const QColor &color = nullptr, int size = 22); private: static QPixmap createCrossPixmap(const QColor &color, int size) ; static QPixmap createEmptyPixmap() ; }; #endif // CUSTOMCURSOR_H ksnip-master/src/widgets/CustomLineEdit.cpp000066400000000000000000000024201457262621600213350ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CustomLineEdit.h" CustomLineEdit::CustomLineEdit(QWidget *parent) : QLineEdit(parent) { } QString CustomLineEdit::textOrPlaceholderText() const { auto currentText = text(); return currentText.isEmpty() ? placeholderText() : currentText; } void CustomLineEdit::setText(const QString &text) { if(text != placeholderText()) { QLineEdit::setText(text); } } void CustomLineEdit::setTextAndPlaceholderText(const QString &text) { setText(text); setPlaceholderText(text); } ksnip-master/src/widgets/CustomLineEdit.h000066400000000000000000000022501457262621600210030ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This 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 Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef CUSTOMLINEEDIT_H #define CUSTOMLINEEDIT_H #include class CustomLineEdit : public QLineEdit { Q_OBJECT public: explicit CustomLineEdit(QWidget *parent = nullptr); ~CustomLineEdit() override = default; QString textOrPlaceholderText() const; void setText(const QString &text); void setTextAndPlaceholderText(const QString &text); }; #endif //CUSTOMLINEEDIT_H ksnip-master/src/widgets/CustomSpinBox.cpp000066400000000000000000000025321457262621600212260ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "CustomSpinBox.h" CustomSpinBox::CustomSpinBox(int min, int max, QWidget* parent) : QSpinBox(parent) { setMinimum(min); setMaximum(max); setWrapping(false); connect(this, static_cast(&QSpinBox::valueChanged), this, &CustomSpinBox::valueChanged); } int CustomSpinBox::value() const { return QSpinBox::value(); } void CustomSpinBox::setValue(int value) { // Don't emit valueChanged signal values set via this method blockSignals(true); QSpinBox::setValue(value); blockSignals(false); } ksnip-master/src/widgets/CustomSpinBox.h000066400000000000000000000021651457262621600206750ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef CUSTOMSPINBOX_H #define CUSTOMSPINBOX_H #include class CustomSpinBox : public QSpinBox { Q_OBJECT public: explicit CustomSpinBox(int min = 1, int max = 100, QWidget *widget = nullptr); int value() const; void setValue(int value); signals: void valueChanged(int); }; #endif // CUSTOMSPINBOX_H ksnip-master/src/widgets/CustomToolButton.cpp000066400000000000000000000044611457262621600217600ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "CustomToolButton.h" CustomToolButton::CustomToolButton(QWidget* parent) : QToolButton(parent) { setPopupMode(QToolButton::MenuButtonPopup); connect(this, &CustomToolButton::triggered, this, &CustomToolButton::setDefaultAction); } // // Public Functions // /* * Function used to set main button text, overriding the usual behavior where * the text of the selected action is set. */ void CustomToolButton::setButtonText(const QString& text) { mButtonText = text; refreshText(); } // // Public Slots // /* * Overriding setDefaultAction function to prevent changing of text when a new * action is selected, the main text on the button is supposed to stay the same. */ void CustomToolButton::setDefaultAction(QAction* action) { QToolButton::setDefaultAction(action); refreshText(); } void CustomToolButton::trigger() { if (defaultAction() != nullptr) { defaultAction()->trigger(); } } void CustomToolButton::refreshText() { QToolButton::setText(mButtonText); } CustomMenu::CustomMenu(QWidget* parent) : QMenu(parent) { if (auto p = dynamic_cast(parent)) { connect(this, &CustomMenu::triggered, p, &CustomToolButton::setDefaultAction); } } void CustomMenu::showEvent(QShowEvent* event) { QMenu::showEvent(event); // Workaround for Qt bug where on first time opening the button text is // changed to the default action, introduced with Qt5 if (auto p = dynamic_cast(parent())) { p->refreshText(); } } ksnip-master/src/widgets/CustomToolButton.h000066400000000000000000000026051457262621600214230ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef CUSTOMTOOLBUTTON_H #define CUSTOMTOOLBUTTON_H #include #include #include class CustomToolButton : public QToolButton { Q_OBJECT public: explicit CustomToolButton(QWidget *parent = 0); void setButtonText(const QString &text); public slots: void setDefaultAction(QAction *action); void trigger(); void refreshText(); private: QString mButtonText; }; class CustomMenu : public QMenu { public: CustomMenu(QWidget *parent = nullptr); protected: virtual void showEvent(QShowEvent *event) override; }; #endif // CUSTOMTOOLBUTTON_H ksnip-master/src/widgets/KeySequenceLineEdit.cpp000066400000000000000000000074011457262621600223100ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "KeySequenceLineEdit.h" KeySequenceLineEdit::KeySequenceLineEdit(QWidget *widget, const QList &allowedKeys, const QSharedPointer &platformChecker) : QLineEdit(widget), mPlatformChecker(platformChecker) { mAllowedKeys = allowedKeys; } KeySequenceLineEdit::~KeySequenceLineEdit() { mSpecialKeyFilters.clear(); } void KeySequenceLineEdit::keyPressEvent(QKeyEvent *event) { mModifiers = event->modifiers(); mKey = getAllowedKey(event); updateKeySequence(); } Qt::Key KeySequenceLineEdit::getAllowedKey(const QKeyEvent *event) const { return mAllowedKeys.contains(static_cast(event->key())) ? static_cast(event->key()) : Qt::Key_unknown; } void KeySequenceLineEdit::updateKeySequence() { mKeySequence = mKey == Qt::Key_unknown ? QKeySequence(mModifiers) : QKeySequence(mModifiers + mKey); updateText(); } void KeySequenceLineEdit::keyReleaseEvent(QKeyEvent *event) { mModifiers = Qt::NoModifier; mKey = Qt::Key_unknown; QWidget::keyReleaseEvent(event); } void KeySequenceLineEdit::updateText() { setText(mKeySequence.toString()); } QKeySequence KeySequenceLineEdit::value() const { return mKeySequence; } void KeySequenceLineEdit::clear() { mKeySequence = QKeySequence(); updateText(); } void KeySequenceLineEdit::setValue(const QKeySequence &keySequence) { mKeySequence = keySequence; updateText(); } void KeySequenceLineEdit::focusInEvent(QFocusEvent *event) { setupSpecialKeyHandling(); QLineEdit::focusInEvent(event); } void KeySequenceLineEdit::focusOutEvent(QFocusEvent *event) { removeSpecialKeyHandler(); QLineEdit::focusOutEvent(event); } void KeySequenceLineEdit::removeSpecialKeyHandler() { for(const auto& keyFilter : mSpecialKeyFilters) { QApplication::instance()->removeNativeEventFilter(keyFilter.data()); } mSpecialKeyFilters.clear(); } void KeySequenceLineEdit::keyPressed(Qt::Key key) { mKey = key; updateKeySequence(); } void KeySequenceLineEdit::setupSpecialKeyHandling() { addSpecialKeyHandler(Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::CTRL + Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::ALT + Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::SHIFT + Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::CTRL + Qt::ALT + Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::CTRL + Qt::SHIFT + Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::ALT + Qt::SHIFT + Qt::Key_Print, Qt::Key_Print); addSpecialKeyHandler(Qt::CTRL + Qt::ALT + Qt::SHIFT + Qt::Key_Print, Qt::Key_Print); } void KeySequenceLineEdit::addSpecialKeyHandler(const QKeySequence &keySequence, Qt::Key key) { auto keyHandler = KeyHandlerFactory::create(mPlatformChecker); keyHandler->registerKey(keySequence); auto keyFilter = QSharedPointer(new NativeKeyEventFilter(keyHandler)); connect(keyFilter.data(), &NativeKeyEventFilter::triggered, [this, key]() { keyPressed(key); }); mSpecialKeyFilters.append(keyFilter); QApplication::instance()->installNativeEventFilter(keyFilter.data()); } ksnip-master/src/widgets/KeySequenceLineEdit.h000066400000000000000000000041701457262621600217550ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_KEYSEQUENCELINEEDIT_H #define KSNIP_KEYSEQUENCELINEEDIT_H #include #include #include #include #include "src/gui/globalHotKeys/keyHandler/KeyHandlerFactory.h" #include "src/gui/globalHotKeys/NativeKeyEventFilter.h" class KeySequenceLineEdit : public QLineEdit { Q_OBJECT public: explicit KeySequenceLineEdit(QWidget *widget, const QList &allowedKeys, const QSharedPointer &platformChecker); ~KeySequenceLineEdit() override; QKeySequence value() const; void setValue(const QKeySequence &keySequence); void clear(); protected: void keyPressEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent *event) override; void focusInEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override; private: QKeySequence mKeySequence; Qt::KeyboardModifiers mModifiers; Qt::Key mKey; QList mAllowedKeys; QList> mSpecialKeyFilters; QSharedPointer mPlatformChecker; void updateText(); void keyPressed(Qt::Key key); void setupSpecialKeyHandling(); void updateKeySequence(); void addSpecialKeyHandler(const QKeySequence &keySequence, Qt::Key key); Qt::Key getAllowedKey(const QKeyEvent *event) const; void removeSpecialKeyHandler(); }; #endif //KSNIP_KEYSEQUENCELINEEDIT_H ksnip-master/src/widgets/MainToolBar.cpp000066400000000000000000000146351457262621600206270ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "MainToolBar.h" MainToolBar::MainToolBar( const QList &captureModes, QAction* undoAction, QAction* redoAction, const QSharedPointer &iconLoader, const QSharedPointer &scaledSizeProvider) : QToolBar(), mSaveButton(new QToolButton(this)), mCopyButton(new QToolButton(this)), mCropButton(new QToolButton(this)), mUndoButton(new QToolButton(this)), mRedoButton(new QToolButton(this)), mCaptureModePicker(new CaptureModePicker(captureModes, iconLoader)), mDelayPicker(new CustomSpinBox(0,100)), mDelayLabel(new QLabel(this)), mNewCaptureAction(new QAction(this)), mSaveAction(new QAction(this)), mCopyAction(new QAction(this)), mCropAction(new QAction(this)), mUndoAction(undoAction), mRedoAction(redoAction) { connect(mCaptureModePicker, &CaptureModePicker::captureModeSelected, this, &MainToolBar::captureModeSelected); setStyleSheet(QLatin1String("QToolBar { border: 0px }")); mNewCaptureAction->setText(tr("New")); mNewCaptureAction->setShortcut(QKeySequence::New); connect(mNewCaptureAction, &QAction::triggered, this, &MainToolBar::newCaptureTriggered); mSaveButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mSaveButton->addAction(mSaveAction); mSaveButton->setDefaultAction(mSaveAction); mCopyButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mCopyButton->addAction(mCopyAction); mCopyButton->setDefaultAction(mCopyAction); mUndoButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mUndoButton->addAction(mUndoAction); mUndoButton->setDefaultAction(mUndoAction); mRedoButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mRedoButton->addAction(mRedoAction); mRedoButton->setDefaultAction(mRedoAction); mCropButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mCropButton->addAction(mCropAction); mCropButton->setDefaultAction(mCropAction); auto clockIcon = iconLoader->loadForTheme(QLatin1String("clock.svg")); auto clockPixmap = clockIcon.pixmap(scaledSizeProvider->scaledSize(QSize(24, 24))); mDelayLabel->setPixmap(clockPixmap); mDelayLabel->setContentsMargins(0, 0, 2, 0); mDelayLabel->setToolTip(tr("Delay in seconds between triggering\n" "and capturing screenshot.")); //: The small letter s stands for seconds. mDelayPicker->setSuffix(tr("s")); mDelayPicker->setFixedWidth(scaledSizeProvider->scaledWidth(55)); mDelayPicker->setToolTip(mDelayLabel->toolTip()); connect(mDelayPicker, &CustomSpinBox::valueChanged, this, &MainToolBar::captureDelayChanged); mSaveAction->setText(tr("Save")); mSaveAction->setToolTip(tr("Save Screen Capture to file system")); mSaveAction->setIcon(iconLoader->loadForTheme(QLatin1String("save.svg"))); mSaveAction->setShortcut(QKeySequence::Save); connect(mSaveAction, &QAction::triggered, this, &MainToolBar::saveActionTriggered); mCopyAction->setText(tr("Copy")); mCopyAction->setToolTip(tr("Copy Screen Capture to clipboard")); mCopyAction->setIcon(iconLoader->loadForTheme(QLatin1String("copy.svg"))); mCopyAction->setShortcut(QKeySequence::Copy); connect(mCopyAction, &QAction::triggered, this, &MainToolBar::copyActionTriggered); mUndoAction->setIcon(iconLoader->loadForTheme(QLatin1String("undo.svg")));; mUndoAction->setText(tr("Undo")); mUndoAction->setShortcut(QKeySequence::Undo); mRedoAction->setIcon(iconLoader->loadForTheme(QLatin1String("redo.svg"))); mRedoAction->setText(tr("Redo")); mRedoAction->setShortcut(QKeySequence::Redo); mCropAction->setText(tr("Crop")); mCropAction->setToolTip(tr("Crop Screen Capture")); mCropAction->setIcon(iconLoader->loadForTheme(QLatin1String("crop.svg"))); mCropAction->setShortcut(Qt::SHIFT + Qt::Key_C); connect(mCropAction, &QAction::triggered, this, &MainToolBar::cropActionTriggered); setWindowTitle(tr("Tools")); setFloatable(false); setMovable(false); setAllowedAreas(Qt::BottomToolBarArea); addWidget(mCaptureModePicker); addSeparator(); addWidget(mSaveButton); addWidget(mCopyButton); addWidget(mUndoButton); addWidget(mRedoButton); addSeparator(); addWidget(mCropButton); addSeparator(); addWidget(mDelayLabel); addWidget(mDelayPicker); setFixedSize(sizeHint()); } MainToolBar::~MainToolBar() { delete mCaptureModePicker; delete mDelayPicker; } void MainToolBar::selectCaptureMode(CaptureModes captureModes) { mCaptureModePicker->setCaptureMode(captureModes); } void MainToolBar::setCaptureDelay(int delay) { mDelayPicker->setValue(delay); } void MainToolBar::newCaptureTriggered() { mCaptureModePicker->trigger(); } void MainToolBar::setSaveActionEnabled(bool enabled) { mSaveAction->setEnabled(enabled); } void MainToolBar::setCopyActionEnabled(bool enabled) { mCopyAction->setEnabled(enabled); } void MainToolBar::setCropEnabled(bool enabled) { mCropAction->setEnabled(enabled); } QAction *MainToolBar::newCaptureAction() const { return mNewCaptureAction; } QAction *MainToolBar::saveAction() const { return mSaveAction; } QAction *MainToolBar::copyToClipboardAction() const { return mCopyAction; } QAction *MainToolBar::cropAction() const { return mCropAction; } QAction *MainToolBar::undoAction() const { return mUndoAction; } QAction *MainToolBar::redoAction() const { return mRedoAction; } QList MainToolBar::captureActions() const { return mCaptureModePicker->captureActions(); } void MainToolBar::setCollapsed(bool isCollapsed) { isCollapsed ? setFixedSize(0, 0) : setFixedSize(sizeHint()); } bool MainToolBar::isCollapsed() const { return size() != sizeHint(); } ksnip-master/src/widgets/MainToolBar.h000066400000000000000000000051371457262621600202710ustar00rootroot00000000000000/* * Copyright (C) 2019 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef KSNIP_MAINTOOLBAR_H #define KSNIP_MAINTOOLBAR_H #include #include #include #include "CaptureModePicker.h" #include "CustomSpinBox.h" #include "src/common/provider/scaledSizeProvider/IScaledSizeProvider.h" class MainToolBar : public QToolBar { Q_OBJECT public: explicit MainToolBar( const QList &captureModes, QAction* undoAction, QAction* redoAction, const QSharedPointer &iconLoader, const QSharedPointer &scaledSizeProvider); ~MainToolBar() override; void selectCaptureMode(CaptureModes captureModes); void setCaptureDelay(int delay); void setSaveActionEnabled(bool enabled); void setCopyActionEnabled(bool enabled); void setCropEnabled(bool enabled); QAction* newCaptureAction() const; QAction* saveAction() const; QAction* copyToClipboardAction() const; QAction* cropAction() const; QAction* undoAction() const; QAction* redoAction() const; QList captureActions() const; void setCollapsed(bool isCollapsed); bool isCollapsed() const; signals: void captureModeSelected(CaptureModes mode) const; void saveActionTriggered() const; void copyActionTriggered() const; void captureDelayChanged(int delay) const; void cropActionTriggered() const; public slots: void newCaptureTriggered(); private: QToolButton *mSaveButton; QToolButton *mCopyButton; QToolButton *mCropButton; QToolButton *mUndoButton; QToolButton *mRedoButton; CaptureModePicker *mCaptureModePicker; CustomSpinBox *mDelayPicker; QLabel *mDelayLabel; QAction *mNewCaptureAction; QAction *mSaveAction; QAction *mCopyAction; QAction *mCropAction; QAction *mUndoAction; QAction *mRedoAction; }; #endif //KSNIP_MAINTOOLBAR_H ksnip-master/src/widgets/NumericComboBox.cpp000066400000000000000000000026131457262621600215040ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include "NumericComboBox.h" NumericComboBox::NumericComboBox(int start, int increment, int steps, QWidget* parent) : QComboBox(parent) { populateList(start, increment, steps); } // // Public Functions // int NumericComboBox::value() const { return itemData(currentIndex()).toInt(); } void NumericComboBox::setValue(int value) { setCurrentIndex(findData(value)); } // // Private Functions // void NumericComboBox::populateList(int start, int increment, int steps) { for (auto i = 0; i < steps; i++) { addItem(QString::number(start + i * increment), start + i * increment); } } ksnip-master/src/widgets/NumericComboBox.h000066400000000000000000000022341457262621600211500ustar00rootroot00000000000000/* * Copyright (C) 2016 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #ifndef NUMERICCOMBOBOX_H #define NUMERICCOMBOBOX_H #include class NumericComboBox : public QComboBox { Q_OBJECT public: NumericComboBox(int start, int increment, int steps, QWidget *widget = 0); int value() const; void setValue(int value); private: void populateList(int start, int increment, int steps); }; #endif // NUMERICCOMBOBOX_H ksnip-master/src/widgets/ProcessIndicator.cpp000066400000000000000000000025241457262621600217250ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ProcessIndicator.h" ProcessIndicator::ProcessIndicator(QWidget *parent) : QLabel(parent), mBaseText(tr("Processing")), mAnimationCharacter("."), mTimer(new QTimer(this)), mDotCount(0) { setText(mBaseText); setFixedSize(100, 50); } void ProcessIndicator::start() { connect(mTimer, &QTimer::timeout, this, &ProcessIndicator::tick); mTimer->start(500); } void ProcessIndicator::stop() { mTimer->stop(); } void ProcessIndicator::tick() { mDotCount = ++mDotCount % 4; auto text = mBaseText + mAnimationCharacter.repeated(mDotCount); setText(text); } ksnip-master/src/widgets/ProcessIndicator.h000066400000000000000000000023051457262621600213670ustar00rootroot00000000000000/* * Copyright (C) 2022 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PROCESSINDICATOR_H #define KSNIP_PROCESSINDICATOR_H #include #include class ProcessIndicator : public QLabel { public: explicit ProcessIndicator(QWidget *parent); ~ProcessIndicator() override = default; void start(); void stop(); private: QString mBaseText; QString mAnimationCharacter; int mDotCount; QTimer *mTimer; private slots: void tick(); }; #endif //KSNIP_PROCESSINDICATOR_H ksnip-master/tests/000077500000000000000000000000001457262621600146505ustar00rootroot00000000000000ksnip-master/tests/CMakeLists.txt000066400000000000000000000060171457262621600174140ustar00rootroot00000000000000find_package(GTest CONFIG REQUIRED) enable_testing() set(UNITTEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/backend/recentImages/RecentImagesPathStoreTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/backend/commandLine/CommandLineCaptureHandlerTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/common/helper/PathHelperTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/common/platform/PlatformCheckerTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/actions/ActionTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/actions/ActionProcessorTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/captureHandler/MultiCaptureHandlerTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/captureHandler/SingleCaptureHandlerTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/operations/DeleteImageOperationTests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/operations/LoadImageFromFileOperationTests.cpp ) set(TESTUTILS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/utils/TestRunner.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/uploader/UploadHandlerMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/imageGrabber/ImageGrabberMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/recentImages/ImagePathStorageMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/recentImages/RecentImageServiceMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/config/ConfigMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/saver/ImageSaverMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/backend/saver/SavePathProviderMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/fileService/FileServiceMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/messageBoxService/MessageBoxServiceMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/NotificationServiceMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/ImageProcessorMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/desktopService/DesktopServiceMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/clipboard/ClipboardMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/gui/captureHandler/CaptureTabStateHandlerMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/common/loader/IconLoaderMock.h ${CMAKE_CURRENT_SOURCE_DIR}/mocks/common/platform/CommandRunnerMock.h) add_library(KSNIP_STATIC ${KSNIP_SRCS}) target_link_libraries(KSNIP_STATIC Qt5::Widgets Qt5::Network Qt5::Xml Qt5::PrintSupport kImageAnnotator::kImageAnnotator kColorPicker::kColorPicker Qt5::Svg ) if (APPLE) target_link_libraries(KSNIP_STATIC "-framework CoreGraphics") elseif (UNIX) target_link_libraries(KSNIP_STATIC Qt5::DBus Qt5::X11Extras XCB::XFIXES ) # X11::X11 imported target only available with sufficiently new CMake if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.14.0) target_link_libraries(KSNIP_STATIC X11::X11) else() target_link_libraries(KSNIP_STATIC X11) endif() target_compile_definitions(KSNIP_STATIC PUBLIC UNIX_X11) elseif(WIN32) target_link_libraries(KSNIP_STATIC Qt5::WinExtras Dwmapi ) endif () foreach (UnitTest ${UNITTEST_SRC}) get_filename_component(UnitTestName ${UnitTest} NAME_WE) add_executable(${UnitTestName} ${UnitTest} ${TESTUTILS_SRC}) target_link_libraries(${UnitTestName} KSNIP_STATIC GTest::gmock Qt${QT_MAJOR_VERSION}::Test) add_test(${UnitTestName} ${UnitTestName}) endforeach (UnitTest) ksnip-master/tests/backend/000077500000000000000000000000001457262621600162375ustar00rootroot00000000000000ksnip-master/tests/backend/commandLine/000077500000000000000000000000001457262621600204655ustar00rootroot00000000000000ksnip-master/tests/backend/commandLine/CommandLineCaptureHandlerTests.cpp000066400000000000000000000136631457262621600272350ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CommandLineCaptureHandlerTests.h" #include "src/backend/commandLine/CommandLineCaptureHandler.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/backend/uploader/UploadHandlerMock.h" #include "tests/mocks/backend/imageGrabber/ImageGrabberMock.h" #include "tests/mocks/backend/saver/ImageSaverMock.h" #include "tests/mocks/backend/saver/SavePathProviderMock.h" void CommandLineCaptureHandlerTests::CaptureAndProcessScreenshot_Should_CallUploader_When_UploadOptionSet() { // arrange auto imageGrabberMock = QSharedPointer(new ImageGrabberMock); auto uploadHandlerMock = QSharedPointer(new UploadHandlerMock); CommandLineCaptureParameter parameter; parameter.isWithUpload = true; auto captureDto = CaptureDto(QPixmap()); EXPECT_CALL(*imageGrabberMock, grabImage(testing::_, testing::_, testing::_)) .WillRepeatedly([imageGrabberMock, captureDto](CaptureModes mode, bool cursor, int delay) { imageGrabberMock->finished(captureDto); testing::Mock::VerifyAndClearExpectations(imageGrabberMock.get()); }); EXPECT_CALL(*uploadHandlerMock, upload(captureDto.screenshot.toImage())).Times(testing::Exactly(1)); CommandLineCaptureHandler commandLineCaptureHandler(imageGrabberMock, uploadHandlerMock, nullptr, nullptr); // act & assert commandLineCaptureHandler.captureAndProcessScreenshot(parameter); } void CommandLineCaptureHandlerTests::CaptureAndProcessScreenshot_Should_NotCallUploader_When_UploadOptionNotSet() { // arrange auto imageGrabberMock = QSharedPointer(new ImageGrabberMock); auto uploadHandlerMock = QSharedPointer(new UploadHandlerMock); CommandLineCaptureParameter parameter; parameter.isWithUpload = false; EXPECT_CALL(*imageGrabberMock, grabImage(testing::_, testing::_, testing::_)) .WillRepeatedly([imageGrabberMock](CaptureModes mode, bool cursor, int delay) { imageGrabberMock->finished(CaptureDto(QPixmap())); testing::Mock::VerifyAndClearExpectations(imageGrabberMock.get()); }); EXPECT_CALL(*uploadHandlerMock, upload(testing::_)).Times(testing::Exactly(0)); CommandLineCaptureHandler commandLineCaptureHandler(imageGrabberMock, uploadHandlerMock, nullptr, nullptr); // act & assert commandLineCaptureHandler.captureAndProcessScreenshot(parameter); } void CommandLineCaptureHandlerTests::CaptureAndProcessScreenshot_Should_CallImageSaverWithDefaultSavePath_When_SaveOptionSetAndSavePathEmpty() { // arrange auto defaultSavePath = QString("/my/default/save/path"); auto imageGrabberMock = QSharedPointer(new ImageGrabberMock); auto uploadHandlerMock = QSharedPointer(new UploadHandlerMock); auto imageSaverMock = QSharedPointer(new ImageSaverMock); auto savePathProviderMock = QSharedPointer(new SavePathProviderMock); CommandLineCaptureParameter parameter; parameter.isWithSave = true; parameter.savePath = QString(); EXPECT_CALL(*imageGrabberMock, grabImage(testing::_, testing::_, testing::_)) .WillRepeatedly([imageGrabberMock](CaptureModes mode, bool cursor, int delay) { imageGrabberMock->finished(CaptureDto(QPixmap())); testing::Mock::VerifyAndClearExpectations(imageGrabberMock.get()); }); EXPECT_CALL(*imageSaverMock, save(testing::_, defaultSavePath)) .Times(testing::Exactly(1)) .WillRepeatedly([=]() { return true; }); EXPECT_CALL(*savePathProviderMock, savePath()) .Times(testing::Exactly(1)) .WillRepeatedly([defaultSavePath]() { return defaultSavePath; }); CommandLineCaptureHandler commandLineCaptureHandler(imageGrabberMock, uploadHandlerMock, imageSaverMock, savePathProviderMock); // act & assert commandLineCaptureHandler.captureAndProcessScreenshot(parameter); } void CommandLineCaptureHandlerTests::CaptureAndProcessScreenshot_Should_CallImageSaverWithSavePath_When_SaveOptionSetAndSavePathNotEmpty() { // arrange auto savePath = QString("/my/default/save/path"); auto captureDto = CaptureDto(QPixmap()); auto imageGrabberMock = QSharedPointer(new ImageGrabberMock); auto uploadHandlerMock = QSharedPointer(new UploadHandlerMock); auto imageSaverMock = QSharedPointer(new ImageSaverMock); auto savePathProviderMock = QSharedPointer(new SavePathProviderMock); CommandLineCaptureParameter parameter; parameter.isWithSave = true; parameter.savePath = savePath; EXPECT_CALL(*imageGrabberMock, grabImage(testing::_, testing::_, testing::_)) .WillRepeatedly([imageGrabberMock, captureDto](CaptureModes mode, bool cursor, int delay) { imageGrabberMock->finished(captureDto); testing::Mock::VerifyAndClearExpectations(imageGrabberMock.get()); }); EXPECT_CALL(*imageSaverMock, save(captureDto.screenshot.toImage(), savePath)) .Times(testing::Exactly(1)) .WillRepeatedly([=]() { return true; }); EXPECT_CALL(*savePathProviderMock, savePath()) .Times(testing::Exactly(0)); CommandLineCaptureHandler commandLineCaptureHandler(imageGrabberMock, uploadHandlerMock, imageSaverMock, savePathProviderMock); // act & assert commandLineCaptureHandler.captureAndProcessScreenshot(parameter); } TEST_MAIN(CommandLineCaptureHandlerTests) ksnip-master/tests/backend/commandLine/CommandLineCaptureHandlerTests.h000066400000000000000000000026361457262621600267000ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COMMANDLINECAPTUREHANDLERTESTS_H #define KSNIP_COMMANDLINECAPTUREHANDLERTESTS_H #include class CommandLineCaptureHandlerTests : public QObject { Q_OBJECT private slots: void CaptureAndProcessScreenshot_Should_CallUploader_When_UploadOptionSet(); void CaptureAndProcessScreenshot_Should_NotCallUploader_When_UploadOptionNotSet(); void CaptureAndProcessScreenshot_Should_CallImageSaverWithDefaultSavePath_When_SaveOptionSetAndSavePathEmpty(); void CaptureAndProcessScreenshot_Should_CallImageSaverWithSavePath_When_SaveOptionSetAndSavePathNotEmpty(); }; #endif //KSNIP_COMMANDLINECAPTUREHANDLERTESTS_H ksnip-master/tests/backend/recentImages/000077500000000000000000000000001457262621600206455ustar00rootroot00000000000000ksnip-master/tests/backend/recentImages/RecentImagesPathStoreTests.cpp000066400000000000000000000152601457262621600266000ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "RecentImagesPathStoreTests.h" #include "src/backend/recentImages/RecentImagesPathStore.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/backend/recentImages/ImagePathStorageMock.h" void RecentImagesPathStoreTests::GetRecentImagesPath_Should_ReturnEmptyStringList_When_Initialized() { // arrange auto imagePathStorageMock = QSharedPointer(new ImagePathStorageMock); EXPECT_CALL(*imagePathStorageMock, count()); RecentImagesPathStore recentImagesPathStore(imagePathStorageMock); // act auto recentImagesPath = recentImagesPathStore.getRecentImagesPath(); // assert QCOMPARE(recentImagesPath.size(), 0); } void RecentImagesPathStoreTests::GetRecentImagesPath_Should_ReturnNonEmptyStringList_When_ImagesAreStored() { // arrange auto imagePathStorageMock = QSharedPointer(new ImagePathStorageMock); EXPECT_CALL(*imagePathStorageMock, count()); EXPECT_CALL(*imagePathStorageMock, store(testing::_, testing::_)).Times(testing::AnyNumber()); RecentImagesPathStore recentImagesPathStore(imagePathStorageMock); recentImagesPathStore.storeImagePath("/path/image.png"); recentImagesPathStore.storeImagePath("/path/image2.png"); // act auto recentImagesPath = recentImagesPathStore.getRecentImagesPath(); // assert QCOMPARE(recentImagesPath.size(), 2); QCOMPARE(recentImagesPath.at(0), QStringLiteral("/path/image2.png")); QCOMPARE(recentImagesPath.at(1), QStringLiteral("/path/image.png")); } void RecentImagesPathStoreTests::GetRecentImagesPath_Should_ReturnListOfEntriesInReversedOrder() { // arrange auto imagePathStorageMock = QSharedPointer(new ImagePathStorageMock); EXPECT_CALL(*imagePathStorageMock, count()); EXPECT_CALL(*imagePathStorageMock, store(testing::_, testing::_)).Times(testing::AnyNumber());; RecentImagesPathStore recentImagesPathStore(imagePathStorageMock); recentImagesPathStore.storeImagePath("/path/image1.png"); recentImagesPathStore.storeImagePath("/path/image2.png"); recentImagesPathStore.storeImagePath("/path/image3.png"); recentImagesPathStore.storeImagePath("/path/image4.png"); recentImagesPathStore.storeImagePath("/path/image5.png"); recentImagesPathStore.storeImagePath("/path/image6.png"); recentImagesPathStore.storeImagePath("/path/image7.png"); recentImagesPathStore.storeImagePath("/path/image8.png"); recentImagesPathStore.storeImagePath("/path/image9.png"); recentImagesPathStore.storeImagePath("/path/image10.png"); // act auto recentImagesPath = recentImagesPathStore.getRecentImagesPath(); // assert QCOMPARE(recentImagesPath.size(), 10); QCOMPARE(recentImagesPath[0], QStringLiteral("/path/image10.png")); QCOMPARE(recentImagesPath[1], QStringLiteral("/path/image9.png")); QCOMPARE(recentImagesPath[2], QStringLiteral("/path/image8.png")); QCOMPARE(recentImagesPath[3], QStringLiteral("/path/image7.png")); QCOMPARE(recentImagesPath[4], QStringLiteral("/path/image6.png")); QCOMPARE(recentImagesPath[5], QStringLiteral("/path/image5.png")); QCOMPARE(recentImagesPath[6], QStringLiteral("/path/image4.png")); QCOMPARE(recentImagesPath[7], QStringLiteral("/path/image3.png")); QCOMPARE(recentImagesPath[8], QStringLiteral("/path/image2.png")); QCOMPARE(recentImagesPath[9], QStringLiteral("/path/image1.png")); } void RecentImagesPathStoreTests::StoreImagesPath_Should_NotSavePath_When_PathAlreadyStored() { // arrange auto path1 = QStringLiteral("/path/image.png"); auto imagePathStorageMock = QSharedPointer(new ImagePathStorageMock); EXPECT_CALL(*imagePathStorageMock, count()); EXPECT_CALL(*imagePathStorageMock, store(path1, 0)).Times(testing::Exactly(1)); RecentImagesPathStore recentImagesPathStore(imagePathStorageMock); // act recentImagesPathStore.storeImagePath(path1); recentImagesPathStore.storeImagePath(path1); // assert auto recentImagesPath = recentImagesPathStore.getRecentImagesPath(); QCOMPARE(recentImagesPath.size(), 1); } void RecentImagesPathStoreTests::StoreImagesPath_Should_DropOlderPaths_When_MoreThenTenPathsAdded() { // arrange auto imagePathStorageMock = QSharedPointer(new ImagePathStorageMock); EXPECT_CALL(*imagePathStorageMock, count()); EXPECT_CALL(*imagePathStorageMock, store(testing::_, testing::_)).Times(testing::AnyNumber());; RecentImagesPathStore recentImagesPathStore(imagePathStorageMock); recentImagesPathStore.storeImagePath("/path/image1.png"); recentImagesPathStore.storeImagePath("/path/image2.png"); recentImagesPathStore.storeImagePath("/path/image3.png"); recentImagesPathStore.storeImagePath("/path/image4.png"); recentImagesPathStore.storeImagePath("/path/image5.png"); recentImagesPathStore.storeImagePath("/path/image6.png"); recentImagesPathStore.storeImagePath("/path/image7.png"); recentImagesPathStore.storeImagePath("/path/image8.png"); recentImagesPathStore.storeImagePath("/path/image9.png"); recentImagesPathStore.storeImagePath("/path/image10.png"); // act recentImagesPathStore.storeImagePath("/path/image11.png"); recentImagesPathStore.storeImagePath("/path/image12.png"); // assert auto recentImagesPath = recentImagesPathStore.getRecentImagesPath(); QCOMPARE(recentImagesPath.size(), 10); QCOMPARE(recentImagesPath[0], QStringLiteral("/path/image12.png")); QCOMPARE(recentImagesPath[1], QStringLiteral("/path/image11.png")); QCOMPARE(recentImagesPath[2], QStringLiteral("/path/image10.png")); QCOMPARE(recentImagesPath[3], QStringLiteral("/path/image9.png")); QCOMPARE(recentImagesPath[4], QStringLiteral("/path/image8.png")); QCOMPARE(recentImagesPath[5], QStringLiteral("/path/image7.png")); QCOMPARE(recentImagesPath[6], QStringLiteral("/path/image6.png")); QCOMPARE(recentImagesPath[7], QStringLiteral("/path/image5.png")); QCOMPARE(recentImagesPath[8], QStringLiteral("/path/image4.png")); QCOMPARE(recentImagesPath[9], QStringLiteral("/path/image3.png")); } TEST_MAIN(RecentImagesPathStoreTests) ksnip-master/tests/backend/recentImages/RecentImagesPathStoreTests.h000066400000000000000000000026021457262621600262410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RECENTIMAGESPATHSTORETESTS_H #define KSNIP_RECENTIMAGESPATHSTORETESTS_H #include class RecentImagesPathStoreTests : public QObject { Q_OBJECT private slots: void GetRecentImagesPath_Should_ReturnEmptyStringList_When_Initialized(); void GetRecentImagesPath_Should_ReturnNonEmptyStringList_When_ImagesAreStored(); void GetRecentImagesPath_Should_ReturnListOfEntriesInReversedOrder(); void StoreImagesPath_Should_NotSavePath_When_PathAlreadyStored(); void StoreImagesPath_Should_DropOlderPaths_When_MoreThenTenPathsAdded(); }; #endif //KSNIP_RECENTIMAGESPATHSTORETESTS_H ksnip-master/tests/common/000077500000000000000000000000001457262621600161405ustar00rootroot00000000000000ksnip-master/tests/common/helper/000077500000000000000000000000001457262621600174175ustar00rootroot00000000000000ksnip-master/tests/common/helper/PathHelperTests.cpp000066400000000000000000000105241457262621600232040ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PathHelperTests.h" #include "src/common/helper/PathHelper.h" #include "tests/utils/TestRunner.h" void PathHelperTests::IsPathValid_Should_ReturnFalse_When_StringEmpty() { // arrange auto input = QStringLiteral(""); // act auto result = PathHelper::isPathValid(input); // assert QCOMPARE(result, false); } void PathHelperTests::IsPathValid_Should_ReturnFalse_When_StringNull() { // arrange auto input = QString(); // act auto result = PathHelper::isPathValid(input); // assert QCOMPARE(result, false); } void PathHelperTests::IsPathValid_Should_ReturnTrue_When_StringHasContent() { // arrange auto input = QStringLiteral("lala"); // act auto result = PathHelper::isPathValid(input); // assert QCOMPARE(result, true); } void PathHelperTests::IsPipePath_Should_ReturnTrue_When_PathIsDash() { // arrange auto input = QStringLiteral("-"); // act auto result = PathHelper::isPipePath(input); // assert QCOMPARE(result, true); } void PathHelperTests::IsPipePath_Should_ReturnFalse_When_PathIsNull() { // arrange auto input = QString(); // act auto result = PathHelper::isPipePath(input); // assert QCOMPARE(result, false); } void PathHelperTests::IsPipePath_Should_ReturnFalse_When_PathIsEmpty() { // arrange auto input = QLatin1Literal(""); // act auto result = PathHelper::isPipePath(input); // assert QCOMPARE(result, false); } void PathHelperTests::ExtractParentDirectory_Should_ReturnStringWithParentDirectoryPath() { // arrange auto expected = QStringLiteral("/theRoot/theHome/myHome"); // act auto result = PathHelper::extractParentDirectory(expected + QStringLiteral("/theFile.me")); // assert QCOMPARE(result, expected); } void PathHelperTests::ExtractFilename_Should_ReturnStringWithFilenameWithoutFormat_When_FormatExists() { // arrange auto expected = QStringLiteral("theFile"); // act auto result = PathHelper::extractFilename(QStringLiteral("/theRoot/theHome/myHome/") + expected + QStringLiteral(".me")); // assert QCOMPARE(result, expected); } void PathHelperTests::ExtractFilename_Should_ReturnStringWithFilenameWithoutFormat_When_NoFormatExists() { // arrange auto expected = QStringLiteral("theFile"); // act auto result = PathHelper::extractFilename(QStringLiteral("/theRoot/theHome/myHome/") + expected); // assert QCOMPARE(result, expected); } void PathHelperTests::ExtractFilenameWithFormat_Should_ReturnStringWithFilenameWithFormat_When_FormatExists() { // arrange auto expected = QStringLiteral("theFile.me"); // act auto result = PathHelper::extractFilenameWithFormat(QStringLiteral("/theRoot/theHome/myHome/") + expected); // assert QCOMPARE(result, expected); } void PathHelperTests::ExtractFilenameWithFormat_Should_ReturnStringWithFilenameWithFormat_When_NoFormatExists() { // arrange auto expected = QStringLiteral("theFile"); // act auto result = PathHelper::extractFilenameWithFormat(QStringLiteral("/theRoot/theHome/myHome/") + expected); // assert QCOMPARE(result, expected); } void PathHelperTests::ExtractFormat_Should_ReturnWithFormat_When_FormatExists() { // arrange auto expected = QStringLiteral("me"); // act auto result = PathHelper::extractFormat(QStringLiteral("/theRoot/theHome/myHome/theFile.") + expected); // assert QCOMPARE(result, expected); } void PathHelperTests::ExtractFormat_Should_ReturnEmptyString_When_NoFormatExists() { // arrange auto path = QStringLiteral("/theRoot/theHome/myHome/theFile"); // act auto result = PathHelper::extractFormat(path); // assert QCOMPARE(result, QStringLiteral("")); } TEST_MAIN(PathHelperTests) ksnip-master/tests/common/helper/PathHelperTests.h000066400000000000000000000036221457262621600226520ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PATHHELPERTESTS_H #define KSNIP_PATHHELPERTESTS_H #include class PathHelperTests : public QObject { Q_OBJECT private slots: void IsPathValid_Should_ReturnFalse_When_StringEmpty(); void IsPathValid_Should_ReturnFalse_When_StringNull(); void IsPathValid_Should_ReturnTrue_When_StringHasContent(); void IsPipePath_Should_ReturnTrue_When_PathIsDash(); void IsPipePath_Should_ReturnFalse_When_PathIsNull(); void IsPipePath_Should_ReturnFalse_When_PathIsEmpty(); void ExtractParentDirectory_Should_ReturnStringWithParentDirectoryPath(); void ExtractFilename_Should_ReturnStringWithFilenameWithoutFormat_When_FormatExists(); void ExtractFilename_Should_ReturnStringWithFilenameWithoutFormat_When_NoFormatExists(); void ExtractFilenameWithFormat_Should_ReturnStringWithFilenameWithFormat_When_FormatExists(); void ExtractFilenameWithFormat_Should_ReturnStringWithFilenameWithFormat_When_NoFormatExists(); void ExtractFormat_Should_ReturnWithFormat_When_FormatExists(); void ExtractFormat_Should_ReturnEmptyString_When_NoFormatExists(); }; #endif //KSNIP_PATHHELPERTESTS_H ksnip-master/tests/common/platform/000077500000000000000000000000001457262621600177645ustar00rootroot00000000000000ksnip-master/tests/common/platform/PlatformCheckerTests.cpp000066400000000000000000000276201457262621600245730ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "PlatformCheckerTests.h" #include "src/common/platform/PlatformChecker.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/common/platform/CommandRunnerMock.h" void PlatformCheckerTests::isX11_Should_ReturnTrue_When_X11InEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_SESSION_TYPE"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-X11-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isX11(); // assert QCOMPARE(result, true); } void PlatformCheckerTests::isX11_Should_ReturnFalse_When_X11NotInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_SESSION_TYPE"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Wayland-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isX11(); // assert QCOMPARE(result, false); } void PlatformCheckerTests::isWayland_Should_ReturnTrue_When_WaylandInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_SESSION_TYPE"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Wayland-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isWayland(); // assert QCOMPARE(result, true); } void PlatformCheckerTests::isWayland_Should_ReturnFalse_When_WaylandNotInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_SESSION_TYPE"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-X11-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isWayland(); // assert QCOMPARE(result, false); } void PlatformCheckerTests::isKde_Should_ReturnTrue_When_KdeInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Kde-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isKde(); // assert QCOMPARE(result, true); } void PlatformCheckerTests::isKde_Should_ReturnFalse_When_KdeNotInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Gnome-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isKde(); // assert QCOMPARE(result, false); } void PlatformCheckerTests::isGnome_Should_ReturnTrue_When_GnomeInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Gnome-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isGnome(); // assert QCOMPARE(result, true); } void PlatformCheckerTests::isGnome_Should_ReturnTrue_When_UnityInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Unity-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isGnome(); // assert QCOMPARE(result, true); } void PlatformCheckerTests::isGnome_Should_ReturnFalse_When_GnomeOrUnityNotInEnvVar() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Kde-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isGnome(); // assert QCOMPARE(result, false); } void PlatformCheckerTests::isSnap_Should_ReturnTrue_When_SnapEnvVarSet() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, isEnvironmentVariableSet(QString("SNAP"))) .WillRepeatedly([=](const QString &variable) { return true; }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isSnap(); // assert QCOMPARE(result, true); } void PlatformCheckerTests::isSnap_Should_ReturnFalse_When_SnapEnvVarNotSet() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, isEnvironmentVariableSet(QString("SNAP"))) .WillRepeatedly([=](const QString &variable) { return false; }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.isSnap(); // assert QCOMPARE(result, false); } void PlatformCheckerTests::gnomeVersion_Should_ReturnGnomeVersion_When_GnomeAndVersionFileExists() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Gnome-somethingElse"); }); EXPECT_CALL(*commandRunnerMock, readFile(QString("/usr/share/gnome/gnome-version.xml"))) .WillRepeatedly([=](const QString &path) { return QString("11142"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.gnomeVersion(); // assert QCOMPARE(result, 42); } void PlatformCheckerTests::gnomeVersion_Should_ReturnMinusOne_When_NotGnomeButVersionFileExists() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Kde-somethingElse"); }); EXPECT_CALL(*commandRunnerMock, readFile(QString("/usr/share/gnome/gnome-version.xml"))) .WillRepeatedly([=](const QString &path) { return QString("11142"); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.gnomeVersion(); // assert QCOMPARE(result, -1); } void PlatformCheckerTests::gnomeVersion_Should_ReturnMinusOne_When_GnomeButVersionFileDoesNotExists() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Gnome-somethingElse"); }); EXPECT_CALL(*commandRunnerMock, readFile(QString("/usr/share/gnome/gnome-version.xml"))) .WillRepeatedly([=](const QString &path) { return QString(); }); PlatformChecker platformChecker(commandRunnerMock); // act auto result = platformChecker.gnomeVersion(); // assert QCOMPARE(result, -1); } void PlatformCheckerTests::isX11_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(testing::_)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-X11-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act platformChecker.isX11(); platformChecker.isX11(); } void PlatformCheckerTests::isWayland_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(testing::_)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-X11-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act platformChecker.isWayland(); platformChecker.isWayland(); } void PlatformCheckerTests::isKde_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(testing::_)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-kde-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act platformChecker.isKde(); platformChecker.isKde(); } void PlatformCheckerTests::isGnome_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(testing::_)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Gnome-somethingElse"); }); PlatformChecker platformChecker(commandRunnerMock); // act platformChecker.isGnome(); platformChecker.isGnome(); } void PlatformCheckerTests::isSnap_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, isEnvironmentVariableSet(QString("SNAP"))) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &variable) { return true; }); PlatformChecker platformChecker(commandRunnerMock); // act platformChecker.isSnap(); platformChecker.isSnap(); } void PlatformCheckerTests::gnomeVersion_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes() { // arrange auto commandRunnerMock = QSharedPointer(new CommandRunnerMock); EXPECT_CALL(*commandRunnerMock, getEnvironmentVariable(QString("XDG_CURRENT_DESKTOP"))) .WillRepeatedly([=](const QString &variable) { return QLatin1String("Test123-Gnome-somethingElse"); }); EXPECT_CALL(*commandRunnerMock, readFile(QString("/usr/share/gnome/gnome-version.xml"))) .WillRepeatedly([=](const QString &path) { return QString(); }); PlatformChecker platformChecker(commandRunnerMock); // act platformChecker.gnomeVersion(); platformChecker.gnomeVersion(); } TEST_MAIN(PlatformCheckerTests) ksnip-master/tests/common/platform/PlatformCheckerTests.h000066400000000000000000000043751457262621600242420ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_PLATFORMCHECKERTESTS_H #define KSNIP_PLATFORMCHECKERTESTS_H #include class PlatformCheckerTests : public QObject { Q_OBJECT private slots: void isX11_Should_ReturnTrue_When_X11InEnvVar(); void isX11_Should_ReturnFalse_When_X11NotInEnvVar(); void isWayland_Should_ReturnTrue_When_WaylandInEnvVar(); void isWayland_Should_ReturnFalse_When_WaylandNotInEnvVar(); void isKde_Should_ReturnTrue_When_KdeInEnvVar(); void isKde_Should_ReturnFalse_When_KdeNotInEnvVar(); void isGnome_Should_ReturnTrue_When_GnomeInEnvVar(); void isGnome_Should_ReturnTrue_When_UnityInEnvVar(); void isGnome_Should_ReturnFalse_When_GnomeOrUnityNotInEnvVar(); void isSnap_Should_ReturnTrue_When_SnapEnvVarSet(); void isSnap_Should_ReturnFalse_When_SnapEnvVarNotSet(); void gnomeVersion_Should_ReturnGnomeVersion_When_GnomeAndVersionFileExists(); void gnomeVersion_Should_ReturnMinusOne_When_NotGnomeButVersionFileExists(); void gnomeVersion_Should_ReturnMinusOne_When_GnomeButVersionFileDoesNotExists(); void isX11_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes(); void isWayland_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes(); void isKde_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes(); void isGnome_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes(); void isSnap_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes(); void gnomeVersion_Should_CallCommandRunnerOnlyOnce_When_CalledMultipleTimes(); }; #endif //KSNIP_PLATFORMCHECKERTESTS_H ksnip-master/tests/gui/000077500000000000000000000000001457262621600154345ustar00rootroot00000000000000ksnip-master/tests/gui/actions/000077500000000000000000000000001457262621600170745ustar00rootroot00000000000000ksnip-master/tests/gui/actions/ActionProcessorTests.cpp000066400000000000000000000221641457262621600237450ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ActionProcessorTests.h" #include "src/gui/actions/ActionProcessor.h" #include "tests/utils/TestRunner.h" void ActionProcessorTests::Process_Should_TriggerCapture_When_CaptureEnabled() { // arrange Action action; action.setIsCaptureEnabled(true); action.setCaptureDelay(2000); action.setIncludeCursor(true); action.setCaptureMode(CaptureModes::CurrentScreen); ActionProcessor processor; QSignalSpy spy(&processor, &ActionProcessor::triggerCapture); // act processor.process(action); // assert QCOMPARE(spy.count(), 1); QCOMPARE(qvariant_cast(spy.at(0).at(0)), CaptureModes::CurrentScreen); QCOMPARE(qvariant_cast(spy.at(0).at(1)), true); QCOMPARE(qvariant_cast(spy.at(0).at(2)), 2000); } void ActionProcessorTests::Process_Should_NotTriggerCapture_When_CaptureDisabled() { // arrange Action action; action.setIsCaptureEnabled(false); action.setCaptureDelay(2000); action.setIncludeCursor(true); action.setCaptureMode(CaptureModes::CurrentScreen); ActionProcessor processor; QSignalSpy spy(&processor, &ActionProcessor::triggerCapture); // act processor.process(action); // assert QCOMPARE(spy.count(), 0); } void ActionProcessorTests::Process_Should_StartPostProcessing_When_CaptureDisabledAndPostProcessingEnabled() { // arrange Action action; action.setIsCaptureEnabled(false); action.setIsSaveEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerSave); // act processor.process(action); // assert QCOMPARE(spy.count(), 1); } void ActionProcessorTests::Process_Should_NotStartPostProcessing_When_CaptureDisabledAndPostProcessingDisabled() { // arrange Action action; action.setIsCaptureEnabled(false); action.setIsSaveEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(false); QSignalSpy spy(&processor, &ActionProcessor::triggerSave); // act processor.process(action); // assert QCOMPARE(spy.count(), 0); } void ActionProcessorTests::Process_Should_NotStartPostProcessing_When_CaptureEnabledAndPostProcessingDisabled() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsSaveEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(false); QSignalSpy spy(&processor, &ActionProcessor::triggerSave); // act processor.process(action); // assert QCOMPARE(spy.count(), 0); } void ActionProcessorTests::Process_Should_NotStartPostProcessing_When_CaptureEnabledAndPostProcessingEnabled() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsSaveEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerSave); // act processor.process(action); // assert QCOMPARE(spy.count(), 0); } void ActionProcessorTests::CaptureFinished_Should_StartPostProcessing_When_CaptureEnabledAndPostProcessingEnabled() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsSaveEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerSave); processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(spy.count(), 1); } void ActionProcessorTests::CaptureFinished_Should_StartPostProcessing_When_CaptureEnabledAndPostProcessingDisabled() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsSaveEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(false); QSignalSpy spy(&processor, &ActionProcessor::triggerSave); processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(spy.count(), 1); } void ActionProcessorTests::CaptureFinished_Should_SendSignalsForAllSelectedActions() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsSaveEnabled(true); action.setIsCopyToClipboardEnabled(true); action.setIsOpenDirectoryEnabled(true); action.setIsUploadEnabled(true); action.setIsPinImageEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(false); QSignalSpy saveSignalSpy(&processor, &ActionProcessor::triggerSave); QSignalSpy copySignalSpy(&processor, &ActionProcessor::triggerCopyToClipboard); QSignalSpy openSignalSpy(&processor, &ActionProcessor::triggerOpenDirectory); QSignalSpy uploadSignalSpy(&processor, &ActionProcessor::triggerUpload); QSignalSpy pinSignalSpy(&processor, &ActionProcessor::triggerPinImage); processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(saveSignalSpy.count(), 1); QCOMPARE(copySignalSpy.count(), 1); QCOMPARE(openSignalSpy.count(), 1); QCOMPARE(uploadSignalSpy.count(), 1); QCOMPARE(pinSignalSpy.count(), 1); } void ActionProcessorTests::CaptureFinished_Should_NotSendSignalsForNotSelectedActions() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsSaveEnabled(false); action.setIsCopyToClipboardEnabled(false); action.setIsOpenDirectoryEnabled(false); action.setIsUploadEnabled(false); action.setIsPinImageEnabled(false); ActionProcessor processor; processor.setPostProcessingEnabled(false); QSignalSpy saveSignalSpy(&processor, &ActionProcessor::triggerSave); QSignalSpy copySignalSpy(&processor, &ActionProcessor::triggerCopyToClipboard); QSignalSpy openSignalSpy(&processor, &ActionProcessor::triggerOpenDirectory); QSignalSpy uploadSignalSpy(&processor, &ActionProcessor::triggerUpload); QSignalSpy pinSignalSpy(&processor, &ActionProcessor::triggerPinImage); processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(saveSignalSpy.count(), 0); QCOMPARE(copySignalSpy.count(), 0); QCOMPARE(openSignalSpy.count(), 0); QCOMPARE(uploadSignalSpy.count(), 0); QCOMPARE(pinSignalSpy.count(), 0); } void ActionProcessorTests::Process_Should_MarkActionAsInProgress_When_CaptureEnabled() { // arrange Action action; action.setIsCaptureEnabled(true); ActionProcessor processor; // act processor.process(action); // assert QCOMPARE(processor.isActionInProgress(), true); } void ActionProcessorTests::CaptureFinished_Should_MarkActionAsNotInProgress_When_CaptureEnabled() { // arrange Action action; action.setIsCaptureEnabled(true); ActionProcessor processor; processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(processor.isActionInProgress(), false); } void ActionProcessorTests::CaptureFinished_Should_SendShowSignalWithMinimizedSetToTrue_When_HideSelected() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsHideMainWindowEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerShow); processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(spy.count(), 1); QCOMPARE(qvariant_cast(spy.at(0).at(0)), true); } void ActionProcessorTests::CaptureFinished_Should_SendShowSignalWithMinimizedSetToFalse_When_HideNotSelected() { // arrange Action action; action.setIsCaptureEnabled(true); action.setIsHideMainWindowEnabled(false); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerShow); processor.process(action); // act processor.captureFinished(); // assert QCOMPARE(spy.count(), 1); QCOMPARE(qvariant_cast(spy.at(0).at(0)), false); } void ActionProcessorTests::Process_Should_NotSendShowSignal_When_HideNotSelectedAndCaptureNotSelected() { // arrange Action action; action.setIsCaptureEnabled(false); action.setIsHideMainWindowEnabled(false); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerShow); // act processor.process(action); // assert QCOMPARE(spy.count(), 0); } void ActionProcessorTests::Process_Should_SendShowSignalWithMinimizedSetToTrue_When_HideSelectedAndCaptureNotSelected() { // arrange Action action; action.setIsCaptureEnabled(false); action.setIsHideMainWindowEnabled(true); ActionProcessor processor; processor.setPostProcessingEnabled(true); QSignalSpy spy(&processor, &ActionProcessor::triggerShow); // act processor.process(action); // assert QCOMPARE(spy.count(), 1); QCOMPARE(qvariant_cast(spy.at(0).at(0)), true); } TEST_MAIN(ActionProcessorTests) ksnip-master/tests/gui/actions/ActionProcessorTests.h000066400000000000000000000045021457262621600234060ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTIONPROCESSORTESTS_H #define KSNIP_ACTIONPROCESSORTESTS_H #include class ActionProcessorTests : public QObject { Q_OBJECT private slots: void Process_Should_TriggerCapture_When_CaptureEnabled(); void Process_Should_NotTriggerCapture_When_CaptureDisabled(); void Process_Should_StartPostProcessing_When_CaptureDisabledAndPostProcessingEnabled(); void Process_Should_NotStartPostProcessing_When_CaptureDisabledAndPostProcessingDisabled(); void Process_Should_NotStartPostProcessing_When_CaptureEnabledAndPostProcessingDisabled(); void Process_Should_NotStartPostProcessing_When_CaptureEnabledAndPostProcessingEnabled(); void CaptureFinished_Should_StartPostProcessing_When_CaptureEnabledAndPostProcessingEnabled(); void CaptureFinished_Should_StartPostProcessing_When_CaptureEnabledAndPostProcessingDisabled(); void CaptureFinished_Should_SendSignalsForAllSelectedActions(); void CaptureFinished_Should_NotSendSignalsForNotSelectedActions(); void Process_Should_MarkActionAsInProgress_When_CaptureEnabled(); void CaptureFinished_Should_MarkActionAsNotInProgress_When_CaptureEnabled(); void CaptureFinished_Should_SendShowSignalWithMinimizedSetToTrue_When_HideSelected(); void CaptureFinished_Should_SendShowSignalWithMinimizedSetToFalse_When_HideNotSelected(); void Process_Should_NotSendShowSignal_When_HideNotSelectedAndCaptureNotSelected(); void Process_Should_SendShowSignalWithMinimizedSetToTrue_When_HideSelectedAndCaptureNotSelected(); }; #endif //KSNIP_ACTIONPROCESSORTESTS_H ksnip-master/tests/gui/actions/ActionTests.cpp000066400000000000000000000505451457262621600220510ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "ActionTests.h" #include "src/gui/actions/Action.h" #include "tests/utils/TestRunner.h" void ActionTests::EqualsOperator_Should_ReturnTrue_When_AllValuesMatch() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, true); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_NameIsDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName("Other"); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_ShortcutDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsCaptureEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(false); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IncludeCursorDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(false); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_CaptureDelayDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(5000); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_CaptureModeDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(CaptureModes::RectArea); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsSaveEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(false); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsCopyToClipboardEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(false); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsUploadEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(false); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsOpenDirectoryEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(false); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsPinScreenshotEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(false); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsHideMainWindowEnabledDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(false); action2.setIsGlobalShortcut(action1.isGlobalShortcut()); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } void ActionTests::EqualsOperator_Should_ReturnFalse_When_IsGlobalShortcutDifferent() { // arrange Action action1; action1.setName("Name"); action1.setShortcut(Qt::CTRL + Qt::Key_A); action1.setIsCaptureEnabled(true); action1.setIncludeCursor(true); action1.setCaptureDelay(2000); action1.setCaptureMode(CaptureModes::FullScreen); action1.setIsSaveEnabled(true); action1.setIsCopyToClipboardEnabled(true); action1.setIsUploadEnabled(true); action1.setIsOpenDirectoryEnabled(true); action1.setIsPinImageEnabled(true); action1.setIsHideMainWindowEnabled(true); action1.setIsGlobalShortcut(true); Action action2; action2.setName(action1.name()); action2.setShortcut(action1.shortcut()); action2.setIsCaptureEnabled(action1.isCaptureEnabled()); action2.setIncludeCursor(action1.includeCursor()); action2.setCaptureDelay(action1.captureDelay()); action2.setCaptureMode(action1.captureMode()); action2.setIsSaveEnabled(action1.isSaveEnabled()); action2.setIsCopyToClipboardEnabled(action1.isCopyToClipboardEnabled()); action2.setIsUploadEnabled(action1.isUploadEnabled()); action2.setIsOpenDirectoryEnabled(action1.isOpenDirectoryEnabled()); action2.setIsPinImageEnabled(action1.isPinImageEnabled()); action2.setIsHideMainWindowEnabled(action1.isHideMainWindowEnabled()); action2.setIsGlobalShortcut(false); // act auto result = action1 == action2; // assert QCOMPARE(result, false); } TEST_MAIN(ActionTests) ksnip-master/tests/gui/actions/ActionTests.h000066400000000000000000000037511457262621600215130ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ACTIONTESTS_H #define KSNIP_ACTIONTESTS_H #include class ActionTests : public QObject { Q_OBJECT private slots: void EqualsOperator_Should_ReturnTrue_When_AllValuesMatch(); void EqualsOperator_Should_ReturnFalse_When_NameIsDifferent(); void EqualsOperator_Should_ReturnFalse_When_ShortcutDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsCaptureEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IncludeCursorDifferent(); void EqualsOperator_Should_ReturnFalse_When_CaptureDelayDifferent(); void EqualsOperator_Should_ReturnFalse_When_CaptureModeDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsSaveEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsCopyToClipboardEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsUploadEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsOpenDirectoryEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsPinScreenshotEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsHideMainWindowEnabledDifferent(); void EqualsOperator_Should_ReturnFalse_When_IsGlobalShortcutDifferent(); }; #endif //KSNIP_ACTIONTESTS_H ksnip-master/tests/gui/captureHandler/000077500000000000000000000000001457262621600203755ustar00rootroot00000000000000ksnip-master/tests/gui/captureHandler/MultiCaptureHandlerTests.cpp000066400000000000000000000673361457262621600260570ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "MultiCaptureHandlerTests.h" #include "src/gui/captureHandler/MultiCaptureHandler.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/gui/imageAnnotator/ImageAnnotatorMock.h" #include "tests/mocks/gui/NotificationServiceMock.h" #include "tests/mocks/gui/fileService/FileServiceMock.h" #include "tests/mocks/gui/desktopService/DesktopServiceMock.h" #include "tests/mocks/gui/clipboard/ClipboardMock.h" #include "tests/mocks/gui/messageBoxService/MessageBoxServiceMock.h" #include "tests/mocks/gui/captureHandler/CaptureTabStateHandlerMock.h" #include "tests/mocks/backend/config/ConfigMock.h" #include "tests/mocks/backend/saver/ImageSaverMock.h" #include "tests/mocks/backend/saver/SavePathProviderMock.h" #include "tests/mocks/backend/recentImages/RecentImageServiceMock.h" #include "tests/mocks/common/loader/IconLoaderMock.h" void MultiCaptureHandlerTests::Copy_Should_CopyCurrentTabImageToClipboard() { // arrange auto index = 22; auto image = QImage(); ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, clipboardMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(imageAnnotatorMock, imageAt(index)) .Times(testing::Exactly(1)) .WillRepeatedly([=](int index) { return image; }); EXPECT_CALL(*clipboardMock, setImage(image)) .Times(testing::Exactly(1)); // act & assert multiCaptureHandler.copy(); } void MultiCaptureHandlerTests::CopyToClipboardTab_Should_FetchCorrectImageFromAnnotator_And_CopyItToClipboard() { // arrange int index = 22; auto image = QImage(); QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(imageAnnotatorMock, imageAt(index)) .Times(testing::Exactly(1)) .WillRepeatedly([=](int index) { return image; }); EXPECT_CALL(*clipboardMock, setImage(image)) .Times(testing::Exactly(1)); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, clipboardMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Copy")) { action->setData(index); action->trigger(); } } } void MultiCaptureHandlerTests::CopyPathToClipboardTab_Should_FetchCorrectPathFromTabStateHandler_And_CopyItToClipboard() { // arrange int index = 22; auto path = QString("lala"); QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, path(index)) .Times(testing::Exactly(1)) .WillRepeatedly([=](int index) { return path; }); EXPECT_CALL(*clipboardMock, setText(path)) .Times(testing::Exactly(1)); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, clipboardMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Copy Path")) { action->setData(index); action->trigger(); } } } void MultiCaptureHandlerTests::OpenDirectory_Should_FetchCorrectPathFromTabStateHandler_And_PassTheParentDirectoryOnlyToDesktopService() { // arrange int index = 22; auto parentDir = QString("/foo"); auto path = parentDir + QString("/bar.png"); QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto desktopServiceMock = QSharedPointer(new DesktopServiceMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, path(index)) .Times(testing::Exactly(1)) .WillRepeatedly([=](int index) { return path; }); EXPECT_CALL(*desktopServiceMock, openFile(parentDir)) .Times(testing::Exactly(1)); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, desktopServiceMock, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Open Directory")) { action->setData(index); action->trigger(); } } } void MultiCaptureHandlerTests::UpdateContextMenuActions_Should_SetAllActionThatRequirePathToEnabled_When_PathIsValid() { // arrange int index = 22; QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(testing::_)); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, isPathValid(index)) .Times(testing::Exactly(1)) .WillRepeatedly([=](int index) { return true; }); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act imageAnnotatorMock.tabContextMenuOpened(index); // assert QAction *saveContextMenuAction = nullptr; QAction *saveAsContextMenuAction = nullptr; QAction *saveAllContextMenuAction = nullptr; QAction *openDirectoryContextMenuAction = nullptr; QAction *copyPathToClipboardContextMenuAction = nullptr; QAction *copyToClipboardContextMenuAction = nullptr; for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Save")) { saveContextMenuAction = action; } if(action->text() == QLatin1Literal("Save As")) { saveAsContextMenuAction = action; } if(action->text() == QLatin1Literal("Save All")) { saveAllContextMenuAction = action; } if(action->text() == QLatin1Literal("Open Directory")) { openDirectoryContextMenuAction = action; } if(action->text() ==QLatin1Literal("Copy Path")) { copyPathToClipboardContextMenuAction = action; } if(action->text() == QLatin1Literal("Copy")) { copyToClipboardContextMenuAction = action; } } EXPECT_TRUE(saveContextMenuAction->isEnabled()); EXPECT_TRUE(saveAsContextMenuAction->isEnabled()); EXPECT_TRUE(saveAllContextMenuAction->isEnabled()); EXPECT_TRUE(openDirectoryContextMenuAction->isEnabled()); EXPECT_TRUE(copyPathToClipboardContextMenuAction->isEnabled()); EXPECT_TRUE(copyToClipboardContextMenuAction->isEnabled()); } void MultiCaptureHandlerTests::UpdateContextMenuActions_Should_SetAllActionThatRequirePathToDisabled_When_PathIsNotValid() { // arrange int index = 22; QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(testing::_)); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, isPathValid(index)) .Times(testing::Exactly(1)) .WillRepeatedly([=](int index) { return false; }); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act imageAnnotatorMock.tabContextMenuOpened(index); // assert QAction *saveContextMenuAction = nullptr; QAction *saveAsContextMenuAction = nullptr; QAction *saveAllContextMenuAction = nullptr; QAction *openDirectoryContextMenuAction = nullptr; QAction *copyPathToClipboardContextMenuAction = nullptr; QAction *copyToClipboardContextMenuAction = nullptr; for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Save")) { saveContextMenuAction = action; } if(action->text() == QLatin1Literal("Save As")) { saveAsContextMenuAction = action; } if(action->text() == QLatin1Literal("Save All")) { saveAllContextMenuAction = action; } if(action->text() == QLatin1Literal("Open Directory")) { openDirectoryContextMenuAction = action; } if(action->text() ==QLatin1Literal("Copy Path")) { copyPathToClipboardContextMenuAction = action; } if(action->text() == QLatin1Literal("Copy")) { copyToClipboardContextMenuAction = action; } } EXPECT_TRUE(saveContextMenuAction->isEnabled()); EXPECT_TRUE(saveAsContextMenuAction->isEnabled()); EXPECT_TRUE(saveAllContextMenuAction->isEnabled()); EXPECT_FALSE(openDirectoryContextMenuAction->isEnabled()); EXPECT_FALSE(copyPathToClipboardContextMenuAction->isEnabled()); EXPECT_TRUE(copyToClipboardContextMenuAction->isEnabled()); } void MultiCaptureHandlerTests::UpdateContextMenuActions_Should_SetSaveActionToDisabled_When_CaptureSaved() { // arrange int index = 22; QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, isPathValid(testing::_)); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(index)) .WillRepeatedly([=](int index) { return true; }); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act imageAnnotatorMock.tabContextMenuOpened(index); // arrange QAction *saveContextMenuAction = nullptr; for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Save")) { saveContextMenuAction = action; } } EXPECT_FALSE(saveContextMenuAction->isEnabled()); } void MultiCaptureHandlerTests::UpdateContextMenuActions_Should_SetSaveActionToEnabled_When_CaptureNotSaved() { // arrange int index = 22; QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, isPathValid(testing::_)); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(index)) .WillRepeatedly([=](int index) { return false; }); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act imageAnnotatorMock.tabContextMenuOpened(index); // arrange QAction *saveContextMenuAction = nullptr; for(auto action : parameterActions) { if(action->text() == QLatin1Literal("Save")) { saveContextMenuAction = action; } } EXPECT_TRUE(saveContextMenuAction->isEnabled()); } void MultiCaptureHandlerTests::CopyPath_Should_CopyCurrentTabPathToClipboard() { // arrange int index = 22; auto parentDir = QString("/foo"); auto path = parentDir + QString("/bar.png"); QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, path(index)) .WillRepeatedly([=](int index) { return path; }); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*clipboardMock, setText(path)).Times(testing::Exactly(1)); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, clipboardMock, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert multiCaptureHandler.copyPath(); } void MultiCaptureHandlerTests::OpenDirectory_Should_FetchCurrentTabPathFromTabStateHandler_And_PassTheParentDirectoryOnlyToDesktopService() { // arrange int index = 22; auto parentDir = QString("/foo"); auto path = parentDir + QString("/bar.png"); QList parameterActions; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto desktopServiceMock = QSharedPointer(new DesktopServiceMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, path(index)) .WillRepeatedly([=](int index) { return path; }); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)) .WillRepeatedly([&](const QList & actions) { parameterActions = actions; }); EXPECT_CALL(*desktopServiceMock, openFile(parentDir)).Times(testing::Exactly(1)); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, desktopServiceMock, nullptr, nullptr, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert multiCaptureHandler.openDirectory(); } void MultiCaptureHandlerTests::RemoveImage_Should_NotRemoveTab_When_OperationDidNotDeleteImage() { // arrange int index = 22; auto parentDir = QString("/foo"); auto path = parentDir + QString("/bar.png"); ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto messageBoxServiceMock = QSharedPointer(new MessageBoxServiceMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, path(index)) .WillRepeatedly([=](int index) { return path; }); EXPECT_CALL(imageAnnotatorMock, removeTab(index)) .Times(testing::Exactly(0)); EXPECT_CALL(*messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &info) { return false; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, nullptr, fileServiceMock, messageBoxServiceMock, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert multiCaptureHandler.removeImage(); } void MultiCaptureHandlerTests::RemoveImage_Should_RemoveTab_When_OperationDidDeleteImage() { // arrange int index = 22; auto parentDir = QString("/foo"); auto path = parentDir + QString("/bar.png"); ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto messageBoxServiceMock = QSharedPointer(new MessageBoxServiceMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(imageAnnotatorMock, hide()); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, tabRemoved(testing::_)); EXPECT_CALL(*captureTabStateHandlerMock, count()); EXPECT_CALL(*captureTabStateHandlerMock, currentTabIndex()) .WillRepeatedly([=]() { return index; }); EXPECT_CALL(*captureTabStateHandlerMock, path(index)) .WillRepeatedly([=](int index) { return path; }); EXPECT_CALL(imageAnnotatorMock, removeTab(index)) .Times(testing::Exactly(1)); EXPECT_CALL(*messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &info) { return true; }); EXPECT_CALL(*fileServiceMock, remove(path)) .WillRepeatedly([=](const QString &path) { return true; }); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, nullptr, captureTabStateHandlerMock, configMock, nullptr, nullptr, fileServiceMock, messageBoxServiceMock, nullptr, nullptr, nullptr, iconLoaderMock, nullptr, nullptr); // act & assert multiCaptureHandler.removeImage(); } void MultiCaptureHandlerTests::SaveAll_Should_CallSaveForAllTabs_When_TabIsNotSaved() { // arrange QWidget parent; ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto captureTabStateHandlerMock = QSharedPointer(new CaptureTabStateHandlerMock); auto configMock = QSharedPointer(new ConfigMock); auto iconLoaderMock = QSharedPointer(new IconLoaderMock); auto imageSaverMock = QSharedPointer(new ImageSaverMock); auto savePathProviderMock = QSharedPointer(new SavePathProviderMock); auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(imageAnnotatorMock, imageAt(testing::_)) .WillRepeatedly(testing::Return(QImage())); EXPECT_CALL(*recentImageServiceMock, storeImagePath(testing::_)) .WillRepeatedly(testing::Return()); EXPECT_CALL(*configMock, trayIconNotificationsEnabled()) .WillRepeatedly(testing::Return(false)); EXPECT_CALL(*configMock, autoHideTabs()); EXPECT_CALL(*captureTabStateHandlerMock, count()) .WillRepeatedly([=]() { return 3; }); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(0)) .Times(testing::Exactly(1)) .WillRepeatedly(testing::Return(false)); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(1)) .Times(testing::Exactly(1)) .WillRepeatedly(testing::Return(true)); EXPECT_CALL(*captureTabStateHandlerMock, isSaved(2)) .Times(testing::Exactly(1)) .WillRepeatedly(testing::Return(false)); EXPECT_CALL(*captureTabStateHandlerMock, setSaveState(0, testing::_)) .Times(testing::Exactly(1)); EXPECT_CALL(*captureTabStateHandlerMock, setSaveState(2, testing::_)) .Times(testing::Exactly(1)); EXPECT_CALL(*captureTabStateHandlerMock, path(testing::_)) .WillRepeatedly(testing::Return(QString())); EXPECT_CALL(*imageSaverMock, save(testing::_, testing::_)) .WillRepeatedly(testing::Return(true)); EXPECT_CALL(*savePathProviderMock, savePath()) .WillRepeatedly(testing::Return(QString())); EXPECT_CALL(imageAnnotatorMock, addTabContextMenuActions(testing::_)); EXPECT_CALL(*iconLoaderMock, loadForTheme(testing::_)) .WillRepeatedly(testing::Return(QIcon())); MultiCaptureHandler multiCaptureHandler( &imageAnnotatorMock, notificationServiceMock, captureTabStateHandlerMock, configMock, nullptr, nullptr, nullptr, nullptr, recentImageServiceMock, imageSaverMock, savePathProviderMock, iconLoaderMock, nullptr, &parent); // act & assert multiCaptureHandler.saveAll(); } TEST_MAIN(MultiCaptureHandlerTests) ksnip-master/tests/gui/captureHandler/MultiCaptureHandlerTests.h000066400000000000000000000041361457262621600255110ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MULTICAPTUREHANDLERTESTS_H #define KSNIP_MULTICAPTUREHANDLERTESTS_H #include class MultiCaptureHandlerTests : public QObject { Q_OBJECT private slots: void Copy_Should_CopyCurrentTabImageToClipboard(); void CopyToClipboardTab_Should_FetchCorrectImageFromAnnotator_And_CopyItToClipboard(); void CopyPathToClipboardTab_Should_FetchCorrectPathFromTabStateHandler_And_CopyItToClipboard(); void OpenDirectory_Should_FetchCorrectPathFromTabStateHandler_And_PassTheParentDirectoryOnlyToDesktopService(); void UpdateContextMenuActions_Should_SetAllActionThatRequirePathToEnabled_When_PathIsValid(); void UpdateContextMenuActions_Should_SetAllActionThatRequirePathToDisabled_When_PathIsNotValid(); void UpdateContextMenuActions_Should_SetSaveActionToDisabled_When_CaptureSaved(); void UpdateContextMenuActions_Should_SetSaveActionToEnabled_When_CaptureNotSaved(); void CopyPath_Should_CopyCurrentTabPathToClipboard(); void OpenDirectory_Should_FetchCurrentTabPathFromTabStateHandler_And_PassTheParentDirectoryOnlyToDesktopService(); void RemoveImage_Should_NotRemoveTab_When_OperationDidNotDeleteImage(); void RemoveImage_Should_RemoveTab_When_OperationDidDeleteImage(); void SaveAll_Should_CallSaveForAllTabs_When_TabIsNotSaved(); }; #endif //KSNIP_MULTICAPTUREHANDLERTESTS_H ksnip-master/tests/gui/captureHandler/SingleCaptureHandlerTests.cpp000066400000000000000000000161361457262621600261760ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "SingleCaptureHandlerTests.h" #include "src/gui/captureHandler/SingleCaptureHandler.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/gui/imageAnnotator/ImageAnnotatorMock.h" #include "tests/mocks/gui/NotificationServiceMock.h" #include "tests/mocks/gui/fileService/FileServiceMock.h" #include "tests/mocks/gui/desktopService/DesktopServiceMock.h" #include "tests/mocks/gui/clipboard/ClipboardMock.h" #include "tests/mocks/gui/messageBoxService/MessageBoxServiceMock.h" #include "tests/mocks/backend/recentImages/RecentImageServiceMock.h" void SingleCaptureHandlerTests::RemoveImage_Should_CleanupAnnotationData_When_ImageDeleted() { // arrange ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto desktopServiceMock = QSharedPointer(new DesktopServiceMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto messageBoxServiceMock = QSharedPointer(new MessageBoxServiceMock); auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); EXPECT_CALL(imageAnnotatorMock, loadImage(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &question) { return true; }); EXPECT_CALL(*fileServiceMock, remove(testing::_)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &path) { return true; }); EXPECT_CALL(imageAnnotatorMock, hide()).Times(testing::Exactly(1)); SingleCaptureHandler captureHandler( &imageAnnotatorMock, notificationServiceMock, clipboardMock, desktopServiceMock, fileServiceMock, messageBoxServiceMock, recentImageServiceMock, nullptr, nullptr, nullptr, nullptr, nullptr); auto capture = CaptureFromFileDto(QPixmap(), QLatin1Literal("lala")); captureHandler.load(capture); // act captureHandler.removeImage(); // assert QCOMPARE(captureHandler.path(), QString()); QCOMPARE(captureHandler.isSaved(), true); } void SingleCaptureHandlerTests::RemoveImage_Should_NotCleanupAnnotationData_When_ImageWasNotDeleted() { // arrange ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto desktopServiceMock = QSharedPointer(new DesktopServiceMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto messageBoxServiceMock = QSharedPointer(new MessageBoxServiceMock); auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); EXPECT_CALL(imageAnnotatorMock, loadImage(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); EXPECT_CALL(*messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &question) { return false; }); EXPECT_CALL(imageAnnotatorMock, hide()).Times(testing::Exactly(0)); SingleCaptureHandler captureHandler( &imageAnnotatorMock, notificationServiceMock, clipboardMock, desktopServiceMock, fileServiceMock, messageBoxServiceMock, recentImageServiceMock, nullptr, nullptr, nullptr, nullptr, nullptr); auto capture = CaptureFromFileDto(QPixmap(), QLatin1Literal("lala")); captureHandler.load(capture); // act captureHandler.removeImage(); // assert QCOMPARE(captureHandler.path(), capture.path); QCOMPARE(captureHandler.isSaved(), true); } void SingleCaptureHandlerTests::Load_Should_SetPathAndIsSavedToValuesFromCaptureDto_When_CaptureLoadedFromFile() { // arrange ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto desktopServiceMock = QSharedPointer(new DesktopServiceMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto messageBoxServiceMock = QSharedPointer(new MessageBoxServiceMock); auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); EXPECT_CALL(imageAnnotatorMock, loadImage(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); SingleCaptureHandler captureHandler( &imageAnnotatorMock, notificationServiceMock, clipboardMock, desktopServiceMock, fileServiceMock, messageBoxServiceMock, recentImageServiceMock, nullptr, nullptr, nullptr, nullptr, nullptr); auto capture = CaptureFromFileDto(QPixmap(), QLatin1Literal("lala")); // act captureHandler.load(capture); // assert QCOMPARE(captureHandler.path(), capture.path); QCOMPARE(captureHandler.isSaved(), true); } void SingleCaptureHandlerTests::Load_Should_SetPathToEmptyAndIsSavedToFalse_When_CaptureNotLoadedFromFile() { // arrange ImageAnnotatorMock imageAnnotatorMock; auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); auto clipboardMock = QSharedPointer(new ClipboardMock); auto desktopServiceMock = QSharedPointer(new DesktopServiceMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto messageBoxServiceMock = QSharedPointer(new MessageBoxServiceMock); auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); EXPECT_CALL(imageAnnotatorMock, loadImage(testing::_)); EXPECT_CALL(imageAnnotatorMock, setTabBarAutoHide(testing::_)); SingleCaptureHandler captureHandler( &imageAnnotatorMock, notificationServiceMock, clipboardMock, desktopServiceMock, fileServiceMock, messageBoxServiceMock, recentImageServiceMock, nullptr, nullptr, nullptr, nullptr, nullptr); auto capture = CaptureDto(QPixmap()); // act captureHandler.load(capture); // assert QCOMPARE(captureHandler.path(), QString()); QCOMPARE(captureHandler.isSaved(), false); } TEST_MAIN(SingleCaptureHandlerTests) ksnip-master/tests/gui/captureHandler/SingleCaptureHandlerTests.h000066400000000000000000000025071457262621600256400ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SINGLECAPTUREHANDLERTESTS_H #define KSNIP_SINGLECAPTUREHANDLERTESTS_H #include class SingleCaptureHandlerTests : public QObject { Q_OBJECT private slots: void RemoveImage_Should_CleanupAnnotationData_When_ImageDeleted(); void RemoveImage_Should_NotCleanupAnnotationData_When_ImageWasNotDeleted(); void Load_Should_SetPathAndIsSavedToValuesFromCaptureDto_When_CaptureLoadedFromFile(); void Load_Should_SetPathToEmptyAndIsSavedToFalse_When_CaptureNotLoadedFromFile(); }; #endif //KSNIP_SINGLECAPTUREHANDLERTESTS_H ksnip-master/tests/gui/operations/000077500000000000000000000000001457262621600176175ustar00rootroot00000000000000ksnip-master/tests/gui/operations/DeleteImageOperationTests.cpp000066400000000000000000000061501457262621600253760ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "DeleteImageOperationTests.h" #include "src/gui/operations/DeleteImageOperation.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/gui/messageBoxService/MessageBoxServiceMock.h" #include "tests/mocks/gui/fileService/FileServiceMock.h" void DeleteImageOperationTests::Execute_Should_ReturnFalse_When_MessageBoxResponseWasCancel() { // arrange auto path = QString("/la/la"); MessageBoxServiceMock messageBoxServiceMock; FileServiceMock fileServiceMock; EXPECT_CALL(messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &question) { return false; }); DeleteImageOperation operation(path, &fileServiceMock, &messageBoxServiceMock); EXPECT_CALL(fileServiceMock, remove(path)).Times(testing::Exactly(0)); // act auto result = operation.execute(); // assert QCOMPARE(result, false); } void DeleteImageOperationTests::Execute_Should_ReturnTrue_When_MessageBoxResponseWasTrue_And_FileServiceSaveSuccessfully() { // arrange auto path = QString("/la/la"); MessageBoxServiceMock messageBoxServiceMock; FileServiceMock fileServiceMock; EXPECT_CALL(messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &question) { return true; }); EXPECT_CALL(fileServiceMock, remove(path)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &path) { return true; }); DeleteImageOperation operation(path, &fileServiceMock, &messageBoxServiceMock); // act auto result = operation.execute(); // assert QCOMPARE(result, true); } void DeleteImageOperationTests::Execute_Should_ReturnFalse_When_MessageBoxResponseWasTrue_And_FileServiceSaveFailed() { // arrange auto path = QString("/la/la"); MessageBoxServiceMock messageBoxServiceMock; FileServiceMock fileServiceMock; EXPECT_CALL(messageBoxServiceMock, okCancel(testing::_, testing::_)) .WillRepeatedly([=](const QString &title, const QString &question) { return true; }); EXPECT_CALL(fileServiceMock, remove(path)) .Times(testing::Exactly(1)) .WillRepeatedly([=](const QString &path) { return false; }); DeleteImageOperation operation(path, &fileServiceMock, &messageBoxServiceMock); // act auto result = operation.execute(); // assert QCOMPARE(result, false); } TEST_MAIN(DeleteImageOperationTests) ksnip-master/tests/gui/operations/DeleteImageOperationTests.h000066400000000000000000000024131457262621600250410ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DELETEIMAGEOPERATIONTESTS_H #define KSNIP_DELETEIMAGEOPERATIONTESTS_H #include class DeleteImageOperationTests : public QObject { Q_OBJECT private slots: void Execute_Should_ReturnFalse_When_MessageBoxResponseWasCancel(); void Execute_Should_ReturnTrue_When_MessageBoxResponseWasTrue_And_FileServiceSaveSuccessfully(); void Execute_Should_ReturnFalse_When_MessageBoxResponseWasTrue_And_FileServiceSaveFailed(); }; #endif //KSNIP_DELETEIMAGEOPERATIONTESTS_H ksnip-master/tests/gui/operations/LoadImageFromFileOperationTests.cpp000066400000000000000000000075671457262621600265140ustar00rootroot00000000000000/* * Copyright (C) 2020 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "LoadImageFromFileOperationTests.h" #include "src/gui/operations/LoadImageFromFileOperation.h" #include "tests/utils/TestRunner.h" #include "tests/mocks/gui/NotificationServiceMock.h" #include "tests/mocks/gui/ImageProcessorMock.h" #include "tests/mocks/gui/fileService/FileServiceMock.h" #include "tests/mocks/backend/recentImages/RecentImageServiceMock.h" #include "tests/mocks/backend/config/ConfigMock.h" void LoadImageFromFileOperationTests::Execute_Should_ShowNotificationAndNotOpenImage_When_PathToImageCannotBeOpened() { // arrange auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); ImageProcessorMock imageProcessorMock; auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto configMock = QSharedPointer(new ConfigMock); EXPECT_CALL(*fileServiceMock, openPixmap(testing::_)) .WillRepeatedly([=](const QString &path) { return QPixmap(); }); EXPECT_CALL(imageProcessorMock, processImage(testing::_)).Times(testing::Exactly(0)); EXPECT_CALL(*recentImageServiceMock, storeImagePath(testing::_)).Times(testing::Exactly(0)); EXPECT_CALL(*notificationServiceMock, showWarning(testing::_, QString("Unable to open image from path /path/image.png"), testing::_)) .Times(testing::Exactly(1)); EXPECT_CALL(*configMock, trayIconNotificationsEnabled()) .Times(testing::Exactly(1)) .WillRepeatedly([=]() { return true; }); LoadImageFromFileOperation operation(QLatin1String("/path/image.png"), &imageProcessorMock, notificationServiceMock, recentImageServiceMock, fileServiceMock, configMock); // act auto result = operation.execute(); // assert QCOMPARE(result, false); } void LoadImageFromFileOperationTests::Execute_Should_OpenImageAndNotShowNotification_When_PathToImageCanBeOpened() { // arrange auto imagePath = QString("/path/image.png"); auto notificationServiceMock = QSharedPointer(new NotificationServiceMock); ImageProcessorMock imageProcessorMock; auto recentImageServiceMock = QSharedPointer(new RecentImageServiceMock); auto fileServiceMock = QSharedPointer(new FileServiceMock); auto configMock = QSharedPointer(new ConfigMock); EXPECT_CALL(*fileServiceMock, openPixmap(imagePath)) .WillRepeatedly([=](const QString &path) { return QPixmap(100, 100); }); EXPECT_CALL(imageProcessorMock, processImage(testing::_)).Times(testing::Exactly(1)); EXPECT_CALL(*recentImageServiceMock, storeImagePath(imagePath)).Times(testing::Exactly(1)); EXPECT_CALL(*notificationServiceMock, showWarning(testing::_, testing::_, testing::_)).Times(testing::Exactly(0)); EXPECT_CALL(*configMock, trayIconNotificationsEnabled()).Times(testing::Exactly(0)); LoadImageFromFileOperation operation(imagePath, &imageProcessorMock, notificationServiceMock, recentImageServiceMock, fileServiceMock, configMock); // act auto result = operation.execute(); // assert QCOMPARE(result, true); } TEST_MAIN(LoadImageFromFileOperationTests) ksnip-master/tests/gui/operations/LoadImageFromFileOperationTests.h000066400000000000000000000023071457262621600261440ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_LOADIMAGEFROMFILEOPERATIONTESTS_H #define KSNIP_LOADIMAGEFROMFILEOPERATIONTESTS_H #include class LoadImageFromFileOperationTests : public QObject { Q_OBJECT private slots: void Execute_Should_ShowNotificationAndNotOpenImage_When_PathToImageCannotBeOpened(); void Execute_Should_OpenImageAndNotShowNotification_When_PathToImageCanBeOpened(); }; #endif //KSNIP_LOADIMAGEFROMFILEOPERATIONTESTS_H ksnip-master/tests/mocks/000077500000000000000000000000001457262621600157645ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/000077500000000000000000000000001457262621600173535ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/config/000077500000000000000000000000001457262621600206205ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/config/ConfigMock.h000066400000000000000000000362671457262621600230260ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CONFIGMOCK_H #define KSNIP_CONFIGMOCK_H #include #include "src/backend/config/IConfig.h" #include "src/gui/actions/Action.h" #include "src/plugins/PluginInfo.h" class ConfigMock : public IConfig { public: MOCK_METHOD(bool, rememberPosition, (), (const, override)); MOCK_METHOD(void, setRememberPosition, (bool enabled), (override)); MOCK_METHOD(bool, promptSaveBeforeExit, (), (const, override)); MOCK_METHOD(void, setPromptSaveBeforeExit, (bool enabled), (override)); MOCK_METHOD(bool, autoCopyToClipboardNewCaptures, (), (const, override)); MOCK_METHOD(void, setAutoCopyToClipboardNewCaptures, (bool enabled), (override)); MOCK_METHOD(bool, autoSaveNewCaptures, (), (const, override)); MOCK_METHOD(void, setAutoSaveNewCaptures, (bool enabled), (override)); MOCK_METHOD(bool, autoHideDocks, (), (const, override)); MOCK_METHOD(void, setAutoHideDocks, (bool enabled), (override)); MOCK_METHOD(bool, autoResizeToContent, (), (const, override)); MOCK_METHOD(void, setAutoResizeToContent, (bool enabled), (override)); MOCK_METHOD(int, resizeToContentDelay, (), (const, override)); MOCK_METHOD(void, setResizeToContentDelay, (int ms), (override)); MOCK_METHOD(bool, overwriteFile, (), (const, override)); MOCK_METHOD(void, setOverwriteFile, (bool enabled), (override)); MOCK_METHOD(bool, useTabs, (), (const, override)); MOCK_METHOD(void, setUseTabs, (bool enabled), (override)); MOCK_METHOD(bool, autoHideTabs, (), (const, override)); MOCK_METHOD(void, setAutoHideTabs, (bool enabled), (override)); MOCK_METHOD(bool, captureOnStartup, (), (const, override)); MOCK_METHOD(void, setCaptureOnStartup, (bool enabled), (override)); MOCK_METHOD(QPoint, windowPosition, (), (const, override)); MOCK_METHOD(void, setWindowPosition, (const QPoint &position), (override)); MOCK_METHOD(CaptureModes, captureMode, (), (const, override)); MOCK_METHOD(void, setCaptureMode, (CaptureModes mode), (override)); MOCK_METHOD(QString, saveDirectory, (), (const, override)); MOCK_METHOD(void, setSaveDirectory, (const QString &path), (override)); MOCK_METHOD(QString, saveFilename, (), (const, override)); MOCK_METHOD(void, setSaveFilename, (const QString &filename), (override)); MOCK_METHOD(QString, saveFormat, (), (const, override)); MOCK_METHOD(void, setSaveFormat, (const QString &format), (override)); MOCK_METHOD(QString, applicationStyle, (), (const, override)); MOCK_METHOD(void, setApplicationStyle, (const QString &style), (override)); MOCK_METHOD(TrayIconDefaultActionMode, defaultTrayIconActionMode, (), (const, override)); MOCK_METHOD(void, setDefaultTrayIconActionMode, (TrayIconDefaultActionMode mode), (override)); MOCK_METHOD(CaptureModes, defaultTrayIconCaptureMode, (), (const, override)); MOCK_METHOD(void, setDefaultTrayIconCaptureMode, (CaptureModes mode), (override)); MOCK_METHOD(bool, useTrayIcon, (), (const, override)); MOCK_METHOD(void, setUseTrayIcon, (bool enabled), (override)); MOCK_METHOD(bool, minimizeToTray, (), (const, override)); MOCK_METHOD(void, setMinimizeToTray, (bool enabled), (override)); MOCK_METHOD(bool, closeToTray, (), (const, override)); MOCK_METHOD(void, setCloseToTray, (bool enabled), (override)); MOCK_METHOD(bool, trayIconNotificationsEnabled, (), (const, override)); MOCK_METHOD(void, setTrayIconNotificationsEnabled, (bool enabled), (override)); MOCK_METHOD(bool, platformSpecificNotificationServiceEnabled, (), (const, override)); MOCK_METHOD(void, setPlatformSpecificNotificationServiceEnabled, (bool enabled), (override)); MOCK_METHOD(bool, startMinimizedToTray, (), (const, override)); MOCK_METHOD(void, setStartMinimizedToTray, (bool enabled), (override)); MOCK_METHOD(bool, rememberLastSaveDirectory, (), (const, override)); MOCK_METHOD(void, setRememberLastSaveDirectory, (bool enabled), (override)); MOCK_METHOD(bool, useSingleInstance, (), (const, override)); MOCK_METHOD(void, setUseSingleInstance, (bool enabled), (override)); MOCK_METHOD(SaveQualityMode, saveQualityMode, (), (const, override)); MOCK_METHOD(void, setSaveQualityMode, (SaveQualityMode mode), (override)); MOCK_METHOD(int, saveQualityFactor, (), (const, override)); MOCK_METHOD(void, setSaveQualityFactor, (int factor), (override)); MOCK_METHOD(bool, isDebugEnabled, (), (const, override)); MOCK_METHOD(void, setIsDebugEnabled, (bool enabled), (override)); MOCK_METHOD(QString, tempDirectory, (), (const, override)); MOCK_METHOD(void, setTempDirectory, (const QString &path), (override)); // Annotator MOCK_METHOD(bool, rememberToolSelection, (), (const, override)); MOCK_METHOD(void, setRememberToolSelection, (bool enabled), (override)); MOCK_METHOD(bool, switchToSelectToolAfterDrawingItem, (), (const, override)); MOCK_METHOD(void, setSwitchToSelectToolAfterDrawingItem, (bool enabled), (override)); MOCK_METHOD(bool, selectItemAfterDrawing, (), (const, override)); MOCK_METHOD(void, setSelectItemAfterDrawing, (bool enabled), (override)); MOCK_METHOD(bool, numberToolSeedChangeUpdatesAllItems, (), (const, override)); MOCK_METHOD(void, setNumberToolSeedChangeUpdatesAllItems, (bool enabled), (override)); MOCK_METHOD(bool, smoothPathEnabled, (), (const, override)); MOCK_METHOD(void, setSmoothPathEnabled, (bool enabled), (override)); MOCK_METHOD(int, smoothFactor, (), (const, override)); MOCK_METHOD(void, setSmoothFactor, (int factor), (override)); MOCK_METHOD(bool, rotateWatermarkEnabled, (), (const, override)); MOCK_METHOD(void, setRotateWatermarkEnabled, (bool enabled), (override)); MOCK_METHOD(QStringList, stickerPaths, (), (const, override)); MOCK_METHOD(void, setStickerPaths, (const QStringList &paths), (override)); MOCK_METHOD(bool, useDefaultSticker, (), (const, override)); MOCK_METHOD(void, setUseDefaultSticker, (bool enabled), (override)); MOCK_METHOD(QColor, canvasColor, (), (const, override)); MOCK_METHOD(void, setCanvasColor, (const QColor &color), (override)); MOCK_METHOD(bool, isControlsWidgetVisible, (), (const, override)); MOCK_METHOD(void, setIsControlsWidgetVisible, (bool isVisible), (override)); // Image Grabber MOCK_METHOD(bool, isFreezeImageWhileSnippingEnabledReadOnly, (), (const, override)); MOCK_METHOD(bool, freezeImageWhileSnippingEnabled, (), (const, override)); MOCK_METHOD(void, setFreezeImageWhileSnippingEnabled, (bool enabled), (override)); MOCK_METHOD(bool, captureCursor, (), (const, override)); MOCK_METHOD(void, setCaptureCursor, (bool enabled), (override)); MOCK_METHOD(bool, snippingAreaRulersEnabled, (), (const, override)); MOCK_METHOD(void, setSnippingAreaRulersEnabled, (bool enabled), (override)); MOCK_METHOD(bool, snippingAreaPositionAndSizeInfoEnabled, (), (const, override)); MOCK_METHOD(void, setSnippingAreaPositionAndSizeInfoEnabled, (bool enabled), (override)); MOCK_METHOD(bool, showMainWindowAfterTakingScreenshotEnabled, (), (const, override)); MOCK_METHOD(void, setShowMainWindowAfterTakingScreenshotEnabled, (bool enabled), (override)); MOCK_METHOD(bool, isSnippingAreaMagnifyingGlassEnabledReadOnly, (), (const, override)); MOCK_METHOD(bool, snippingAreaMagnifyingGlassEnabled, (), (const, override)); MOCK_METHOD(void, setSnippingAreaMagnifyingGlassEnabled, (bool enabled), (override)); MOCK_METHOD(int, captureDelay, (), (const, override)); MOCK_METHOD(void, setCaptureDelay, (int delay), (override)); MOCK_METHOD(int, snippingCursorSize, (), (const, override)); MOCK_METHOD(void, setSnippingCursorSize, (int size), (override)); MOCK_METHOD(QColor, snippingCursorColor, (), (const, override)); MOCK_METHOD(void, setSnippingCursorColor, (const QColor &color), (override)); MOCK_METHOD(QColor, snippingAdornerColor, (), (const, override)); MOCK_METHOD(void, setSnippingAdornerColor, (const QColor &color), (override)); MOCK_METHOD(int, snippingAreaTransparency, (), (const, override)); MOCK_METHOD(void, setSnippingAreaTransparency, (int transparency), (override)); MOCK_METHOD(QRect, lastRectArea, (), (const, override)); MOCK_METHOD(void, setLastRectArea, (const QRect &rectArea), (override)); MOCK_METHOD(bool, isForceGenericWaylandEnabledReadOnly, (), (const, override)); MOCK_METHOD(bool, forceGenericWaylandEnabled, (), (const, override)); MOCK_METHOD(void, setForceGenericWaylandEnabled, (bool enabled), (override)); MOCK_METHOD(bool, isScaleGenericWaylandScreenshotEnabledReadOnly, (), (const, override)); MOCK_METHOD(bool, scaleGenericWaylandScreenshotsEnabled, (), (const, override)); MOCK_METHOD(void, setScaleGenericWaylandScreenshots, (bool enabled), (override)); MOCK_METHOD(bool, hideMainWindowDuringScreenshot, (), (const, override)); MOCK_METHOD(void, setHideMainWindowDuringScreenshot, (bool enabled), (override)); MOCK_METHOD(bool, allowResizingRectSelection, (), (const, override)); MOCK_METHOD(void, setAllowResizingRectSelection, (bool enabled), (override)); MOCK_METHOD(bool, showSnippingAreaInfoText, (), (const, override)); MOCK_METHOD(void, setShowSnippingAreaInfoText, (bool enabled), (override)); MOCK_METHOD(bool, snippingAreaOffsetEnable, (), (const, override)); MOCK_METHOD(void, setSnippingAreaOffsetEnable, (bool enabled), (override)); MOCK_METHOD(QPointF, snippingAreaOffset, (), (const, override)); MOCK_METHOD(void, setSnippingAreaOffset, (const QPointF &offset), (override)); MOCK_METHOD(int, implicitCaptureDelay, (), (const, override)); MOCK_METHOD(void, setImplicitCaptureDelay, (int delay), (override)); // Uploader MOCK_METHOD(bool, confirmBeforeUpload, (), (const, override)); MOCK_METHOD(void, setConfirmBeforeUpload, (bool enabled), (override)); MOCK_METHOD(UploaderType, uploaderType, (), (const, override)); MOCK_METHOD(void, setUploaderType, (UploaderType type), (override)); // Imgur Uploader MOCK_METHOD(QString, imgurUsername, (), (const, override)); MOCK_METHOD(void, setImgurUsername, (const QString &username), (override)); MOCK_METHOD(QByteArray, imgurClientId, (), (const, override)); MOCK_METHOD(void, setImgurClientId, (const QString &clientId), (override)); MOCK_METHOD(QByteArray, imgurClientSecret, (), (const, override)); MOCK_METHOD(void, setImgurClientSecret, (const QString &clientSecret), (override)); MOCK_METHOD(QByteArray, imgurAccessToken, (), (const, override)); MOCK_METHOD(void, setImgurAccessToken, (const QString &accessToken), (override)); MOCK_METHOD(QByteArray, imgurRefreshToken, (), (const, override)); MOCK_METHOD(void, setImgurRefreshToken, (const QString &refreshToken), (override)); MOCK_METHOD(bool, imgurForceAnonymous, (), (const, override)); MOCK_METHOD(void, setImgurForceAnonymous, (bool enabled), (override)); MOCK_METHOD(bool, imgurLinkDirectlyToImage, (), (const, override)); MOCK_METHOD(void, setImgurLinkDirectlyToImage, (bool enabled), (override)); MOCK_METHOD(bool, imgurAlwaysCopyToClipboard, (), (const, override)); MOCK_METHOD(void, setImgurAlwaysCopyToClipboard, (bool enabled), (override)); MOCK_METHOD(bool, imgurOpenLinkInBrowser, (), (const, override)); MOCK_METHOD(void, setImgurOpenLinkInBrowser, (bool enabled), (override)); MOCK_METHOD(QString, imgurUploadTitle, (), (const, override)); MOCK_METHOD(void, setImgurUploadTitle, (const QString &uploadTitle), (override)); MOCK_METHOD(QString, imgurUploadDescription, (), (const, override)); MOCK_METHOD(void, setImgurUploadDescription, (const QString &uploadDescription), (override)); MOCK_METHOD(QString, imgurBaseUrl, (), (const, override)); MOCK_METHOD(void, setImgurBaseUrl, (const QString &baseUrl), (override)); // Script Uploader MOCK_METHOD(QString, uploadScriptPath, (), (const, override)); MOCK_METHOD(void, setUploadScriptPath, (const QString &path), (override)); MOCK_METHOD(bool, uploadScriptCopyOutputToClipboard, (), (const, override)); MOCK_METHOD(void, setUploadScriptCopyOutputToClipboard, (bool enabled), (override)); MOCK_METHOD(QString, uploadScriptCopyOutputFilter, (), (const, override)); MOCK_METHOD(void, setUploadScriptCopyOutputFilter, (const QString ®ex), (override)); MOCK_METHOD(bool, uploadScriptStopOnStdErr, (), (const, override)); MOCK_METHOD(void, setUploadScriptStopOnStdErr, (bool enabled), (override)); // FTP Uploader MOCK_METHOD(bool, ftpUploadForceAnonymous, (), (const, override)); MOCK_METHOD(void, setFtpUploadForceAnonymous, (bool enabled), (override)); MOCK_METHOD(QString, ftpUploadUrl, (), (const, override)); MOCK_METHOD(void, setFtpUploadUrl, (const QString &path), (override)); MOCK_METHOD(QString, ftpUploadUsername, (), (const, override)); MOCK_METHOD(void, setFtpUploadUsername, (const QString &username), (override)); MOCK_METHOD(QString, ftpUploadPassword, (), (const, override)); MOCK_METHOD(void, setFtpUploadPassword, (const QString &password), (override)); // HotKeys MOCK_METHOD(bool, isGlobalHotKeysEnabledReadOnly, (), (const, override)); MOCK_METHOD(bool, globalHotKeysEnabled, (), (const, override)); MOCK_METHOD(void, setGlobalHotKeysEnabled, (bool enabled), (override)); MOCK_METHOD(QKeySequence, rectAreaHotKey, (), (const, override)); MOCK_METHOD(void, setRectAreaHotKey, (const QKeySequence &keySequence), (override)); MOCK_METHOD(QKeySequence, lastRectAreaHotKey, (), (const, override)); MOCK_METHOD(void, setLastRectAreaHotKey, (const QKeySequence &keySequence), (override)); MOCK_METHOD(QKeySequence, fullScreenHotKey, (), (const, override)); MOCK_METHOD(void, setFullScreenHotKey, (const QKeySequence &keySequence), (override)); MOCK_METHOD(QKeySequence, currentScreenHotKey, (), (const, override)); MOCK_METHOD(void, setCurrentScreenHotKey, (const QKeySequence &keySequence), (override)); MOCK_METHOD(QKeySequence, activeWindowHotKey, (), (const, override)); MOCK_METHOD(void, setActiveWindowHotKey, (const QKeySequence &keySequence), (override)); MOCK_METHOD(QKeySequence, windowUnderCursorHotKey, (), (const, override)); MOCK_METHOD(void, setWindowUnderCursorHotKey, (const QKeySequence &keySequence), (override)); MOCK_METHOD(QKeySequence, portalHotKey, (), (const, override)); MOCK_METHOD(void, setPortalHotKey, (const QKeySequence &keySequence), (override)); // Actions MOCK_METHOD(QList, actions, (), (override)); MOCK_METHOD(void, setActions, (const QList &actions), (override)); // Plugins MOCK_METHOD(QString, pluginPath, (), (const, override)); MOCK_METHOD(void, setPluginPath, (const QString &path), (override)); MOCK_METHOD(QList, pluginInfos, (), (override)); MOCK_METHOD(void, setPluginInfos, (const QList &pluginInfos), (override)); MOCK_METHOD(bool, customPluginSearchPathEnabled, (), (const, override)); MOCK_METHOD(void, setCustomPluginSearchPathEnabled, (bool enabled), (override)); }; #endif //KSNIP_CONFIGMOCK_H ksnip-master/tests/mocks/backend/imageGrabber/000077500000000000000000000000001457262621600217225ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/imageGrabber/ImageGrabberMock.h000066400000000000000000000024321457262621600252150ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEGRABBERMOCK_H #define KSNIP_IMAGEGRABBERMOCK_H #include #include "src/backend/imageGrabber/IImageGrabber.h" class ImageGrabberMock : public IImageGrabber { public: MOCK_METHOD(bool, isCaptureModeSupported, (CaptureModes captureMode), (const, override)); MOCK_METHOD(QList, supportedCaptureModes, (), (const, override)); MOCK_METHOD(void, grabImage, (CaptureModes captureMode, bool captureCursor, int delay), (override)); }; #endif //KSNIP_IMAGEGRABBERMOCK_H ksnip-master/tests/mocks/backend/recentImages/000077500000000000000000000000001457262621600217615ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/recentImages/ImagePathStorageMock.h000066400000000000000000000023131457262621600261270ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEPATHSTORAGEMOCK_H #define KSNIP_IMAGEPATHSTORAGEMOCK_H #include #include "src/backend/recentImages/IImagePathStorage.h" class ImagePathStorageMock : public IImagePathStorage { public: MOCK_METHOD(void, store, (const QString &value, int index), (override)); MOCK_METHOD(QString, load, (int index), (override)); MOCK_METHOD(int, count, (), (override)); }; #endif //KSNIP_IMAGEPATHSTORAGEMOCK_H ksnip-master/tests/mocks/backend/recentImages/RecentImageServiceMock.h000066400000000000000000000023001457262621600264430ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_RECENTIMAGESERVICEMOCK_H #define KSNIP_RECENTIMAGESERVICEMOCK_H #include #include "src/backend/recentImages/IRecentImageService.h" class RecentImageServiceMock : public IRecentImageService { public: MOCK_METHOD(void, storeImagePath, (const QString &imagePath), (override)); MOCK_METHOD(QStringList, getRecentImagesPath, (), (const, override)); }; #endif //KSNIP_RECENTIMAGESERVICEMOCK_H ksnip-master/tests/mocks/backend/saver/000077500000000000000000000000001457262621600204735ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/saver/ImageSaverMock.h000066400000000000000000000021071457262621600235010ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGESAVERMOCK_H #define KSNIP_IMAGESAVERMOCK_H #include #include "src/backend/saver/IImageSaver.h" class ImageSaverMock : public IImageSaver { public: MOCK_METHOD(bool, save, (const QImage &image, const QString &path), (override)); }; #endif //KSNIP_IMAGESAVERMOCK_H ksnip-master/tests/mocks/backend/saver/SavePathProviderMock.h000066400000000000000000000023451457262621600247100ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_SAVEPATHPROVIDERMOCK_H #define KSNIP_SAVEPATHPROVIDERMOCK_H #include #include "src/backend/saver/ISavePathProvider.h" class SavePathProviderMock : public ISavePathProvider { public: MOCK_METHOD(QString, savePath, (), (const, override)); MOCK_METHOD(QString, savePathWithFormat, (const QString& format), (const, override)); MOCK_METHOD(QString, saveDirectory, (), (const, override)); }; #endif //KSNIP_SAVEPATHPROVIDERMOCK_H ksnip-master/tests/mocks/backend/uploader/000077500000000000000000000000001457262621600211665ustar00rootroot00000000000000ksnip-master/tests/mocks/backend/uploader/UploadHandlerMock.h000066400000000000000000000022441457262621600246750ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_UPLOADHANDLERMOCK_H #define KSNIP_UPLOADHANDLERMOCK_H #include #include "src/backend/uploader/IUploadHandler.h" class UploadHandlerMock : public IUploadHandler { public: MOCK_METHOD(void, upload, (const QImage &image), (override)); MOCK_METHOD(UploaderType, type, (), (const, override)); MOCK_METHOD(void, finished, ()); }; #endif //KSNIP_UPLOADHANDLERMOCK_H ksnip-master/tests/mocks/common/000077500000000000000000000000001457262621600172545ustar00rootroot00000000000000ksnip-master/tests/mocks/common/loader/000077500000000000000000000000001457262621600205225ustar00rootroot00000000000000ksnip-master/tests/mocks/common/loader/IconLoaderMock.h000066400000000000000000000021711457262621600235250ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_ICONLOADERMOCK_H #define KSNIP_ICONLOADERMOCK_H #include #include "src/common/loader/IIconLoader.h" class IconLoaderMock : public IIconLoader { public: MOCK_METHOD(QIcon, load, (const QString& name), (override)); MOCK_METHOD(QIcon, loadForTheme, (const QString& name), (override)); }; #endif //KSNIP_ICONLOADERMOCK_H ksnip-master/tests/mocks/common/platform/000077500000000000000000000000001457262621600211005ustar00rootroot00000000000000ksnip-master/tests/mocks/common/platform/CommandRunnerMock.h000066400000000000000000000024151457262621600246350ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_COMMANDRUNNERMOCK_H #define KSNIP_COMMANDRUNNERMOCK_H #include #include "src/common/platform/ICommandRunner.h" class CommandRunnerMock : public ICommandRunner { public: MOCK_METHOD(QString, getEnvironmentVariable, (const QString& variable), (const, override)); MOCK_METHOD(bool, isEnvironmentVariableSet, (const QString& variable), (const, override)); MOCK_METHOD(QString, readFile, (const QString &path), (const, override)); }; #endif //KSNIP_COMMANDRUNNERMOCK_H ksnip-master/tests/mocks/gui/000077500000000000000000000000001457262621600165505ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/ImageProcessorMock.h000066400000000000000000000021161457262621600224550ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEPROCESSORMOCK_H #define KSNIP_IMAGEPROCESSORMOCK_H #include #include "src/gui/IImageProcessor.h" class ImageProcessorMock : public IImageProcessor { public: MOCK_METHOD(void, processImage, (const CaptureDto &capture), (override)); }; #endif //KSNIP_IMAGEPROCESSORMOCK_H ksnip-master/tests/mocks/gui/NotificationServiceMock.h000066400000000000000000000026071457262621600235070ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_NOTIFICATIONSERVICEMOCK_H #define KSNIP_NOTIFICATIONSERVICEMOCK_H #include #include "src/gui/INotificationService.h" class NotificationServiceMock : public INotificationService { public: MOCK_METHOD(void, showInfo, (const QString &title, const QString &message, const QString &contentUrl), (override)); MOCK_METHOD(void, showWarning, (const QString &title, const QString &message, const QString &contentUrl), (override)); MOCK_METHOD(void, showCritical, (const QString &title, const QString &message, const QString &contentUrl), (override)); }; #endif //KSNIP_NOTIFICATIONSERVICEMOCK_H ksnip-master/tests/mocks/gui/captureHandler/000077500000000000000000000000001457262621600215115ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/captureHandler/CaptureTabStateHandlerMock.h000066400000000000000000000036661457262621600270400ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CAPTURETABSTATEHANDLERMOCK_H #define KSNIP_CAPTURETABSTATEHANDLERMOCK_H #include #include "src/gui/captureHandler/ICaptureTabStateHandler.h" class CaptureTabStateHandlerMock : public ICaptureTabStateHandler { public: MOCK_METHOD(void, add, (int index, const QString &filename, const QString &path, bool isSaved), (override)); MOCK_METHOD(bool, isSaved, (int index), (override)); MOCK_METHOD(bool, isPathValid, (int index), (override)); MOCK_METHOD(QString, path, (int index), (override)); MOCK_METHOD(QString, filename, (int index), (override)); MOCK_METHOD(void, setSaveState, (int index, const SaveResultDto &saveResult), (override)); MOCK_METHOD(void, renameFile, (int index, const RenameResultDto &renameResult), (override)); MOCK_METHOD(int, count, (), (const, override)); MOCK_METHOD(int, currentTabIndex, (), (const, override)); MOCK_METHOD(void, tabMoved, (int fromIndex, int toIndex), (override)); MOCK_METHOD(void, currentTabChanged, (int index), (override)); MOCK_METHOD(void, tabRemoved, (int index), (override)); MOCK_METHOD(void, currentTabContentChanged, (), (override)); }; #endif //KSNIP_CAPTURETABSTATEHANDLERMOCK_H ksnip-master/tests/mocks/gui/clipboard/000077500000000000000000000000001457262621600205075ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/clipboard/ClipboardMock.h000066400000000000000000000024161457262621600233740ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_CLIPBOARDMOCK_H #define KSNIP_CLIPBOARDMOCK_H #include #include "src/gui/clipboard/IClipboard.h" class ClipboardMock : public IClipboard { public: MOCK_METHOD(QPixmap, pixmap, (), (const, override)); MOCK_METHOD(bool, isPixmap, (), (const, override)); MOCK_METHOD(void, setImage, (const QImage &image), (override)); MOCK_METHOD(void, setText, (const QString &text), (override)); MOCK_METHOD(QString, url, (), (const, override)); }; #endif //KSNIP_CLIPBOARDMOCK_H ksnip-master/tests/mocks/gui/desktopService/000077500000000000000000000000001457262621600215425ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/desktopService/DesktopServiceMock.h000066400000000000000000000022221457262621600254550ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_DESKTOPSERVICEMOCK_H #define KSNIP_DESKTOPSERVICEMOCK_H #include #include "src/gui/desktopService/IDesktopService.h" class DesktopServiceMock : public IDesktopService { public: MOCK_METHOD(void, openFile, (const QString &path), (override)); MOCK_METHOD(void, openUrl, (const QString &url), (override)); }; #endif //KSNIP_DESKTOPSERVICEMOCK_H ksnip-master/tests/mocks/gui/fileService/000077500000000000000000000000001457262621600210105ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/fileService/FileServiceMock.h000066400000000000000000000022021457262621600241670ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_FILESERVICEMOCK_H #define KSNIP_FILESERVICEMOCK_H #include #include "src/gui/fileService/IFileService.h" class FileServiceMock : public IFileService { public: MOCK_METHOD(bool, remove, (const QString &path), (override)); MOCK_METHOD(QPixmap, openPixmap, (const QString &path), (override)); }; #endif //KSNIP_FILESERVICEMOCK_H ksnip-master/tests/mocks/gui/imageAnnotator/000077500000000000000000000000001457262621600215205ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/imageAnnotator/ImageAnnotatorMock.h000066400000000000000000000061551457262621600254220ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_IMAGEANNOTATORMOCK_H #define KSNIP_IMAGEANNOTATORMOCK_H #include #include "src/gui/imageAnnotator/IImageAnnotator.h" class ImageAnnotatorMock : public IImageAnnotator { public: MOCK_METHOD(QImage, image, (), (const, override)); MOCK_METHOD(QImage, imageAt, (int index), (const, override)); MOCK_METHOD(QAction*, undoAction, (), (override)); MOCK_METHOD(QAction*, redoAction, (), (override)); MOCK_METHOD(QSize, sizeHint, (), (const, override)); MOCK_METHOD(void, showAnnotator, (), (override)); MOCK_METHOD(void, showCropper, (), (override)); MOCK_METHOD(void, showScaler, (), (override)); MOCK_METHOD(void, showCanvasModifier, (), (override)); MOCK_METHOD(void, showRotator, (), (override)); MOCK_METHOD(void, showCutter, (), (override)); MOCK_METHOD(void, setSettingsCollapsed, (bool isCollapsed), (override)); MOCK_METHOD(void, hide, (), (override)); MOCK_METHOD(void, close, (), (override)); MOCK_METHOD(bool, isVisible, (), (const, override)); MOCK_METHOD(QWidget*, widget, (), (const, override)); MOCK_METHOD(void, loadImage, (const QPixmap &pixmap), (override)); MOCK_METHOD(int, addTab, (const QPixmap &pixmap, const QString &title, const QString &toolTip), (override)); MOCK_METHOD(void, updateTabInfo, (int index, const QString &title, const QString &toolTip), (override)); MOCK_METHOD(void, insertImageItem, (const QPointF &position, const QPixmap &pixmap), (override)); MOCK_METHOD(void, setSmoothPathEnabled, (bool enabled), (override)); MOCK_METHOD(void, setSaveToolSelection, (bool enabled), (override)); MOCK_METHOD(void, setSmoothFactor, (int factor), (override)); MOCK_METHOD(void, setSwitchToSelectToolAfterDrawingItem, (bool enabled), (override)); MOCK_METHOD(void, setSelectItemAfterDrawing, (bool enabled), (override)); MOCK_METHOD(void, setNumberToolSeedChangeUpdatesAllItems, (bool enabled), (override)); MOCK_METHOD(void, setTabBarAutoHide, (bool enabled), (override)); MOCK_METHOD(void, removeTab, (int index), (override)); MOCK_METHOD(void, setStickers, (const QStringList &stickerPaths, bool keepDefault), (override)); MOCK_METHOD(void, addTabContextMenuActions, (const QList &actions), (override)); MOCK_METHOD(void, setCanvasColor, (const QColor &color), (override)); MOCK_METHOD(void, setControlsWidgetVisible, (bool isVisible), (override)); }; #endif //KSNIP_IMAGEANNOTATORMOCK_H ksnip-master/tests/mocks/gui/messageBoxService/000077500000000000000000000000001457262621600221665ustar00rootroot00000000000000ksnip-master/tests/mocks/gui/messageBoxService/MessageBoxServiceMock.h000066400000000000000000000026231457262621600265320ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KSNIP_MESSAGEBOXSERVICEMOCK_H #define KSNIP_MESSAGEBOXSERVICEMOCK_H #include #include "src/gui/messageBoxService/IMessageBoxService.h" class MessageBoxServiceMock : public IMessageBoxService { public: MOCK_METHOD(bool, yesNo, (const QString &title, const QString &question), (override)); MOCK_METHOD(MessageBoxResponse, yesNoCancel, (const QString &title, const QString &question), (override)); MOCK_METHOD(void, ok, (const QString &title, const QString &info), (override)); MOCK_METHOD(bool, okCancel, (const QString &title, const QString &info), (override)); }; #endif //KSNIP_MESSAGEBOXSERVICEMOCK_H ksnip-master/tests/utils/000077500000000000000000000000001457262621600160105ustar00rootroot00000000000000ksnip-master/tests/utils/TestRunner.h000066400000000000000000000066361457262621600203050ustar00rootroot00000000000000/* * Copyright (C) 2021 Damir Porobic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ /* * Example taken from https://rodolfotech.blogspot.com/2017/01/qtest-google-mock.html */ #ifndef KSNIP_TESTRUNNER_H #define KSNIP_TESTRUNNER_H #include class GoogleTestEventListener : public ::testing::EmptyTestEventListener { void OnTestStart(const ::testing::TestInfo&) override { } void OnTestPartResult(const ::testing::TestPartResult& test_part_result) override { if (test_part_result.failed()) { QFAIL( QString("mock objects failed with '%1' at %2:%3") .arg(QString(test_part_result.summary())) .arg(test_part_result.file_name()) .arg(test_part_result.line_number()) .toLatin1().constData() ); } } void OnTestEnd(const ::testing::TestInfo&) override { } }; #define INIT_GOOGLE_MOCKS(argc, argv) { \ ::testing::InitGoogleTest (&(argc), (argv)); \ ::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners(); \ delete listeners.Release(listeners.default_result_printer());\ listeners.Append(new GoogleTestEventListener); } /* * Taken from QTEST_MAIN macro and added additional INIT_GOOGLE_MOCKS in the calls. */ #if defined(QT_WIDGETS_LIB) #include #ifdef QT_KEYPAD_NAVIGATION # define QTEST_DISABLE_KEYPAD_NAVIGATION QApplication::setNavigationMode(Qt::NavigationModeNone); #else # define QTEST_DISABLE_KEYPAD_NAVIGATION #endif #define TEST_MAIN(TestObject) \ QT_BEGIN_NAMESPACE \ QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \ QT_END_NAMESPACE \ int main(int argc, char *argv[]) \ { \ INIT_GOOGLE_MOCKS (argc, argv); \ \ QApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ QTEST_DISABLE_KEYPAD_NAVIGATION \ QTEST_ADD_GPU_BLACKLIST_SUPPORT \ TestObject tc; \ QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } #elif defined(QT_GUI_LIB) #include #define TEST_MAIN(TestObject) \ QT_BEGIN_NAMESPACE \ QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \ QT_END_NAMESPACE \ int main(int argc, char *argv[]) \ { \ INIT_GOOGLE_MOCKS (argc, argv); \ \ QGuiApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ QTEST_ADD_GPU_BLACKLIST_SUPPORT \ TestObject tc; \ QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } #else #define TEST_MAIN(TestObject) \ int main(int argc, char *argv[]) \ { \ INIT_GOOGLE_MOCKS (argc, argv); \ \ QCoreApplication app(argc, argv); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ TestObject tc; \ QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } #endif // QT_GUI_LIB #endif //KSNIP_TESTRUNNER_H ksnip-master/translations/000077500000000000000000000000001457262621600162275ustar00rootroot00000000000000ksnip-master/translations/CMakeLists.txt000066400000000000000000000016441457262621600207740ustar00rootroot00000000000000find_package(Qt5LinguistTools) set(KSNIP_LANG_TS ksnip_ar.ts ksnip_bn_BD.ts ksnip_ca.ts ksnip_cs.ts ksnip_da.ts ksnip_de.ts ksnip_el.ts ksnip_es.ts ksnip_eu.ts ksnip_fa.ts ksnip_fi.ts ksnip_fr.ts ksnip_fr_CA.ts ksnip_gl.ts ksnip_he.ts ksnip_hr.ts ksnip_hu.ts ksnip_id.ts ksnip_it.ts ksnip_ja.ts ksnip_ko.ts ksnip_nl.ts ksnip_no.ts ksnip_pl.ts ksnip_pt.ts ksnip_pt_BR.ts ksnip_ro.ts ksnip_ru.ts ksnip_si.ts ksnip_sl.ts ksnip_sv.ts ksnip_tr.ts ksnip_uk.ts ksnip_zh_CN.ts ksnip_zh_Hant.ts) if (DEFINED UPDATE_TS_FILES) qt5_create_translation(KSNIP_LANG_QM ${CMAKE_SOURCE_DIR}/translations ${KSNIP_SRCS} ${KSNIP_LANG_TS} OPTIONS "-no-obsolete") else () qt5_add_translation(KSNIP_LANG_QM ${KSNIP_LANG_TS}) endif () add_custom_target(translations ALL DEPENDS ${KSNIP_LANG_QM}) install(FILES ${KSNIP_LANG_QM} DESTINATION ${KSNIP_LANG_INSTALL_DIR}) ksnip-master/translations/ksnip_ar.ts000066400000000000000000001700331457262621600204110ustar00rootroot00000000000000 AboutDialog About عن البرنامج About عن البرنامج Version الإصدار Author المؤل٠Close إغلاق Donate تبرع Contact توصال AboutTab License: الرخصة Screenshot and Annotation Tool لقطة الشاشة وأدوات التوضيح ActionSettingTab Name الاسم Shortcut اختصار Clear مسح Take Capture التقط صورة Include Cursor اشمل مؤشر Ø§Ù„ÙØ£Ø±Ø© Delay تأخير التقاط الشاشة s The small letter s stands for seconds. Capture Mode وضع التقاط الشاشة Show image in Pin Window ثبت الصورة الملتقطة ÙÙŠ Ù†Ø§ÙØ°Ø© Copy image to Clipboard انسخ الصورة Upload image Ø§Ø±ÙØ¹ الصورة Open image parent directory Ø§ÙØªØ­ مجلد الصورة Save image Ø§Ø­ÙØ¸ الصورة Hide Main Window اخÙÙŠ Ø§Ù„Ù†Ø§ÙØ°Ø© الرئيسية Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add أض٠Actions Settings إعدادات الإجراءات Action الإجراء AddWatermarkOperation Watermark Image Required العلامة المائية مطلوبة Please add a Watermark Image via Options > Settings > Annotator > Update الرجاء Ø£ÙØ§Ø¶Ø© صورة العلامة المائية عن طريق إختيارات > إعدادت > أداة التوضيع > تحديث AnnotationSettings Smooth Painter Paths مؤشر رسم سلس When enabled smooths out pen and marker paths after finished drawing. Smooth Factor عامل سلس Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. زيادة عامل السلاسة سينقص دقة القلم ولكن سيجعل خطوط الرسم سلسة Annotator Settings إعدادات علامات التوضيح Remember annotation tool selection and load on startup تذكر أداة التوضيح المختارة وحملها عند بدئ التشغيل Switch to Select Tool after drawing Item انتقل إلى أداة الاختيار بعد رسم العنصر Number Tool Seed change updates all Number Items تحديث جميع الأرقام ÙÙŠ أداة الترقيم Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. تعطيل هذا الاختيار يغير تحديث الترقيم تشمل العناصر الجديدة Ùقط. تعطيل هذا الاختيار يسمح بوجود ترقيم مكررز Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing اختر العنصر بعد الرسم With this option enabled the item gets selected after being created, allowing changing settings. ØªÙØ¹ÙŠÙ„ هذا الاختيار يقوم باختيار العنصر بعد انشاءه, للسماح بتغير اعداداته. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode التقط الشاشة عند بدئ التشغيل بالوضع Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ Application Style تصميم التطبيق Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings إعدادات البرنامج Automatically copy new captures to clipboard انسخ الصورة الملتقطة تلقائيا Use Tabs استخدم الألسنة Change requires restart. التغير يتطلب إعادة تشغيل البرنامج Ù„ØªÙØ¹ÙŠÙ„Ù‡. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup تذكر مكان الشاشة الرئيسية عند تحريكها وحملها عند بدئ التشغيل Auto hide Tabs اخ٠التبويب تلقائيا Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse AuthorTab Contributors: المساهمون: Spanish Translation الترجمة الأسبانية Dutch Translation الترجمة الهولندية Russian Translation الترجمة الروسية Norwegian BokmÃ¥l Translation الترجمة النرويجية French Translation الترجمة Ø§Ù„ÙØ±Ù†Ø³ÙŠØ© Polish Translation الترجمة البوليندية Snap & Flatpak Support دعم Snap Ùˆ Flatpak The Authors: المؤلÙ: CanDiscardOperation Warning - تحذير- The capture %1%2%3 has been modified. Do you want to save it? تم التعديل على الصورة الملتقطة %1%2%3 هل تريد Ø­ÙØ¸ التعديلات؟ CaptureModePicker New جديد Draw a rectangular area with your mouse ارسم مربع Ø¨Ø§Ù„ÙØ£Ø±Ø© Capture full screen including all monitors التقط صورة لكامل الشاشة ولجميع الشاشات Capture screen where the mouse is located التقط صورة للشاشة تحت مؤشر Ø§Ù„ÙØ£Ø±Ø© Capture window that currently has focus التقط صورة Ù„Ù„Ù†Ø§ÙØ°Ø© Ø§Ù„Ù…ÙØ¹Ù„Ø© Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard ÙØ´Ù„ ÙÙŠ نسخ الصورة الملتقطة Failed to copy to clipboard as base64 encoded image. ÙØ´Ù„ ÙÙŠ نسخة الصورة بترميز Base64. Copied to clipboard تم النسخ Copied to clipboard as base64 encoded image. تم نسخ الصورة كترميز Base64. DeleteImageOperation Delete Image امسح الصورة The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome التبرع مرحب بها دوما Donation تبرع ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Password FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear مسح Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Close إغلاق Time Stamp Link Delete Link ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Client Secret PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New جديد Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. Save Save Screen Capture to file system Copy Copy Screen Capture to clipboard Tools Undo Redo Crop Crop Screen Capture MainWindow Unsaved Upload Print Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Settings اﻹعدادات &About Open &Edit &Options &Help Add Watermark Add Watermark to captured image. Multiple watermarks can be added. &File Unable to show image Save As... Paste Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Save As Open Directory Copy Copy Path Delete Rename Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close إغلاق Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default The directory where the plugins are located. Browse Name الاسم Version الإصدار Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved Saving Image Failed Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Saver Settings Capture save location Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings الإعدادات OK Cancel Image Grabber Imgur Uploader Application Annotator HotKeys Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add أض٠Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version الإصدار Build Using: WatermarkSettings Watermark Image Update Rotate Watermark When enabled, Watermark will be added with a rotation of 45° Watermark Settings ksnip-master/translations/ksnip_bn_BD.ts000066400000000000000000001652021457262621600207550ustar00rootroot00000000000000 AboutDialog About সমà§à¦ªà¦°à§à¦•ে About সমà§à¦ªà¦°à§à¦•ে Version ভারà§à¦¸à¦¨ Author পà§à¦°à§‹à¦—à§à¦°à¦¾à¦®à¦¾à¦° Close বনà§à¦§ করà§à¦¨ Donate অনà§à¦¦à¦¾à¦¨ করà§à¦¨ Contact AboutTab License: লাইসেনà§à¦¸ Screenshot and Annotation Tool ActionSettingTab Name Shortcut Clear Take Capture Include Cursor Delay s The small letter s stands for seconds. Capture Mode Show image in Pin Window Copy image to Clipboard Upload image Open image parent directory Save image Hide Main Window Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Actions Settings Action AddWatermarkOperation Watermark Image Required ওয়াটারমারà§à¦• দেয়ার ছবি লাগবে Please add a Watermark Image via Options > Settings > Annotator > Update AnnotationSettings Smooth Painter Paths When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Application Style Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Automatically copy new captures to clipboard Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse AuthorTab Contributors: Spanish Translation Dutch Translation Russian Translation Norwegian BokmÃ¥l Translation French Translation Polish Translation Snap & Flatpak Support The Authors: CanDiscardOperation Warning - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Password FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Close বনà§à¦§ করà§à¦¨ Time Stamp Link Delete Link ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Client Secret PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. Save Save Screen Capture to file system Copy Copy Screen Capture to clipboard Tools Undo Redo Crop Crop Screen Capture MainWindow Unsaved Upload Print Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Settings &About Open &Edit &Options &Help Add Watermark Add Watermark to captured image. Multiple watermarks can be added. &File Unable to show image Save As... Paste Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Save As Open Directory Copy Copy Path Delete Rename Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close বনà§à¦§ করà§à¦¨ Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default The directory where the plugins are located. Browse Name Version ভারà§à¦¸à¦¨ Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved Saving Image Failed Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Saver Settings Capture save location Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings OK Cancel Image Grabber Imgur Uploader Application Annotator HotKeys Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version ভারà§à¦¸à¦¨ Build Using: WatermarkSettings Watermark Image Update Rotate Watermark When enabled, Watermark will be added with a rotation of 45° Watermark Settings ksnip-master/translations/ksnip_ca.ts000066400000000000000000001520201457262621600203660ustar00rootroot00000000000000 AboutDialog About Quant a About Quant a Version Versió Author Autor Close Tanca Donate Contact Contacte AboutTab License: Llicència: Screenshot and Annotation Tool Eina per a capturar la pantalla i fer-ne anotacions ActionSettingTab Name Nom Shortcut Drecera Clear Neteja Take Capture Fes la captura Include Cursor Delay s The small letter s stands for seconds. s Capture Mode Mode de captura Show image in Pin Window Copy image to Clipboard Copia la imatge al porta-retalls Upload image Puja la imatge Open image parent directory Save image Desa la imatge Hide Main Window Amaga la finestra principal ActionsSettings Add Afegeix Actions Settings Paràmetres de les accions Action Acció AddWatermarkOperation Watermark Image Required Please add a Watermark Image via Options > Settings > Annotator > Update AnnotationSettings Smooth Painter Paths When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Paràmetres de l’anotador Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. ApplicationSettings Capture screenshot at startup with default mode Application Style Estil de l’aplicació Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Paràmetres de l’aplicació Automatically copy new captures to clipboard Use Tabs Utilitza pestanyes Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Amaga automàticament les pestanyes Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Activa la depuració Enables debug output written to the console. Change requires ksnip restart to take effect. Resize to content delay Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. AuthorTab Contributors: Contribuïdors: Spanish Translation Traducció al castellà Dutch Translation Traducció al neerlandès Russian Translation Traducció al rus Norwegian BokmÃ¥l Translation French Translation Traducció al francès Polish Translation Traducció al polonès Snap & Flatpak Support Compatibilitat amb l’Snap i el Flatpak The Authors: CanDiscardOperation Warning - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Nou Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Comunitat Bug Reports Informes d’errors If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard No s’ha pogut copiar al porta-retalls Failed to copy to clipboard as base64 encoded image. Copied to clipboard S’ha copiat al porta-retalls Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image Suprimeix la imatge The item '%1' will be deleted. Do you want to continue? Se suprimirà l’element «%1». Voleu continuar? DonateTab Donations are always welcome Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Àrea rectangular Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url URL Username Nom d’usuari Password Contrasenya FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots ImgurHistoryDialog Imgur History Close Tanca Time Stamp Data i hora Link Enllaç Delete Link Suprimeix l’enllaç ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Id. del client Client Secret Secret del client PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Nom d’usuari Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: URL de base: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Neteja el testimoni LoadImageFromFileOperation Unable to open image No s’ha pogut obrir la imatge Unable to open image from path %1 MainToolBar New Nou Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. s Save Desa Save Screen Capture to file system Copy Copia Copy Screen Capture to clipboard Tools Eines Undo Desfés Redo Refés Crop Escapça Crop Screen Capture MainWindow Unsaved Sense desar Upload Puja Print Imprimeix Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Surt Settings Paràmetres &About &Quant a Open Obre &Edit &Edita &Options &Opcions &Help &Ajuda Add Watermark Afegeix una marca d’aigua Add Watermark to captured image. Multiple watermarks can be added. &File &Fitxer Unable to show image Save As... Anomena i desa… Paste Enganxa Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Copia el camí Open Directory &View &Visualitza Delete Suprimeix Rename Canvia el nom Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Gira Rotate Image Gira la imatge Actions Accions Image Files Fitxers d’imatge MultiCaptureHandler Save Desa Save As Anomena i desa Open Directory Copy Copia Copy Path Copia el camí Delete Suprimeix Rename Canvia el nom NewCaptureNameProvider Capture Captura PinWindow Close Tanca Close Other Tanca la resta Close All Tanca-ho tot PinWindowHandler Pin Window %1 RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved S’ha desat la imatge Saving Image Failed No s’ha pogut desar la imatge Image Files Fitxers d’imatge Saved to %1 S’ha desat a %1 Failed to save image to %1 No s’ha pogut desar la imatge a %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Navega Saver Settings Capture save location Default Per defecte Factor Factor Save Quality Qualitat de desament Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. ScriptUploaderSettings Copy script output to clipboard Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Navega Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: Filtre: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings Paràmetres OK D’acord Cancel Cancel·la Image Grabber Imgur Uploader Application Aplicació Annotator Anotador HotKeys Dreceres de teclat Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Marca d’aigua Actions Accions FTP Uploader SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. Confirm selection by pressing ENTER/RETURN or abort by pressing ESC. This message can be disabled via settings. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Fitxers d’imatge vectorial (*.svg) Add Afegeix Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Mostra l’editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP FTP VersionTab Version Versió Build Using: WatermarkSettings Watermark Image Update Actualitza Rotate Watermark Gira la marca d’aigua When enabled, Watermark will be added with a rotation of 45° Watermark Settings Paràmetres de la marca d’aigua ksnip-master/translations/ksnip_cs.ts000066400000000000000000002030631457262621600204140ustar00rootroot00000000000000 AboutDialog About O aplikaci About O aplikaci Version Verze Author Autor Close Zavřít Donate PodpoÅ™it vývoj darem Contact Kontakt AboutTab License: Licence: Screenshot and Annotation Tool Aplikace pro zachycení snímku obrazovky a tvorbu popisků ActionSettingTab Name Název Shortcut Zkratka Clear Vymazat Take Capture Zachytit Include Cursor VÄetnÄ› kurzoru Delay ZpoždÄ›ní s The small letter s stands for seconds. s Capture Mode Režim Zachycení Show image in Pin Window Zobraz obrázek v samostatném oknÄ› Copy image to Clipboard Zkopírovat obrázek do schránky Upload image Nahrát obrázek Open image parent directory Otevřít nadÅ™azený adresář obrázku Save image Uložit obrázek Hide Main Window Skryj hlavní okno Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add PÅ™idat Actions Settings Nastavení akcí Action Akce AddWatermarkOperation Watermark Image Required Je vyžadován obrázek vodoznaku Please add a Watermark Image via Options > Settings > Annotator > Update PÅ™idejte obrázek vodoznaku pÅ™es Možnosti> Nastavení> ZnaÄkovaÄ> Aktualizovat AnnotationSettings Smooth Painter Paths Vyhlazovat cesty kreslení When enabled smooths out pen and marker paths after finished drawing. Pokud je povoleno, vyhlazuje Äáry pera a cesty zvýrazňovaÄů po dokonÄení kreslení. Smooth Factor Síla vyhlazení Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Zvýšením síly vyhlazení se sníží pÅ™esnost pera a znaÄkovaÄe, ale bude je více vyhlazovat. Annotator Settings Nastavení znaÄkovaÄe Remember annotation tool selection and load on startup Zapamatovat výbÄ›r anotaÄního nástroje a nahrát jej pÅ™i startu Switch to Select Tool after drawing Item PÅ™epnout do Nástroje pro výbÄ›r po nakreslení položky Number Tool Seed change updates all Number Items ZmÄ›na nástroje pro Äíslování aktualizuje vÅ¡echny Äíselné položky Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Zakázání této možnosti způsobí, že zmÄ›ny nástroje pro Äíslování ovlivní pouze nové položky, ne vÅ¡ak ty existující. Zakázání této možniosti povolí duplicitní Äíslování. Canvas Color Barva plátna Default Canvas background color for annotation area. Changing color affects only new annotation areas. Výchozí barva pozadí plátna pro oblast poznámek. ZmÄ›na barvy ovlivní pouze nové oblasti anotací. Select Item after drawing Po kreslení vyber prvek With this option enabled the item gets selected after being created, allowing changing settings. S výbÄ›rem této volby získá prvek okamžité vybrání poté, co je vytvoÅ™en. A zpřístupní možnost editace prvku. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Zachytit snímek obrazovky pÅ™i spuÅ¡tÄ›ní ve výchozím režimu Application Style Styl aplikace Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Nastavuje styl aplikace, který definuje vzhled GUI. ZmÄ›na vyžaduje restartování aplikace. Application Settings Nastavení aplikace Automatically copy new captures to clipboard Automaticky kopírovat nové snímky do schránky Use Tabs Použít karty Change requires restart. ZmÄ›na vyžaduje restart. Run ksnip as single instance Spustit ksnip v jedné instanci Hide Tabbar when only one Tab is used. Skrýt panel karet, pokud je použita pouze jedna karta. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Povolení této možnosti umožní spuÅ¡tÄ›ní pouze jedné instance ksnip, vÅ¡echny ostatní instance spuÅ¡tÄ›né poté pÅ™edají svoje argumenty první instanci. ZmÄ›na této možnosti vyžaduje restart vÅ¡ech instancí. Remember Main Window position on move and load on startup Zapamatovat pozici hlavního okna a naÄíst ji pÅ™i startu aplikace Auto hide Tabs Automaticky skrývat karty Auto hide Docks Automaticky skrýt doky On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. PÅ™i spuÅ¡tÄ›ní skrýt panel nástrojů a Nastavení poznámek. Viditelnost doků lze pÅ™epínat pomocí klávesy Tabulátor. Auto resize to content Automaticky zmÄ›nit velikost podle obsahu Automatically resize Main Window to fit content image. Automaticky zmÄ›nit velikost hlavního okna podle velikosti obrázku. Enable Debugging Povolit ladÄ›ní aplikace Enables debug output written to the console. Change requires ksnip restart to take effect. Povolit režim ladÄ›ní do okna konzole. Pro zmÄ›nu je nutné restartovat ksnip. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Procházet AuthorTab Contributors: PÅ™ispÄ›vatelé: Spanish Translation Å panÄ›lský pÅ™eklad Dutch Translation Holandský pÅ™eklad Russian Translation Ruský pÅ™eklad Norwegian BokmÃ¥l Translation PÅ™eklad do norÅ¡tiny v bokmÃ¥lu French Translation Francouzský pÅ™eklad Polish Translation Polský pÅ™eklad Snap & Flatpak Support Podpora distribuce pomocí Snap & Flatpak The Authors: AutoÅ™i: CanDiscardOperation Warning - Varování - The capture %1%2%3 has been modified. Do you want to save it? Zachycení %1 %2 %3 bylo upraveno. Chcete zmÄ›ny uložit? CaptureModePicker New Nový Draw a rectangular area with your mouse Nakreslete obdélníkovou oblast pomocí myÅ¡i Capture a screenshot of the last selected rectangular area Zachytit snímek obrazovky poslední vybrané obdélníkové plochy Capture full screen including all monitors Zachytit celou obrazovku vÄetnÄ› vÅ¡ech monitorů Capture screen where the mouse is located ZachyÅ¥te obrazovku, kde se nachází myÅ¡ Capture window that currently has focus Zachytit okno, které je v tuto chvíli zaměřeno Capture that is currently under the mouse cursor Zachycení okna, které je aktuálnÄ› pod kurzorem myÅ¡i Uses the screenshot Portal for taking screenshot Používá Portál snímků obrazovky pro poÅ™izování snímků obrazovky ContactTab Community Komunita Bug Reports Nahlášení chyb If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Pokud máte obecné otázky, nápady nebo si jen chcete povídat o ksnip,<br/>prosím, pÅ™ipojte se na náš %1 nebo náš %2 server. Please use %1 to report bugs. Prosím použijte %1 pro nahlaÅ¡ování chyb. CopyAsDataUriOperation Failed to copy to clipboard Kopírování do schránky se nezdaÅ™ilo Failed to copy to clipboard as base64 encoded image. NezdaÅ™ilo se kopírování base64 kodováného obrázku do schránky. Copied to clipboard zkopírovat do schránky Copied to clipboard as base64 encoded image. Zkopírováno do schránky jako base64 kódovaný obrázek. DeleteImageOperation Delete Image Smazat obrázek The item '%1' will be deleted. Do you want to continue? Položka %1 bude odstranÄ›na. Chcete pokraÄovat? DonateTab Donations are always welcome Dary jsou vždy vítány Donation Sponzorský dar ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip je neziskový copyleft volný softwarový projekt a <br/> stále má nÄ›jaké výdaje, které je tÅ™eba pokrýt,<br/>jako domény nebo hardware pro podporu více platforem. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Pokud chcete pomoct nebo jen chcete ocenit práci, kterou dÄ›láme,<br/>tím, že zaplatíte vývojářům pivo nebo kávu, můžete tak uÄinit %1zde%2. Become a GitHub Sponsor? Stát se GitHub sponzorem? Also possible, %1here%2. Také možnost, %1zde%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Nové akce pÅ™idáte stisknutím tlaÄítka na kartÄ› "PÅ™idat". EnumTranslator Rectangular Area Obdélníková oblast Last Rectangular Area Poslední obdélníková oblast Full Screen (All Monitors) Celá obrazovka (vÅ¡echny monitory) Current Screen Aktuální obrazovka Active Window Aktivní okno Window Under Cursor Okno pod kurzorem Screenshot Portal Portál snímků obrazovky FtpUploaderSettings Force anonymous upload. Vynutit anonymní nahrání. Url Url Username Uživatelské jméno Password Heslo FTP Uploader Nahrání na FTP HandleUploadResultOperation Upload Successful Odeslání probÄ›hlo úspěšnÄ› Unable to save temporary image for upload. Nelze uložit doÄasný obrázek pro nahrání. Unable to start process, check path and permissions. Nelze spustit proces, zkontrolujte cestu a oprávnÄ›ní. Process crashed Proces selhal Process timed out. Proces vyprÅ¡el. Process read error. Chyba Ätení procesu. Process write error. Chyba zápisu procesu. Web error, check console output. Chyba webu, zkontrolujte výstup konzoly. Upload Failed Nahrání se nezdaÅ™ilo Script wrote to StdErr. Skript zapisoval do StdErr. FTP Upload finished successfully. Byl úspěšnÄ› dokonÄen FTP pÅ™enos. Unknown error. Neznámá chyba. Connection Error. Chyba pÅ™ipojení. Permission Error. Chyba v přístupových oprávnÄ›ní. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Povolit globální klávesové zkratky Capture Rect Area Zachytit oblast obdélníku Capture Last Rect Area Zachytit poslední oblast obdélníku Capture Full Screen Zachytit celou obrazovku Capture current Screen Zachytit aktuální obrazovku Capture active Window Zachytit aktivní okno Capture Window under Cursor Zachytit okno pod kurzorem Global HotKeys Globální klávesové zkratky Clear Vymazat Capture using Portal Zachycení pomocí portálu HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Zachytit kurzor myÅ¡i na snímku Should mouse cursor be visible on screenshots. Kurzor myÅ¡i bude viditelný na snímku obrazovky. Image Grabber Snímkování Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Generické implementace Wayland, které používají XDG-DESKTOP-PORTAL oÅ¡etÅ™ují měřítko obrazovky rozdílným způsobem. Povolení této možnosti bude urÄeno aktuální měřítko obrazovky a aplikováno na snímek obrazovky v ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME and KDE Plasma podporují pro Wayland a Generic XDG-DESKTOP-PORTAL jejich vlastní snímkování obrazovky. Zapnutí této možnosti pÅ™inutí KDE Plasma a GNOME použít XDG-DESKTOP-PORTAL snímkování obrazovky. ZmÄ›na tohoto nastavení se projeví po restartu ksnip. Show Main Window after capturing screenshot Zobrazit hlavní okno po pořízení snímku obrazovky Hide Main Window during screenshot Skrýt hlavní okno bÄ›hem snímku obrazovky Hide Main Window when capturing a new screenshot. Skrýt hlavní okno pÅ™i poÅ™izování nového snímku obrazovky. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Vynutit snímek pÅ™es Wayland Generic (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Historie Imgur Close Zavřít Time Stamp ÄŒasové razítko Link Odkaz Delete Link Odstranit odkaz ImgurUploader Upload to imgur.com finished! Nahrávání na imgur.com dokonÄeno! Received new token, trying upload again… Byl pÅ™ijat nový token, zkouším znovu odeslat … Imgur token has expired, requesting new token… Platnost tokenu imgur vyprÅ¡ela, žádání o nový token… ImgurUploaderSettings Force anonymous upload Vynutit anonymní odesílání After uploading open Imgur link in default browser Po odeslání otevřít odkaz Imgur ve výchozím prohlížeÄi Always copy Imgur link to clipboard Vždy kopírovat odkaz Imgur do schránky Client ID ID klienta Client Secret Heslo klienta PIN PIN Enter imgur Pin which will be exchanged for a token. Zadejte PIN Imgur, který bude vymÄ›nÄ›n za token. Get PIN Získat PIN Get Token Získat token Imgur History Historie Imgur Imgur Uploader Imgur služba Username Uživatelské jméno Waiting for imgur.com… ÄŒekání na imgur.com… Imgur.com token successfully updated. Token Imgur.com byl úspěšnÄ› aktualizován. Imgur.com token update error. Chyba aktualizace Imgur.com tokenu. Link directly to image Odkaz přímo na obrázek Base Url: Základní adresa URL: Base url that will be used for communication with Imgur. Changing requires restart. Základní adresa URL, která bude použita pro komunikaci s Imgurem. ZmÄ›na vyžaduje restart. Clear Token Vymazat token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Obrázek nelze otevřít Unable to open image from path %1 Nelze otevřít obrázek z místa %1 MainToolBar New Nový Delay in seconds between triggering and capturing screenshot. Prodleva v sekundách mezi spuÅ¡tÄ›ním a zachycením obrazovky. s The small letter s stands for seconds. s Save Uložit Save Screen Capture to file system Uložit výstÅ™ižek obrazovky do systému souborů Copy Kopírovat Copy Screen Capture to clipboard Kopírovat výstÅ™ižek obrazovky do schránky Undo ZpÄ›t Redo Znovu Crop Oříznutí Crop Screen Capture Oříznout snímek obrazovky Tools Nástroje MainWindow Unable to show image Obrázek nelze zobrazit Unsaved Neuloženo Upload Odeslat Print Tisk Opens printer dialog and provide option to print image OtevÅ™e dialog tiskárny a poskytne možnost pro tisk obrázku Print Preview Náhled tisku Opens Print Preview dialog where the image orientation can be changed OtevÅ™e dialog náhledu, kde lze zmÄ›nit orientaci obrázku Scale ZmÄ›nit velikost Add Watermark PÅ™idat vodoznak Add Watermark to captured image. Multiple watermarks can be added. PÅ™idat vodoznak do zachyceného obrázku. Lze pÅ™idat i více vodoznaků. Quit UkonÄit Settings Nastavení &About &O aplikaci Open Otevřít &File &Soubor &Edit &Upravit &Options &Možnosti &Help &Pomoc Save As... Uložit jako... Paste Vložit Paste Embedded Vložit do aktvní karty Pin PIN Pin screenshot to foreground in frameless window PÅ™ipnout snímek obrazovky k popÅ™edí v bezrámovém oknÄ› No image provided but one was expected. Nebyl poskytnut žádný obrázek, ale jeden se oÄekával. Copy Path Kopírovat cestu Open Directory Otevřít adresář &View &Pohled Delete Vymazat Rename PÅ™ejmenovat Open Images Otevřít obrázky Show Docks Zobrazit doky Hide Docks Skrýt doky Copy as data URI Kopírovat jako data URI Open &Recent Otevřít nedávné Modify Canvas Upravit plátno Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image ZmÄ›nit Velikost Rotate OtoÄit Rotate Image OtoÄit Obrázek Actions Akce Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Uložit Save As Uložit jako Open Directory Otevřít adresář Copy Kopírovat Copy Path Kopírovat cestu Delete Smazat Rename PÅ™ejmenovat Save All NewCaptureNameProvider Capture Zachytit OcrWindowCreator OCR Window %1 PinWindow Close Zavřít Close Other Zavřít ostatní Close All Zavřít vÅ¡e PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Výchozí The directory where the plugins are located. Browse Procházet Name Název Version Verze Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Obrázek byl pÅ™ejmenován Image Rename Failed PÅ™ejmenování obrázku se nezdaÅ™ilo Rename image PÅ™ejmenovat obrázek New filename: Nový název souboru: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As Uložit jako All Files VÅ¡echny soubory Image Saved Obrázek uložen Saving Image Failed Ukládání obrázku selhalo Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Automaticky ukládat nové snímky do výchozího umístÄ›ní Prompt to save before discarding unsaved changes Zobrazit výzvu k uložení pÅ™ed zahozením neuložených zmÄ›n Remember last Save Directory Zapamatovat si poslední adresář uložení When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Je-li povoleno, je pÅ™epsán adresář pro ukládání v Nastavení cestou posledního uloženého obrázku pro každé následující uložení. Capture save location and filename UmístÄ›ní a název souboru pro uložení zachycení Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Podporované formáty jsou JPG, PNG a BMP. Pokud není k dispozici žádný formát, použije se jako výchozí PNG. Název souboru může obsahovat následující zástupné znaky: - $Y, $M, $D pro datum, $h, $m, $s pro Äas nebo $T pro Äas ve formátu hhmmss. - Více po sobÄ› jdoucích # pro poÄítadlo. #### generuje první položku 0001, další snímek bude 0002. Browse Procházet Saver Settings Nastavení UkládaÄe Capture save location UmístÄ›ní pro uložení zachycení Default Výchozí Factor Faktor Save Quality Kvalita uložení Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Zadejte 0 pro získání malých komprimovaných souborů, 100 pro velké nekomprimované soubory. Ne vÅ¡echny formáty obrázků podporují celý rozsah, JPEG ano. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Kopírování výstupu skriptu do schránky Script: Skript: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Cesta ke skriptu, který bude použit pro nahrávání. BÄ›hem nahrávání bude skript volán s jedním argumentem a to cestou k doÄasnému souboru png. Browse Procházet Script Uploader Nahrávací skript Select Upload Script Vybrat nahrávací skript Stop when upload script writes to StdErr Zastavit, když nahrávací skript zapíše do StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. OznaÄí nahrávání jako neúspěšné, když skript zapíše do StdErr. Bez tohoto nastavení budou chyby ve skriptu ignorovány. Filter: Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. RegEx výraz. Zkopírujte do schránky pouze to, co odpovídá výrazu RegEx. Když je vynechán, zkopíruje se vÅ¡e. SettingsDialog Settings Nastavení OK OK Cancel ZruÅ¡it Application Aplikace Image Grabber Snímkování Imgur Uploader Imgur služba Annotator ZnaÄkovaÄ HotKeys Klávesové zkratky Uploader Nahrání Script Uploader Nahrávací skript Saver UkládaÄ Stickers Samolepky Snipping Area VýstÅ™ižková oblast Tray Icon Ikona v systémové oblasti Watermark Vodoznak Actions Akce FTP Uploader Nahrání na FTP Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Změňte velikost vybraného tvaru pomocí úchytů nebo jej pÅ™esuňte pÅ™etažením výbÄ›ru. Use arrow keys to move the selection. K pÅ™esunutí výbÄ›ru použijte klávesy se Å¡ipkami. Use arrow keys while pressing CTRL to move top left handle. Pomocí kláves se Å¡ipkami souÄasnÄ› se stisknutou klávesou CTRL pohybujte levým horním úchytem. Use arrow keys while pressing ALT to move bottom right handle. Pomocí kláves se Å¡ipkami souÄasnÄ› se stisknutou klávesou ALT posuňte pravý dolní úchyt. This message can be disabled via settings. Tuto zprávu lze deaktivovat pomocí nastavení. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Kliknutím a tažením vyberte obdélníkovou oblast nebo ji ukonÄete stisknutím klávesy ESC. Hold CTRL pressed to resize selection after selecting. Po výbÄ›ru podržte stisknutou klávesu CTRL a změňte tak velikost výbÄ›ru. Hold CTRL pressed to prevent resizing after selecting. Podržte stisknutou klávesu CTRL, abyste po výbÄ›ru zabránili zmÄ›nÄ› velikosti. Operation will be canceled after 60 sec when no selection made. Pokud nebude proveden žádný výbÄ›r, operace bude zruÅ¡ena po 60 sekundách. This message can be disabled via settings. Tuto zprávu lze deaktivovat pomocí nastavení. SnippingAreaSettings Freeze Image while snipping Zmrazení obrazu pÅ™i snímání When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Pokud je tato možnost povolena, zamrzne pozadí pÅ™i výbÄ›ru obdélníkové oblasti. MÄ›ní také chování zpoždÄ›ných snímků obrazovky, s touto možností povolenou se zpoždÄ›ní objeví pÅ™ed zobrazením oblasti a s vypnutou možností se zpoždÄ›ní provede až po zobrazení oblasti. Tato funkce nefunguje pro Wayland a je vždy používána pro MacO. Show magnifying glass on snipping area Zobrazit lupu v oblasti výstÅ™ižku Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Zobrazit lupu, která pÅ™iblíží obrázek na pozadí. Tato možnost funguje pouze se zapnutou funkcí 'Zmrazení obrazu pÅ™i snímání'. Show Snipping Area rulers Zobrazit pravítko oblasti výstÅ™ižku Horizontal and vertical lines going from desktop edges to cursor on snipping area. Vodorovné a svislé Äáry vedoucí z okraje plochy ke kurzoru snímané oblasti. Show Snipping Area position and size info Zobrazit informace o poloze a velikosti oblasti snímku When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Pokud není stisknuto levé tlaÄítko myÅ¡i, je zobrazena pozice, pÅ™i stisknutí tlaÄítka myÅ¡i je zobrazna velikost vybrané oblasti vlevo a nad zachycenou oblastí. Allow resizing rect area selection by default Ve výchozím nastavení povolit zmÄ›nu velikosti obdélníkové oblasti When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Je-li povoleno, po výbÄ›ru obdélníkové oblasti, je možno zmÄ›nit velikosti tohot výbÄ›ru. UkonÄení zmÄ›ny velikosti lze potvrdit klávesou return. Show Snipping Area info text Zobrazit text informací o oblasti výstÅ™ižku Snipping Area cursor color Barva kurzoru v oblasti výstÅ™ižku Sets the color of the snipping area cursor. Nastaví barvu kurzoru oblasti výstÅ™ižku. Snipping Area cursor thickness Tloušťka kurzoru v oblasti výstÅ™ižku Sets the thickness of the snipping area cursor. Nastaví tloušťku kurzoru oblasti výstÅ™ižku. Snipping Area VýstÅ™ižková oblast Snipping Area adorner color Barva doplňků VýstÅ™ižkové oblasti Sets the color of all adorner elements on the snipping area. Nastaví barvu vÅ¡ech doplňkových prvků v odstÅ™ižené oblasti. Snipping Area Transparency Průhlednost výstÅ™ižkové oblasti Alpha for not selected region on snipping area. Smaller number is more transparent. Průhlednost pro nevybranou oblast v oblasti výstÅ™ižku. Menší Äíslo je průhlednÄ›jší. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Nahoru Down Dolů Use Default Stickers Použití výchozích nálepek Sticker Settings Nastavení nálepky Vector Image Files (*.svg) Soubory vektorových obrázků (* .svg) Add PÅ™idat Remove Odstranit Add Stickers PÅ™idat samolepky TrayIcon Show Editor Zobrazit editor TrayIconSettings Use Tray Icon Použít ikonu v oznamovací oblasti When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Pokud je tato možnost povolena, pÅ™idá se ikona do oznamovací oblasti, pokud ji správce oken sytému podporuje. ZmÄ›na vyžaduje restart. Minimize to Tray Minimalizovat do oznamovací oblasti Start Minimized to Tray Spustit minimalizované do oznamovací oblasti Close to Tray Zavřít do oznamovací oblasti Show Editor Zobrazit editor Capture Zachytit Default Tray Icon action Výchozí akce pro ikonu v oznamovací oblasti Default Action that is triggered by left clicking the tray icon. Výchozí akce, která se spustí klepnutím levým tlaÄítkem myÅ¡i na ikonu v oznamovací oblasti. Tray Icon Settings Nastavení ikony v oznamovací oblasti Use platform specific notification service Používat službu oznámení dané platformy When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Pokud je možnost povolená, ksnip se pokusí používat službu oznámení dané platformy, pokud existuje. ZmÄ›na vyžaduje restart pro projevení. Display Tray Icon notifications UpdateWatermarkOperation Select Image Vybrat obrázek Image Files UploadOperation Upload Script Required Je vyžadován skript pro nahrávání Please add an upload script via Options > Settings > Upload Script PÅ™idejte prosím skript pro nahrávání pomocí Možnosti> Nastavení> Nahrát skript Capture Upload Zachytit nahraní You are about to upload the image to an external destination, do you want to proceed? Chystáte se nahrát obrázek do externího umístÄ›ní, chcete pokraÄovat? UploaderSettings Ask for confirmation before uploading PÅ™ed odesláním požádat o potvrzení Uploader Type: Typ uploaderu: Imgur Imgur Script Skript Uploader Nahrání FTP VersionTab Version Verze Build Sestavení Using: Používá: WatermarkSettings Watermark Image Obrázek vodoznaku Update Aktualizovat Rotate Watermark OtoÄit vodoznak When enabled, Watermark will be added with a rotation of 45° Pokud je povoleno, bude vodoznak pÅ™idán s rotací 45 ° Watermark Settings Nastavení vodoznaku ksnip-master/translations/ksnip_da.ts000066400000000000000000001734351457262621600204040ustar00rootroot00000000000000 AboutDialog About Om About Om Version Version Author Forfatter Donate Donér Close Luk Contact Kontakt AboutTab License: Licens: Screenshot and Annotation Tool Skærmbillede- og annoteringsværktøj ActionSettingTab Name Navn Shortcut Genvej Clear Ryd Take Capture Tag Skærmbillede Include Cursor Medtag Musmarkøren Delay Udsæt s The small letter s stands for seconds. s Capture Mode OptagelsesmÃ¥de Show image in Pin Window Vis Billede I Fastgjort Vindue Copy image to Clipboard Kopier Billede Til Udklipsholder Upload image Upload Billede Open image parent directory Ã…bn Billedes Overordnet Mappe Save image Gem Billede Hide Main Window Skjul Hovedvindue Global Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Tilføj Actions Settings Handlingsindstillinger Action Handling AddWatermarkOperation Watermark Image Required Vandmærke billede krævet Please add a Watermark Image via Options > Settings > Annotator > Update Vær sød at tilføje vandmærket billede via Valg > Indstillinger > Annotator > Opdateringer AnnotationSettings Smooth Painter Paths Jævn malede stier When enabled smooths out pen and marker paths after finished drawing. NÃ¥r aktiveret, og nÃ¥r tegning er færdig, jævner blyant og markørs linier ud. Smooth Factor Udjævningsfaktor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Forhøjelse af udjævningsfaktoren vil forringe blyants og markørs nøjagtighed, men vil ogsÃ¥ gør dem mere jævne. Annotator Settings Annotator Indstillinger Remember annotation tool selection and load on startup Husk annoteringsværktøjsvalg og indlæs det ved computer opstart Switch to Select Tool after drawing Item NÃ¥r du er færdig med at tegne et element, skift til Vælg Værktøj menu Number Tool Seed change updates all Number Items Med ændring af Tæller Værktøj, opdateres alle nummeriske elementer Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Deaktivering af dette her valg betyder at nummereringsværktøjet pÃ¥virker kun de nye elementer, og ikke de gamle. Deaktivering lader dig anvende dubletnumre. Canvas Color Kanvas Farve Default Canvas background color for annotation area. Changing color affects only new annotation areas. Standard kanvas baggrundsfarve for annoteringsomrÃ¥de. Farveændring pÃ¥virker kun de nye annoteringsomrÃ¥der. Select Item after drawing Valg element nÃ¥r tegning er færdig With this option enabled the item gets selected after being created, allowing changing settings. Med denne valgmulighed aktiveret, markeres elementet lige efter det er blevet tegnet, hvilket gør det muligt at ændre indstillingerne. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Tag skærmbillede i standard mÃ¥de ved computerens opstart Application Style Programmets Brugergrænseflade Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Indstiller programmets brugergrænseflade og pÃ¥ den mÃ¥de definerer den overordnede grafiske brugergrænseflade. For at fÃ¥ ændringerne til at træde i kraft, skal Ksnip genstartes. Application Settings Programindstillinger Automatically copy new captures to clipboard Kopier automatisk de nye skærmbilleder til udklipsholderen Use Tabs Brug faneblade Change requires restart. Ændring kræver genstart. Run ksnip as single instance Kør Ksnip som enkelt instans Hide Tabbar when only one Tab is used. Skjul fanebladslinjen nÃ¥r kun et faneblad bruges. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Aktivering af denne valgmulighed vil lade kun et Ksnip instans at køre, alle andre instanser der starter bagefter vil overføre deres argumenter til det første, og derefter lukke. Remember Main Window position on move and load on startup Husk hovedvinduets placering ved flyttning og indlæs den ved opstart Auto hide Tabs Skjul automatisk faneblade Auto hide Docks Skjul Docks/Faner Automatisk On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Ved opstart, skjul værktøjslinjen og annoteringsindstillingerne. Dockens synlighed kan slÃ¥s til og fra med Tab tasten Auto resize to content Tilpas automatisk til indholdet Automatically resize Main Window to fit content image. Skaler automatisk hovedvinduet og tilpas det til skærmbilledet. Enable Debugging Aktiver fejlsøgning Enables debug output written to the console. Change requires ksnip restart to take effect. Aktiverer fejlsøgnings udskrift i terminalen. Ændringen træder i kraft efter Ksnips genstart. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. ??? Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Gennemse AuthorTab Contributors: Bidragydere: Spanish Translation Spansk oversættelse Dutch Translation Hollandsk oversættelse Russian Translation Russisk oversættelse Norwegian BokmÃ¥l Translation Norsk bokmÃ¥l oversættelse French Translation Fransk oversættelse Polish Translation Polsk oversættelse Snap & Flatpak Support Snap & Flatpak support The Authors: Ophavsmænd: CanDiscardOperation Warning - Advarsel - The capture %1%2%3 has been modified. Do you want to save it? Skærmbilledet %1%2%3 er blevet ændret. Vil du gemme ændringerne? CaptureModePicker New Ny Draw a rectangular area with your mouse Tegn et rektangulært omrÃ¥de ved at bruge musen Capture a screenshot of the last selected rectangular area Tag et skærmbillede af den sidste markerede rektangulære omrÃ¥de Capture full screen including all monitors Tag billeder af hele skærme pÃ¥ alle skærme Capture screen where the mouse is located Tag billedet hvor musmarkøren ligger Capture window that currently has focus Tag billede af vindue som har fokus Capture that is currently under the mouse cursor Tag billede af vindue under musmarkøren Uses the screenshot Portal for taking screenshot Bruger skærmbilledsportal ContactTab Community Fællesskabet Bug Reports Fejlrapporter If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Har du nogle generelle spørgsmÃ¥l, ideer, eller hvis du vil bare snakke om Ksnip,<br/> være sød at slutte dig til vores %1 eller %2 server. Please use %1 to report bugs. Vær sød at bruge %1 til fejlrepportering. CopyAsDataUriOperation Failed to copy to clipboard Kopiering til udklipsholderen mislykkedes Failed to copy to clipboard as base64 encoded image. Kopiering til udklipsholderen som base64 indkodet billede mislykkedes. Copied to clipboard Kopieret til udklipsholderen Copied to clipboard as base64 encoded image. Kopieret til udklipsholderen som base64 indkodet billede. DeleteImageOperation Delete Image Slet billede The item '%1' will be deleted. Do you want to continue? Elementet %1 vil blive slettet. Vil du fortsætte? DonateTab Donations are always welcome Donationer er altid velkomne Donation Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. Ksnip er et ikke-kommercielt libre software projekt, men<br/>den har stadigvæk nogle omkostninger der skal dækkes<br/>ligesom domæne omkostninger eller hardware omkostninger for support pÃ¥ tværs af styresystemmer. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Hvis du vil hjælpe eller sætte pris pÃ¥ det arbejde de laver<br/>ved at give udviklerne et glas øl eller en kop kaffe, kan du gøre det %1here2%. Become a GitHub Sponsor? Bliv GitHub Sponsor? Also possible, %1here%2. OgsÃ¥ muligt, %1her%1. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Tilføj nye handlinger ved at trykke pÃ¥ 'Tilføj' fanebjælkeknappen. EnumTranslator Rectangular Area Firkantet OmrÃ¥de Last Rectangular Area Sidste Firkantet OmrÃ¥de Full Screen (All Monitors) Fuld Skærm (Alle Skærme) Current Screen Nuværende Skærm Active Window Aktivt Vindue Window Under Cursor Vindue Under Markør Screenshot Portal Skærmbilledsportal FtpUploaderSettings Force anonymous upload. Tving anonym overførsel Url URL-adresse Username Brugernavn Password Adgangskode FTP Uploader FTP overførselsværktoj HandleUploadResultOperation Upload Successful Overførsel Succesfuld Unable to save temporary image for upload. Ikke i stand til at gemme midlertidligt billede for overførsel. Unable to start process, check path and permissions. Ikke i stand til at starte processen, check sti og rettigheder. Process crashed Processen crashede Process timed out. Processen tidsudløbet. Process read error. Proces læsefejl. Process write error. Proces skrivefejl. Web error, check console output. Netværksfejl, check konsoleudskrift. Upload Failed Overførsel Mislykkedes Script wrote to StdErr. Script skrev til StdErr. FTP Upload finished successfully. FTP Overførsel færdig succesfuldt. Unknown error. Ukendt fejl. Connection Error. Forbindelsesfejl. Permission Error. Rettighedsfejl. Upload script %1 finished successfully. Overførsel af script %1 færdig succesfuldt. Uploaded to %1 Overført til %1 HotKeySettings Enable Global HotKeys Aktiver Globale Genvejstaster Capture Rect Area Tag Skærmbillede Af Firkantet OmrÃ¥de Capture Last Rect Area Tag Skærmbillede Af Den Sidste Firkantet OmrÃ¥de Capture Full Screen Tag Skærmbillede Af Komplet Skrivebord Capture current Screen Tag Skærmbillede Af Den Nuværende Skrivebord Capture active Window Tag skærmbillede af aktivt vindue Capture Window under Cursor Tag skærmbillede af vindue som er under markør Global HotKeys Globale genvejstaster Clear Ryd Capture using Portal Tag skærmbillede ved at bruge Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. PÃ¥ nuværende tidspunkt understøttes genvejstester kun af Windows og X11. Deaktivering af denne valgmulighed gør at handlingsgenveje er begrænset kun til Ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Tag musmarkør med i skærmbillede Should mouse cursor be visible on screenshots. Om musmarkør burde være synlig i skærmbillede. Image Grabber Billedgriber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Vis hovedvindue efter have taget skærmbillede Hide Main Window during screenshot Skjul hovedvindue mens skærmbillede tages Hide Main Window when capturing a new screenshot. Skjul hovedvindue mens nyt skærmbillede tages. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Vis hovedvindue efter have taget nyt skærmbillede nÃ¥r hovedvindue var skjult eller minimeret. Force Generic Wayland (xdg-desktop-portal) Screenshot Tving generisk Wayland (xdg-skrivebord-portal) skærmbillede Scale Generic Wayland (xdg-desktop-portal) Screenshots Skaler generisk Wayland (xdg.desktop.portal) skærmbilleder Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Imgur historie Close Luk Time Stamp Tidsstempel Link Link Delete Link Slet link ImgurUploader Upload to imgur.com finished! Overførsel til imgur.com færdig! Received new token, trying upload again… Nyt token modtaget, prøver at overføre pÃ¥ ny… Imgur token has expired, requesting new token… Imgur token udløbet, anmoder om nyt token… ImgurUploaderSettings Force anonymous upload Tving anonym overførsel After uploading open Imgur link in default browser Efter færdig overførsel Ã¥bn Imgur i standardbrowser Link directly to image Link direkt til billede Always copy Imgur link to clipboard Altid kopier Imgur link til udklipsholder Client ID Klient ID Client Secret Hemmelig klient PIN PIN Enter imgur Pin which will be exchanged for a token. Skriv Imgur PIN som vil blive vekslet til et token. Get PIN FÃ¥ PIN Get Token FÃ¥ token Imgur History Imgur historie Imgur Uploader Imgur overførselsværktøj Username Brugernavn Waiting for imgur.com… Venter pÃ¥ imgur.com… Imgur.com token successfully updated. Imgur.com token opdateret succesfuldt. Imgur.com token update error. Imgur.com token opdateringsfejl. Base Url: Basis-Url: Base url that will be used for communication with Imgur. Changing requires restart. Basis-Url der vil blive brugt for kommunikation med Imgur. Ændring kræver genstart. Clear Token Ryd token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Ikke i stand til at Ã¥bne billede Unable to open image from path %1 Ikke i stand til at Ã¥bne billede fra sti %1 MainToolBar New Ny Delay in seconds between triggering and capturing screenshot. Udsættelsen i sekunder mellem udløsning og tagning af skærmbillede. s The small letter s stands for seconds. s Save Gem Save Screen Capture to file system Gem skærmbillede til filsystem Copy Kopier Copy Screen Capture to clipboard Kopier skærmbillede til udklipsholderen Undo Fortryd Redo Annuler fortryd Crop Beskær Crop Screen Capture Beskær skærmbillede Tools Værktøjer MainWindow Unable to show image Ikke i stand til at vise billede Unsaved Ikke gemt Upload Overfør Print Udskriv Opens printer dialog and provide option to print image Ã…bner printers dialog og angiver valgmulighed til at udskrive billede Print Preview ForhÃ¥ndsvisning af udskrift Opens Print Preview dialog where the image orientation can be changed Ã…bner forhÃ¥ndsvisning af udskrift dialog hvor billedorientering kan ændres Scale Skaler Add Watermark T Add Watermark to captured image. Multiple watermarks can be added. Tilføj vandmærke til taget skærmbillede. Flere vandmærker kan tilføjes. Quit Afslut Settings Indstillinger &About &Om Open Ã…bn &File &Fil &Edit &Rediger &Options &Valgmuligheder &Help &Hjælp Save As... Gem som... Paste Indsæt Paste Embedded Indsæt indlejret Pin Fastgør Pin screenshot to foreground in frameless window Fastgør skærmbillede til forgrund i rammeløst vindue No image provided but one was expected. Ingen tilgængelige billeder, men et er forventet Copy Path Kopier sti Open Directory Ã…bn mappe &View &Visning Delete Slet Rename Omdøb Open Images Ã…bn billeder Show Docks Vis docks Hide Docks Skjul docks Copy as data URI Kopier som data URI Open &Recent Ã…bn &Senest Modify Canvas Modificer kanvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Skaler billede Rotate Roter Rotate Image Roter billede Actions Handlinger Image Files Billedfiler Save All Close Window Cut OCR MultiCaptureHandler Save Gem Save As Gem som Open Directory Ã…bn mappe Copy Kopier Copy Path Kopier sti Delete Slet Rename Omdøb Save All NewCaptureNameProvider Capture Indfang OcrWindowCreator OCR Window %1 PinWindow Close Luk Close Other Luk andre Close All Luk alle PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Standard The directory where the plugins are located. Browse Gennemse Name Navn Version Version Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Billede omdøbt Image Rename Failed Billedomdøbning mislykkedes Rename image Omdøb billede New filename: Nyt filnavn: Successfully renamed image to %1 Succesfuldt omdøbt billede til %1 Failed to rename image to %1 Omdøbning af billede %1 mislykkedes SaveOperation Save As Gem som All Files Alle filer Image Saved Billede gemt Saving Image Failed Fejl: Kunne ikke gemme billede Image Files Billedfiler Saved to %1 Gemt til %1 Failed to save image to %1 Fejl: Kunne ikke gemme billede til %1 SaverSettings Automatically save new captures to default location Gem automatisk nye skærmbilleder til standardplacering Prompt to save before discarding unsaved changes Remember last Save Directory Husk den seneste gemmemappe When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Gemmested og filnavn Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Gennemse Saver Settings Gemmeindstillinger Capture save location Gemmeplacering Default Standard Factor Faktor Save Quality Gemmekvalitet Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Kopier scriptuddata til udklipsholder Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Gennemse Script Uploader Scriptoverførselsværktøj Select Upload Script Valg overførselsscript Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings Indstillinger OK OK Cancel Fortryd Application Program Image Grabber Billedgriberen Imgur Uploader Imgur overførselsværktøj Annotator Annotator HotKeys Genvejstaster Uploader Overfører Script Uploader Scriptoverførselsværktøj Saver ??? Stickers Klistemærker Snipping Area AfklipningsomrÃ¥de Tray Icon Statusfeltikon Watermark Vandmærke Actions Handlinger FTP Uploader FTP Overførselsværktøj Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Denne meddelelse kan deaktiveres i indstillingerne. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Tryk og hold CTRL nede for at undgÃ¥ størrelsesændring efter markering. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. Denne meddelelse kan deaktiveres i indstillingerne. SnippingAreaSettings Freeze Image while snipping Frys billede under afklipning When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default Som standardindstilling tillad størrelsesændring af firkantet omrÃ¥de When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area AfklipningsomrÃ¥de Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency AfklipningsomrÃ¥des gennemsigtighed Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Op Down Ned Use Default Stickers Brug standardklistemærker Sticker Settings Klistemærkeindstillinger Vector Image Files (*.svg) Vektorbilledfiler (*.svg) Add Tilføj Remove Fjern Add Stickers Tilføj klistemærker TrayIcon Show Editor Vis redigeringsprogram TrayIconSettings Use Tray Icon Brug statusfeltikon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Minimer til statusfelt Start Minimized to Tray Start minimeret i statusfeltet Close to Tray Luk til statusfeltet Show Editor Vis redigeringsprogram Capture Indfang Default Tray Icon action Standard statusfeltsikonhandling Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Statusfeltikon indstillinger Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications Vis statusfeltikonsnotifikationer UpdateWatermarkOperation Select Image Valg billede Image Files Billedfiler UploadOperation Upload Script Required Overførselsscript pÃ¥krævet Please add an upload script via Options > Settings > Upload Script Capture Upload Billedoverførsel You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Overførselstype: Imgur Imgur Script Script Uploader Uploaderen FTP FTP VersionTab Version Version Build Version Using: Bruger: WatermarkSettings Watermark Image Vandmærkebillede Update Opdater Rotate Watermark Roter vandmærke When enabled, Watermark will be added with a rotation of 45° Watermark Settings Vandmærkeindstillinger ksnip-master/translations/ksnip_de.ts000066400000000000000000002053711457262621600204030ustar00rootroot00000000000000 AboutDialog About Über About Über Version Version Author Autor Close Schließen Donate Spenden Contact Kontakt AboutTab License: Lizenz: Screenshot and Annotation Tool Werkzeug für Screenshots und Anmerkungen ActionSettingTab Name Name Shortcut Verknüpfung Clear Leeren Take Capture Aufnehmen Include Cursor Cursor einschließen Delay Verzögerung s The small letter s stands for seconds. s Capture Mode Aufnahmemodus Show image in Pin Window Bild im angehefteten Fenster zeigen Copy image to Clipboard Bild in die Zwischenablage kopieren Upload image Bild hochladen Open image parent directory Übergeordnetes Bildverzeichnis öffnen Save image Bild speichern Hide Main Window Hauptfenster verstecken Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Hinzufügen Actions Settings Aktionen-Einstellungen Action Aktion AddWatermarkOperation Watermark Image Required Bild für Wasserzeichen erforderlich Please add a Watermark Image via Options > Settings > Annotator > Update Bitte fügen Sie ein Bild für das Wasserzeichen via Optionen > Einstellungen > Annotator > Aktualisieren hinzu AnnotationSettings Smooth Painter Paths Malpfade glätten When enabled smooths out pen and marker paths after finished drawing. Wenn aktiviert, werden Stift und Markerpfade nach dem fertigen Zeichnen geglättet. Smooth Factor Glättungsfaktor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Das Erhöhen des Glättungsfaktors wird die Präzision für Stift und Marker verringern, aber macht sie glatter. Annotator Settings Beschriftungs-Einstellungen Remember annotation tool selection and load on startup Merke Auswahl des Beschriftungstools und stelle diese beim Starten wieder her Switch to Select Tool after drawing Item Nach dem Zeichnen des Elements zum Auswahlwerkzeug wechseln Number Tool Seed change updates all Number Items Eine Änderung des Seeds aktualisiert alle Zahlenwerte Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Das Deaktivieren dieser Option bewirkt, dass Änderungen des Nummernwerkzeugs sich nur auf neue Elemente auswirken, nicht aber auf vorhandene. Die Deaktivierung dieser Option ermöglicht das Vorhandensein von doppelten Nummern. Canvas Color Leinwandfarbe Default Canvas background color for annotation area. Changing color affects only new annotation areas. Standard-Leinwandhintergrundfarbe für den Anmerkungsbereich. Die Änderung der Farbe wirkt sich nur auf neue Anmerkungsbereiche aus. Select Item after drawing Objekt nach dem Zeichnen auswählen With this option enabled the item gets selected after being created, allowing changing settings. Mit dieser Option wird das Objekt nach dem Erstellen ausgewählt, was eine Änderung der Einstellungen erlaubt. Show Controls Widget Steuerelemente-Widget anzeigen The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Beim Starten Screenshot im Standardmodus aufnehmen Application Style Anwendungsstil Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Setzt den Anwendungsstil, welcher das Aussehen der GUI definiert. Eine Änderung benötigt einen Neustart von ksnip, um wirksam zu werden. Application Settings Anwendungseinstellungen Automatically copy new captures to clipboard Neue Aufnahmen automatisch in die Zwischenablage kopieren Use Tabs Registerkarten verwenden Change requires restart. Änderung erfordert Neustart. Run ksnip as single instance Nur eine Instanz von ksnip starten Hide Tabbar when only one Tab is used. Registerkartenleiste verstecken, wenn nur eine Registerkarte offen ist. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Mit dieser Option wird das Ausführen von nur einer ksnip-Instanz erlaubt, alle weiteren Instanzen werden ihre Argumente an die zuerst gestartete Instanz übergeben und sich wieder schließen. Eine Änderung dieser Einstellung erfordert einen Neustart aller Instanzen. Remember Main Window position on move and load on startup Position des Hauptfensters beim Verschieben merken und beim Starten wiederherstellen Auto hide Tabs Tabs automatisch verstecken Auto hide Docks Docks automatisch verstecken On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Beim Start Toolbar- und Anmerkungs-Einstellungen verstecken. Die Sichtbarkeit der Docks kann mit der Tabulatortaste umgeschaltet werden. Auto resize to content Größe automatisch an Inhalt anpassen Automatically resize Main Window to fit content image. Hauptfenster automatisch der Bildgröße anpassen. Enable Debugging Debugging aktivieren Enables debug output written to the console. Change requires ksnip restart to take effect. Aktiviert das Schreiben von Debug-Ausgaben in die Konsole. Eine Änderung erfordert den Neustart von ksnip. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Das Anpassen an den Inhalt wird verzögert, um dem Fenstermanager das Empfangen des neuen Inhaltes zu erlauben. Falls die Hauptfenster für den neuen Inhalt nicht korrekt ausgerichtet sind, kann eine Erhöhung dieser Verzögerung jenes Verhalten verbessern. Resize delay Temp Directory Temp-Verzeichnis Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Temp-Verzeichnis, in dem Bilder temporär gespeichert werden, die nach dem Beenden von ksnip gelöscht werden. Browse Durchsuchen AuthorTab Contributors: Mitwirkende: Spanish Translation Spanische Übersetzung Dutch Translation Niederländische Übersetzung Russian Translation Russische Übersetzung Norwegian BokmÃ¥l Translation Norwegische Übersetzung French Translation Französische Übersetzung Polish Translation Polnische Übersetzung Snap & Flatpak Support Snap- und Flatpak-Support The Authors: Die Autoren: CanDiscardOperation Warning - Warnung - The capture %1%2%3 has been modified. Do you want to save it? Die Bildschirmaufnahme %1%2%3 wurde verändert. Speichern? CaptureModePicker New Neu Draw a rectangular area with your mouse Zeichnen Sie einen rechteckigen Bereich mit der Maus Capture full screen including all monitors Vollbild-Aufnahme aller Monitore Capture screen where the mouse is located Aufnahme des Bildschirms, auf dem sich derzeit die Maus befindet Capture window that currently has focus Aufnahme des fokussierten Fensters Capture that is currently under the mouse cursor Aufnahme des Fensters unter der Maus Capture a screenshot of the last selected rectangular area Einen Screenshot des zuletzt ausgewählten rechteckigen Bereichs aufnehmen Uses the screenshot Portal for taking screenshot Verwendet das Screenshot-Portal, um Screenshots zu erstellen ContactTab Community Gemeinschaft Bug Reports Fehlermeldungen If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Wenn Sie allgemeine Fragen, Ideen haben oder einfach nur über ksnip sprechen möchten,<br/>Bitte treten Sie unserem %1 oder unserem %2 Server bei. Please use %1 to report bugs. Bitte verwenden Sie %1, um Fehler zu melden. CopyAsDataUriOperation Failed to copy to clipboard Kopieren in die Zwischenablage fehlgeschlagen Failed to copy to clipboard as base64 encoded image. Kopieren des Base64-kodierten Bildes in die Zwischenablage fehlgeschlagen. Copied to clipboard In Zwischenablage kopiert Copied to clipboard as base64 encoded image. Als Base64-kodiertes Bild in die Zwischenablage kopiert. DeleteImageOperation Delete Image Bild löschen The item '%1' will be deleted. Do you want to continue? Das Objekt '%1' wird gelöscht. Möchten Sie fortfahren? DonateTab Donations are always welcome Spenden sind immer willkommen Donation Spende ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip ist ein nicht-gewinnbringendes Copyleft-freie-Software-Projekt und<br/>hat immer noch einige Kosten, die gedeckt werden müssen,<br/>wie Domain-Kosten oder Hardware-Kosten für plattformübergreifende Unterstützung. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Wenn Sie helfen oder einfach nur die Arbeit der Entwickler<br/>bei einem Bier oder Kaffee würdigen wollen, können Sie das %1hier%2 tun. Become a GitHub Sponsor? Werden Sie ein GitHub-Sponsor? Also possible, %1here%2. Auch möglich, %1hier%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Fügen Sie neue Aktionen durch Klicken des „Hinzufügen“-Buttons hinzu. EnumTranslator Rectangular Area Rechteckiger Bereich Last Rectangular Area Letzter rechteckiger Bereich Full Screen (All Monitors) Vollbild (alle Monitore) Current Screen Aktueller Bildschirm Active Window Aktives Fenster Window Under Cursor Fenster unter der Maus Screenshot Portal Portal aufnehmen FtpUploaderSettings Force anonymous upload. Anonymen Upload erzwingen. Url URL Username Benutzername Password Passwort FTP Uploader FTP-Uploader HandleUploadResultOperation Upload Successful Erfolgreich hochgeladen Unable to save temporary image for upload. Temporäres Speichern des Bildes zum Upload nicht möglich. Unable to start process, check path and permissions. Starten des Prozesses nicht möglich, prüfen Sie Pfad und Berechtigungen. Process crashed Prozess abgestürzt Process timed out. Der Prozess hat ein Timeout erreicht. Process read error. Prozess-Lesefehler. Process write error. Prozess-Schreibfehler. Web error, check console output. Web-Fehler, Konsolenausgabe prüfen. Upload Failed Hochladen fehlgeschlagen Script wrote to StdErr. Script hat in die Fehlerausgabe (StdErr) geschrieben. FTP Upload finished successfully. FTP-Upload erfolgreich beendet. Unknown error. Unbekannter Fehler. Connection Error. Verbindungsfehler. Permission Error. Berechtigungsfehler. Upload script %1 finished successfully. Das Skript %1 wurde erfolgreich hochgeladen. Uploaded to %1 Hochgeladen auf %1 HotKeySettings Enable Global HotKeys Systemweite Tastenkürzel aktivieren Capture Rect Area Rechteckigen Bereich aufnehmen Capture Full Screen Gesamten Bildschirm aufnehmen Capture current Screen Aktuellen Bildschirm aufnehmen Capture active Window Aktives Fenster aufnehmen Capture Window under Cursor Fenster unter Mauszeiger aufnehmen Global HotKeys Systemweite Tastenkürzel Capture Last Rect Area Letzten rechteckigen Bereich aufnehmen Clear Leeren Capture using Portal Aufnahme über Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. HotKeys werden aktuell nur unter Windows und X11 unterstützt. Das Deaktivieren dieser Option macht zudem die Aktions-Shortcuts ksnip-exklusiv. ImageGrabberSettings Capture mouse cursor on screenshot Mauszeiger auf Screenshot aufnehmen Should mouse cursor be visible on screenshots. Legt fest, ob der Mauszeiger auf Screenshots sichtbar sein soll. Image Grabber Bildgrabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Generische Wayland-Implementierungen, die XDG-DESKTOP-PORTAL verwenden, handhaben die Bildschirmskalierung unterschiedlich. Wird diese Option aktiviert, wird die aktuelle Bildschirmskalierung ermittelt und auf den Screenshot in ksnip angewendet. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME und KDE Plasma unterstützen sowohl eigene Wayland- als auch die standardmäßigen XDG-DESKTOP-PORTAL-Screenshots. Wird diese Option aktiviert, werden KDE Plasma und GNOME gezwungen, XDG-DESKTOP-PORTAL-Screenshots zu verwenden. Eine Änderung dieser Option erfordert einen Neustart von ksnip. Show Main Window after capturing screenshot Hauptfenster nach Aufnahme des Screenshots anzeigen Hide Main Window during screenshot Hauptfenster während Screenshot ausblenden Hide Main Window when capturing a new screenshot. Hauptfenster ausblenden, wenn ein neues Bildschirmfoto aufgenommen wird. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Hauptfenster nach der Aufnahme eines neuen Screenshots anzeigen, wenn jenes versteckt oder minimiert war. Force Generic Wayland (xdg-desktop-portal) Screenshot Generischen Wayland-Screenshot (xdg-desktop-portal) erzwingen Scale Generic Wayland (xdg-desktop-portal) Screenshots Generische Wayland-Screenshots (xdg-desktop-portal) skalieren Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Imgur-Verlauf Close Schließen Time Stamp Zeitstempel Link Link Delete Link Link löschen ImgurUploader Upload to imgur.com finished! Hochladen zu imgur.com abgeschlossen! Received new token, trying upload again… Neues Token erhalten, versuche erneut hochzuladen … Imgur token has expired, requesting new token… Das Imgur-Token ist abgelaufen, fordere neues Token an … ImgurUploaderSettings Force anonymous upload Anonymen Upload erzwingen Always copy Imgur link to clipboard Imgur-Link immer in die Zwischenablage kopieren Client ID Client-ID Client Secret Client-Secret PIN PIN Enter imgur Pin which will be exchanged for a token. Imgur-PIN eingeben, die gegen ein Token ausgetauscht wird. Get PIN PIN anfordern Get Token Token anfordern Imgur History Imgur-Verlauf Imgur Uploader Imgur-Uploader Username Benutzername Waiting for imgur.com… Warte auf imgur.com … Imgur.com token successfully updated. Imgur-Token wurde erfolgreich aktualisiert. Imgur.com token update error. Fehler beim Aktualisieren des Imgur-Tokens. After uploading open Imgur link in default browser Nach dem Hochladen Imgur-Link im Standardbrowser öffnen Link directly to image Direkt zum Bild verlinken Base Url: Basis-URL: Base url that will be used for communication with Imgur. Changing requires restart. Basis-URL, die für Kommunikation mit Imgur verwendet wird. Änderung erfordert Neustart. Clear Token Token löschen Upload title: Upload-Titel: Upload description: Upload-Beschreibung: LoadImageFromFileOperation Unable to open image Bild kann nicht geöffnet werden Unable to open image from path %1 Bild kann nicht aus Pfad %1 geöffnet werden MainToolBar New Neu Delay in seconds between triggering and capturing screenshot. Zeitverzögerung in Sekunden zwischen dem Auslösen und der Aufnahme des Bildschirmfotos. s The small letter s stands for seconds. s Save Speichern Save Screen Capture to file system Bildschirmaufnahme im Dateisystem speichern Copy Kopieren Copy Screen Capture to clipboard Bildschirmaufnahme in die Zwischenablage kopieren Tools Werkzeuge Undo Rückgängig Redo Wiederherstellen Crop Zuschneiden Crop Screen Capture Bildschirmaufnahme zuschneiden MainWindow Unsaved Ungespeichert Upload Hochladen Print Drucken Opens printer dialog and provide option to print image Öffnet Druckerdialog und bietet Optionen zum Drucken des Bildes Print Preview Druckvorschau Opens Print Preview dialog where the image orientation can be changed Öffnet die Druckvorschau, wo die Bildausrichtung angepasst werden kann Scale Skalieren Quit Beenden Settings Einstellungen &About &Über Open Öffnen &Edit &Bearbeiten &Options &Optionen &Help &Hilfe Add Watermark Wasserzeichen hinzufügen Add Watermark to captured image. Multiple watermarks can be added. Fügt dem aufgenommenem Bild ein Wasserzeichen hinzu. Mehrere Wasserzeichen können hinzugefügt werden. &File &Datei Unable to show image Bild kann nicht angezeigt werden Save As... Speichern als… Paste Einfügen Paste Embedded Eingebettet einfügen Pin Anheften Pin screenshot to foreground in frameless window Hefte Screenshot im Vordergrund in einem rahmenlosen Fenster an No image provided but one was expected. Kein Bild angegeben, obwohl eines erwartet wurde. Copy Path Pfad kopieren Open Directory Verzeichnis öffnen &View &Anzeigen Delete Löschen Rename Umbenennen Open Images Bilder öffnen Show Docks Docks anzeigen Hide Docks Docks verbergen Copy as data URI Als Daten-URI kopieren Open &Recent Kü&rzlich verwendet Modify Canvas Leinwand ändern Upload triggerCapture to external source Aufnahme nach extern hochladen Copy triggerCapture to system clipboard Aufnahme in die Zwischenablage kopieren Scale Image Bild skalieren Rotate Drehen Rotate Image Bild drehen Actions Aktionen Image Files Bilddateien Save All Alle speichern Close Window Fenster schließen Cut Ausschneiden OCR OCR MultiCaptureHandler Save Speichern Save As Speichern als Open Directory Verzeichnis öffnen Copy Kopieren Copy Path Pfad kopieren Delete Löschen Rename Umbenennen Save All Alle speichern NewCaptureNameProvider Capture Aufnahme OcrWindowCreator OCR Window %1 OCR-Fenster %1 PinWindow Close Schließen Close Other Andere schließen Close All Alles schließen PinWindowCreator OCR Window %1 OCR-Fenster %1 PluginsSettings Search Path Such-Pfad Default Standard The directory where the plugins are located. Speicherort in dem sich die Plugins befinden. Browse Durchsuchen Name Name Version Version Detect Ermitteln Plugin Settings Plugin-Einstellungen Plugin location Plugin-Ordner ProcessIndicator Processing RenameOperation Image Renamed Bild umbenannt Image Rename Failed Umbenennen des Bildes fehlgeschlagen Rename image Bild umbenennen New filename: Neuer Dateiname: Successfully renamed image to %1 Bild erfolgreich nach %1 umbenannt Failed to rename image to %1 Bild kann nicht in %1 umbenannt werden SaveOperation Save As Speichern als All Files Alle Dateien Image Saved Bild gespeichert Saving Image Failed Speichern des Bildes fehlgeschlagen Image Files Bilddateien Saved to %1 Gespeichert in %1 Failed to save image to %1 Bild kann nicht in %1 gespeichert werden SaverSettings Automatically save new captures to default location Neue Aufnahmen automatisch im Standardverzeichnis speichern Prompt to save before discarding unsaved changes Aufforderung zum Speichern, bevor nicht gespeicherte Änderungen verworfen werden Remember last Save Directory Zuletzt verwendeten Speicherort merken When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Ist diese Option gesetzt, wird das in den Einstellungen gesetzte Verzeichnis zum Abspeichern bei jedem Speichern ignoriert und durch das zuletzt benutzte Speicherverzeichnis ersetzt. Capture save location and filename Speicherort und Dateiname für Aufnahmen Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Unterstützte Formate sind JPG, PNG und BMP. Wenn kein Format angegeben ist, wird standardmäßig PNG benutzt. Dateinamen können die folgenden Platzhalter verwenden: - $Y, $M, $D für das Datum, $h, $m, $s für die Uhrzeit, oder $T für die Zeit im Format hhmmss. - Mehrere aufeinander folgende # als Zähler. #### ergibt 0001, der darauf folgende Screenshot wäre 0002. Browse Durchsuchen Saver Settings Speichereinstellungen Capture save location Speicherort für Aufnahmen Default Standard Factor Faktor Save Quality Speicherqualität Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. 0 angeben, um kleine komprimierte Dateien zu erhalten, 100 für große unkomprimierte Dateien. Nicht alle Bildformate unterstützen die gesamte Bandbreite, JPEG schon. Overwrite file with same name Datei mit gleichem Namen überschreiben ScriptUploaderSettings Copy script output to clipboard Skriptausgabe in Zwischenablage kopieren Script: Skript: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Pfad zum Skript, das zum Hochladen aufgerufen wird. Beim Hochladen wird der Pfad zur temporären PNG-Datei als einziges Argument an das Script übergeben. Browse Durchsuchen Script Uploader Skriptbasiertes Hochladen Select Upload Script Upload-Skript auswählen Stop when upload script writes to StdErr Das Skript anhalten, wenn es in die Standardfehlerausgabe (StdErr) schreibt Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Markiert den Upload als fehlgeschlagen, wenn das Skript in die Standardfehlerausgabe (StdErr) schreibt. Ohne diese Einstellung bleiben Fehler im Skript möglicherweise unbemerkt. Filter: Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Reguläre Ausdrücke. Nur das in die Zwischenablage kopieren, was dem regulären Ausdruck entspricht. Falls leer, wird alles kopiert. SettingsDialog Settings Einstellungen OK OK Cancel Abbrechen Image Grabber Bild-Grabber Imgur Uploader Imgur-Uploader Application Anwendung Annotator Beschriftung HotKeys Tastenkürzel Uploader Uploader Script Uploader Skriptbasierter Upload Saver Speichern Stickers Aufkleber Snipping Area Bereich zum Ausschneiden Tray Icon Tray-Icon Watermark Wasserzeichen Actions Aktionen FTP Uploader FTP-Uploader Plugins Plugins Search Settings... Einstellungen durchsuchen... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ausgewählten Bereich durch die Handler skalieren oder durch das Ziehen der Auswahl bewegen. Use arrow keys to move the selection. Verwenden Sie die Pfeiltasten, um die Auswahl zu verschieben. Use arrow keys while pressing CTRL to move top left handle. Verwenden Sie die Pfeiltasten bei gedrückter STRG-Taste, um den oberen linken Griff zu verschieben. Use arrow keys while pressing ALT to move bottom right handle. Verwenden Sie die Pfeiltasten bei gedrückter ALT-Taste, um den unteren rechten Griff zu verschieben. This message can be disabled via settings. Diese Nachricht kann in den Einstellungen deaktiviert werden. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. Mit ESC-Taste abbrechen. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Klicken und ziehen Sie, um einen rechteckigen Bereich auszuwählen, oder drücken Sie ESC, um die Aufnahme zu beenden. Hold CTRL pressed to resize selection after selecting. Halten Sie die STRG-Taste gedrückt, um die Größe des Bereichs nach der Auswahl zu ändern. Hold CTRL pressed to prevent resizing after selecting. Halten Sie die STRG-Taste gedrückt, um eine Größenänderung nach der Auswahl zu verhindern. Operation will be canceled after 60 sec when no selection made. Die Aktion wird nach 60 Sekunden abgebrochen, wenn keine Auswahl getroffen wurde. This message can be disabled via settings. Diese Nachricht kann in den Einstellungen deaktiviert werden. SnippingAreaSettings Freeze Image while snipping Bild während der Aufnahme einfrieren When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Ist diese Option gesetzt, wird der Hintergrund eingefroren und eine rechteckige Auswahl kann getroffen werden. Sie wirkt sich auch auf verzögerte Screenshots aus; wenn aktiviert, geschieht die Verzögerung, bevor die Auswahl getroffen werden kann; wenn deaktiviert, geschieht die Verzögerung, nachdem die Auswahl getroffen wurde. Diese Option ist unter Wayland stets deaktiviert, unter macOS stets aktiviert. Show magnifying glass on snipping area Lupe im Ausschnittsbereich anzeigen Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Zeigt eine Lupe an, welche in das Hintergrundbild hineinzoomt. Diese Option funktioniert nur, wenn „Bild während der Aufnahme einfrieren“ aktiviert wurde. Show Snipping Area rulers Lineale bei der Auswahl des rechteckigen Bereichs anzeigen Horizontal and vertical lines going from desktop edges to cursor on snipping area. Horizontale und vertikale Linien vom Bildschirmrand zum Mauszeiger anzeigen. Show Snipping Area position and size info Position und Größe des Ausschnittsbereichs anzeigen When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Wenn der Mauszeiger nicht gedrückt ist, wird die Position angezeigt; wenn der Mauszeiger gedrückt ist, wird die Größe des markierten Bereichs linksseitig und oberhalb des Ausschnittsbereichs angezeigt. Allow resizing rect area selection by default Standardmäßig das Ändern der rechteckigen Auswahl erlauben When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Wenn dies aktiviert ist, kann nach einer rechteckigen Auswahl jene skaliert werden. Nach Fertigstellung kann die Auswahl mittels ENTER bestätigt werden. Show Snipping Area info text Informationen zum Auswahlbereich anzeigen Snipping Area cursor color Mauszeigerfarbe für Auswahlbereich Sets the color of the snipping area cursor. Setzt die Farbe des Mauszeigers für den Auswahlbereich. Snipping Area cursor thickness Mauszeigerstärke für Auswahlbereich Sets the thickness of the snipping area cursor. Setzt die Stärke des Mauszeigers für den Auswahlbereich. Snipping Area Auswahlbereich Snipping Area adorner color Randfarbe für Aufnahmebereich Sets the color of all adorner elements on the snipping area. Setzt die Farbe für alle Dekorationselemente des Aufnahmebereichs. Snipping Area Transparency Transparenz des Aufnahmebereichs Alpha for not selected region on snipping area. Smaller number is more transparent. Alpha-Wert für nicht ausgewählte Regionen im Aufnahmebereich. Kleinere Werte bedeuten mehr Transparenz. Enable Snipping Area offset Offset für Aufnahmebereich verwenden When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Hoch Down Runter Use Default Stickers Standard-Aufkleber nutzen Sticker Settings Aufkleber-Einstellungen Vector Image Files (*.svg) Vektorgrafik-Dateien (*.svg) Add Hinzufügen Remove Entfernen Add Stickers Sticker hinzufügen TrayIcon Show Editor Editor anzeigen TrayIconSettings Use Tray Icon Benutze Tray-Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Bei Aktivierung wird ein Tray-Icon in der Taskbar hinzugefügt, sofern das Betriebssystem dies unterstützt. Diese Änderung erfordert einen Neustart. Minimize to Tray In Tray minimieren Start Minimized to Tray Im Tray minimiert starten Close to Tray In Tray schließen Show Editor Editor anzeigen Capture Aufnahme Default Tray Icon action Standard-Tray-Icon-Aktion Default Action that is triggered by left clicking the tray icon. Standardaktion, die beim Linksklick auf das Tray-Icon ausgeführt wird. Tray Icon Settings Tray-Icon-Einstellungen Use platform specific notification service Plattformspezifischen Benachrichtigungsdienst verwenden When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Bei Aktivierung wird versucht, den plattformspezifischen Benachrichtungsservice zu verwenden, falls jener existiert. Diese Änderung erfordert einen Neustart. Display Tray Icon notifications Benachrichtigungen über das Aufgabeleistensymbol anzeigen UpdateWatermarkOperation Select Image Bild auswählen Image Files Bilddateien UploadOperation Upload Script Required Upload-Skript erforderlich Please add an upload script via Options > Settings > Upload Script Bitte fügen Sie ein Upload-Skript über Optionen > Einstellungen > Upload-Skript hinzu Capture Upload Aufnahme hochladen You are about to upload the image to an external destination, do you want to proceed? Sind sind dabei, das Bild zu einem externen Ziel hochzuladen. Möchten Sie fortfahren? UploaderSettings Ask for confirmation before uploading Vor dem Hochladen nach Bestätigung fragen Uploader Type: Uploader-Typ: Imgur Imgur Script Skript Uploader Uploader FTP FTP VersionTab Version Version Build Build Using: Verwendet: WatermarkSettings Watermark Image Wasserzeichen-Bild Update Aktualisieren Rotate Watermark Wasserzeichen drehen When enabled, Watermark will be added with a rotation of 45° Wenn aktiviert, wird das Wasserzeichen beim Einfügen um 45° gedreht Watermark Settings Wasserzeichen-Einstellungen ksnip-master/translations/ksnip_el.ts000066400000000000000000002347401457262621600204150ustar00rootroot00000000000000 AboutDialog About Σχετικά About Σχετικά Version Έκδοση Author ΔημιουÏγός Close Κλείσιμο Donate ΔωÏεά Contact Επικοινωνία AboutTab License: Άδεια χÏήσης: Screenshot and Annotation Tool ΕÏγαλείο λήψης στιγμιότυπων και σημειώσεων ActionSettingTab Name Όνομα Shortcut Συντόμευση Clear ΚαθαÏισμός Take Capture ΣÏλληψη Include Cursor ΣυμπεÏίληψη του δÏομέα Delay ΚαθυστέÏηση s The small letter s stands for seconds. δ Capture Mode ΛειτουÏγία σÏλληψης Show image in Pin Window ΠÏοβολή της εικόνας σε καÏφιτσωμένο παÏάθυÏο Copy image to Clipboard ΑντιγÏαφή της εικόνας στο Ï€ÏόχειÏο Upload image Αποστολή εικόνας Open image parent directory Άνοιγμα του Î³Î¿Î½Î¹ÎºÎ¿Ï ÎºÎ±Ï„Î±Î»ÏŒÎ³Î¿Ï… της εικόνας Save image Αποθήκευση εικόνας Hide Main Window ΑπόκÏυψη του κÏÏιου παÏαθÏÏου Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add ΠÏοσθήκη Actions Settings Ρυθμίσεις ενεÏγειών Action ΕνέÏγεια AddWatermarkOperation Watermark Image Required Απαιτείται μια εικόνα υδατογÏαφήματος Please add a Watermark Image via Options > Settings > Annotator > Update ΠαÏακαλώ Ï€Ïοσθέστε μια εικόνα υδατογÏαφήματος από τις Επιλογές > Ρυθμίσεις > Σχολιαστής > ΕνημέÏωση AnnotationSettings Smooth Painter Paths Εξομάλυνση των γÏαμμών σχεδίασης When enabled smooths out pen and marker paths after finished drawing. Όταν είναι ενεÏγοποιημένο, εξομαλÏνει την χάÏαξη της γÏαφίδας και των σημαδευτών μετά το πέÏας της ενέÏγειας. Smooth Factor Συντελεστής εξομάλυνσης Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Η αÏξηση της του συντελεστή εξομάλυνσης θα μειώσει την ακÏίβεια της γÏαφίδας και των σημαδευτών αλλά η χάÏαξη θα φαίνεται πιο ομαλοποιημένη. Annotator Settings Ρυθμίσεις σχολιαστή Remember annotation tool selection and load on startup Απομνημόνευση της επιλογής του εÏγαλείου σημειώσεων και φόÏτωση στην εκκίνηση Switch to Select Tool after drawing Item Εναλλαγή στο εÏγαλείο επιλογής μετά τον σχεδιασμό του αντικειμένου Number Tool Seed change updates all Number Items Μια αλλαγή στον αÏχικό αÏιθμό αλλάζει όλα τα αÏιθμημένα αντικείμενα Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. ΑπενεÏγοποιώντας αυτήν την επιλογή, οι αλλαγές στον αÏχικό αÏιθμό επηÏεάζουν μόνον τα νέα αντικείμενα και όχι τα υπάÏχοντα. Η απενεÏγοποίηση της επιλογής επιτÏέπει διπλότυπους αÏιθμοÏÏ‚. Canvas Color ΧÏώμα του καμβά Default Canvas background color for annotation area. Changing color affects only new annotation areas. Το Ï€ÏοκαθοÏισμένο χÏώμα παÏασκηνίου του καμβά για την πεÏιοχή σχολιασμοÏ. Η αλλαγή του χÏώματος επηÏεάζει μόνον τις νέες πεÏιοχές σχολιασμοÏ. Select Item after drawing Επιλογή του αντικειμένου μετά τον σχεδιασμό With this option enabled the item gets selected after being created, allowing changing settings. Αν αυτή η επιλογή είναι ενεÏγοποιημένη, το αντικείμενο επιλέγεται αμέσως μετά την δημιουÏγία του και επιτÏέπει την επεξεÏγασία των παÏαμέτÏων. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Λήψη στιγμιότυπου κατά την έναÏξη στην Ï€ÏοκαθοÏισμένη λειτουÏγία Application Style ΤεχνοτÏοπία της εφαÏμογής Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. ΟÏίζει την τεχνοτÏοπία εμφάνισης της εφαÏμογής. Για να ληφθοÏν υπόψιν οι αλλαγές, απαιτείται επανεκκίνηση του ksnip. Application Settings Ρυθμίσεις της εφαÏμογής Automatically copy new captures to clipboard Αυτόματη αντιγÏαφή των νέων συλλήψεων στο Ï€ÏόχειÏο Use Tabs ΧÏήση καÏτελών Change requires restart. Η αλλαγή απαιτεί επανεκκίνηση. Run ksnip as single instance Μοναδική εκτέλεση του ksnip Hide Tabbar when only one Tab is used. ΑπόκÏυψη της γÏαμμής καÏτελών κατά την χÏήση μιας καÏτέλας. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. ΕνεÏγοποιώντας αυτήν την επιλογή θα επιτÏέπεται μόνο μια υπηÏεσία του ksnip, όλες οι υπόλοιπες θα εκτελεστοÏν όταν ολοκληÏωθεί η Ï€Ïώτη. Η αλλαγή αυτής της επιλογής απαιτεί επανεκκίνηση όλων των υπηÏεσιών. Remember Main Window position on move and load on startup Απομνημόνευση της θέσης του κÏÏιου παÏαθÏÏου κατά την μετακίνηση και φόÏτωση στην εκκίνηση Auto hide Tabs Αυτόματη απόκÏυψη των καÏτελών Auto hide Docks Αυτόματη απόκÏυψη αποβάθÏων On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. ΑπόκÏυψη της εÏγαλειοθήκης και των Ïυθμίσεων ÏƒÏ‡Î¿Î»Î¹Î±ÏƒÎ¼Î¿Ï ÎºÎ±Ï„Î¬ την εκκίνηση. ΧÏησιμοποιήστε το πλήκτÏο Tab για εναλλαγή της οÏατότητας των αποβάθÏων. Auto resize to content Αυτόματη κλιμάκωση βάσει του πεÏιεχομένου Automatically resize Main Window to fit content image. Αυτόματη αλλαγή μεγέθους του κυÏίως παÏαθÏÏου για Ï€ÏοσαÏμογή στο πεÏιεχόμενο της εικόνας. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse ΠεÏιήγηση AuthorTab Contributors: Οι συνεισφέÏοντες: Spanish Translation Ισπανική μετάφÏαση Dutch Translation Ολλανδική μετάφÏαση Russian Translation Ρωσική μετάφÏαση Norwegian BokmÃ¥l Translation ÎοÏβηγική μετάφÏαση (BokmÃ¥l) French Translation Γαλλική μετάφÏαση Polish Translation Πολωνική μετάφÏαση Snap & Flatpak Support ΥποστήÏιξη Snap & Flatpak The Authors: Οι δημιουÏγοί: CanDiscardOperation Warning - ΠÏοειδοποίηση - The capture %1%2%3 has been modified. Do you want to save it? Η σÏλληψη %1%2%3 έχει Ï„Ïοποποιηθεί. Θέλετε να την αποθηκεÏσετε; CaptureModePicker New Îέα Draw a rectangular area with your mouse Σχεδιασμός μιας οÏθογώνιας πεÏιοχής με το ποντίκι Capture full screen including all monitors ΣÏλληψη ολόκληÏης της οθόνης συμπεÏιλαμβανομένου όλων των οθονών Capture screen where the mouse is located ΣÏλληψη της οθόνης που βÏίσκεται ο δÏομέας του Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï Capture window that currently has focus ΣÏλληψη του παÏαθÏÏου που έχει την εστίαση Capture that is currently under the mouse cursor ΣÏλληψη του παÏαθÏÏου κάτω από τον δÏομέα του Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï Capture a screenshot of the last selected rectangular area ΣÏλληψη στιγμιότυπου της τελευταίας επιλεγμένης οÏθογώνιας πεÏιοχής Uses the screenshot Portal for taking screenshot ΧÏησιμοποιήστε την Ï€Ïλη στιγμιότυπου για την λήψη ενός στιγμιότυπου ContactTab Community Κοινότητα Bug Reports ΑναφοÏές σφαλμάτων If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Αποτυχία αντιγÏαφής στο Ï€ÏόχειÏο Failed to copy to clipboard as base64 encoded image. Αποτυχία αντιγÏαφής στο Ï€ÏόχειÏο ως εικόνα κωδικοποιημένη σε base64. Copied to clipboard ΑντιγÏάφηκε στο Ï€ÏόχειÏο Copied to clipboard as base64 encoded image. ΑντιγÏαφή στο Ï€ÏόχειÏο ως εικόνα κωδικοποιημένη σε base64. DeleteImageOperation Delete Image ΔιαγÏαφή της εικόνας The item '%1' will be deleted. Do you want to continue? Το αντικείμενο %1 δια διαγÏαφεί. Θέλετε να συνεχίσετε; DonateTab Donations are always welcome Οι δωÏεές είναι ευπÏόσδεκτες Donation ΔωÏεά ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. ΠÏοσθήκη νέων ενεÏγειών με το πλήκτÏο "ΠÏοσθήκη" της καÏτέλας. EnumTranslator Rectangular Area ΟÏθογώνια πεÏιοχή Last Rectangular Area Τελευταία οÏθογώνια πεÏιοχή Full Screen (All Monitors) ΠλήÏης οθόνη (Όλες οι οθόνες) Current Screen ΤÏέχουσα οθόνη Active Window ΕνεÏγό παÏάθυÏο Window Under Cursor ΠαÏάθυÏο κάτω από τον δÏομέα Screenshot Portal ΠÏλη στιγμιότυπου FtpUploaderSettings Force anonymous upload. Url Username Όνομα χÏήστη Password FTP Uploader HandleUploadResultOperation Upload Successful Επιτυχής αποστολή Unable to save temporary image for upload. ΑδÏνατη η Ï€ÏοσωÏινή αποθήκευση της εικόνας για αποστολή. Unable to start process, check path and permissions. ΑδÏνατη η εκκίνηση της διεÏγασίας· ελέγξτε την διαδÏομή και τις άδειες. Process crashed Η διεÏγασία κατέÏÏευσε Process timed out. Λήξη χÏÎ¿Î½Î¹ÎºÎ¿Ï Î¿Ïίου της διεÏγασίας. Process read error. Σφάλμα ανάγνωσης της διεÏγασίας. Process write error. Σφάλμα εγγÏαφής της διεÏγασίας. Web error, check console output. Σφάλμα ιστοÏ, ελέγξτε την έξοδο του τεÏματικοÏ. Upload Failed Αποτυχία αποστολής Script wrote to StdErr. Η μακÏοεντολή έγγÏαψε στο StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys ΕνεÏγοποίηση των καθολικών συντομεÏσεων Capture Rect Area ΣÏλληψη οÏθογώνιας πεÏιοχής Capture Full Screen ΣÏλληψη πλήÏους οθόνης Capture current Screen ΣÏλληψη Ï„Ïέχουσας οθόνης Capture active Window ΣÏλληψη ενεÏÎ³Î¿Ï Ï€Î±ÏαθÏÏου Capture Window under Cursor ΣÏλληψη παÏαθÏÏου κάτω από τον δÏομέα Global HotKeys ΠλήκτÏα καθολικών συντομεÏσεων Capture Last Rect Area ΣÏλληψη της τελευταίας οÏθογώνιας πεÏιοχής Clear ΚαθαÏισμός Capture using Portal ΣÏλληψη μέσω της Ï€Ïλης HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Οι συντομεÏσεις υποστηÏίζονται Ï€Ïος το παÏόν μόνο για Windows και X11. ΑπενεÏγοποιώντας αυτήν την επιλογή οι συντομεÏσεις θα έχουν Î¹ÏƒÏ‡Ï Î¼ÏŒÎ½Î¿ στο ksnip. ImageGrabberSettings Capture mouse cursor on screenshot ΣÏλληψη του δÏομέα του Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï ÏƒÏ„Î¿ στιγμιότυπο Should mouse cursor be visible on screenshots. Αν θα Ï€Ïέπει να είναι οÏατός ο δÏομέας του Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï ÏƒÏ„Î¿ στιγμιότυπο. Image Grabber ΣÏλληψη εικόνας Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Η ενσωμάτωση σε γενικό Wayland που χÏησιμοποιεί XDG-DESKTOP-PORTAL διαχειÏίζεται την κλιμάκωση της εικόνας διαφοÏετικά. Η ενεÏγοποίηση αυτής της επιλογής θα Ï€ÏοσδιοÏίσει την Ï„Ïέχουσα κλιμάκωση της εικόνας και θα την εφαÏμόσει στην στο στιγμιότυπο στο ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Το GNOME και το KDE Plasma υποστηÏίζουν τα δικά τους Wayland και Î³ÎµÎ½Î¹ÎºÎ¿Ï XDG-DESKTOP-PORTAL στιγμιότυπα. ΕνεÏγοποιώντας αυτήν την επιλογή θα εξαναγκάσει το KDE Plasma και το GNOME να χÏησιμοποιήσουν τα στιγμιότυπα XDG-DESKTOP-PORTAL. Η αλλαγή της επιλογής αυτής απαιτεί την επανεκκίνηση του ksnip. Show Main Window after capturing screenshot Εμφάνιση του κÏÏιου παÏαθÏÏου μετά την σÏλληψη του στιγμιότυπου Hide Main Window during screenshot ΑπόκÏυψη του κÏÏιου παÏαθÏÏου κατά την σÏλληψη του στιγμιότυπου Hide Main Window when capturing a new screenshot. ΑπόκÏυψη του κÏÏιου παÏαθÏÏου κατά την σÏλληψη ενός στιγμιότυπου. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Εμφάνιση του κÏÏιου παÏαθÏÏου μετά την σÏλληψη ενός στιγμιότυπου όταν το κÏÏιο παÏάθυÏο είναι καταχωνιασμένο ή ελαχιστοποιημένο. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History ΙστοÏικό Imgur Close Κλείσιμο Time Stamp ΧÏονοσφÏαγίδα Link ΣÏνδεσμος Delete Link ΔιαγÏαφή Î´ÎµÏƒÎ¼Î¿Ï ImgurUploader Upload to imgur.com finished! Η αποστολή στο Imgur ολοκληÏώθηκε! Received new token, trying upload again… Λήψη νέου αδειοδοτικοÏ, Ï€Ïοσπάθεια αποστολής ξανά… Imgur token has expired, requesting new token… Το αδειοδοτικό του Imgur έληξε, γίνεται αίτηση νέας αδειοδότησης… ImgurUploaderSettings Force anonymous upload Εξαναγκασμός ανώνυμης αποστολής Always copy Imgur link to clipboard ΑντιγÏαφή πάντα του Î´ÎµÏƒÎ¼Î¿Ï Imgur στο Ï€ÏόχειÏο Client ID ΑναγνωÏιστικό πελάτη Client Secret Μυστικό πελάτη PIN PIN Enter imgur Pin which will be exchanged for a token. Εισαγάγετε το PIN του Imgur το οποίο θα χÏησιμοποιηθεί για την αδειοδότηση. Get PIN Λήψη PIN Get Token Λήψη Î±Î´ÎµÎ¹Î¿Î´Î¿Ï„Î¹ÎºÎ¿Ï Imgur History ΙστοÏικό Imgur Imgur Uploader Αποστολέας Imgur Username Όνομα χÏήστη Waiting for imgur.com… Αναμονή του imgur.com… Imgur.com token successfully updated. Το αδειοδοτικό του imgur.com ενημεÏώθηκε επιτυχώς. Imgur.com token update error. Σφάλμα στην ενημέÏωση της αδειοδότησης του imgur.com. After uploading open Imgur link in default browser Μετά την αποστολή άνοιγμα του Î´ÎµÏƒÎ¼Î¿Ï Imgur στον Ï€ÏοκαθοÏισμένο φυλλομετÏητή Link directly to image Απευθείας δεσμός της εικόνας Base Url: Βασικό Url: Base url that will be used for communication with Imgur. Changing requires restart. Το βασικό url που θα χÏησιμοποιηθεί για την επικοινωνία με το Imgur. Για να ληφθεί υπόψιν η αλλαγή απαιτείται επανεκκίνηση. Clear Token ΕκκαθάÏιση Î±Î´ÎµÎ¹Î¿Î´Î¿Ï„Î¹ÎºÎ¿Ï Upload title: Upload description: LoadImageFromFileOperation Unable to open image ΑδÏνατο το άνοιγμα της εικόνας Unable to open image from path %1 ΑδÏνατο το άνοιγμα της εικόνας από την διαδÏομή %1 MainToolBar New Îέα Delay in seconds between triggering and capturing screenshot. ΚαθυστέÏηση σε δευτεÏόλεπτα Î¼ÎµÏ„Î±Î¾Ï Ï„Î·Ï‚ ενεÏγοποίησης και της σÏλληψης του στιγμιότυπου. s The small letter s stands for seconds. δ Save Αποθήκευση Save Screen Capture to file system Αποθήκευση της σÏλληψης στο σÏστημα αÏχείων Copy ΑντιγÏαφή Copy Screen Capture to clipboard ΑντιγÏαφή της σÏλληψης στο Ï€ÏόχειÏο Tools ΕÏγαλεία Undo ΑναίÏεση Redo Επανάληψη Crop ΠεÏικοπή Crop Screen Capture ΠεÏικοπή της σÏλληψης της οθόνης MainWindow Unsaved Μη αποθηκευμένο Upload Αποστολή Print ΕκτÏπωση Opens printer dialog and provide option to print image Ανοίγει τον διάλογο εκτÏπωσης και Ï€ÏοσφέÏει την επιλογή εκτÏπωσης της εικόνας Print Preview ΠÏοεπισκόπηση εκτÏπωσης Opens Print Preview dialog where the image orientation can be changed Ανοίγει τον διάλογο Ï€Ïοεπισκόπησης της εκτÏπωσης από όπου μποÏεί να γίνει αλλαγή του Ï€ÏÎ¿ÏƒÎ±Î½Î±Ï„Î¿Î»Î¹ÏƒÎ¼Î¿Ï Scale Κλιμάκωση Quit Έξοδος Settings Ρυθμίσεις &About &Σχετικά Open Άνοιγμα &Edit &ΕπεξεÏγασία &Options Επιλο&γές &Help &Βοήθεια Add Watermark ΠÏοσθήκη υδατογÏαφήματος Add Watermark to captured image. Multiple watermarks can be added. ΠÏοσθήκη υδατογÏαφήματος στο στιγμιότυπο. ΥποστηÏίζεται και η πολλαπλή Ï€Ïοσθήκη. &File &ΑÏχείο Unable to show image ΑδÏνατη η εμφάνιση της εικόνας Save As... Αποθήκευση ως... Paste Επικόλληση Paste Embedded Ενσωματωμένη επικόλληση Pin ΚαÏφίτσωμα Pin screenshot to foreground in frameless window ΚαÏφίτσωμα του στιγμιότυπου στο Ï€Ïοσκήνιο σε άνευ πλαισίου παÏάθυÏα No image provided but one was expected. Αναμενόταν μια εικόνα αλλά δεν παÏείχατε κάποια. Copy Path ΑντιγÏαφή της διαδÏομής Open Directory Άνοιγμα καταλόγου &View &ΠÏοβολή Delete ΔιαγÏαφή Rename Μετονομασία Open Images Άνοιγμα εικόνων Show Docks Εμφάνιση αποβάθÏας Hide Docks ΑπόκÏυψη αποβάθÏας Copy as data URI ΑντιγÏαφή ως URI δεδομένων Open &Recent Άνοιγμα &Ï€Ïόσφατου Modify Canvas ΤÏοποποίηση του καμβά Upload triggerCapture to external source Αποστολή της σÏλληψης του ενεÏγοποιητή Ï€Ïος μια εξωτεÏική πηγή Copy triggerCapture to system clipboard ΑντιγÏαφή της σÏλληψης του ενεÏγοποιητή στο Ï€ÏόχειÏο του συστήματος Scale Image Κλιμάκωση εικόνας Rotate ΠεÏιστÏοφή Rotate Image ΠεÏιστÏοφή εικόνας Actions ΕνέÏγειες Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Αποθήκευση Save As Αποθήκευση ως Open Directory Άνοιγμα καταλόγου Copy ΑντιγÏαφή Copy Path ΑντιγÏαφή της διαδÏομής Delete ΔιαγÏαφή Rename Μετονομασία Save All NewCaptureNameProvider Capture ΣÏλληψη OcrWindowCreator OCR Window %1 PinWindow Close Κλείσιμο Close Other Κλείσιμο των άλλων Close All Κλείσιμο όλων PinWindowCreator OCR Window %1 PluginsSettings Search Path Default ΠÏοεπιλογή The directory where the plugins are located. Browse ΠεÏιήγηση Name Όνομα Version Έκδοση Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Η εικόνα μετονομάστηκε Image Rename Failed Η μετονομασία της εικόνας απέτυχε Rename image Μετονομασία της εικόνας New filename: Îέο όνομα αÏχείου: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As Αποθήκευση ως All Files Όλα τα αÏχεία Image Saved Η εικόνα αποθηκεÏτηκε Saving Image Failed Η αποθήκευση της εικόνας απέτυχε Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Αυτόματη αποθήκευση των νέων λήψεων στην Ï€ÏοκαθοÏισμένη τοποθεσία Prompt to save before discarding unsaved changes ΠÏοτÏοπή για αποθήκευση Ï€Ïιν την απόÏÏιψη των μη αποθηκευμένων αλλαγών Remember last Save Directory Απομνημόνευση του τελευταίου καταλόγου αποθήκευσης When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Όταν είναι ενεÏγοποιημένο απομνημονεÏεται ο τελευταία χÏησιμοποιοÏμενος κατάλογος για χÏήση στις επόμενες αποθηκεÏσεις. Capture save location and filename Τοποθεσία και όνομα αÏχείου αποθήκευσης της σÏλληψης Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Οι υποστηÏιζόμενοι Ï„Ïποι είναι JPG, PNG και BMP. Αν δεν οÏίσετε τον Ï„Ïπο θα χÏησιμοποιηθεί εξ οÏÎ¹ÏƒÎ¼Î¿Ï Ï„Î¿ PNG. Το όνομα αÏχείου μποÏεί να πεÏιέχει τα ακόλουθα σÏμβολα υποκατάστασης: - $Y, $M, $D για την ημεÏομηνία, $h, $m, $s για την ÏŽÏα, ή $T για την ÏŽÏα σε μοÏφή hhmmss. - Πολλαπλές ακολουθίες # για τον μετÏητή. Με χÏήση των #### θα λάβετε 0001, και στην επόμενη σÏλληψη θα γίνει 0002. Browse ΠεÏιήγηση Saver Settings Αποθήκευση των Ïυθμίσεων Capture save location Τοποθεσία αποθήκευσης της σÏλληψης Default ΠÏοεπιλογή Factor Συντελεστής Save Quality Ποιότητα αποθήκευσης Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. ΟÏίστε 0 για να αποκτήσετε μικÏά συμπιεσμένα αÏχεία, 100 για μεγάλα μη συμπιεσμένα αÏχεία. Το πλήÏες εÏÏος δεν υποστηÏίζεται από όλους τους Ï„Ïπους εικόνας· το JPEG το υποστηÏίζει. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard ΑντιγÏαφή της εξόδου της μακÏοεντολής στο Ï€ÏόχειÏο Script: ΜακÏοεντολή: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Η διαδÏομή της μακÏοεντολής που θα εκτελεστεί για την αποστολή. Κατά την αποστολή η μακÏοεντολή θα εκτελεστεί με μοναδικό ÏŒÏισμα την διαδÏομή ενός Ï€ÏοσωÏÎ¹Î½Î¿Ï Î±Ïχείου png. Browse ΠεÏιήγηση Script Uploader ΜακÏοεντολή αποστολής Select Upload Script Επιλογή μακÏοεντολής αποστολής Stop when upload script writes to StdErr Διακοπή όταν η μακÏοεντολή αποστολής γÏάφει στο StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Σημειώνει την αποστολή ως αποτυχημένη όταν η μακÏοεντολή γÏάφει στο StdErr. ΧωÏίς αυτήν την ÏÏθμιση τα τυχόν σφάλματα της μακÏοεντολής θα πεÏάσουν απαÏατήÏητα. Filter: ΦίλτÏο: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Κανονική έκφÏαση. ΑντιγÏαφή στο Ï€ÏόχειÏο μόνο ÏŒ,τι ταιÏιάζει στην κανονική έκφÏαση. Αν δεν οÏιστεί κάποιο φίλτÏο θα αντιγÏαφοÏν όλες οι γÏαμμές. SettingsDialog Settings Ρυθμίσεις OK Εντάξει Cancel ΆκυÏο Image Grabber ΣÏλληψη εικόνας Imgur Uploader Αποστολέας Imgur Application ΕφαÏμογή Annotator Σχολιαστής HotKeys ΠλήκτÏα συντομεÏσεων Uploader Αποστολέας Script Uploader ΜακÏοεντολή αποστολής Saver Αποθήκευση Stickers Αυτοκόλλητα Snipping Area ΠεÏιοχή σÏλληψης Tray Icon Εικονίδιο πλαισίου συστήματος Watermark ΥδατογÏάφημα Actions ΕνέÏγειες FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Αλλαγή μεγέθους του επιλεγμένου οÏθογωνίου χÏησιμοποιώντας τις λαβές ή μετακίνηση με σÏÏσιμο της επιλογής. Use arrow keys to move the selection. ΧÏησιμοποιήστε τα βελάκια για να μετακινήσετε την επιλογή. Use arrow keys while pressing CTRL to move top left handle. ΧÏησιμοποιήστε τα βελάκια κÏατώντας πατημένο το πλήκτÏο CTRL για να μετακινήσετε την πάνω αÏιστεÏά λαβή. Use arrow keys while pressing ALT to move bottom right handle. ΧÏησιμοποιήστε τα βελάκια κÏατώντας πατημένο το πλήκτÏο ALT για να μετακινήσετε την κάτω δεξιά λαβή. This message can be disabled via settings. Αυτό το μήνυμα μποÏεί να απενεÏγοποιηθεί από τις Ïυθμίσεις. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Κλικ και σÏÏσιμο για να επιλέξετε μια οÏθογώνια πεÏιοχή ή πιέστε ESC για εγκατάλειψη. Hold CTRL pressed to resize selection after selecting. Î‘Ï†Î¿Ï Ï€Ïαγματοποιήσετε την επιλογή, κÏατήστε πατημένο το CTRL για να αλλάξετε το μέγεθός της. Hold CTRL pressed to prevent resizing after selecting. Î‘Ï†Î¿Ï Ï€Ïαγματοποιήσετε την επιλογή, κÏατήστε πατημένο το CTRL για να αποτÏέψετε την αλλαγή του μεγέθους της. Operation will be canceled after 60 sec when no selection made. Η ενέÏγεια θα ακυÏωθεί μετά από 60 δευτ. αν δεν Ï€Ïαγματοποιηθεί κάποια επιλογή. This message can be disabled via settings. Αυτό το μήνυμα μποÏεί να απενεÏγοποιηθεί από τις Ïυθμίσεις. SnippingAreaSettings Freeze Image while snipping Πάγωμα της οθόνης κατά την σÏλληψη When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Όταν είναι ενεÏγοποιημένο, το παÏασκήνιο θα είναι παγωμένο κατά την επιλογή της οÏθογώνιας πεÏιοχής. Επίσης αλλάζει την συμπεÏιφοÏά των στιγμιότυπων με καθυστέÏηση: η καθυστέÏηση λαμβάνει χώÏα Ï€Ïιν την εμφάνιση της πεÏιοχής σÏλληψης ενώ όταν είναι απενεÏγοποιημένο η καθυστέÏηση λαμβάνει χώÏα μετά την εμφάνιση της πεÏιοχής σÏλληψης. Αυτό το χαÏακτηÏιστικό είναι απενεÏγοποιημένο για τον εξυπηÏετητή Wayland και πάντα ενεÏγοποιημένο για το MacOs. Show magnifying glass on snipping area Εμφάνιση του Î¼ÎµÎ³ÎµÎ¸Ï…Î½Ï„Î¹ÎºÎ¿Ï Ï†Î±ÎºÎ¿Ï ÏƒÏ„Î·Î½ πεÏιοχή σÏλληψης Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Εμφανίζει έναν μεγεθυντικό φακό ο οποίος εστιάζει στην εικόνα του παÏασκηνίου. Αυτή η επιλογή λειτουÏγεί μόνο όταν το "πάγωμα της οθόνης κατά την σÏλληψη" είναι ενεÏγοποιημένο. Show Snipping Area rulers Εμφάνιση των χαÏάκων στην πεÏιοχή σÏλληψης Horizontal and vertical lines going from desktop edges to cursor on snipping area. ΟÏιζόντιες και κάθετες γÏαμμές από τις άκÏες της επιφάνειας εÏγασίας μέχÏι τον δÏομέα στην πεÏιοχή της σÏλληψης. Show Snipping Area position and size info Εμφάνιση των πληÏοφοÏιών θέσης και μεγέθους στην πεÏιοχή σÏλληψης When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Όταν το αÏιστεÏÏŒ κλικ του Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï Î´ÎµÎ½ είναι πιεσμένο, εμφανίζεται η θέση. Όταν το κλικ του Ï€Î¿Î½Ï„Î¹ÎºÎ¹Î¿Ï ÎµÎ¯Î½Î±Î¹ πατημένο, το μέγεθος της επιλεγμένης πεÏιοχής εμφανίζεται στα αÏιστεÏά και κάτω από την πεÏιοχή σÏλληψης. Allow resizing rect area selection by default Îα επιτÏέπεται η αλλαγή μεγέθους της οÏθογώνιας πεÏιοχής επιλογής εξ οÏÎ¹ÏƒÎ¼Î¿Ï When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Όταν είναι ενεÏγοποιημένο και Î±Ï†Î¿Ï Î­Ï‡ÎµÎ¹ επιλεγεί μια οÏθογώνια πεÏιοχή, επιτÏέπει την αλλαγή μεγέθους της επιλογής. Μετά το πέÏας της ενέÏγειας επιβεβαιώστε πιέζοντας το πλήκτÏο Enter. Show Snipping Area info text Εμφάνιση του κειμένου πληÏοφοÏιών στην πεÏιοχή σÏλληψης Snipping Area cursor color ΧÏώμα του δÏομέα της πεÏιοχής σÏλληψης Sets the color of the snipping area cursor. ΟÏίζει το χÏώμα του δÏομέα της πεÏιοχής σÏλληψης. Snipping Area cursor thickness Πάχος του δÏομέα της πεÏιοχής σÏλληψης Sets the thickness of the snipping area cursor. ΟÏίζει το πάχος του δÏομέα της πεÏιοχής σÏλληψης. Snipping Area ΠεÏιοχή σÏλληψης Snipping Area adorner color ΧÏώμα διακόσμησης της πεÏιοχής σÏλληψης Sets the color of all adorner elements on the snipping area. ΟÏίζει το χÏώμα όλων των αντικειμένων διακόσμησης στην πεÏιοχή σÏλληψης. Snipping Area Transparency Διαφάνεια της πεÏιοχής σÏλληψης Alpha for not selected region on snipping area. Smaller number is more transparent. Άλφα για το με επιλεγμένο τμήμα της πεÏιοχής σÏλληψης. Με μικÏότεÏη τιμή αποκτάτε πεÏισσότεÏη διαφάνεια. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Πάνω Down Κάτω Use Default Stickers ΧÏήση των Ï€ÏοκαθοÏισμένων αυτοκόλλητων Sticker Settings Ρυθμίσεις αυτοκόλλητων Vector Image Files (*.svg) ΑÏχεία διανυσματικών εικόνων (*.svg) Add ΠÏοσθήκη Remove ΑφαίÏεση Add Stickers ΠÏοσθήκη αυτοκόλλητων TrayIcon Show Editor Εμφάνιση επεξεÏγαστή TrayIconSettings Use Tray Icon Εικονίδιο στο πλαίσιο συστήματος When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Όταν είναι ενεÏγοποιημένο Ï€Ïοστίθεται ένα εικονίδιο στο πλαίσιο συστήματος αν υποστηÏίζεται από τον διαχειÏιστή παÏαθÏÏων του λειτουÏÎ³Î¹ÎºÎ¿Ï ÏƒÏ…ÏƒÏ„Î®Î¼Î±Ï„Î¿Ï‚. Για να ληφθοÏν υπόψιν οι αλλαγές, απαιτείται επανεκκίνηση. Minimize to Tray Ελαχιστοποίηση στο πλαίσιο συστήματος Start Minimized to Tray Εκκίνηση ελαχιστοποιημένο στο πλαίσιο συστήματος Close to Tray Κλείσιμο στο πλαίσιο συστήματος Show Editor Εμφάνιση επεξεÏγαστή Capture ΣÏλληψη Default Tray Icon action ΠÏοκαθοÏισμένη ενέÏγεια του εικονιδίου στο πλαίσιο συστήματος Default Action that is triggered by left clicking the tray icon. Η Ï€ÏοκαθοÏισμένη ενέÏγεια που Ï€Ïοκαλείται με αÏιστεÏÏŒ κλικ στο εικονίδιο του πλαισίου συστήματος. Tray Icon Settings Ρυθμίσεις του εικονιδίου του πλαισίου συστήματος Use platform specific notification service ΧÏήση μιας ειδικής υπηÏεσίας ειδοποιήσεων του πλατÏβαθÏου When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Όταν είναι ενεÏγοποιημένο, θα γίνει Ï€Ïοσπάθεια χÏήσης της ειδικής υπηÏεσίας ειδοποιήσεων του πλατÏβαθÏου, εφόσον υπάÏχει μία. Για να λάβει χώÏα η αλλαγή αυτής της ÏÏθμισης απαιτείται επανεκκίνηση. Display Tray Icon notifications UpdateWatermarkOperation Select Image Επιλογή εικόνας Image Files UploadOperation Upload Script Required Απαιτείται μια μακÏοεντολή αποστολής Please add an upload script via Options > Settings > Upload Script ΠαÏακαλώ Ï€Ïοσθέστε μια μακÏοεντολή αποστολής από το Î¼ÎµÎ½Î¿Ï Î•Ï€Î¹Î»Î¿Î³Î­Ï‚ > Ρυθμίσεις > ΜακÏοεντολή αποστολής Capture Upload Αποστολή της σÏλληψης You are about to upload the image to an external destination, do you want to proceed? ΠÏόκειται να κάνετε αποστολή της εικόνας σε έναν εξωτεÏικό Ï€ÏοοÏισμό. Επιθυμείτε να συνεχίσετε; UploaderSettings Ask for confirmation before uploading ΕÏώτηση επιβεβαίωσης Ï€Ïιν την αποστολή Uploader Type: ΤÏπος αποστολέα: Imgur Imgur Script ΜακÏοεντολή Uploader Αποστολέας FTP VersionTab Version Έκδοση Build Κατασκευή Using: Γίνεται χÏήση: WatermarkSettings Watermark Image Εικόνα υδατογÏαφήματος Update ΕνημέÏωση Rotate Watermark ΠεÏιστÏοφή υδατογÏαφήματος When enabled, Watermark will be added with a rotation of 45° Όταν είναι ενεÏγοποιημένο, το υδατογÏάφημα θα εισαχθεί με πεÏιστÏοφή 45° Watermark Settings Ρυθμίσεις υδατογÏαφήματος ksnip-master/translations/ksnip_es.ts000066400000000000000000002073671457262621600204310ustar00rootroot00000000000000 AboutDialog About Acerca de About Acerca de Version Versión Author Autor Close Cerrar Donate Donar Contact Contacto AboutTab License: Licencia: Screenshot and Annotation Tool Herramienta de Captura de Pantalla y Anotación ActionSettingTab Name Nombre Shortcut Atajo Clear Limpiar Take Capture Tomar captura Include Cursor Incluir cursor Delay Retrasar s The small letter s stands for seconds. s Capture Mode Modo de captura Show image in Pin Window Mostrar imagen en la ventana de alfiler Copy image to Clipboard Copiar imagen al portapapeles Upload image Cargar imagen Open image parent directory Abrir directorio principal de imágenes Save image Guardar imagen Hide Main Window Ocultar la Ventana Principal Global Global When enabled will make the shortcut available even when ksnip has no focus. Cuando se activa hará que el acceso directo disponible incluso cuando ksnip no tenga foco. ActionsSettings Add Añadir Actions Settings Configuración de acciones Action Acción AddWatermarkOperation Watermark Image Required Imagen de marca de agua requerida Please add a Watermark Image via Options > Settings > Annotator > Update Agrega una Imagen de Marca de Agua via Opciones > Configuracion > Anotador > Actualizar AnnotationSettings Smooth Painter Paths Suavizar Rutas del dibujo When enabled smooths out pen and marker paths after finished drawing. Cuando está habilitado, suavizar pluma y trazados de marcador al terminar de dibujar. Smooth Factor Factor del suavizado Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Aumentar el factor del suavizado, disminuirá precisión para lápiz y marcador, los hará más suaves. Annotator Settings Ajustes del anotador Remember annotation tool selection and load on startup Recordar herramienta de selección y cargarla al iniciar Switch to Select Tool after drawing Item Cambiar a Selección de Herramienta después de dibujar Item Number Tool Seed change updates all Number Items El cambio de semilla de herramienta numérica actualiza todos los elementos numéricos Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. La desactivación de esta opción provoca cambios en la simiente de la herramienta numérica para afectar solo a los elementos nuevos, pero no a los existentes. Desactivar esta opción permite tener números duplicados. Canvas Color Color del lienzo Default Canvas background color for annotation area. Changing color affects only new annotation areas. Color de fondo del lienzo predeterminado para el área de anotaciones. El cambio de color afecta solo a las áreas de anotación nuevas. Select Item after drawing Seleccionar Elemento tras dibujar With this option enabled the item gets selected after being created, allowing changing settings. Con esta opción seleccionada, los elementos se seleccionan después de ser creados, permitiendo cambiar la configuración. Show Controls Widget Mostrar controles del Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Los controles del Widget contiene los botones Deshacer/Rehacer, Recortar, Escalar, Rotar y Modificar lienzo. ApplicationSettings Capture screenshot at startup with default mode Captura de pantalla al inicio con el modo predeterminado Application Style Estilo de aplicación Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Establece el estilo de la aplicación que define la apariencia de la GUI El cambio requiere el reinicio de ksnip para que tenga efecto. Application Settings Ajustes de la aplicación Automatically copy new captures to clipboard Copiar automáticamente al portapapeles las nuevas capturas Use Tabs Usar pestañas Change requires restart. El cambio requiere reiniciar. Run ksnip as single instance Mantener ksnip como una única instancia al abrirla nuevamente Hide Tabbar when only one Tab is used. Ocultar barra de pestañas solo cuando una pestaña está en uso. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Habilitando esta opción permitirá que solo una instancia de ksnip inicie, el resto de las instancias iniciadas después pasarán sus argumentos a la primera y se cerrarán. Cambiar esta opción requiere un nuevo inicio de todas las instancias. Remember Main Window position on move and load on startup Al mover la ventana principal recordar la posición y restaurarla al iniciar Auto hide Tabs Ocultar automáticamente las pestañas Auto hide Docks Ocultar automáticamente los Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Al inicio ocultar la barra de herramientas y las opciones de comentarios. Se puede alternar la visibilidad del Dock con el tabulador. Auto resize to content Cambiar de tamaño automáticamente al contenido Automatically resize Main Window to fit content image. Cambie automáticamente el tamaño de la ventana principal para que se ajuste a la imagen del contenido. Enable Debugging Activar depuración Enables debug output written to the console. Change requires ksnip restart to take effect. Activa la salida de depuración en consola. Este cambio require reiniciar ksnip. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Cambiar el tamaño al contenido es un retraso para permitir que el Administrador de ventanas reciba el nuevo contenido. En caso de que la ventana principal no esté correctamente ajustada al nuevo contenido, aumentar este retraso podría mejorar el comportamiento. Resize delay Retraso en el cambio del tamaño Temp Directory Directorio temporal Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Directorio temporal utilizado para almacenar imágenes temporales que se eliminará después de que se cierre ksnip. Browse Navegar AuthorTab Contributors: Colaboradores: Spanish Translation Traducción al castellano Dutch Translation Traducción al neerlandés Russian Translation Traducción al ruso Norwegian BokmÃ¥l Translation Traducción al noruego «bokmÃ¥l» French Translation Traducción al francés Polish Translation Traducción al polaco Snap & Flatpak Support Compatibilidad con Snap y Flatpak The Authors: Autores: CanDiscardOperation Warning - Advertencia - The capture %1%2%3 has been modified. Do you want to save it? La captura %1%2%3 ha sido modificada ¿Desea guardar? CaptureModePicker New Nuevo Draw a rectangular area with your mouse Dibuje un área rectangular con el ratón Capture full screen including all monitors Capturar pantalla completa, incluidos todos los monitores Capture screen where the mouse is located Capturar pantalla donde se localiza el ratón Capture window that currently has focus Capturar ventana que actualmente tiene el foco Capture that is currently under the mouse cursor Captura que se encuentra actualmente debajo del cursor del mouse Capture a screenshot of the last selected rectangular area Realiza una captura de pantalla de la última área rectangular seleccionada Uses the screenshot Portal for taking screenshot Usa el portal de capturas para tomar capturas ContactTab Community Comunidad Bug Reports Reporte de errores If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Si tiene preguntas generales, ideas o simplemente quiere hablar sobre ksnip,<br/>únase a nuestro %1 o nuestro %2 servidor. Please use %1 to report bugs. Utilice %1 para informar errores. CopyAsDataUriOperation Failed to copy to clipboard No se pudo copiar al portapapeles Failed to copy to clipboard as base64 encoded image. No se pudo copiar al portapapeles como imagen codificada en base64. Copied to clipboard Copiado al portapapeles Copied to clipboard as base64 encoded image. Copiado al portapapeles como imagen codificada en base64. DeleteImageOperation Delete Image Eliminar imagen The item '%1' will be deleted. Do you want to continue? Se eliminará el elemento «%1». ¿Quiere continuar? DonateTab Donations are always welcome Las donaciones son siempre bienvenidas Donation Donación ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip es un proyecto de software libre copyleft no rentable, y<br/>todavía tiene algunos costos que deben cubrirse,<br/>como costos de dominio o costos de hardware para el soporte multiplataforma. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Si desea ayudar o simplemente desea apreciar el trabajo que se está realizando<br/>invitando a los desarrolladores a tomar una cerveza o un café, puede hacerlo %1aquí%2. Become a GitHub Sponsor? ¿Convertirse en patrocinador de GitHub? Also possible, %1here%2. También es posible, %1aquí%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Agregue nuevas acciones presionando el botón de la pestaña 'Agregar'. EnumTranslator Rectangular Area Ãrea rectangular Last Rectangular Area Última área rectangular Full Screen (All Monitors) Pantalla completa (todos los monitores) Current Screen Pantalla actual Active Window Ventana activa Window Under Cursor Ventana bajo el puntero Screenshot Portal Portal de capturas FtpUploaderSettings Force anonymous upload. Forzar subida anónima. Url Url Username Usuario Password Clave FTP Uploader Cargador FTP HandleUploadResultOperation Upload Successful Subida con éxito Unable to save temporary image for upload. Incapaz de guardar temporalmente la imagen para subir. Unable to start process, check path and permissions. Incapaz de iniciar el proceso, revise la ruta y los permisos. Process crashed Proceso se cayó Process timed out. Proceso con tiempo de espera agotado. Process read error. Proceso con error de lectura. Process write error. Proceso con error de escritura. Web error, check console output. Error Web, revise la salida en la consola. Upload Failed Subida fallida Script wrote to StdErr. El script escribió en StdErr. FTP Upload finished successfully. Carga FTP finalizada con éxito. Unknown error. Error desconocido. Connection Error. Error de conexión. Permission Error. Error de permiso. Upload script %1 finished successfully. El script de carga %1 finalizó correctamente. Uploaded to %1 Subido a %1 HotKeySettings Enable Global HotKeys Activar atajos de teclado globales Capture Rect Area Capturar área rectangular Capture Full Screen Capturar pantalla completa Capture current Screen Capturar pantalla actual Capture active Window Capturar ventana activa Capture Window under Cursor Capturar ventana bajo el puntero Global HotKeys Atajos de teclado globales Capture Last Rect Area Captura la última área rectangular Clear Limpiar Capture using Portal Capturar mediante portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Actualmente, las teclas de acceso rápido solo son compatibles con Windows y X11. La desactivación de esta opción también hace que los atajos de acción sean solo en ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Capturar el cursor del ratón en la captura de pantalla Should mouse cursor be visible on screenshots. El cursor del mouse debe estar visible sobre las capturas de pantalla. Image Grabber Capturador de imágenes Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Implementaciones genéricas de Wayland que utilizan Escalado de pantalla de control XDG-DESKTOP-PORTAL diferentemente. Habilitar esta opción determinar la escala de pantalla actual y aplicar eso a la captura de pantalla en ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME y KDE Plasma admiten su propio Wayland y las capturas de pantalla genéricas de XDG-DESKTOP-PORTAL. Habilitar esta opción forzará KDE Plasma y GNOME para usar las capturas de pantalla de XDG-DESKTOP-PORTAL. El cambio en esta opción requiere un reinicio de ksnip. Show Main Window after capturing screenshot Mostrar ventana principal después de una captura de pantalla Hide Main Window during screenshot Ocultar la ventana principal durante una captura de pantalla Hide Main Window when capturing a new screenshot. Ocultar la ventana principal al realizar una nueva captura de pantalla. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Mostrar ventana principal después de capturar una nueva captura de pantalla cuando la ventana principal estaba oculta o minimizada. Force Generic Wayland (xdg-desktop-portal) Screenshot Forzar Genérico Wayland (xdg-desktop-portal) Captura de pantalla Scale Generic Wayland (xdg-desktop-portal) Screenshots Escala Genérica Wayland (xdg-desktop-portal) Captura de pantalla Implicit capture delay Retraso implícito de la captura This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Este retraso se utiliza cuando no se seleccionó ningún retraso en la interfaz del usuario, permite que ksnip se oculte antes de tomar una captura de pantalla. Este valor no se aplica cuando ksnip ya estaba minimizado. Reduciendo este valor puede tener el efecto de que la ventana principal de ksnip es visible en la captura de pantalla. ImgurHistoryDialog Imgur History Historial Imgur Close Cerrar Time Stamp Cronomarcador Link Enlace Delete Link Eliminar enlace ImgurUploader Upload to imgur.com finished! Finalizó la carga en imgur.com! Received new token, trying upload again… Se recibió una ficha nueva; reintentando la carga… Imgur token has expired, requesting new token… La ficha de Imgur ha caducado; solicitando una nueva… ImgurUploaderSettings Force anonymous upload Forzar carga anónima Always copy Imgur link to clipboard Siempre copiar enlace de Imgur al portapapeles Client ID Id. de cliente Client Secret Secreto de cliente PIN PIN Enter imgur Pin which will be exchanged for a token. Introduzca el PIN de Imgur, que se intercambiará por una ficha. Get PIN Obtener PIN Get Token Obtener ficha Imgur History Historial de Imgur Imgur Uploader Cargador de Imgur Username Nombre de usuario Waiting for imgur.com… Esperando a imgur.com… Imgur.com token successfully updated. Se actualizó la ficha de Imgur.com correctamente. Imgur.com token update error. Error de actualización de la ficha de Imgur.com. After uploading open Imgur link in default browser Después de subir, abra el enlace de Imgur en el navegador predeterminado Link directly to image Enlazar directamente a la imagen Base Url: URL de base: Base url that will be used for communication with Imgur. Changing requires restart. El URL de base que se utilizará para la comunicación con Imgur. Cambiarlo requiere reiniciar. Clear Token Limpiar Token Upload title: Cargar el título: Upload description: Cargar la descripción: LoadImageFromFileOperation Unable to open image No se puede abrir la imagen Unable to open image from path %1 No se puede abrir la imagen de la ruta% 1 MainToolBar New Nuevo Delay in seconds between triggering and capturing screenshot. Demora en segundos entre la activación y la captura de pantalla. s The small letter s stands for seconds. s Save Guardar Save Screen Capture to file system Guardar captura de pantalla en el sistema de archivos Copy Copiar Copy Screen Capture to clipboard Copiar captura de pantalla en el portapapeles Tools Herramientas Undo Deshacer Redo Rehacer Crop Recortar Crop Screen Capture Recortar captura de pantalla MainWindow Unsaved No guardado Upload Cargar Print Imprimir Opens printer dialog and provide option to print image Abre el cuadro de diálogo de la impresora y proporciona la opción para imprimir la imagen Print Preview Previsualizar impresión Opens Print Preview dialog where the image orientation can be changed Abre el cuadro de diálogo Previsualizar impresión, donde se puede cambiar la orientación de la imagen Scale Escalar Quit Salir Settings Configuración &About &Acerca de Open Abrir &Edit &Editar &Options &Opciones &Help Ay&uda Add Watermark Añadir marca de agua Add Watermark to captured image. Multiple watermarks can be added. Añade la marca de agua a la imagen capturada. Se pueden añadir múltiples marcas de agua. &File &Archivo Unable to show image No se puede mostrar la imagen Save As... Guardar como... Paste Pegar Paste Embedded Pegar incrustado Pin Fijar Pin screenshot to foreground in frameless window Fijar captura de pantalla en primer plano, en una ventana sin bordes No image provided but one was expected. No se proporcionó ninguna imagen aunque se esperaba una. Copy Path Copiar ruta Open Directory Abrir directorio &View &Ver Delete Eliminar Rename Renombrar Open Images Abrir imagenes Show Docks Mostrar muelles Hide Docks Esconder Docks Copy as data URI Copiar como URI de datos Open &Recent Abierto & reciente Modify Canvas Modificar lienzo Upload triggerCapture to external source Cargar captura de disparo a una fuente externa Copy triggerCapture to system clipboard Copiar captura de disparador al portapapeles del sistema Scale Image Escalar Imagen Rotate Girar Rotate Image Rotar Imagen Actions Acciones Image Files Archivos de Imagen Save All Guardar todo Close Window Cerrar la ventana Cut Cortar OCR Reconocimiento óptico de caracteres (OCR) MultiCaptureHandler Save Guardar Save As Guardar como Open Directory Abrir directorio Copy Copiar Copy Path Copiar ruta Delete Eliminar Rename Renombrar Save All Guardar todo NewCaptureNameProvider Capture Capturar OcrWindowCreator OCR Window %1 Ventana OCR %1 PinWindow Close Cerrar Close Other Cerrar otros Close All Cerrar todos PinWindowCreator OCR Window %1 Ventana OCR %1 PluginsSettings Search Path Ruta de la búsqueda Default Por defecto The directory where the plugins are located. El directorio donde se encuentran los complementos. Browse Navegar Name Nombre Version Versión Detect Detectar Plugin Settings Configuración del complemento Plugin location Ubicación del complemento ProcessIndicator Processing Procesando RenameOperation Image Renamed Imagen renombrada Image Rename Failed Fallo al renombrar la imagen Rename image Renombrar imagen New filename: Nuevo nombre de archivo: Successfully renamed image to %1 Imagen renombrada correctamente a %1 Failed to rename image to %1 Error al cambiar el nombre de la imagen a %1 SaveOperation Save As Guardar como All Files Todos los archivos Image Saved Imagen guardada Saving Image Failed No se pudo guardar la imagen Image Files Archivos de Imagen Saved to %1 Salvado a %1 Failed to save image to %1 Error al guardar la imagen en %1 SaverSettings Automatically save new captures to default location Guardar automáticamente las capturas nuevas a la ubicación predeterminada Prompt to save before discarding unsaved changes Preguntar antes de descartar cambios no guardados Remember last Save Directory Recordar última carpeta de guardado When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Cuando está habilitado, sobreescribe la última carpeta guardada en las configuraciones con la última carpeta en donde se guarda, esto lo hace en cada guardado. Capture save location and filename Captura la ubicación de guardado y el nombre del archivo Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Los formatos soportados son JPG, PNG and BMP. Si no se indica un formato, se usará PNG por defecto. El nombre del archivo puede contener los siguientes comodines: - $Y, $M, $D para la fecha, $h, $m, $s para la hora, or $T para hora en el formato hhmmss. - Multiples consecutivos # para un correlativo. #### generará un 0001, siguiente captura será 0002. Browse Examinar Saver Settings Configuraciones de guardado Capture save location Ubicación de guardado de capturas Default Predeterminado Factor Factor Save Quality Calidad de guardado Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Defina 0 para obtener archivos pequeños y comprimidos, 100 para archivos grandes y sin comprimir. No todos los formatos de imagen son compatibles con la gama completa, JPEG sí lo es. Overwrite file with same name Sobrescribir archivo con el mismo nombre ScriptUploaderSettings Copy script output to clipboard Copiar salida de la secuencia en el portapapeles Script: Secuencia de órdenes: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Ruta a la secuencia que se llamará para la carga. Durante la carga la secuencia se invocará con la ruta a un archivo PNG temporal como único argumento. Browse Examinar Script Uploader Cargador por secuencia Select Upload Script Seleccione secuencia de carga Stop when upload script writes to StdErr Detener cuando la secuencia de carga escriba en la salida de errores estándar Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Marca la carga como fallida cuando el script escribe en StdErr. Sin esta configuración, los errores en el script pasarán desapercibidos. Filter: Filtro: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Expresión RegEx. Solo copie al portapapeles lo que coincida con la expresión RegEx. Cuando se omite, se copia todo. SettingsDialog Settings Ajustes OK Aceptar Cancel Cancelar Image Grabber Capturador de imágenes Imgur Uploader Cargador de Imgur Application Aplicación Annotator Anotador HotKeys Atajos de teclado Uploader Cargador Script Uploader Cargar con secuencia Saver Guardado Stickers Adhesivos Snipping Area Ãrea de recorte Tray Icon Icono de bandeja Watermark Marca de Agua Actions Acciones FTP Uploader Cargador FTP Plugins Complementos Search Settings... Opciones de la búsqueda... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Cambie el tamaño del rectángulo seleccionado usando las manijas o muévalo arrastrando la selección. Use arrow keys to move the selection. Utilice las teclas de flecha para mover la selección. Use arrow keys while pressing CTRL to move top left handle. Use las teclas de flecha mientras presiona CTRL para mover la manija superior izquierda. Use arrow keys while pressing ALT to move bottom right handle. Use las teclas de flecha mientras presiona ALT para mover la manija inferior derecha. This message can be disabled via settings. Este mensaje se puede desactivar a través de la configuración. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Confirme la selección presionando ENTER/RETURN o haciendo doble clic en cualquier lugar con el ratón. Abort by pressing ESC. Cancele presionando la tecla ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Haga clic y arrastre para seleccionar un área rectangular o presione ESC para salir. Hold CTRL pressed to resize selection after selecting. Mantenga presionada la tecla CTRL para cambiar el tamaño de la selección después de seleccionarla. Hold CTRL pressed to prevent resizing after selecting. Mantenga presionada la tecla CTRL para evitar cambiar el tamaño después de seleccionar. Operation will be canceled after 60 sec when no selection made. La operación se cancelará después de 60 segundos cuando no se realice ninguna selección. This message can be disabled via settings. Este mensaje se puede desactivar a través de la configuración. SnippingAreaSettings Freeze Image while snipping Congele la imagen mientras se corta When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Cuando está habilitado, congelará el fondo mientras seleccionando una región rectangular. También cambia el comportamiento de las capturas de pantalla retrasadas, con esto opción habilitada, el retraso ocurre antes de que se muestra el área de recorte y con la opción desactivada el retraso ocurre después de que se muestra el área de recorte. Esta función siempre está desactivada para Wayland y siempre habilitado para MacOs. Show magnifying glass on snipping area Mostrar lupa en el área de recorte Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Muestra una lupa que se acerca a la imagen de fondo. Esta opción solo funciona con la opción "Congelar la imagen mientras se corta" activada. Show Snipping Area rulers Mostrar reglas del área de recorte Horizontal and vertical lines going from desktop edges to cursor on snipping area. Líneas horizontales y verticales que van desde los bordes del escritorio al cursor en el área de corte. Show Snipping Area position and size info Mostrar la posición del área de corte y la información del tamaño When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Cuando no se presiona el botón izquierdo del mouse, se muestra la posición, cuando se presiona el botón del mouse, el tamaño del área seleccionada se muestra a la izquierda y arriba del área capturada. Allow resizing rect area selection by default Permitir cambiar el tamaño de la selección del área recta por defecto When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Cuando está habilitado, después de seleccionar una area recta, permite cambiar el tamaño de la selección. Cuando terminado de cambiar el tamaño de la selección se puede confirmar presionando regresar. Show Snipping Area info text Mostrar información del área de recorte Snipping Area cursor color Color del cursor de área de corte Sets the color of the snipping area cursor. Establece el color del cursor del área de recorte. Snipping Area cursor thickness Grosor del cursor del área de recorte Sets the thickness of the snipping area cursor. Establece el grosor del cursor del área de recorte. Snipping Area Ãrea de recorte Snipping Area adorner color Color del recuadro de recorte Sets the color of all adorner elements on the snipping area. Establece el color de todos los elementos de adorno en el área de corte. Snipping Area Transparency Transparencia del area de recorte Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa para la región no seleccionada en el área de recorte. El número más pequeño es más transparente. Enable Snipping Area offset Usar la compensación del área de la captura When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Si se activa, se aplicará el desplazamiento a la posición del área de recorte cuando la posición no se calculada correctamente. Esto es a veces con el escalado de pantalla activado. X X Y Y StickerSettings Up Arriba Down Abajo Use Default Stickers Utilizar adhesivos predeterminados Sticker Settings Configuración de adhesivos Vector Image Files (*.svg) Archivos de imagen vectorial (*.svg) Add Añadir Remove Remover Add Stickers Adicionar pegatina TrayIcon Show Editor Mostrar editor TrayIconSettings Use Tray Icon Usar icono de bandeja When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Al activarse, añadirá un icono de bandeja a la barra de tareas si el administrador de ventanas del sistema operativo lo admite. El cambio requiere que se reinicie. Minimize to Tray Minimizar a la bandeja Start Minimized to Tray Iniciar minimizado en la bandeja Close to Tray Cierre a la Bandeja Show Editor Mostrar editor Capture Capturar Default Tray Icon action Acción por defecto del icono de bandeja Default Action that is triggered by left clicking the tray icon. Acción por defecto de clic izquierdo en el icono de la bandeja. Tray Icon Settings Configuración del icono de bandeja Use platform specific notification service Usar el servicio de notificaciones del sistema When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Cuando esté habilitado, intentará usar el servicio de notificación específico de la plataforma cuando exista. El cambio requiere reiniciar para tener efecto. Display Tray Icon notifications Mostrar notificaciones del icono de la bandeja UpdateWatermarkOperation Select Image Seleccionar imagen Image Files Archivos de imagen UploadOperation Upload Script Required Se requiere la secuencia de carga Please add an upload script via Options > Settings > Upload Script Añada una secuencia de carga en Opciones â–¸ Configuración â–¸ Secuencia de carga Capture Upload Carga de captura You are about to upload the image to an external destination, do you want to proceed? Está a punto de cargar la imagen en un destino externo. ¿Quiere continuar? UploaderSettings Ask for confirmation before uploading Pedir confirmación antes de cargar Uploader Type: Tipo de cargador: Imgur Imgur Script Secuencia de órdenes Uploader Subir imagen FTP FTP VersionTab Version Versión Build Construcción Using: Usando: WatermarkSettings Watermark Image Imagen de marca de agua Update Actualización Rotate Watermark Rotar la marca de agua When enabled, Watermark will be added with a rotation of 45° Cuando esté activada, la marca de agua se añadirá con una rotación de 45° Watermark Settings Configuración de marca de agua ksnip-master/translations/ksnip_eu.ts000066400000000000000000002041121457262621600204140ustar00rootroot00000000000000 AboutDialog About Honi buruz About Honi buruz Version Bertsioa Author Egilea Donate Diruz lagundu Close Itxi Contact Kontaktua AboutTab License: Lizentzia: Screenshot and Annotation Tool Pantaila argazkia eta oharrak hartzeko tresna ActionSettingTab Name Izena Shortcut Lasterbidea Clear Garbitu Take Capture Argazkia egin Include Cursor Kurtsorea hartu Delay Atzerapena s The small letter s stands for seconds. s Capture Mode Argazki modua Show image in Pin Window Erakutsi irudia finkatutako leihoan Copy image to Clipboard Kopiatu irudia arbelera Upload image Kargatu irudia Open image parent directory Ireki irudien direktorio nagusia Save image Gorde irudia Hide Main Window Ezkutatu leiho nagusia Global Orokorra When enabled will make the shortcut available even when ksnip has no focus. Gaituta dagoenean lasterbidea egingo du eskuragarri ksnip-ek fokurik ez duenean ere. ActionsSettings Add Gehitu Actions Settings Ekintzen ezarpenak Action Ekintza AddWatermarkOperation Watermark Image Required Ur-markarako irudia behar da Please add a Watermark Image via Options > Settings > Annotator > Update Ur-markarako irudia gehitu honela Aukerak > Ezarpenak > Ohar-hartzailea > Eguneratu AnnotationSettings Smooth Painter Paths Leundu marrazkien lineak When enabled smooths out pen and marker paths after finished drawing. Aktibatuta dagoenean, leundu arkatza eta markatzailearen lerroak marrazketa bukatzean. Smooth Factor Leuntze faktorea Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Leuntze faktorean handitzeak arkatza eta markatzailearen zehaztasun galera dakar, haien leuntasuna areagotuz. Annotator Settings Nabarmentzearen ezarpenak Remember annotation tool selection and load on startup Gogoratu ohargilearen hautaketa eta kargatu abiatzean Switch to Select Tool after drawing Item Aldatu Hautatu tresnara elementua marraztu ondoren Number Tool Seed change updates all Number Items Zenbakien tresna aldatzean zenbaki elementu guztiak eguneratzen dira Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Aukera hau desgaitzeak zenbakien tresnan aldaketak eragiten ditu soilik elementu berrietan, baina ez dauden elementuak. Aukera hau desgaitzeak zenbaki bikoiztuak edukitzea ahalbidetzen du. Canvas Color Oihalaren kolorea Default Canvas background color for annotation area. Changing color affects only new annotation areas. Oharpen-eremurako oihalaren atzeko planoaren kolore lehenetsia. Koloreak aldatzeak oharpen gune berriei eragiten die. Select Item after drawing Hautatu elementua marraztu ondoren With this option enabled the item gets selected after being created, allowing changing settings. Aukera hau gaituta dagoenean, elementua hautatuta geratzen da sortu ondoren, hartara ezarpenak aldatu daitezke. Show Controls Widget Erakutsi kontrolen widgeta The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Kontrolen widgetak du: Desegin/Berregin, Moztu, Eskalatu, Biratu eta Aldatu Canvas botoiak. ApplicationSettings Capture screenshot at startup with default mode Kapturatu pantaila-argazkia abiaraztean modu lehenetsian Application Style Aplikazioaren estiloa Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Erabiltzailearen Interfaze Grafikoaren itxura ezartzen du. Ksnip berrabiarazi behar du aldaketek eragina izateko. Application Settings Aplikazioaren ezarpenak Automatically copy new captures to clipboard Kopiatu kaptura berriak arbelera automatikoki Use Tabs Erabili fitxak Change requires restart. Aldaketak berrabiaraztea eskatzen du. Run ksnip as single instance Erabili ksnip instantzia bakarrean Hide Tabbar when only one Tab is used. Ezkutatu fitxen barra fitxa bakarra dagoenean. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Aukera hau gaituz gero ksnip instantzia bakarra exekutatu ahal izango da, haren ondoren abiatutako beste instantziek lehenegoari pasatuko diote euren argumentuak eta itxiko dira. Aukera hau aldatzeak instantzia guztiak berrabiaraztea eskatzen du. Remember Main Window position on move and load on startup Gogoratu leiho nagusiaren kokapena mugitzean eta kargatu abioan Auto hide Tabs Ezkutatu fitxak automatikoki Auto hide Docks Auto ezkutatu kaiak On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Ezkutatu tresna barra eta oharpen ezarpenak abiatzean. Kaien ikusgarritasuna Tab teklarekin txandakatu daiteke. Auto resize to content Aldatu automatikoki tamainara egokituz Automatically resize Main Window to fit content image. Aldatu automatikoki leiho nagusiaren tamaina edukiaren irudira doitzeko. Enable Debugging Gaitu arazketa Enables debug output written to the console. Change requires ksnip restart to take effect. Arazte-irteera gaitzen du kontsolan idatzita. Ksnip berrabiarazi behar da eragina izateko. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Edukira doitzeko atzerapena Leiho-kudeatzaileari eduki berria jaso ahal izateko atzerapena da. Leiho nagusia eduki berrira behar bezala doitzen ez bada, atzerapen hori handitzeak portaera hobe dezake. Resize delay Aldatu atzerapena Temp Directory Temp direktorioa Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Temp direktorioa aldi baterako irudiak gordetzeko erabiltzen da, ksnip itxi ondoren ezabatu egingo da. Browse Arakatu AuthorTab Contributors: Laguntzaileak: Spanish Translation Gaztelerako itzulpena Dutch Translation Alemanerako itzulpena Russian Translation Errusierako itzulpena Norwegian BokmÃ¥l Translation Norvegierako itzulpena French Translation Frantseserako itzulpena Polish Translation Polonierako itzulpena Snap & Flatpak Support Snap eta Flatpak euskarria The Authors: Egileak: CanDiscardOperation Warning - Oharra - The capture %1%2%3 has been modified. Do you want to save it? %1%2%3 argazkia aldatu da. Nahi duzu gordetzea? CaptureModePicker New Berria Draw a rectangular area with your mouse Marraztu area laukizuzena saguaren bidez Capture a screenshot of the last selected rectangular area Egin pantailan hautatutako azken area laukizuzenaren argazkia Capture full screen including all monitors Egin monitore guztiak barne hartzen dituen pantaila-argazkia Capture screen where the mouse is located Egin sagua kokatuta dagoen pantailaren argazkia Capture window that currently has focus Egin fokuratuta dagoen leihoaren argazkia Capture that is currently under the mouse cursor Egin kurtsorearen azpian dagoenaren argazkia Uses the screenshot Portal for taking screenshot Pantaila-argazkien ataria erabiltzen du pantaila-argazkia egiteko ContactTab Community Komunitatea Bug Reports Erroreen txostenak If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Galdera orokorrak edo ideiak badituzu edo ksnip-i buruz hitz egin nahi baduzu,<br/>sartu gure %1 edo %2 zerbitzarian. Please use %1 to report bugs. Erabili %1 akatsen berri emateko. CopyAsDataUriOperation Failed to copy to clipboard Arbelera kopiatzeak huts egin du Failed to copy to clipboard as base64 encoded image. Arbelera base54 kodetutako irudi gisa kopiatzeak huts egin du. Copied to clipboard Arbelera kopiatu da Copied to clipboard as base64 encoded image. Arbelera base64 kodetutako irudi gisa kopiatu da. DeleteImageOperation Delete Image Ezabatu irudia The item '%1' will be deleted. Do you want to continue? '%1' elementua ezabatuko da. Jarraitu nahi duzu? DonateTab Donations are always welcome Diru-laguntzak beti dira ongi etorriak Donation Dohaintza ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip irabazi asmorik gabeko copyleft libreko software proiektu bat da, eta<br/>oraindik estali beharreko kostu batzuk ditu,<br/>esaterako, domeinu-kostuak edo hardware-kostuak plataforma anitzeko zerbitzua emateko. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Garatzaileei garagardo bat edo kafe bat gonbidatuz lagundu nahi baduzu edo besterik gabe eskertu nahi baduzu egiten ari den lana<br/>, %1 hemen%2 egin dezakezu. Become a GitHub Sponsor? Githuben babeslea izan nahi duzu? Also possible, %1here%2. Hori ere posible da, %1hemen%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Gehitu ekintza berriak 'Gehitu' fitxaren botoia sakatuta. EnumTranslator Rectangular Area Area laukizuzena Last Rectangular Area Azken area laukizuzena Full Screen (All Monitors) Pantaila osoa (monitore guztiak) Current Screen Uneko pantaila Active Window Leiho aktiboa Window Under Cursor Kurtsorearen azpiko leihoa Screenshot Portal Pantaila argazkien ataria FtpUploaderSettings Force anonymous upload. Behartu karga anonimoa. Url Url Username Erabiltzaile-izena Password Pasahitza FTP Uploader FTP kargatzailea HandleUploadResultOperation Upload Successful Karga ongi burutu da Unable to save temporary image for upload. Ezin izan da irudia behin behinean gorde kargatzeko. Unable to start process, check path and permissions. Ezin izan da prozesua abiarazi, begiratu bidea eta baimenak. Process crashed Prozesuak huts egin du Process timed out. Prozesuaren epemuga agortu da. Process read error. Prozesuaren irakurketa errorea. Process write error. Prozesuaren idazketa errorea. Web error, check console output. Web errorea, begiratu kontsolaren irteera. Upload Failed Kargak huts egin du Script wrote to StdErr. StdErr-ra bidalitako scripta. FTP Upload finished successfully. FTP karga behar bezala burutu da. Unknown error. Errore ezezaguna. Connection Error. Konexio errorea. Permission Error. Baimen errorea. Upload script %1 finished successfully. % 1 script-aren karga behar bezala amaitu da. Uploaded to %1 %1-era kargatu da HotKeySettings Enable Global HotKeys Aktibatuta laster-tekla globalak Capture Rect Area Egin laukizuzenaren arearen argazkia Capture Last Rect Area Egin azken laukizuzenaren arearen argazkia Capture Full Screen Egin pantaila osoaren argazkia Capture current Screen Egin uneko pantailaren argazkia Capture active Window Egin leiho aktiboaren argazkia Capture Window under Cursor Egin kurtsore azpiko leihoaren argazkia Global HotKeys Laster-tekla orokorrak Clear Garbitu Capture using Portal Egin argazkia atariaren bidez HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Laster-teklak une honetan bakarrik onartzen dira Windows eta X11n. Aukera hau desgaituz gero, ekintza lasterbideak ksnip-en soilik izango dira. ImageGrabberSettings Capture mouse cursor on screenshot Kurtsorea sartu pantailaren argazkian Should mouse cursor be visible on screenshots. Kurtsorea pantailen argazkietan ikusiko da. Image Grabber Irudien kapturatzailea Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. XDG-DESKTOP-PORTAL erabiltzen duten Wayland inplementazio generikoak pantailaren eskalatzea desberdin egiten du. Aukera hau gaituz gero zehaztu uneko pantailaren eskala eta aplikatu hori ksnip-eko pantailan. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOMEk eta KDE Plasma-k onartzen ditu beren Wayland eta XDG-DESKTOP-PORTAL generikoaren pantaila-argazkiak. Aukera hau gaitzeak behartzen ditu KDE Plasma eta GNOME pantaila-argazkiak XDG-DESKTOP-PORTALaren bidez egiten. Aukera hau aldatzeak ksnip berrabiaraztea eskatzen du. Show Main Window after capturing screenshot Erakutsi leiho nagusia pantaila-argazkia egin ondoren Hide Main Window during screenshot Ezkutatu leiho nagusia pantaila-argazkiak egitean Hide Main Window when capturing a new screenshot. Ezkutatu leiho nagusia pantaila-argazki berria egitean. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Erakutsi leiho nagusia pantaila argazki berri bat egin ondoren leiho nagusia ezkutuan edo minimizatuta dagoenean. Force Generic Wayland (xdg-desktop-portal) Screenshot Behartu Generic Wayland (xdg-desktop-portal) pantaila-argazkia Scale Generic Wayland (xdg-desktop-portal) Screenshots Eskalatu Generic Wayland (xdg-desktop-portal) pantaila-argazkia Implicit capture delay Kapturaren atzerapen inplizitua This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Atzerapen hau atzerapenik hautatu ez denean erabiltzen da, Ksnip pantaila-argazki bat egin aurretik ezkutatzeko aukera ematen du. Balio hau ez da aplikatzen Ksnip dagoeneko minimizatuta badago. Balio hori murrizteak eragin dezake Ksnip-en leiho nagusia pantaila-argazkian agertzea. ImgurHistoryDialog Imgur History Imgur historia Close Itxi Time Stamp Denbora-zigilua Link Esteka Delete Link Ezabatu esteka ImgurUploader Upload to imgur.com finished! imgur.com gunera kargatu da! Received new token, trying upload again… Token berri bat jaso da, berriro kargatzen saiatzen… Imgur token has expired, requesting new token… Imgur-en tokena iraungi da, token berria eskatzen… ImgurUploaderSettings Force anonymous upload Behartu karga anonimoa After uploading open Imgur link in default browser Kargatu ondoren ireki Imgur-en esteka lehenetsitako nabigatzailean Link directly to image Estekatu irudia zuzenean Always copy Imgur link to clipboard Kopiatu beti Imgur-en esteka arbelera Client ID Bezeroaren ID Client Secret Bezeroaren sekretua PIN PINa Enter imgur Pin which will be exchanged for a token. Sartu imgur-en Pina haren truke tokena eskuratzeko. Get PIN Eskuratu PINa Get Token Eskuratu tokena Imgur History Imgur historia Imgur Uploader Imgur-en kargatzailea Username Erabiltzaile-izena Waiting for imgur.com… imgur.com-en zain… Imgur.com token successfully updated. Imgur.com-en tokena behar bezala eguneratu da. Imgur.com token update error. Imgur.com-en tokenaren eguneraketak huts egin du. Base Url: Url oinarria: Base url that will be used for communication with Imgur. Changing requires restart. Imgur-ekin komunikatzeko erabiliko den url oinarria. Aldatzeak berrabiaraztea eskatzen du. Clear Token Garbitu Tokena Upload title: Kargatu izenburua: Upload description: Kargatu deskribapena: LoadImageFromFileOperation Unable to open image Ezin izan da irudia ireki Unable to open image from path %1 Ezin izan da irudia path %1-tik ireki MainToolBar New Berria Delay in seconds between triggering and capturing screenshot. Atzerapena segundotan aktibazioa eta pantaila-argazkiaren artean. s The small letter s stands for seconds. s Save Gorde Save Screen Capture to file system Gorde pantaila-argazkia fitxategi-sisteman Copy Kopiatu Copy Screen Capture to clipboard Kopiatu pantaila-argazkia arbelera Undo Desegin Redo Berregin Crop Moztu Crop Screen Capture Moztu pantaila-argazkia Tools Tresnak MainWindow Unable to show image Ezin da irudia erakutsi Unsaved Gorde gabe Upload Kargatu Print Inprimatu Opens printer dialog and provide option to print image Irekitzen du inprimagailuaren elkarrizketa-koadroa eta irudia inprimatzeko aukera ematen du Print Preview Inprimatzeko aurrebista Opens Print Preview dialog where the image orientation can be changed Irekitzen du inprimatzeko aurrebistaren elkarrizketa-koadroa non irudiaren orientazioa alda daitekeen Scale Eskalatu Add Watermark Gehitu ur-marka Add Watermark to captured image. Multiple watermarks can be added. Gehitu ur-marka egindako argazkiari. Hainbat ur-marka gehitu daitezke. Quit Irten Settings Ezarpenak &About &Honi buruz Open Ireki &File &Fitxategia &Edit &Editatu &Options Aukerak &Help &Laguntza Save As... Gorde honela... Paste Itsatsi Paste Embedded Itsatsi kapsulatua Pin Ainguratu Pin screenshot to foreground in frameless window Finkatu pantaila-argazkia markorik gabeko lehen plano batean No image provided but one was expected. Espero bazen arren, ez da irudirik jaso. Copy Path Kopiatu bidea Open Directory Ireki direktorioa &View &Ikusi Delete Ezabatu Rename Aldatu izena Open Images Ireki irudiak Show Docks Erakutsi kaiak Hide Docks Ezkutatu kaiak Copy as data URI URl data gisa kopiatu da Open &Recent Ireki duela gutxikoa Modify Canvas Aldatu oihala Upload triggerCapture to external source Kargatu egindako argazkia kanpoko iturri batera Copy triggerCapture to system clipboard Kopiatu egindako argazkia sistemaren arbelera Scale Image Eskalako irudia Rotate Biratu Rotate Image Biratu irudia Actions Ekintzak Image Files Irudi fitxategiak Save All Gorde guztiak Close Window Itxi leihoa Cut Ebaki OCR OCR MultiCaptureHandler Save Gorde Save As Gorde honela Open Directory Ireki direktorioa Copy Kopiatu Copy Path Kopiatu bidea Delete Ezabatu Rename Aldatu izena Save All Gorde guztiak NewCaptureNameProvider Capture Argazkia OcrWindowCreator OCR Window %1 OCR leihoa %1 PinWindow Close Itxi Close Other Itxi besteak Close All Itxi denak PinWindowCreator OCR Window %1 OCR leihoa %1 PluginsSettings Search Path Bilaketa-bidea Default Lehenetsia The directory where the plugins are located. Pluginak dauden direktorioa. Browse Arakatu Name Izena Version Bertsioa Detect Antzeman Plugin Settings Plugin ezarpenak Plugin location Plugin kokapena ProcessIndicator Processing Prozesatzen RenameOperation Image Renamed Irudia berrizendatua Image Rename Failed Irudiaren berrizendatzeak huts egin du Rename image Berrizendatu irudia New filename: Fitxategi-izen berria: Successfully renamed image to %1 Irudiari %1 izen berria ezarri zaio Failed to rename image to %1 Ezin izan da %1 izena ezarri irudiari SaveOperation Save As Gorde honela All Files Fitxategi guztiak Image Saved Irudia gorde da Saving Image Failed Irudiaren gordetzeak huts egin du Image Files Irudi fitxategiak Saved to %1 %1 izenarekin gorde da Failed to save image to %1 Ezin izan da %1 izenarekin gorde SaverSettings Automatically save new captures to default location Gorde automatikoki kaptura berriak lehenetsitako kokagunera Prompt to save before discarding unsaved changes Eskatu gordetzea gorde gabeko aldaketak baztertu aurretik Remember last Save Directory Gogoratu gordetzeko erabilitako azken direktorioa When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Aktibatuta dagoenean ezarpenetan gordetako direktorioa gainidatziko du gordetzeko erabilitako karpetarekin, gordetzen den aldiro. Capture save location and filename Atzitu gordetzeko kokapena eta fitxategiaren izena Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Onartzen diren formatuak dira JPG, PNG eta BMP. Formaturik zehazten ez bada, PNG erabiliko da lehenetsi gisa. Fitxategiaren izenak honako komodinak eduki ditzake: - $Y, $M, $D datarako, $h, $m, $s ordurako, edo $T denborarako hhmmss formatuan. - Hainbat # jarraian kontagailurako. #### bihurtuko da 0001 eta hurrengo argazkian 0002. Browse Arakatu Saver Settings Gordetze-ezarpenak Capture save location Gordetzeko kokapena Default Lehenetsia Factor Faktorea Save Quality Gordetze kalitatea Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Jarri 0 konprimitutako fitxategi txikiak sortzeko, 100 konpresiorik gabeko fitxategiak sortzeko. Irudi formatu guztiek ez dute gama osoa onartzen, JPEG-ek bai. Overwrite file with same name Gainidatzi fitxategia izen berdinarekin ScriptUploaderSettings Copy script output to clipboard Kopiatu irteerako scripta arbelera Script: Scripta: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Kargan eskatuko den scriptaren bidea. Kargan scripta erabiliko da behin behineko png fitxategi baten bidea argumentu sinplea duela. Browse Arakatu Script Uploader Kargarako scripta Select Upload Script Hautatu kargarako scripta Stop when upload script writes to StdErr Gelditu kargako scripta StdErr-ra gehitzean Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Scriptak StdErr-ra gehitzeak huts egin duela markatzen du. Ezarpen hau gabe scripteko akatsak oharkabean geratuko dira. Filter: Iragazkia: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. RegEx adierazpena. Kopiatu arbelera bakarrik RegEx adierazpenarekin bat datorrenarekin. Ez badago, dena kopiatzen da. SettingsDialog Settings Ezarpenak OK Ados Cancel Utzi Application Aplikazioa Image Grabber Irudi kapturatzailea Imgur Uploader Imgur-en kargatzailea Annotator Ohargilea HotKeys Laster-teklak Uploader Kargagailua Script Uploader Kargako scripta Saver Gordetzea Stickers Eranskailuak Snipping Area Argazki-area Tray Icon Erretiluko ikonoa Watermark Ur-marka Actions Ekintzak FTP Uploader FTP kargatzailea Plugins Pluginak Search Settings... Bilaketa ezarpenak... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Hautatutako zuzenaren tamaina aldatu heldulekuak erabiliz edo mugitu hautapena arrastatuz. Use arrow keys to move the selection. Erabili gezi-teklak hautaketa mugitzeko. Use arrow keys while pressing CTRL to move top left handle. Erabili gezi-teklak CTRL sakatzen duzun bitartean goiko ezkerreko heldulekua mugitzeko. Use arrow keys while pressing ALT to move bottom right handle. Erabili gezi-teklak ALT sakatzen duzun bitartean beheko eskuineko heldulekua mugitzeko. This message can be disabled via settings. Mezu hau ezarpenen bidez desgaitu daiteke. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Berretsi hautapena SARTU sakatuz edo saguaren klik bikoitza egin edozein lekutan. Abort by pressing ESC. Utzi ESC sakatuz. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Egin klik eta arrastatu area laukizuzena hautatzeko edo ESC ateratzeko. Hold CTRL pressed to resize selection after selecting. Mantendu CTRL sakatuta hautaketaren tamaina aldatzeko. Hold CTRL pressed to prevent resizing after selecting. Mantendu CTRL sakatuta hautatu ondoren tamaina aldatzea ekiditeko. Operation will be canceled after 60 sec when no selection made. Eragiketa bertan behera geratuko da 60 segundoren buruan hautaketa egin ez denean. This message can be disabled via settings. Mezu hau ezarpenen bidez desgaitu daiteke. SnippingAreaSettings Freeze Image while snipping Izoztu irudia markatu bitartean When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Aktibatuta dagoenean atzeko planoa izoztuko da area laukizuzena hautatu bitartean. Atzeratutako pantailen portaera ere aldatzen du, aukera hau aktibatuta atzerapena argazki-area erakutsi aurretik gertatzen da eta aukera desgaituta dagonean atzerapena argazki-area erakutsi ondoren gertatzen da. Ezaugarri hau beti desgaituta dago Wayland-entzat eta beti aktibatuta MacOs-entzat. Show magnifying glass on snipping area Erakutsi lupa argazki-arean Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Erakutsi atzeko planoko irudia handitzen duen lupa. Aukera honek bakarrik funtzionatzen du "Izoztu irudia markatu bitartean" aktibatuta badago. Show Snipping Area rulers Erakutsi argazki-arearen erregelak Horizontal and vertical lines going from desktop edges to cursor on snipping area. Lerro horizontal eta bertikalak zabaltzen dira mahaigainaren izkinetatik kurtsorera argazki-zonan. Show Snipping Area position and size info Erakutsi argaki-arearen kokapena eta tamainaren informazioa When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Saguaren ezkerreko botoia sakatu gabe kokapena ikusten da, sakatuta dagoenean, hautatutako arearen tamaina ikusten da haren goiko ezker aldean. Allow resizing rect area selection by default Onartu berez hautatutako area laukizuzenaren tamaina aldatzea When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Gaituta badago onartzen da hautatutako arearen tamaina aldatzea. Tamaina aldatu ondoren hautaketa berretsi behar da Sartu sakatuta. Show Snipping Area info text Erakutsi argazki-arearen informazioa Snipping Area cursor color Argazki-arearen kurtsorearen kolorea Sets the color of the snipping area cursor. Argazki-arearen kurtsorearen kolorea ezartzen du. Snipping Area cursor thickness Argazki-arearen kurtsorearen zabalera Sets the thickness of the snipping area cursor. Argazki-arearen kurtsorearen lodiera ezartzen du. Snipping Area Argazki-area Snipping Area adorner color Argazki-arearen dekorazioaren kolorea Sets the color of all adorner elements on the snipping area. Argazki-arearen dekorazio elementuen kolorea ezartzen du. Snipping Area Transparency Argazki-arearen gardentasuna Alpha for not selected region on snipping area. Smaller number is more transparent. Argazki-areako hautatu gabeko zonaren Alpha. Zenbaki txikiagoak gardenagoa adierazten du. Enable Snipping Area offset Gaitu ebakitzeko eremuaren desplazamendua When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Gaituta dagoenean konfiguratutako desplazamendua aplikatuko zaio mozteko areari posiziora kokapena behar bezala kalkulatuta ez denean. Hau batzuetan beharrezkoa da pantaila eskalatzea gaituta dagoenean. X X Y Y StickerSettings Up Gora Down Behera Use Default Stickers Erabili berezko eranskailuak Sticker Settings Eranskailuen ezarpenak Vector Image Files (*.svg) Irudi bektorialen fitxategiak (*.svg) Add Gehitu Remove Kendu Add Stickers Gehitu eranskailuak TrayIcon Show Editor Erakutsi editorea TrayIconSettings Use Tray Icon Erabili erretiluko ikonoa When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Aktibatuta dagoenean, sistemaren erretiluan ikonoa gehituko du, sistemaren leiho kudeatzaileak onartzen badu. Aldaketak berrabiaraztea eskatzen du. Minimize to Tray Minimizatu erretilura Start Minimized to Tray Abiatu erretiluan minimizatua Close to Tray Itxi erretilura Show Editor Erakutsi editorea Capture Argazkia Default Tray Icon action Erretiluko ikonoaren eragiketa lehenetsia Default Action that is triggered by left clicking the tray icon. Erretiluaren ikonoan ezkerreko klik egitean aktibatzen den eragiketa lehenetsia. Tray Icon Settings Erretiluko ikonoaren ezarpenak Use platform specific notification service Erabili plataformaren berariazko jakinarazpen zerbitzua When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Aktibatuta dagoenean saiatuko da plataformaren berariazko jakinarazpen zerbitzua erabiltzen baldin badago. Aldaketak berrabiaraztea eskatzen du eragina izateko. Display Tray Icon notifications Bistaratu erretiluko ikonoaren jakinarazpenak UpdateWatermarkOperation Select Image Aukeratu irudia Image Files Irudi fitxategiak UploadOperation Upload Script Required Kargarako scripta behar da Please add an upload script via Options > Settings > Upload Script Gehitu kargarako script bat Aukerak » Ezarpenak » Kargarako scripta Capture Upload Argazkiaren karga You are about to upload the image to an external destination, do you want to proceed? Argazkia kanpoko kokapen batera igotzear zaude, ekin nahi diozu? UploaderSettings Ask for confirmation before uploading Eskatu berrespena kargatu aurretik Uploader Type: Karga mota: Imgur Imgur Script Scripta Uploader Kargagailua FTP FTP VersionTab Version Bertsioa Build Sorrera Using: Erabiltzen: WatermarkSettings Watermark Image Ur-markaren irudia Update Eguneratu Rotate Watermark Biratu ur-marka When enabled, Watermark will be added with a rotation of 45° Aktibatuta dagoenean, ur-marka 45ªko biraketarekin gehituko da Watermark Settings Ur-markaren ezarpenak ksnip-master/translations/ksnip_fa.ts000066400000000000000000001646711457262621600204100ustar00rootroot00000000000000 AboutDialog About درباره About درباره Version نسخه Author مول٠Close بستن Donate حمایت Contact AboutTab License: مجوز: Screenshot and Annotation Tool ActionSettingTab Name Shortcut Clear Take Capture Include Cursor Delay s The small letter s stands for seconds. Capture Mode Show image in Pin Window Copy image to Clipboard Upload image Open image parent directory Save image Hide Main Window Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Actions Settings Action AddWatermarkOperation Watermark Image Required تصویر واترمارک نیاز است Please add a Watermark Image via Options > Settings > Annotator > Update AnnotationSettings Smooth Painter Paths When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Application Style Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Automatically copy new captures to clipboard Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse AuthorTab Contributors: Spanish Translation Dutch Translation Russian Translation Norwegian BokmÃ¥l Translation French Translation Polish Translation Snap & Flatpak Support The Authors: CanDiscardOperation Warning - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Password FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Close بستن Time Stamp Link Delete Link ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Client Secret PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. Save Save Screen Capture to file system Copy Copy Screen Capture to clipboard Tools Undo Redo Crop Crop Screen Capture MainWindow Unsaved Upload Print Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Settings &About Open &Edit &Options &Help Add Watermark Add Watermark to captured image. Multiple watermarks can be added. &File Unable to show image Save As... Paste Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Save As Open Directory Copy Copy Path Delete Rename Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close بستن Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default The directory where the plugins are located. Browse Name Version نسخه Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved Saving Image Failed Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Saver Settings Capture save location Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings OK Cancel Image Grabber Imgur Uploader Application Annotator HotKeys Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version نسخه Build Using: WatermarkSettings Watermark Image Update Rotate Watermark When enabled, Watermark will be added with a rotation of 45° Watermark Settings ksnip-master/translations/ksnip_fi.ts000066400000000000000000002031101457262621600203760ustar00rootroot00000000000000 AboutDialog About Tietoa About Tietoa Version Versio Author Tekijä Close Sulje Donate Lahjoita Contact Ota yhteyttä AboutTab License: Lisenssi: Screenshot and Annotation Tool Ruudunkaappaus ja merkintätyökalu ActionSettingTab Name Nimi Shortcut Pikanäppäin Clear Tyhjennä Take Capture Ota kaappaus Include Cursor Tallenna kursori Delay Viive s The small letter s stands for seconds. s Capture Mode Kaappaustila Show image in Pin Window Näytä kuva ikkunassa Copy image to Clipboard Kopioi kuva leikepöydälle Upload image Lataa kuva Open image parent directory Avaa kuvan hakemisto Save image Tallenna kuva Hide Main Window Piilota pääikkuna Global Yleinen When enabled will make the shortcut available even when ksnip has no focus. Kun käytössä, pikanäppäin on käytettävissä vaikka ksnip ei ole tarkentunut. ActionsSettings Add Lisää Actions Settings Toimintojen asetukset Action Toiminta AddWatermarkOperation Watermark Image Required Vesileiman kuva vaaditaan Please add a Watermark Image via Options > Settings > Annotator > Update Lisää vesileiman kuva valitsemalla Vaih­to­eh­dot > Asetukset> Korostus > Päivitä AnnotationSettings Smooth Painter Paths Tasainen maalaus When enabled smooths out pen and marker paths after finished drawing. Kun käytössä, tasoittaa kynän ja korostuksen piirtämisen jälkeen. Smooth Factor Tasaisuus Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Tasoituskertoimen kasvattaminen pienentää tarkkuutta kynän ja merkinnän osalta, mutta tekee tasaisempaa jälkeä. Annotator Settings Korostuksen asetukset Remember annotation tool selection and load on startup Muista korostustyökalun valinta ja lataa se käynnistyksen yhteydessä Switch to Select Tool after drawing Item Vaihda Valinta-työkaluun piirtämisen jälkeen Number Tool Seed change updates all Number Items Numerotyökalu päivittää kaikki numeroidut kohteet Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Poistaminen käytöstä muuttaa numerointi-työkalua ja vaikuttaa vain uusiin kohteisiin, mutta sallii päällekkäisten numeroiden käytön. Canvas Color Piirtoalustan väri Default Canvas background color for annotation area. Changing color affects only new annotation areas. Korostusalueen oletusväri. Värin vaihtaminen vaikuttaa vain uusiin korostuksiin. Select Item after drawing Valitse väline piirtämisen jälkeen With this option enabled the item gets selected after being created, allowing changing settings. Kun käytössä, kohde valitaan luomisen jälkeen, jolloin asetuksia voidaan muuttaa. Show Controls Widget Näytä säätimet The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Säätimet sisältää painikkeet Kumoa/Uudelleen, Rajaus, Skaalaus, Kierrä ja Muokkaa. ApplicationSettings Capture screenshot at startup with default mode Ota ruudunkaappaus käynnistyksen yhteydessä oletustilassa Application Style Sovelluksen tyyli Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Asettaa sovellusen tyylin ja graafisen käyttöliittymän ulkoasun. Muutos vaatii ksnipin uudelleen käynnistyksen tullakseen voimaan. Application Settings Sovelluksen asetukset Automatically copy new captures to clipboard Kopioi uudet kaappaukset automaattisesti leikepöydälle Use Tabs Käytä välilehtiä Change requires restart. Muutos vaatii käynnistyksen. Run ksnip as single instance Suorita ksnip yhtenä esiintymänä Hide Tabbar when only one Tab is used. Piilota välilehtipalkki, kun vain yhtä välilehteä käytetään. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Jos asetus käytössä, vain yksi ksnip voidaan suorittaa, kaikki muut tapaukset, jotka on aloitettu sen jälkeen läpäisevät argumentit ensimmäiselle ja sulkeutuu. Asetuksen muutos edellyttää käynnistyksen kaikille esiintymille. Remember Main Window position on move and load on startup Muista pääikkunan sijainti liikkuessa ja käynnistyksen yhteydessä Auto hide Tabs Piilota välilehdet automaattisesti Auto hide Docks Piilota paneelit automaattisesti On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Käynnistyksessä piilota työkalupalkki ja korostuksen asetukset. Valikon näkyvyyttä voidaan vaihtaa sarkaimella. Auto resize to content Muuta kokoa automaattisesti Automatically resize Main Window to fit content image. Muuttaa pääikkunan kokoa automaattisesti kuvaan sopivaksi. Enable Debugging Ota virheenkorjaus käyttöön Enables debug output written to the console. Change requires ksnip restart to take effect. Ottaa käyttöön konsoliin kirjoitettavan debug-listauksen. Muutos vaatii ksnipin käynnistyksen tullakseen voimaan. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Sisällön koon muuttaminen viivästyy, jotta Ikkunanhallinta voi vastaanottaa uutta sisältöä. Jos pääikkunaa ei ole säädetty oikein uuteen sisältöön, viiveen lisääminen saattaa parantaa toimintaa. Resize delay Muutos viiveellä Temp Directory Temp-hakemisto Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Temp-hakemistoa käytetään tilapäisten kuvien tallentamiseen ja ne poistetaan kun ksnip suljetaan. Browse Selaa AuthorTab Contributors: Kehittäjät: Spanish Translation Espanjan käännökset Dutch Translation Hollannin käännökset Russian Translation Venäjän käännökset Norwegian BokmÃ¥l Translation Norjan käännökset French Translation Ranskan käännökset Polish Translation Puolan käännökset Snap & Flatpak Support Tuettu Snap & Flatpak The Authors: Tekijät: CanDiscardOperation Warning - Varoitus - The capture %1%2%3 has been modified. Do you want to save it? Kaappausta %1%2%3 on muokattu. Haluatko tallentaa sen? CaptureModePicker New Uusi Draw a rectangular area with your mouse Piirrä hiirellä suorakaiteen muotoinen alue Capture full screen including all monitors Kaappaa koko näyttö, mukaan lukien kaikki näytöt Capture screen where the mouse is located Kaappaa näyttö, jossa hiiri sijaitsee Capture window that currently has focus Kaappaa ikkuna, joka on tällä hetkellä aktiivinen Capture that is currently under the mouse cursor Kaappaa se, joka on hiiren kursorin alla Capture a screenshot of the last selected rectangular area Ota ruudunkaappaus viimeksi valitusta suorakulmaisesta alueesta Uses the screenshot Portal for taking screenshot Käytä kuvalle portaalia otettuasi ruudunkaappauksen ContactTab Community Yhteisö Bug Reports Virheraportit If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Jos sinulla on kysymyksiä, ideoita tai haluat vain puhua ksnipistä,<br/>liity %1 tai %2-palvelimelle. Please use %1 to report bugs. Ilmoita virheistä %1 toiminnolla. CopyAsDataUriOperation Failed to copy to clipboard Kopioiminen leikepöydälle epäonnistui Failed to copy to clipboard as base64 encoded image. Leikepöydälle kopioiminen epäonnistui base64-koodattulla kuvalla. Copied to clipboard Kopioitu leikepöydälle Copied to clipboard as base64 encoded image. Kopioitu leikepöydälle base64-koodattuna kuvana. DeleteImageOperation Delete Image Poista kuva The item '%1' will be deleted. Do you want to continue? Kohde "%1" poistetaan. Haluatko jatkaa? DonateTab Donations are always welcome Lahjoitukset ovat aina tervetulleita Donation Lahjoitus ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip on voittoa tavoittelematon ohjelmaisto projekti. <br/>Silti joitakin kustannuksia on katettava,<br/> kuten verkkotunnus ja laitteistokulua alustojen välisen tuen testaamisesi. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Jos haluat auttaa tai vain arvostaa tehtyä työtä<br/> tarjoamalla kehittäjille oluen tai kahvin, voit tehdä sen %1 täällä %2. Become a GitHub Sponsor? Ryhdy GitHub-sponsoriksi? Also possible, %1here%2. Mahdollista myös, %1 täällä %2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Lisää uusia toimintoja painamalla "Lisää" välilehden painiketta. EnumTranslator Rectangular Area Suorakulmainen alue Last Rectangular Area Viimeisin suorakulmainen alue Full Screen (All Monitors) Koko näyttö (kaikki näytöt) Current Screen Nykyinen näyttö Active Window Aktiivinen ikkuna Window Under Cursor Ikkuna kohdistimen alla Screenshot Portal Ruudunkaappaus portaali FtpUploaderSettings Force anonymous upload. Pakota anonyymi lataus. Url Url Username Käyttäjätunnus Password Salasana FTP Uploader FTP-lataaja HandleUploadResultOperation Upload Successful Lataaminen onnistui Unable to save temporary image for upload. Väliaikaista kuvaa ei voi tallentaa lähetettäväksi. Unable to start process, check path and permissions. Prosessia ei voi aloittaa, tarkista polku ja käyttöoikeudet. Process crashed Prosessi kaatui Process timed out. Prosessi aikakatkaistiin. Process read error. Prosessin lukuvirhe. Process write error. Prosessin kirjoitusvirhe. Web error, check console output. Verkkovirhe, tarkista konsolin tulos. Upload Failed Lataaminen epäonnistui Script wrote to StdErr. Skriptin kirjoitti StdErr. FTP Upload finished successfully. FTP-lataus päättyi onnistuneesti. Unknown error. Tuntematon virhe. Connection Error. Yhteysvirhe. Permission Error. Käyttöoikeusvirhe. Upload script %1 finished successfully. Scriptin %1 lataus päättyi onnistuneesti. Uploaded to %1 Ladattu %1 HotKeySettings Enable Global HotKeys Ota pikanäppäimet käyttöön Capture Rect Area Kaappaa valitsemasi alue Capture Full Screen Kaappaa koko näyttö Capture current Screen Kaappaa nykyinen näyttö Capture active Window Kaappaa aktiivinen ikkuna Capture Window under Cursor Kaappaa ikkuna kohdistimen alla Global HotKeys Yleiset pikanäppäimet Capture Last Rect Area Kaappaa valitsemasi alue uudelleen Clear Tyhjennä Capture using Portal Kaappaa portaaliin HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Pikanäppäimiä tuetaan vain X11 ikkunassa tällä hetkellä. Poistamalla toiminnon käytöstä, pikanäppäimet ovat vain ksnipille. ImageGrabberSettings Capture mouse cursor on screenshot Kaappaa hiiren osoitin kuvaan Should mouse cursor be visible on screenshots. Pitäisikö hiiren osotin näkyä kaappauksissa. Image Grabber Kuvan kaappaaja Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Yleiset Wayland-toteutukset, jotka käyttävät tapaa XDG-DESKTOP-PORTAL käsittelevät skaalautumista eri tavalla. Käyttöönotto määrittää näytön nykyisen skaalauksen ja soveltaa sitä ksnipin kaappaukseen. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME ja KDE Plasma tukevat heidän omaa Waylandia. ja yleiset XDG-DESKTOP-PORTAL ruudunkaappausta. Tämän ottaminen käyttöön, pakottaa KDE Plasman ja GNOME:n käyttämään XDG-DESKTOP-PORTAL ruurun- kaappausta. Vaatii ksnipin käynnistyksen uudelleen. Show Main Window after capturing screenshot Näytä pääikkuna kaappauksen jälkeen Hide Main Window during screenshot Piilota pääikkuna kaappauksen aikana Hide Main Window when capturing a new screenshot. Piilota pääikkuna, kun otat uuden kaappauksen. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Näytä pääikkuna kaappauksen ottamisen jälkeen kun pääikkuna oli piilotettu tai minimoitu. Force Generic Wayland (xdg-desktop-portal) Screenshot Pakota Wayland (xdg-desktop-portal) ruudunkaappaus Scale Generic Wayland (xdg-desktop-portal) Screenshots Skaalaa Wayland (xdg-desktop-portal) ruudunkaappaus Implicit capture delay Laskennallinen kaappausviive This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Viivettä käytetään, jos sitä ei ole valittu käyttö- liittymässä ja sen avulla ksnip voi piiloutua ennen kaappausta. Tätä arvoa ei käytetä, jos ksnip oli jo minimoitu. Arvon pienentäminen voi vaikuttaa ksnipin pääikkunan näkymiseen kaappatussa kuvassa. ImgurHistoryDialog Imgur History Imgur-historia Close Sulje Time Stamp Aikaleima Link Linkki Delete Link Poista linkki ImgurUploader Upload to imgur.com finished! Lähetys osoitteeseen imgur.com valmis! Received new token, trying upload again… Uusi tunnus vastaanotettu, yritetään ladata uudelleen… Imgur token has expired, requesting new token… Imgur-tunnus on vanhentunut, pyydetään uutta tunnusta… ImgurUploaderSettings Force anonymous upload Pakota anonyymi lataus Always copy Imgur link to clipboard Kopioi aina Imgur-linkki leikepöydälle Client ID Asiakkaan tunnus Client Secret Asiakkaan salaus PIN PIN Enter imgur Pin which will be exchanged for a token. Anna imgur pin, joka vaihdetaan tunnukseksi. Get PIN Hanki PIN-koodi Get Token Hanki tunnus Imgur History Imgur-historia Imgur Uploader Imgur lataaja Username Käyttäjätunnus Waiting for imgur.com… Odotetaan sivustoa imgur.com… Imgur.com token successfully updated. Imgur.com-tunnuksen päivitys onnistui. Imgur.com token update error. Imgur.com-tunnuksen päivitysvirhe. After uploading open Imgur link in default browser Lataamisen jälkeen avaa Imgur-linkki oletus selaimessa Link directly to image Linkitä suoraan kuvaan Base Url: Verkko-osoite: Base url that will be used for communication with Imgur. Changing requires restart. Verkko-osoite, jota käytetään viestintään Imgurin kanssa. Muuttaminen vaatii ohjelman käynnistyksen uudelleen. Clear Token Tyhjennä tunnus Upload title: Latauksen otsikko: Upload description: Latauksen kuvaus: LoadImageFromFileOperation Unable to open image Kuvaa ei voi avata Unable to open image from path %1 Kuvaa ei voi avata polusta %1 MainToolBar New Uusi Delay in seconds between triggering and capturing screenshot. Laukaisun viive sekunteina kaappauksen ottamisen välillä. s The small letter s stands for seconds. s Save Tallenna Save Screen Capture to file system Tallenna kaappaus kiintolevylle Copy Kopioi Copy Screen Capture to clipboard Kopioi kaappaus leikepöydälle Tools Työkalut Undo Kumoa Redo Toista Crop Rajaa Crop Screen Capture Rajaa ruudunkaappaus MainWindow Unsaved Tallentamaton Upload Lähetä Print Tulosta Opens printer dialog and provide option to print image Avaa tulostinikkunan ja antaa mahdollisuuden kuvan tulostamiseen Print Preview Tulostuksen esikatselu Opens Print Preview dialog where the image orientation can be changed Avaa tulostuksen esikatseluikkuna, jossa kuvan suuntaa voidaan muuttaa Scale Skaalaus Quit Lopeta Settings Asetukset &About &Tietoja Open Avaa &Edit &Muokkaa &Options &Lisäasetukset &Help &Ohje Add Watermark Lisää vesileima Add Watermark to captured image. Multiple watermarks can be added. Lisää vesileima kaapattuun kuvaan. Vesileimoja voi lisätä useita. &File &Tiedosto Unable to show image Kuvaa ei voi näyttää Save As... Tallenna nimellä... Paste Liitä Paste Embedded Liitä upotettuna Pin Kiinnitä Pin screenshot to foreground in frameless window Kiinnitä kaappaus etualalle kehyksettömässä ikkunassa No image provided but one was expected. Kuvaa ei toimitettu, mutta sellaista odotettiin. Copy Path Kopioi polku Open Directory Avaa kansio &View &Näytä Delete Poista Rename Nimeä uudelleen Open Images Avaa kuvat Show Docks Näytä paneeli Hide Docks Piilota paneeli Copy as data URI Kopioi datana URI Open &Recent Avaa &viimeisin Modify Canvas Muokkaa piirtoalustaa Upload triggerCapture to external source Lataa triggerCapture ulkoiseen lähteeseen Copy triggerCapture to system clipboard Kopioi triggerCapture leikepöydälle Scale Image Skaalaa kuva Rotate Pyöritä Rotate Image Pyöritä kuvaa Actions Toimet Image Files Kuvatiedostot Save All Tallenna kaikki Close Window Sulje ikkuna Cut Leikkaa OCR OCR MultiCaptureHandler Save Tallenna Save As Tallenna nimellä Open Directory Avaa kansio Copy Kopioi Copy Path Kopion polku Delete Poista Rename Nimeä uudelleen Save All Tallenna kaikki NewCaptureNameProvider Capture Kaappaa OcrWindowCreator OCR Window %1 OCR-ikkuna %1 PinWindow Close Sulje Close Other Sulje muut Close All Sulje kaikki PinWindowCreator OCR Window %1 OCR-ikkuna %1 PluginsSettings Search Path Hakupolku Default Oletus The directory where the plugins are located. Hakemisto, jossa laajennukset sijaitsevat. Browse Selaa Name Nimi Version Versio Detect Tunnista Plugin Settings Laajennuksen asetukset Plugin location Laajennuksen sijainti ProcessIndicator Processing Käsittely RenameOperation Image Renamed Kuva nimetty Image Rename Failed Kuvan nimeäminen epäonnistui Rename image Nimeä kuva uudelleen New filename: Uusi tiedostonimi: Successfully renamed image to %1 Kuvan nimi muutettiin onnistuneesti muotoon %1 Failed to rename image to %1 Kuvan nimeäminen muotoon %1 epäonnistui SaveOperation Save As Tallenna nimellä All Files Kaikki tiedostot Image Saved Kuva tallennettu Saving Image Failed Kuvan tallentaminen epäonnistui Image Files Kuvatiedostot Saved to %1 Tallennettu %1 Failed to save image to %1 Kuvan tallentaminen %1 epäonnistui SaverSettings Automatically save new captures to default location Tallenna uudet kaappaukset automaattisesti oletussijaintiin Prompt to save before discarding unsaved changes Pyydä tallentamista, ennen kuin hylkäät muutokset Remember last Save Directory Muista viimeisin tallennuskansio When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Kun käytössä, se korvaa asetuksiin tallennetun kansion uusimman tallennuksen mukaan jokaisella tallennuskerralla. Capture save location and filename Kaappauksen tallennuspaikka ja tiedostonimi Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Tuetut formaatit ovat JPG, PNG ja BMP. Jos mitään päätettä ei ole annettu, PNG on oletus. Tiedostonimi voi sisältää seuraavia merkkejä: - $Y, $M, $D päivämäärälle, $h, $m, $s ajalle tai $T ajalle hhmmss-muodossa. - Useita peräkkäisiä #-merkkejä laskurille. #### antaa tulokseksi 0001, seuraava kaappaus olisi 0002. Browse Selaa Saver Settings Säästäjän asetukset Capture save location Kaappauksen tallennussijainti Default Oletus Factor Kerroin Save Quality Tallenna laatu Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Määritä 0, jos haluat hankkia pieniä pakattuja tiedostoja, 100 suurille pakkaamattomille tiedostoille. Kaikki kuvamuodot eivät tue täyttä aluetta, mutta JPEG tukee. Overwrite file with same name Korvaa tiedosto jolla on sama nimi ScriptUploaderSettings Copy script output to clipboard Kopioi skriptin tulos leikepöydälle Script: Skripti: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Polku skriptiin, jota kutsutaan latausta varten. Latauksen aikana skriptiä kutsutaan väliaikaisen png-tiedoston polun kanssa yhtenä argumenttina. Browse Selaa Script Uploader Skriptin lataaja Select Upload Script Valitse lähetävä skripti Stop when upload script writes to StdErr Lopeta, kun latausskripti kirjoittaa StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Merkitsee lataus epäonnistuneeksi, kun skripti kirjoittaa StdErr-tiedostoon. Ilman tätä asetusta skriptin virheet jäävät huomaamatta. Filter: Suodatin: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. RegEx-lauseke. Kopioi leikepöydälle vain, mikä vastaa RegEx-lauseketta. Kun kaikki jätetään pois, kaikki kopioidaan. SettingsDialog Settings Asetukset OK OK Cancel Peruuta Image Grabber Kuvan kaappaaja Imgur Uploader Imgur lataaja Application Sovellus Annotator Huomautus HotKeys Pikanäppäimet Uploader Lataaja Script Uploader Skriptin lataaja Saver Säästäjä Stickers Tarrat Snipping Area Leikkausalue Tray Icon Paneelin kuvake Watermark Vesileima Actions Toimet FTP Uploader FTP-lataaja Plugins Laajennukset Search Settings... Hakuasetukset... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Muuta valitun suorakulman kokoa kahvoilla tai siirrä sitä vetämällä valintaa. Use arrow keys to move the selection. Siirrä valintaa nuolinäppäimillä. Use arrow keys while pressing CTRL to move top left handle. Siirrä vasenta yläkahvaa nuolinäppäimillä ja paina samalla CTRL-näppäintä. Use arrow keys while pressing ALT to move bottom right handle. Siirrä oikeaa alakahvaa nuolinäppäimillä ja paina samalla ALT-näppäintä. This message can be disabled via settings. Tämä viesti voidaan poistaa käytöstä asetuksissa. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Vahvista valinta näppäimellä ENTER tai painamalla kahdesti hiirellä missä tahansa. Abort by pressing ESC. Keskeytä painamalla ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Valitse suorakulmainen alue napsauttamalla ja vetämällä tai lopeta painamalla ESC. Hold CTRL pressed to resize selection after selecting. Pidä CTRL-näppäintä painettuna, kun haluat muuttaa valinnan kokoa jälkeenpäin. Hold CTRL pressed to prevent resizing after selecting. Pidä CTRL-näppäintä painettuna estääksesi koon muuttamisen valinnan jälkeen. Operation will be canceled after 60 sec when no selection made. Toiminto peruutetaan 60 sekunnin kuluttua, jos valintaa ei ole tehty. This message can be disabled via settings. Tämä viesti voidaan poistaa käytöstä asetuksissa. SnippingAreaSettings Freeze Image while snipping Pysäytä kuva leikkaamisen aikana When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Kun asetus on käytössä, tausta pysähtyy ja valittaan suorakulmaista alue. Muuttaa myös viiveen käyttäytymistä, sillä viive tapahtuu ennen kuin leikkausalue näytetään. Kun asetus on pois käytöstä viive tapahtuu leikkausalueen näyttämisen jälkeen. Ominaisuus on aina pois käytöstä Waylandissa ja MacOS aina käytössä. Show magnifying glass on snipping area Näytä suurennuslasi leikkausalueella Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Näytä suurennuslasi, joka zoomaa taustakuvaa. Tämä vaihtoehto toimii vain kun ominaisuus "Pysäytä kuva leikkauksen aikana" on käytössä. Show Snipping Area rulers Näytä leikkausalueen viivaimet Horizontal and vertical lines going from desktop edges to cursor on snipping area. Vaaka- ja pystyviivat, jotka kulkevat työpöydän reunoista kohdistimeen leikkausalueella. Show Snipping Area position and size info Näytä leikkausalueen sijainti ja koko When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Kun hiiren vasenta painiketta ei paineta, sijainti näytetään, kun taas hiiren painiketta painetaan, valinta-alueen koko näkyy vasemmalla ja sen yläpuolelta kaapatulta alueelta. Allow resizing rect area selection by default Salli alueen valinnan muuttaminen oletuksena When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Kun asetus on käytössä, suorakulmaisen alueen valitsemisen jälkeen, se sallii valinnan koon muuttamisen. Kun koon muuttaminen on tehty, valinta vahvistetaan askelpalautin-näppäimellä. Show Snipping Area info text Näytä leikkausalueen infoteksti Snipping Area cursor color Leikkausalueen kohdistimen väri Sets the color of the snipping area cursor. Asettaa leikkausalueen kohdistimen värin. Snipping Area cursor thickness Leikkausalueen kohdistimen paksuus Sets the thickness of the snipping area cursor. Asettaa leikkausalueen kohdistimen paksuuden. Snipping Area Leikkausalue Snipping Area adorner color Leikkausalueen merkintäväri Sets the color of all adorner elements on the snipping area. Asettaa kaikkien merkintä-elementtien värin leikkausalueella. Snipping Area Transparency Leikkausalueen läpinäkyvyys Alpha for not selected region on snipping area. Smaller number is more transparent. Alpha-arvo ei valittulla leikkausalueella. Pienempi numero on läpinäkyvämpi. Enable Snipping Area offset Ota leikkausalueen siirto käyttöön When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Kun käytössä, määritys otetaan käyttöön leikkausalueen aseman siirtoon. Tarvitaan, jos asemaa ei ole laskettu oikein. Tämä on joskus tarpeellinen kun näytön skaalaus on käytössä. X X Y Y StickerSettings Up Ylös Down Alas Use Default Stickers Käytä oletus tarroja Sticker Settings Tarran asetukset Vector Image Files (*.svg) Vektorikuva (* .svg) Add Lisää Remove Poista Add Stickers Lisää tarroja TrayIcon Show Editor Näytä muokkain TrayIconSettings Use Tray Icon Käytä paneelin kuvaketta When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Kun asetus käytössä, se lisää alavalikon kuvakkeen, jos käyttöjärjestelmä sitä tukee. Muutos vaatii käynnistämisen uudelleen. Minimize to Tray Pienennä alavalikkoon Start Minimized to Tray Käynnistä pienennettynä alavalikkoon Close to Tray Sulje alavalikkoon Show Editor Näytä muokkain Capture Kaappaa Default Tray Icon action Kuvakkeen oletustoiminto alavalikossa Default Action that is triggered by left clicking the tray icon. Oletustoiminto, napsauttamalla hiiren vasen alavalikon kuvakeessa. Tray Icon Settings Alavalikon kuvakkeen asetukset Use platform specific notification service Käytä alustakohtaista ilmoituspalvelua When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Kun asetus on käytössä, se yrittää käyttää alustakohtaista ilmoitusta, palvelua, jos sellainen on olemassa. Vaatii käynnistyksen uudelleen. Display Tray Icon notifications Näytä alavalikon kuvakkeen ilmoitukset UpdateWatermarkOperation Select Image Valitse kuva Image Files Kuvatiedostot UploadOperation Upload Script Required Latausskripti vaaditaan Please add an upload script via Options > Settings > Upload Script Lisää latausskripti valitsemalla Valinnat > Asetukset > Latausskripti Capture Upload Kaappauksen lataus You are about to upload the image to an external destination, do you want to proceed? Olet lataamassa kuvaa ulkoiseen kohteeseen, haluatko jatkaa? UploaderSettings Ask for confirmation before uploading Pyydä vahvistusta ennen lataamista Uploader Type: Lataajan tyyppi: Imgur Imgur palvelu Script Skripti Uploader Lataaja FTP FTP VersionTab Version Versio Build Käännös Using: Käyttäen: WatermarkSettings Watermark Image Vesileiman kuva Update Päivitys Rotate Watermark Pyöritä vesileimaa When enabled, Watermark will be added with a rotation of 45° Kun tämä on käytössä, vesileima lisätään kiertämällä 45° Watermark Settings Vesileiman asetukset ksnip-master/translations/ksnip_fr.ts000066400000000000000000002125721457262621600204230ustar00rootroot00000000000000 AboutDialog About À propos de About À propos Version Version Author Auteur Close Fermer Donate Faire un don Contact Contact AboutTab License: Licence : Screenshot and Annotation Tool Outil de capture d'écran et d'annotation ActionSettingTab Name Nom Shortcut Raccourci Clear Effacer Take Capture Capture d’écran Include Cursor Inclure le curseur Delay Retarder s The small letter s stands for seconds. s Capture Mode Mode de capture Show image in Pin Window Afficher l’image dans la fenêtre d’épinglage Copy image to Clipboard Copier l’image dans le presse-papier Upload image Téléverser l’image Open image parent directory Ouvrir le répertoire parent de l’image Save image Enregistrer l’image Hide Main Window Masquer la fenêtre principale Global Global When enabled will make the shortcut available even when ksnip has no focus. Lorsqu'il est activé, le raccourci sera disponible même lorsque ksnip n'a pas le focus. ActionsSettings Add Ajouter Actions Settings Paramètres des actions Action Action AddWatermarkOperation Watermark Image Required Image en filigrane requise Please add a Watermark Image via Options > Settings > Annotator > Update Veuillez ajouter une image en filigrane via Options > Paramètres > Annotateur > Mettre à jour AnnotationSettings Smooth Painter Paths Lisser les tracés peints When enabled smooths out pen and marker paths after finished drawing. Lorsque cette option est activée, le stylo lisse les trajectoires des marqueurs après la fin du dessin. Smooth Factor Facteur de lissage Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Augmenter le facteur de lissage diminuera la précision du stylo et du marqueur mais les rendra plus lisses. Annotator Settings Paramètres d’annotation Remember annotation tool selection and load on startup Se souvenir de la sélection de l’outil d’annotation et le charger au démarrage Switch to Select Tool after drawing Item Passer à l’outil de sélection après avoir dessiné l’élément Number Tool Seed change updates all Number Items Un changement du numéro de début met à jour tous les items numérotés Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Lorsqu'on désactive cette option, les changements du numéro de début n'affectent que les nouveaux items et pas les items existants. La désactivation de cette option permet des numéros dupliqués. Canvas Color Couleur du canevas Default Canvas background color for annotation area. Changing color affects only new annotation areas. Couleur d'arrière-plan du canevas par défaut pour la zone d'annotation. Le changement de couleur n'affecte que les nouvelles zones d'annotation. Select Item after drawing Sélectionner l'élément après le dessin With this option enabled the item gets selected after being created, allowing changing settings. Si cette option est activée, l'élément est sélectionné après avoir été créé, ce qui permet de modifier les paramètres. Show Controls Widget Afficher le widget des contrôles The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Le Widget Controls contient les boutons Undo/Redo, les boutons Recadrage, Échelle, Rotation et Modifier le canevas. ApplicationSettings Capture screenshot at startup with default mode Faire une capture d'écran au lancement avec le mode par défaut Application Style Style de l'application Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Définit le style d'interface et d’interactivité de l’application. Vous devrez redémarrer knsip pour le prendre en compte. Application Settings Paramètres de l’application Automatically copy new captures to clipboard Copier automatiquement les nouvelles captures dans le presse-papier Use Tabs Utiliser les onglets Change requires restart. Le changement nécessite un redémarrage. Run ksnip as single instance Exécuter Ksnip en tant qu'instance unique Hide Tabbar when only one Tab is used. Masquer la barre d'onglet lorsqu'un seul onglet est utilisé. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Cette option n'autorise à lancer qu'une seule instance ksnip. Si d'autres instances sont lancées, elles passeront leurs arguments à la première avant de s'arrêter. Il faut redémarrer toutes les instances pour activer ou désactiver cette option. Remember Main Window position on move and load on startup Mémoriser la position de la fenêtre principale lors du déplacement et la charger au démarrage Auto hide Tabs Cacher automatiquement les onglets Auto hide Docks Masquer les panneaux automatiquement On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Masquer au démarrage la barre d’outils et les outils d’annotation. La visibilité du panneau d’outils peut être basculée avec la touche TAB. Auto resize to content Redimensionnement automatique en fonction du contenu Automatically resize Main Window to fit content image. Redimensionner automatiquement la fenêtre principale pour l'adapter à l'image du contenu. Enable Debugging Activer le débogage Enables debug output written to the console. Change requires ksnip restart to take effect. Active la sortie de débogage écrite sur la console. Le changement nécessite le redémarrage de ksnip pour prendre effet. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Le redimensionnement du contenu est retardé pour permettre au gestionnaire de fenêtres de recevoir le nouveau contenu. le nouveau contenu. Dans le cas où la fenêtre principale n'est pas ajustée correctement au nouveau contenu, l'augmentation de ce délai peut améliorer le comportement. au nouveau contenu, l'augmentation de ce délai peut améliorer le comportement. Resize delay Délai de redimensionnement Temp Directory Répertoire temporaire Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Répertoire temporaire utilisé pour stocker les images temporaires qui seront supprimées après la fermeture de ksnip. Browse Parcourir AuthorTab Contributors: Contributeurs : Spanish Translation Traduction en espagnol Dutch Translation Traduction en néerlandais Russian Translation Traduction en russe Norwegian BokmÃ¥l Translation Traduction en norvégien French Translation Traduction en français Polish Translation Traduction en polonais Snap & Flatpak Support Support Snap & Flatpak The Authors: Les auteurs : CanDiscardOperation Warning - Alerte - The capture %1%2%3 has been modified. Do you want to save it? La capture %1%2%3 a été modifiée. Voulez-vous l'enregistrer ? CaptureModePicker New Nouveau Draw a rectangular area with your mouse Tracer un rectangle avec la souris Capture full screen including all monitors Capture en plein écran, incluant tous les moniteurs Capture screen where the mouse is located Capture de l'écran où se trouve la souris Capture window that currently has focus Capturer la fenêtre active Capture that is currently under the mouse cursor Capturer ce qui est actuellement sous le curseur de la souris Capture a screenshot of the last selected rectangular area Fait une capture d'écran de la dernière zone sélectionnée Uses the screenshot Portal for taking screenshot Utilise le portail de capture d'écran pour les captures ContactTab Community Communauté Bug Reports Signalements d'erreurs If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Si vous avez des questions générales, des idées ou si vous voulez simplement parler de ksnip,<br/>veuillez rejoindre notre %1 ou notre %2 serveur. Please use %1 to report bugs. Veuillez utiliser %1 pour signaler les erreurs. CopyAsDataUriOperation Failed to copy to clipboard Impossible de copier dans le presse-papier Failed to copy to clipboard as base64 encoded image. Échec de la copie dans le presse-papier en tant qu’image encodée en base64. Copied to clipboard Copié dans le presse-papier Copied to clipboard as base64 encoded image. Copié dans le presse-papier en tant qu’image encodée en base64. DeleteImageOperation Delete Image Supprimer l'image The item '%1' will be deleted. Do you want to continue? L'élément '%1' va être supprimer. Voulez-vous continuer ? DonateTab Donations are always welcome Les dons sont toujours les bienvenus Donation Dons ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip est un projet de logiciel libre copylefté non rentable, et <br/>a toujours certains coûts qui doivent être couverts,<br/>comme les coûts de domaine ou les coûts de matériel pour la prise en charge multiplateforme. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Si vous voulez aider ou simplement apprécier le travail accompli<br/>en offrant aux développeurs une bière ou un café, vous pouvez le faire %1here%2. Become a GitHub Sponsor? Devenir un sponsor de GitHub ? Also possible, %1here%2. Également possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Ajouter de nouvelles actions en cliquant sur le bouton de l'onglet « Ajouter Â». EnumTranslator Rectangular Area Zone rectangulaire Last Rectangular Area Dernière zone rectangulaire Full Screen (All Monitors) Plein Écran (tous les moniteurs) Current Screen Écran actuel Active Window Fenêtre active Window Under Cursor Fenêtre sous le curseur Screenshot Portal Portail de capture d'écran FtpUploaderSettings Force anonymous upload. Forcer le téléversement anonyme. Url URL Username Nom d'utilisateur Password Mot de passe FTP Uploader Téléverseur FTP HandleUploadResultOperation Upload Successful Téléversement réussi Unable to save temporary image for upload. Impossible de sauvegarder une image temporaire pour le téléversement. Unable to start process, check path and permissions. Impossible de démarrer le processus, vérifiez le chemin et les permissions. Process crashed L’application a planté Process timed out. L’application a mis trop de temps à répondre. Process read error. Erreur de lecture de l’application. Process write error. Erreur d’écriture de l’application. Web error, check console output. Erreur web, vérifier la sortie de la console. Upload Failed Échec de téléversement Script wrote to StdErr. Le script a écrit sur StdErr. FTP Upload finished successfully. Le téléversement FTP s'est terminé avec succès. Unknown error. Erreur inconnue. Connection Error. Erreur de connexion. Permission Error. Erreur d'autorisation. Upload script %1 finished successfully. Le script de téléversement %1 s'est terminé avec succès. Uploaded to %1 Téléversé sur %1 HotKeySettings Enable Global HotKeys Activer les raccourcis globaux Capture Rect Area Capturer zone rectangulaire Capture Full Screen Capturer tout l'écran Capture current Screen Capturer l'écran actif Capture active Window Capturer la fenêtre active Capture Window under Cursor Capturer la fenêtre sous le curseur Global HotKeys Raccourcis globaux Capture Last Rect Area Capturer la dernière zone rectangulaire Clear Effacer Capture using Portal Capturer par le portail HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Les HotKeys ne sont actuellement prises en charge que pour Windows et X11. La désactivation de cette option rend également les raccourcis d'action ksnip uniquement. ImageGrabberSettings Capture mouse cursor on screenshot Inclure le curseur de la souris lors d'une capture d'écran Should mouse cursor be visible on screenshots. Le curseur de la souris doit-il être visible les captures d’écran. Image Grabber Captureur d'image Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. L'implémentation de Generic Wayland qui utilise XDG-DESKTOP-PORTAL gère les changements d'échelle différemment. Cette option détermine le changement d'échelle en cours pour l'appliquer à la capture ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME et KDE Plasma prennent en charge leur propre Wayland et les captures Generic XDG-DESKTOP-PORTAL. Cette option force KDE Plasma et GNOME à utiliser les captures XDG-DESKTOP-PORTAL. Redémarrage requis. Show Main Window after capturing screenshot Afficher la fenêtre principale après la capture d'écran Hide Main Window during screenshot Cacher la fenêtre principale pendant la capture Hide Main Window when capturing a new screenshot. Cacher la fenêtre principale pendant une nouvelle capture. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Afficher la fenêtre principale après avoir créé une nouvelle capture d'écran lorsque la fenêtre principale a été masquée ou réduite. Force Generic Wayland (xdg-desktop-portal) Screenshot Capture d'écran de Force Generic Wayland (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots Captures d'écran de Scale Generic Wayland (xdg-desktop-portal) Implicit capture delay Délai de capture implicite This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Ce délai est utilisé lorsqu'aucun délai n'a été sélectionné dans l'interface utilisateur. l'interface utilisateur, il permet à ksnip de se cacher avant de prendre une capture d'écran. Cette valeur n'est pas appliquée lorsque ksnip a déjà été minimisé. Réduire cette valeur peut avoir pour effet que la fenêtre principale de ksnip est visible sur la capture d'écran. ImgurHistoryDialog Imgur History Historique Imgur Close Fermer Time Stamp Horodatage Link Lien Delete Link Supprimer le lien ImgurUploader Upload to imgur.com finished! Téléversement sur imgur.com terminé ! Received new token, trying upload again… Nouveau jeton reçu, nouvelle tentative de téléversement… Imgur token has expired, requesting new token… Jeton Imgur expiré, demande de renouvellement… ImgurUploaderSettings Force anonymous upload Anonymiser le téléversement Always copy Imgur link to clipboard Toujours copier le lien Imgur dans le presse-papier Client ID ID Client Client Secret Client secret PIN NIP Enter imgur Pin which will be exchanged for a token. Entrez le NIP Imgur pour l'échanger contre un jeton. Get PIN Obtenir un NIP Get Token Obtenir un jeton Imgur History Historique Imgur Imgur Uploader Envoyer sur Imgur Username Nom d'utilisateur Waiting for imgur.com… En attente d'imgur.com… Imgur.com token successfully updated. Jeton imgur.com mis à jour avec succès. Imgur.com token update error. Erreur de mise à jour du jeton Imgur.com. After uploading open Imgur link in default browser Après téléversement, ouvrir le lien imgur avec le navigateur par défaut Link directly to image Relier directement l'image Base Url: URL de base : Base url that will be used for communication with Imgur. Changing requires restart. L’URL de base sera utilisée pour communiquer avec Imgur. La modifier nécessite un redémarrage. Clear Token Effacer les jetons Upload title: Téléverser le titre : Upload description: Téléverser la description : LoadImageFromFileOperation Unable to open image Impossible d’ouvrir l’image Unable to open image from path %1 Impossible d’ouvrir l’image à partir du chemin %1 MainToolBar New Nouveau Delay in seconds between triggering and capturing screenshot. Délai en secondes entre le déclenchement et la capture de l'écran. s The small letter s stands for seconds. s Save Enregistrer Save Screen Capture to file system Enregistrer la capture d'écran sur le disque Copy Copier Copy Screen Capture to clipboard Copier la capture d'écran dans le presse-papier Tools Outils Undo Annuler Redo Rétablir Crop Découper Crop Screen Capture Découper la capture d'écran MainWindow Unsaved Non enregistré Upload Téléverser Print Imprimer Opens printer dialog and provide option to print image Ouvre l'interface de l'imprimante et affiche les options d'impression Print Preview Aperçu avant impression Opens Print Preview dialog where the image orientation can be changed Ouvre la boîte de dialogue Aperçu avant impression où l'orientation de l'image peut être modifiée Scale Redimensionner Quit Quitter Settings Paramètres &About &À propos Open Ouvrir &Edit É&dition &Options &Options &Help &Aide Add Watermark Ajouter un filigrane Add Watermark to captured image. Multiple watermarks can be added. Ajout d'un filigrane à l'image capturée. Plusieurs filigranes peuvent être ajoutés. &File &Fichier Unable to show image Impossible d'afficher l'image Save As... Enregistrer sous… Paste Coller Paste Embedded Coller l'intégration Pin Épingler Pin screenshot to foreground in frameless window Épingler la capture au premier plan dans une fenêtre sans bords No image provided but one was expected. Une image est attendue mais aucune fournie. Copy Path Chemin de copie Open Directory Ouvrir le dossier &View &Afficher Delete Supprimer Rename Renommer Open Images Ouvrir les images Show Docks Afficher le panneau d'outils Hide Docks Cacher le panneau d'outils Copy as data URI Copie en tant qu’URI de données Open &Recent Ouvrir &Récent Modify Canvas Modifier le canevas Upload triggerCapture to external source Téléverser la capture du déclencheur vers une source externe Copy triggerCapture to system clipboard Copier la capture du déclencheur dans le presse-papier du système Scale Image Image à l'échelle Rotate Pivoter Rotate Image Pivoter l'image Actions Actions Image Files Fichiers d'images Save All Tout enregistrer Close Window Fermer la fenêtre Cut Couper OCR ROC MultiCaptureHandler Save Enregistrer Save As Enregistrer sous Open Directory Ouvrir le dossier Copy Copier Copy Path Copier le chemin Delete Supprimer Rename Renommer Save All Tout enregistrer NewCaptureNameProvider Capture Capture OcrWindowCreator OCR Window %1 Fenêtre ROC %1 PinWindow Close Fermer Close Other Fermer les autres Close All Tout fermer PinWindowCreator OCR Window %1 Fenêtre ROC %1 PluginsSettings Search Path Chemin de recherche Default Par défaut The directory where the plugins are located. Le répertoire où se trouvent les greffons. Browse Parcourir Name Nom Version Version Detect Détecter Plugin Settings Paramètres des greffons Plugin location Emplacement du greffon ProcessIndicator Processing Traitement en cours RenameOperation Image Renamed Image renommée Image Rename Failed Échec du renommage de l'image Rename image Renommer l'image New filename: Nouveau nom de fichier : Successfully renamed image to %1 L'image a été renommée avec succès en %1 Failed to rename image to %1 Échec du renommage de l'image en %1 SaveOperation Save As Enregistrer sous All Files Tous les fichiers Image Saved Image sauvegardée Saving Image Failed Échec de la sauvegarde de l'image Image Files Fichiers d'images Saved to %1 Enregistré dans %1 Failed to save image to %1 Échec de la sauvegarde de l'image dans %1 SaverSettings Automatically save new captures to default location Enregistrer automatiquement les nouvelles captures dans l'emplacement par défaut Prompt to save before discarding unsaved changes Proposer d'enregistrer en cas d'abandon de modifications non enregistrées Remember last Save Directory Se souvenir du dernier emplacement de sauvegarde When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Proposer le dernier emplacement utilisé pour l'enregistrement plutôt que celui défini ci-dessous. Capture save location and filename Répertoire d'enregistrement et nom du fichier Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Les formats pris en charge sont JPG, PNG et BMP. Si aucun format n’est spécifié, PNG sera utilisé par défaut. Le nom du fichier peut contenir les jokers suivants : - $Y : année, $M : mois, $D : jour, $h : heure, $m : minutes, $s : secondes, $T : temps au format « hhmmss Â». - Plusieurs caractères # permettent de numéroter. Par exemple : #### donnera 0001 puis 0002 à la prochaine capture. Browse Parcourir Saver Settings Paramètres d'enregistrement Capture save location Répertoire d'enregistrement des captures Default Par défaut Factor Facteur Save Quality Qualité d'enregistrement Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Préciser 0 pour des fichiers compressés légers, 100 pour des fichiers lourds non compressés. Certains format ne prennent pas en charge l'intervalle en entier comme c'est le cas pour le JPEG. Overwrite file with same name Écraser le fichier avec le même nom ScriptUploaderSettings Copy script output to clipboard Copier la sortie du script vers le presse-papier Script: Script : Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Chemin vers le script qui sera utilisé pour le téléversement. Le script sera appelé avec le chemin vers une image temporaire au format PNG comme unique argument. Browse Parcourir Script Uploader Script d'envoi Select Upload Script Sélectionner le script d'envoi Stop when upload script writes to StdErr Arrêter quand le script d'envoi écrit sur StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. L'envoi sera noté comme échoué si le script a écrit sur StdErr. Si cette case n'est pas cochée, les erreurs du script passeront inaperçues. Filter: Filtre : RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Expression rationnelle (RegEx). Seules les lignes correspondant à la RegEx seront copiées dans le presse-papier. Si aucun filtre n'est défini, toutes les lignes seront copiées. SettingsDialog Settings Préférences OK OK Cancel Annuler Image Grabber Captureur d'image Imgur Uploader Envoyer sur Imgur Application Application Annotator Annotation HotKeys Raccourcis clavier Uploader Envoi sur un serveur Script Uploader Script d'envoi Saver Enregistrement Stickers Autocollants Snipping Area Zone de capture Tray Icon Icône de la barre des tâches Watermark Filigrane Actions Actions FTP Uploader Téléverseur FTP Plugins Greffons Search Settings... Paramètres de recherche… SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ajuster la taille du rectangle sélectionné en utilisant les poignées ou déplacez-le en glissant la sélection. Use arrow keys to move the selection. Utilisez les touches fléchées pour déplacer la sélection. Use arrow keys while pressing CTRL to move top left handle. Utiliser les touches flèches en pressant CTRL pour déplacer la poignée en haut à gauche. Use arrow keys while pressing ALT to move bottom right handle. Utiliser les touches flèches en pressant ALT pour déplacer la poignée en bas à droite. This message can be disabled via settings. Ce message peut être désactivé via les préférences. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Confirmez la sélection en appuyant sur ENTRÉE/RETOUR ou en double-cliquant n'importe où avec la souris. Abort by pressing ESC. Abandonnez en appuyant sur Échap. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Cliquez et faites glisser pour sélectionner une zone rectangulaire ou appuyez sur ÉCHAP pour quitter. Hold CTRL pressed to resize selection after selecting. Maintenez la touche CTRL enfoncée pour redimensionner la sélection après avoir fait une sélection. Hold CTRL pressed to prevent resizing after selecting. Maintenez la touche CTRL enfoncée pour empêcher le redimensionnement après avoir effectué une sélection. Operation will be canceled after 60 sec when no selection made. L’opération sera annulée après 60 secondes si aucune sélection n’est effectuée. This message can be disabled via settings. Ce message peut être désactivé via les préférences. SnippingAreaSettings Freeze Image while snipping Figer l’image lors de la capture When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Pour figer l'arrière-plan lors de la sélection rectangulaire. Cela affecte aussi le comportement des captures avec délai. Activé, la durée est avant l'affichage de la zone de sélection. Désactivé, la durée est après. Cette fonctionnalité n'est jamais active sur Wayland mais toujours sur MacOS. Show magnifying glass on snipping area Afficher la loupe sur la zone de capture Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Afficher une loupe qui grossit le fond d’écran. Cette option ne fonctionne que si « Figer l’image avant capture Â» est activé. Show Snipping Area rulers Afficher les règles de la zone de capture Horizontal and vertical lines going from desktop edges to cursor on snipping area. Afficher des lignes horizontales et verticales depuis les bords de l'écran jusqu'au pointeur pour aider au cadrage. Show Snipping Area position and size info Afficher les informations sur la position et la taille de la zone de capture When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Lorsque le bouton gauche de la souris n'est pas enfoncé, la position s'affiche, lorsque le bouton de la souris est enfoncé, la taille de la zone sélectionnée est indiquée à gauche et au-dessus de la zone capturée. Allow resizing rect area selection by default Autoriser le redimensionnement de la sélection de la zone rectangulaire par défaut When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Lorsque l'option est activée, après avoir sélectionné une zone rectangulaire, celle-ci peut être redimensionnée. Le redimensionnement de la sélection peut être confirmé en appuyant sur la touche retour. Show Snipping Area info text Afficher le texte d’informations sur la zone de capture Snipping Area cursor color Couleur du curseur de la zone de capture Sets the color of the snipping area cursor. Définit la couleur du curseur de la zone de capture. Snipping Area cursor thickness Épaisseur du curseur de la zone de capture Sets the thickness of the snipping area cursor. Règle l’épaisseur du curseur de la zone de capture. Snipping Area Zone de capture Snipping Area adorner color Couleur d'ornement de la zone de capture Sets the color of all adorner elements on the snipping area. Définit la couleur de tous les éléments d’ornement sur la zone de capture. Snipping Area Transparency Transparence de la zone de capture Alpha for not selected region on snipping area. Smaller number is more transparent. Alpha pour la région en dehors de la zone de capture. Une petite valeur est plus transparente. Enable Snipping Area offset Activer le décalage de la zone de découpe When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Lorsqu'il est activé, il applique le décalage configuré à la position de la zone de découpe, ce qui est nécessaire lorsque la position n'est pas correctement calculée. Ceci est parfois nécessaire lorsque la mise à l'échelle de l'écran est activée. X X Y Y StickerSettings Up Haut Down Bas Use Default Stickers Utiliser les stickers par défaut Sticker Settings Paramètres des autocollants Vector Image Files (*.svg) Images vectorielles (*.svg) Add Ajouter Remove Retirer Add Stickers Ajouter des Stickers TrayIcon Show Editor Montrer l'éditeur TrayIconSettings Use Tray Icon Utiliser l'icône de la barre de tâches When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Si activé, ajoute une icône dans la barre des tâches si le système d’exploitation le permet. Le changement nécessite un redémarrage. Minimize to Tray Réduire vers la barre des tâches Start Minimized to Tray Démarrer en miniature dans la barre des tâches Close to Tray Fermer vers la barre des tâches Show Editor Afficher l’éditeur Capture Capture Default Tray Icon action Action par défaut de l’icône de la barre des tâches Default Action that is triggered by left clicking the tray icon. Action par défaut déclenchée par un clic gauche sur l’icône dans la barre des tâches. Tray Icon Settings Paramètres de l’icône de la barre des tâches Use platform specific notification service Utiliser un service de notification spécifique à la plateforme When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Lorsque cette option est activée, elle essaiera d'utiliser un service de notification spécifique à la plateforme lorsqu'il existe. spécifique à la plateforme lorsqu'il existe. Le changement nécessite un redémarrage pour prendre effet. Display Tray Icon notifications Afficher les notifications de l'icône de la barre d'état système UpdateWatermarkOperation Select Image Sélectionner l'image Image Files Fichiers d'images UploadOperation Upload Script Required Un script d'envoi est nécessaire Please add an upload script via Options > Settings > Upload Script Veuillez ajouter un script d'envoi dans Options > Paramètres > Script d'envoi Capture Upload Envoi de la capture You are about to upload the image to an external destination, do you want to proceed? La capture va être téléversée sur un serveur externe. Souhaitez-vous continuer ? UploaderSettings Ask for confirmation before uploading Demander une confirmation avant de téléverser Uploader Type: Méthode d'envoi : Imgur Imgur Script Script Uploader Envoi sur un serveur FTP FTP VersionTab Version Version Build Compiler Using: Dépendances : WatermarkSettings Watermark Image Image en filigrane Update Mettre à jour Rotate Watermark Pivoter le filigrane When enabled, Watermark will be added with a rotation of 45° Si activé, le filigrane sera ajouté avec une rotation de 45° Watermark Settings Paramètres des filigranes ksnip-master/translations/ksnip_fr_CA.ts000066400000000000000000002125571457262621600207710ustar00rootroot00000000000000 AboutDialog About À propos de About À propos Version Version Author Auteur Close Fermer Donate Faire un don Contact Contact AboutTab License: Licence : Screenshot and Annotation Tool Outil de capture d'écran et d'annotation ActionSettingTab Name Nom Shortcut Raccourci Clear Effacer Take Capture Capture d’écran Include Cursor Inclure le curseur Delay Retarder s The small letter s stands for seconds. s Capture Mode Mode de capture Show image in Pin Window Afficher l’image dans la fenêtre d’épinglage Copy image to Clipboard Copier l’image dans le presse-papier Upload image Téléverser l’image Open image parent directory Ouvrir le répertoire parent de l’image Save image Enregistrer l’image Hide Main Window Masquer la fenêtre principale Global Global When enabled will make the shortcut available even when ksnip has no focus. Lorsqu'il est activé, le raccourci sera disponible même lorsque ksnip n'a pas le focus. ActionsSettings Add Ajouter Actions Settings Paramètres des actions Action Action AddWatermarkOperation Watermark Image Required Image en filigrane requise Please add a Watermark Image via Options > Settings > Annotator > Update Veuillez ajouter une image en filigrane via Options > Paramètres > Annotateur > Mettre à jour AnnotationSettings Smooth Painter Paths Lisser les tracés peints When enabled smooths out pen and marker paths after finished drawing. Lorsque cette option est activée, le stylo lisse les trajectoires des marqueurs après la fin du dessin. Smooth Factor Facteur de lissage Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Augmenter le facteur de lissage diminuera la précision du stylo et du marqueur mais les rendra plus lisses. Annotator Settings Paramètres d’annotation Remember annotation tool selection and load on startup Se souvenir de la sélection de l’outil d’annotation et le charger au démarrage Switch to Select Tool after drawing Item Passer à l’outil de sélection après avoir dessiné l’élément Number Tool Seed change updates all Number Items Un changement du numéro de début met à jour tous les items numérotés Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Lorsqu'on désactive cette option, les changements du numéro de début n'affectent que les nouveaux items et pas les items existants. La désactivation de cette option permet des numéros dupliqués. Canvas Color Couleur du canevas Default Canvas background color for annotation area. Changing color affects only new annotation areas. Couleur d'arrière-plan du canevas par défaut pour la zone d'annotation. Le changement de couleur n'affecte que les nouvelles zones d'annotation. Select Item after drawing Sélectionner l'élément après le dessin With this option enabled the item gets selected after being created, allowing changing settings. Si cette option est activée, l'élément est sélectionné après après avoir été créé, ce qui permet de modifier les paramètres. Show Controls Widget Afficher le widget des contrôles The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Le Widget Controls contient les boutons Undo/Redo, les boutons Recadrage, Échelle, Rotation et Modifier le canevas. ApplicationSettings Capture screenshot at startup with default mode Faire une capture d'écran au lancement avec le mode par défaut Application Style Style de l'application Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Définit le style d'interface et d’interactivité de l’application. Vous devrez redémarrer knsip pour le prendre en compte. Application Settings Paramètres de l’application Automatically copy new captures to clipboard Copier automatiquement les nouvelles captures dans le presse-papier Use Tabs Utiliser les onglets Change requires restart. Le changement nécessite un redémarrage. Run ksnip as single instance Exécuter Ksnip en tant qu'instance unique Hide Tabbar when only one Tab is used. Masquer la barre d'onglet lorsqu'un seul onglet est utilisé. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Cette option n'autorise à lancer qu'une seule instance ksnip. Si d'autres instances sont lancées, elles passeront leurs arguments à la première avant de s'arrêter. Il faut redémarrer toutes les instances pour activer ou désactiver cette option. Remember Main Window position on move and load on startup Mémoriser la position de la fenêtre principale lors du déplacement et la charger au démarrage Auto hide Tabs Cacher automatiquement les onglets Auto hide Docks Masquer les panneaux automatiquement On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Masquer au démarrage la barre d’outils et les outils d’annotation. La visibilité du panneau d’outils peut être basculée avec la touche TAB. Auto resize to content Redimensionnement automatique en fonction du contenu Automatically resize Main Window to fit content image. Redimensionner automatiquement la fenêtre principale pour l'adapter à l'image du contenu. Enable Debugging Activer le débogage Enables debug output written to the console. Change requires ksnip restart to take effect. Active la sortie de débogage écrite sur la console. Le changement nécessite le redémarrage de ksnip pour prendre effet. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Le redimensionnement du contenu est retardé pour permettre au gestionnaire de fenêtres de recevoir le nouveau contenu. le nouveau contenu. Dans le cas où la fenêtre principale n'est pas ajustée correctement au nouveau contenu, l'augmentation de ce délai peut améliorer le comportement. au nouveau contenu, l'augmentation de ce délai peut améliorer le comportement. Resize delay Délai de redimensionnement Temp Directory Répertoire temporaire Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Répertoire temporaire utilisé pour stocker les images temporaires qui seront supprimées après la fermeture de ksnip. Browse Parcourir AuthorTab Contributors: Contributeurs : Spanish Translation Traduction en espagnol Dutch Translation Traduction en néérlandais Russian Translation Traduction en russe Norwegian BokmÃ¥l Translation Traduction en norvégien French Translation Traduction en français Polish Translation Traduction en polonais Snap & Flatpak Support Support Snap & Flatpak The Authors: Les auteurs : CanDiscardOperation Warning - Alerte - The capture %1%2%3 has been modified. Do you want to save it? La capture %1%2%3 a été modifiée. Voulez-vous l'enregistrer? CaptureModePicker New Nouveau Draw a rectangular area with your mouse Tracer un rectangle avec la souris Capture full screen including all monitors Capture en plein écran, incluant tous les moniteurs Capture screen where the mouse is located Capture de l'écran où se trouve la souris Capture window that currently has focus Capturer la fenêtre active Capture that is currently under the mouse cursor Capturer ce qui est actuellement sous le curseur de la souris Capture a screenshot of the last selected rectangular area Fait une capture d'écran de la dernière zone sélectionnée Uses the screenshot Portal for taking screenshot Utilise le portail de capture d'écran pour les captures ContactTab Community Communauté Bug Reports Signalements d'erreurs If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Si vous avez des questions générales, des idées ou si vous voulez simplement parler de ksnip,<br/>veuillez rejoindre notre %1 ou notre %2 serveur. Please use %1 to report bugs. Veuillez utiliser %1 pour signaler les bogues. CopyAsDataUriOperation Failed to copy to clipboard Impossible de copier dans le presse-papier Failed to copy to clipboard as base64 encoded image. Échec de la copie dans le presse-papier en tant qu’image encodée en base64. Copied to clipboard Copié dans le presse-papier Copied to clipboard as base64 encoded image. Copié dans le presse-papier en tant qu’image encodée en base64. DeleteImageOperation Delete Image Supprimer l'image The item '%1' will be deleted. Do you want to continue? L'élément « %1 Â» va être supprimer. Voulez-vous continuer? DonateTab Donations are always welcome Les dons sont toujours les bienvenus Donation Dons ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip est un projet de logiciel libre copylefté non rentable, et <br/>a toujours certains coûts qui doivent être couverts,<br/>comme les coûts de domaine ou les coûts de matériel pour la prise en charge multiplateforme. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Si vous voulez aider ou simplement apprécier le travail accompli<br/>en offrant aux développeurs une bière ou un café, vous pouvez le faire %1here%2. Become a GitHub Sponsor? Devenir un sponsor de GitHub? Also possible, %1here%2. Également possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Ajouter de nouvelles actions en cliquant sur le bouton de l'onglet « Ajouter Â». EnumTranslator Rectangular Area Zone rectangulaire Last Rectangular Area Dernière zone rectangulaire Full Screen (All Monitors) Plein Écran (tous les moniteurs) Current Screen Écran actuel Active Window Fenêtre active Window Under Cursor Fenêtre sous le curseur Screenshot Portal Portail de capture d'écran FtpUploaderSettings Force anonymous upload. Forcer le téléversement anonyme. Url URL Username Nom d'utilisateur Password Mot de passe FTP Uploader Téléverseur FTP HandleUploadResultOperation Upload Successful Téléversement réussi Unable to save temporary image for upload. Impossible de sauvegarder une image temporaire pour le téléversement. Unable to start process, check path and permissions. Impossible de démarrer le processus, vérifiez le chemin et les permissions. Process crashed L’application a planté Process timed out. L’application a mis trop de temps à répondre. Process read error. Erreur de lecture de l’application. Process write error. Erreur d’écriture de l’application. Web error, check console output. Erreur Web, vérifier la sortie de la console. Upload Failed Échec de téléversement Script wrote to StdErr. Le script a écrit sur StdErr. FTP Upload finished successfully. Le téléversement FTP s'est terminé avec succès. Unknown error. Erreur inconnue. Connection Error. Erreur de connexion. Permission Error. Erreur d'autorisation. Upload script %1 finished successfully. Le script de téléversement %1 s'est terminé avec succès. Uploaded to %1 Téléversé sur %1 HotKeySettings Enable Global HotKeys Activer les raccourcis globaux Capture Rect Area Capturer zone rectangulaire Capture Full Screen Capturer tout l'écran Capture current Screen Capturer l'écran actif Capture active Window Capturer la fenêtre active Capture Window under Cursor Capturer la fenêtre sous le curseur Global HotKeys Raccourcis globaux Capture Last Rect Area Capturer la dernière zone rectangulaire Clear Effacer Capture using Portal Capturer par le portail HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Les HotKeys ne sont actuellement prises en charge que pour Windows et X11. La désactivation de cette option rend également les raccourcis d'action ksnip uniquement. ImageGrabberSettings Capture mouse cursor on screenshot Inclure le curseur de la souris lors d'une capture d'écran Should mouse cursor be visible on screenshots. Le curseur de la souris doit-il être visible les captures d’écran. Image Grabber Captureur d'image Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. L'implémentation de Generic Wayland qui utilise XDG-DESKTOP-PORTAL gère les changements d'échelle différemment. Cette option détermine le changement d'échelle en cours pour l'appliquer à la capture ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME et KDE Plasma prennent en charge leur propre Wayland et les captures Generic XDG-DESKTOP-PORTAL. Cette option force KDE Plasma et GNOME à utiliser les captures XDG-DESKTOP-PORTAL. Redémarrage requis. Show Main Window after capturing screenshot Afficher la fenêtre principale après la capture d'écran Hide Main Window during screenshot Cacher la fenêtre principale pendant la capture Hide Main Window when capturing a new screenshot. Cacher la fenêtre principale pendant une nouvelle capture. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Afficher la fenêtre principale après avoir créé une nouvelle capture d'écran lorsque la fenêtre principale a été masquée ou réduite. Force Generic Wayland (xdg-desktop-portal) Screenshot Capture d'écran de Force Generic Wayland (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots Captures d'écran de Scale Generic Wayland (xdg-desktop-portal) Implicit capture delay Délai de capture implicite This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Ce délai est utilisé lorsqu'aucun délai n'a été sélectionné dans l'interface utilisateur. l'interface utilisateur, il permet à ksnip de se cacher avant de prendre une capture d'écran. Cette valeur n'est pas appliquée lorsque ksnip a déjà été minimisé. Réduire cette valeur peut avoir pour effet que la fenêtre principale de ksnip est visible sur la capture d'écran. ImgurHistoryDialog Imgur History Historique Imgur Close Fermer Time Stamp Horodatage Link Lien Delete Link Supprimer le lien ImgurUploader Upload to imgur.com finished! Téléversement sur imgur.com terminé! Received new token, trying upload again… Nouveau jeton reçu, nouvelle tentative de téléversement… Imgur token has expired, requesting new token… Jeton Imgur expiré, demande de renouvellement… ImgurUploaderSettings Force anonymous upload Anonymiser le téléversement Always copy Imgur link to clipboard Toujours copier le lien Imgur dans le presse-papier Client ID ID Client Client Secret Client secret PIN NIP Enter imgur Pin which will be exchanged for a token. Entrez le NIP Imgur pour l'échanger contre un jeton. Get PIN Obtenir un NIP Get Token Obtenir un token Imgur History Historique Imgur Imgur Uploader Envoyer sur Imgur Username Nom d'utilisateur Waiting for imgur.com… En attente d'imgur.com… Imgur.com token successfully updated. Jeton imgur.com mis à jour avec succès. Imgur.com token update error. Erreur de mise à jour du token Imgur.com. After uploading open Imgur link in default browser Après téléversement, ouvrir le lien imgur avec le navigateur par défaut Link directly to image Relier directement l'image Base Url: URL de base : Base url that will be used for communication with Imgur. Changing requires restart. L’URL de base sera utilisée pour communiquer avec Imgur. La modifier nécessite un redémarrage. Clear Token Effacer les jetons Upload title: Téléverser le titre : Upload description: Téléverser la description : LoadImageFromFileOperation Unable to open image Impossible d’ouvrir l’image Unable to open image from path %1 Impossible d’ouvrir l’image à partir du chemin %1 MainToolBar New Nouveau Delay in seconds between triggering and capturing screenshot. Délai en secondes entre le déclenchement et la capture de l'écran. s The small letter s stands for seconds. s Save Enregistrer Save Screen Capture to file system Enregistrer la capture d'écran sur le disque Copy Copier Copy Screen Capture to clipboard Copier la capture d'écran dans le presse-papier Tools Outils Undo Annuler Redo Rétablir Crop Découper Crop Screen Capture Découper la capture d'écran MainWindow Unsaved Non enregistré Upload Téléverser Print Imprimer Opens printer dialog and provide option to print image Ouvre l'interface de l'imprimante et affiche les options d'impression Print Preview Aperçu avant impression Opens Print Preview dialog where the image orientation can be changed Ouvre la boîte de dialogue Aperçu avant impression où l'orientation de l'image peut être modifiée Scale Redimensionner Quit Quitter Settings Préférences &About &À propos Open Ouvrir &Edit É&dition &Options &Options &Help &Aide Add Watermark Ajouter un filigrane Add Watermark to captured image. Multiple watermarks can be added. Ajout d'un filigrane à l'image capturée. Plusieurs filigranes peuvent être ajoutés. &File &Fichier Unable to show image Impossible d'afficher l'image Save As... Enregistrer sous… Paste Coller Paste Embedded Coller l'intégration Pin Épingler Pin screenshot to foreground in frameless window Épingler la capture au premier plan dans une fenêtre sans bords No image provided but one was expected. Une image est attendue mais aucune fournie. Copy Path Chemin de copie Open Directory Ouvrir le dossier &View &Afficher Delete Supprimer Rename Renommer Open Images Ouvrir les images Show Docks Afficher le panneau d'outils Hide Docks Cacher le panneau d'outils Copy as data URI Copie en tant qu’URI de données Open &Recent Ouvrir &Récent Modify Canvas Modifier le canevas Upload triggerCapture to external source Téléverser la capture du déclencheur vers une source externe Copy triggerCapture to system clipboard Copier la capture du déclencheur dans le presse-papier du système Scale Image Image à l'échelle Rotate Pivoter Rotate Image Pivoter l'image Actions Actions Image Files Fichiers d'images Save All Tout enregistrer Close Window Fermer la fenêtre Cut Couper OCR ROC MultiCaptureHandler Save Enregistrer Save As Enregistrer sous Open Directory Ouvrir le dossier Copy Copier Copy Path Copier le chemin Delete Supprimer Rename Renommer Save All Tout enregistrer NewCaptureNameProvider Capture Capture OcrWindowCreator OCR Window %1 Fenêtre ROC %1 PinWindow Close Fermer Close Other Fermer les autres Close All Tout fermer PinWindowCreator OCR Window %1 Fenêtre ROC %1 PluginsSettings Search Path Chemin de recherche Default Par défaut The directory where the plugins are located. Le répertoire où se trouvent les greffons. Browse Parcourir Name Nom Version Version Detect Détecter Plugin Settings Paramètres des greffons Plugin location Emplacement du greffon ProcessIndicator Processing Traitement en cours RenameOperation Image Renamed Image renommée Image Rename Failed Échec du renommage de l'image Rename image Renommer l'image New filename: Nouveau nom de fichier : Successfully renamed image to %1 L'image a été renommée avec succès en %1 Failed to rename image to %1 Échec du renommage de l'image en %1 SaveOperation Save As Enregistrer sous All Files Tous les fichiers Image Saved Image sauvegardée Saving Image Failed Échec de la sauvegarde de l'image Image Files Fichiers d'images Saved to %1 Enregistré dans %1 Failed to save image to %1 Échec de la sauvegarde de l'image dans %1 SaverSettings Automatically save new captures to default location Enregistrer automatiquement les nouvelles captures dans l'emplacement par défaut Prompt to save before discarding unsaved changes Proposer d'enregistrer en cas d'abandon de modifications non enregistrées Remember last Save Directory Se souvenir du dernier emplacement de sauvegarde When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Proposer le dernier emplacement utilisé pour l'enregistrement plutôt que celui défini ci-dessous. Capture save location and filename Répertoire d'enregistrement et nom du fichier Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Les formats supportés sont JPG, PNG et BMP. Si aucun format n’est spécifié, PNG sera utilisé par défaut. Le nom du fichier peut contenir les jokers suivants : - $Y : année, $M : mois, $D : jour, $h : heure, $m : minutes, $s : secondes, $T : temps au format « hhmmss Â». - Plusieurs caractères # permettent de numéroter. Par exemple : #### donnera 0001 puis 0002 à la prochaine capture. Browse Parcourir Saver Settings Paramètres d'enregistrement Capture save location Répertoire d'enregistrement des captures Default Par défaut Factor Facteur Save Quality Qualité d'enregistrement Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Préciser 0 pour des fichiers compressés légers, 100 pour des fichiers lourds non compressés. Certains format ne prennent pas en charge l'intervalle en entier comme c'est le cas pour le JPEG. Overwrite file with same name Écraser le fichier avec le même nom ScriptUploaderSettings Copy script output to clipboard Copier la sortie du script vers le presse-papier Script: Script : Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Chemin vers le script qui sera utilisé pour le téléversement. Le script sera appelé avec le chemin vers une image temporaire au format PNG comme unique argument. Browse Parcourir Script Uploader Script d'envoi Select Upload Script Sélectionner le script d'envoi Stop when upload script writes to StdErr Arrêter quand le script d'envoi écrit sur StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. L'envoi sera noté comme échoué si le script a écrit sur StdErr. Si cette case n'est pas cochée, les erreurs du script passeront inaperçues. Filter: Filtre : RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Expression rationnelle (RegEx). Seules les lignes correspondant à la RegEx seront copiées dans le presse-papier. Si aucun filtre n'est défini, toutes les lignes seront copiées. SettingsDialog Settings Préférences OK OK Cancel Annuler Image Grabber Captureur d'image Imgur Uploader Envoyer sur Imgur Application Application Annotator Annotation HotKeys Raccourcis clavier Uploader Envoi sur un serveur Script Uploader Script d'envoi Saver Enregistrement Stickers Autocollants Snipping Area Zone de capture Tray Icon Icône de la barre des tâches Watermark Filigrane Actions Actions FTP Uploader Téléverseur FTP Plugins Greffons Search Settings... Paramètres de recherche… SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ajuster la taille du rectangle sélectionné en utilisant les poignées ou déplacez-le en glissant la sélection. Use arrow keys to move the selection. Utilisez les touches fléchées pour déplacer la sélection. Use arrow keys while pressing CTRL to move top left handle. Utiliser les touches flèches en pressant CTRL pour déplacer la poignée en haut à gauche. Use arrow keys while pressing ALT to move bottom right handle. Utiliser les touches flèches en pressant ALT pour déplacer la poignée en bas à droite. This message can be disabled via settings. Ce message peut être désactivé via les préférences. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Confirmez la sélection en appuyant sur ENTRÉE/RETOUR ou en double-cliquant n'importe où avec la souris. Abort by pressing ESC. Abandonnez en appuyant sur Échap. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Cliquez et faites glisser pour sélectionner une zone rectangulaire ou appuyez sur ÉCHAP pour quitter. Hold CTRL pressed to resize selection after selecting. Maintenez la touche CTRL enfoncée pour redimensionner la sélection après avoir fait une sélection. Hold CTRL pressed to prevent resizing after selecting. Maintenez la touche CTRL enfoncée pour empêcher le redimensionnement après avoir effectué une sélection. Operation will be canceled after 60 sec when no selection made. L’opération sera annulée après 60 secondes si aucune sélection n’est effectuée. This message can be disabled via settings. Ce message peut être désactivé via les préférences. SnippingAreaSettings Freeze Image while snipping Figer l’image lors de la capture When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Pour figer l'arrière-plan lors de la sélection rectangulaire. Cela affecte aussi le comportement des captures avec délai. Activé, la durée est avant l'affichage de la zone de sélection. Désactivé, la durée est après. Cette fonctionnalité n'est jamais active sur Wayland mais toujours sur MacOS. Show magnifying glass on snipping area Afficher la loupe sur la zone de capture Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Afficher une loupe qui grossit le fond d’écran. Cette option ne fonctionne que si « Figer l’image avant capture Â» est activé. Show Snipping Area rulers Afficher les règles de la zone de capture Horizontal and vertical lines going from desktop edges to cursor on snipping area. Afficher des lignes horizontales et verticales depuis les bords de l'écran jusqu'au pointeur pour aider au cadrage. Show Snipping Area position and size info Afficher les informations sur la position et la taille de la zone de capture When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Lorsque le bouton gauche de la souris n'est pas enfoncé, la position s'affiche, lorsque le bouton de la souris est enfoncé, la taille de la zone sélectionnée est indiquée à gauche et au-dessus de la zone capturée. Allow resizing rect area selection by default Autoriser le redimensionnement de la sélection de la zone rectangulaire par défaut When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Lorsque l'option est activée, après avoir sélectionné une zone rectangulaire, celle-ci peut être redimensionnée. Le redimensionnement de la sélection peut être confirmé en appuyant sur la touche retour. Show Snipping Area info text Afficher le texte d’informations sur la zone de capture Snipping Area cursor color Couleur du curseur de la zone de capture Sets the color of the snipping area cursor. Définit la couleur du curseur de la zone de capture. Snipping Area cursor thickness Épaisseur du curseur de la zone de capture Sets the thickness of the snipping area cursor. Règle l’épaisseur du curseur de la zone de capture. Snipping Area Zone de capture Snipping Area adorner color Couleur d'ornement de la zone de capture Sets the color of all adorner elements on the snipping area. Définit la couleur de tous les éléments d’ornement sur la zone de capture. Snipping Area Transparency Transparence de la zone de capture Alpha for not selected region on snipping area. Smaller number is more transparent. Alpha pour la région en dehors de la zone de capture. Une petite valeur est plus transparente. Enable Snipping Area offset Activer le décalage de la zone de découpe When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Lorsqu'il est activé, il applique le décalage configuré à la position de la zone de découpe, ce qui est nécessaire lorsque la position n'est pas correctement calculée. Ceci est parfois nécessaire lorsque la mise à l'échelle de l'écran est activée. X X Y Y StickerSettings Up Monter Down Descendre Use Default Stickers Utiliser les stickers par défaut Sticker Settings Paramètres des stickers Vector Image Files (*.svg) Images vectorielles (*.svg) Add Ajouter Remove Supprimer Add Stickers Ajouter des Stickers TrayIcon Show Editor Montrer l'éditeur TrayIconSettings Use Tray Icon Utiliser l'icône de la barre de tâches When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Si activé, ajoute une icône dans la barre des tâches si le système d’exploitation le permet. Le changement nécessite un redémarrage. Minimize to Tray Réduire vers la barre des tâches Start Minimized to Tray Démarrer en miniature dans la barre des tâches Close to Tray Fermer vers la barre des tâches Show Editor Afficher l’éditeur Capture Capture Default Tray Icon action Action par défaut de l’icône de la barre des tâches Default Action that is triggered by left clicking the tray icon. Action par défaut déclenchée par un clic gauche sur l’icône dans la barre des tâches. Tray Icon Settings Paramètres de l’icône de la barre des tâches Use platform specific notification service Utiliser un service de notification spécifique à la plateforme When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Lorsque cette option est activée, elle essaiera d'utiliser un service de notification spécifique à la plateforme lorsqu'il existe. spécifique à la plateforme lorsqu'il existe. Le changement nécessite un redémarrage pour prendre effet. Display Tray Icon notifications Afficher les notifications de l'icône de la barre d'état système UpdateWatermarkOperation Select Image Sélectionner l'image Image Files Fichiers d'images UploadOperation Upload Script Required Un script d'envoi est nécessaire Please add an upload script via Options > Settings > Upload Script Veuillez ajouter un script d'envoi dans Options > Paramètres > Script d'envoi Capture Upload Envoi de la capture You are about to upload the image to an external destination, do you want to proceed? La capture va être téléversée sur un serveur externe. Souhaitez-vous continuer? UploaderSettings Ask for confirmation before uploading Demander une confirmation avant de téléverser Uploader Type: Méthode d'envoi : Imgur Imgur Script Script Uploader Envoi sur un serveur FTP FTP VersionTab Version Version Build Compiler Using: Dépendances : WatermarkSettings Watermark Image Image en filigrane Update Mettre à jour Rotate Watermark Pivoter le filigrane When enabled, Watermark will be added with a rotation of 45° Si activé, le filigrane sera ajouté avec une rotation de 45° Watermark Settings Paramètres des filigranes ksnip-master/translations/ksnip_gl.ts000066400000000000000000002045541457262621600204170ustar00rootroot00000000000000 AboutDialog About Sobre About Sobre Version Versión Author Autor Close Pechar Donate Doar Contact Contacto AboutTab License: Licenza: Screenshot and Annotation Tool Ferramenta de captura de pantalla e anotación ActionSettingTab Name Nome Shortcut Atallo Clear Limpar Take Capture Facer captura Include Cursor Incluír cursor Delay Atraso s The small letter s stands for seconds. s Capture Mode Modo de captura Show image in Pin Window Mostrar imaxe na xanela fixada Copy image to Clipboard Copiar imaxe para a área de transferencia Upload image Subir imaxe Open image parent directory Abrir o directorio da imaxe Save image Gardar imaxe Hide Main Window Ocultar a xanela principal Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Engadir Actions Settings Configuración de accións Action Acción AddWatermarkOperation Watermark Image Required Marca de auga requerida Please add a Watermark Image via Options > Settings > Annotator > Update Por favor, engade unha imaxe de marca de auga via Opcións > Configuracións > Editor > Subir AnnotationSettings Smooth Painter Paths Suavizar trazos When enabled smooths out pen and marker paths after finished drawing. Cando está habilitado, suaviza os trazos do lapis e o rotulador ao rematar de debuxar. Smooth Factor Factor de suavizado Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Aumentar o factor de suavidade diminuirá a precisión do bolígrafo e do rotulador, pero faráos máis suaves. Annotator Settings Configuracións do editor Remember annotation tool selection and load on startup Lembra a selección da ferramenta de anotación e cárgaa no inicio Switch to Select Tool after drawing Item Cambia á ferramenta Seleccionar despois de debuxar o elemento Number Tool Seed change updates all Number Items Ao seleccionar un modo diferente na ferramenta numérica actualízanse todos os elementos numéricos Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Desactivar esta opción causa mudanzas na ferramenta númerica para afectar apenas novos elementos, mais non os elementos existentes. Desactivar esta opción permite ter números duplicados. Canvas Color Cor do lenzo Default Canvas background color for annotation area. Changing color affects only new annotation areas. Cor de fondo predeterminada do lenzo para a área de anotación. O cambio de cor afecta só ás novas áreas de anotación. Select Item after drawing Selecciona o elemento despois de debuxar With this option enabled the item gets selected after being created, allowing changing settings. Con esta opción activada, o elemento é seleccionado despois de ser creado, permitindo cambiar a configuración. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Captura de pantalla no inicio co modo predeterminado Application Style Estilo do aplicativo Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Establece o estilo do aplicativo que define a aparencia da interface O cambio require do reinicio do ksnip para que teña efecto. Application Settings Configuracións da aplicación Automatically copy new captures to clipboard Copia automaticamente novas capturas para a área de transferencia Use Tabs Usar separadores Change requires restart. O cambio require reiniciar. Run ksnip as single instance Executar ksnip como instancia única Hide Tabbar when only one Tab is used. Ocultar a barra de separadores cando só se utiliza un separador. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Activar esta opción permitirá que só se execute unha instancia de ksnip, todas as outras instancias iniciadas despois da primeira pasarán os seus argumentos á primeira e pecharán. Cambiar esta opción require un novo inicio de todas as instancias. Remember Main Window position on move and load on startup Lembra a posición da xanela principal ao mover e cargar ao iniciar Auto hide Tabs Ocultar automaticamente os separadores Auto hide Docks Ocultar automaticamente Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. No inicio ocultar a barra de ferramentas e a configuración de anotacións. A visibilidade dos Docks pódese cambiar coa tecla Tab. Auto resize to content Redimensionar automaticamente para o contido Automatically resize Main Window to fit content image. Cambia automaticamente o tamaño da xanela principal para axustar a imaxe de contido. Enable Debugging Habilitar a depuración Enables debug output written to the console. Change requires ksnip restart to take effect. Activa a saída de depuración escrita na consola. O cambio require o reinicio de ksnip para que teña efecto. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Cambiar o tamaño ao contido é un atraso para permitir que o Xestor de fiestras reciba o novo contido. No caso de que as fiestras principais non se axusten correctamente ao novo contido, aumentar este atraso pode mellorar o comportamento. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Explorar AuthorTab Contributors: Colaboradores: Spanish Translation Tradución ao español Dutch Translation Tradución ao holandés Russian Translation Tradución ao ruso Norwegian BokmÃ¥l Translation Tradución ao noruegués BokmÃ¥l French Translation Tradución ao francés Polish Translation Tradución ao polaco Snap & Flatpak Support Compatibilidade con Snap e Flatpak The Authors: Autoras: CanDiscardOperation Warning - Aviso - The capture %1%2%3 has been modified. Do you want to save it? A captura %1%2%3 foi modificada. Desexas gardala? CaptureModePicker New Novo Draw a rectangular area with your mouse Debuxe unha área rectangular co rato Capture full screen including all monitors Capturar a pantalla completa incluíndo todos os monitores Capture screen where the mouse is located Capturar a pantalla na que se atopa o rato Capture window that currently has focus Capturar a pantalla que está en foco agora Capture that is currently under the mouse cursor Captura a xanela que se atopa agora baixo o cursor do rato Capture a screenshot of the last selected rectangular area Realiza unha captura de pantalla da última área rectangular seleccionada Uses the screenshot Portal for taking screenshot Usa o Portal de capturas de pantalla para facer unha captura ContactTab Community Comunidade Bug Reports Relatorio de erros If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Se tes preguntas xerais, ideas ou só queres falar sobre ksnip,<br/>únete ao noso servidor %1 ou %2. Please use %1 to report bugs. Por favor, usa %1 para notificar de algún bug. CopyAsDataUriOperation Failed to copy to clipboard Erro ao copiar para a área de transferencia Failed to copy to clipboard as base64 encoded image. Produciuse un erro ao copiar para a área de transferencia como imaxe codificada en base64. Copied to clipboard Copiado para a área de transferencia Copied to clipboard as base64 encoded image. Copiado para a àrea de transferencia como imaxe codificada en base64. DeleteImageOperation Delete Image Eliminar imaxe The item '%1' will be deleted. Do you want to continue? Vaise eliminar o elemento '%1'. Desexas continuar? DonateTab Donations are always welcome As doazóns son sempre benvidas Donation Doazón ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip é un proxecto de software libre de copyleft non rendible e<br/>aínda ten algúns custos que deben ser cubertos,<br/>como os custos de dominio ou de hardware para o soporte multiplataforma. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Se queres axudar ou só queres apreciar o traballo que se está a facer<br/>agasallando aos desenvolvedores cunha cervexa ou un café, podes facelo %1aquí%2. Become a GitHub Sponsor? Quéreste converter nun patrocinador en GitHub? Also possible, %1here%2. Tamén é posible, %1aquí%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Engade novas accións premendo o botón do separador "Engadir". EnumTranslator Rectangular Area Ãrea rectangular Last Rectangular Area Última área rectangular Full Screen (All Monitors) Pantalla completa (todos os monitores) Current Screen Pantalla actual Active Window Xanela activa Window Under Cursor Xanela baixo o cursor Screenshot Portal Portal de captura de pantalla FtpUploaderSettings Force anonymous upload. Forzar a subida anónima. Url URL Username Nome do usuario Password Chave de acceso FTP Uploader Cargador FTP HandleUploadResultOperation Upload Successful Subida con suceso Unable to save temporary image for upload. Non se puido gardar a imaxe temporal para subila. Unable to start process, check path and permissions. Non se puido iniciar o proceso, comprobe a ruta e os permisos. Process crashed O proceso fallou Process timed out. O tempo de espera do proceso esgotouse. Process read error. Erro de lectura do proceso. Process write error. Erro de escritura do proceso. Web error, check console output. Erro web, comprobe a saída da consola. Upload Failed Erro na subida Script wrote to StdErr. Saída do script para a saída estándar de erros. FTP Upload finished successfully. Subida por FPT finalizada con suceso. Unknown error. Erro descoñecido. Connection Error. Erro de conexión. Permission Error. Erro de permisos. Upload script %1 finished successfully. A carga do script % 1 rematou correctamente. Uploaded to %1 Subido para %1 HotKeySettings Enable Global HotKeys Activa os atallos de teclado globais Capture Rect Area Captrurar área rectangular Capture Full Screen Capturar a pantalla completa Capture current Screen Capturar a pantalla actual Capture active Window Capturar a xanela activa Capture Window under Cursor Capturar a xanela baixo o cursor Global HotKeys Atallos de teclado globais Capture Last Rect Area Captura da última área rectangular Clear Limpar Capture using Portal Capturar utilizando o Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Actualmente, as teclas de acceso rápido só son compatibles con Windows e X11. Ao desactivar esta opción, os atallos de accións son só do ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Capturar o cursor do rato na captura de pantalla Should mouse cursor be visible on screenshots. O cursor do rato estará visíbel nas capturas de pantalla. Image Grabber Captura de imaxe Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. As implementacións xenéricas de Wayland que usan XDG-DESKTOP-PORTAL manexan a escala da pantalla de forma diferente. Activar esta opción determinará a escala actual da pantalla e aplicarase á captura de pantalla en ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME e KDE Plasma admiten as súas propias capturas de pantalla Wayland e Generic XDG-DESKTOP-PORTAL. Activar esta opción obrigará a KDE Plasma e GNOME a usar as capturas de pantalla XDG-DESKTOP-PORTAL. O cambio nesta opción require un reinicio de ksnip. Show Main Window after capturing screenshot Mostrar a xanela principal despois de unha captura de pantalla Hide Main Window during screenshot Ocultar a xanela principal durante a captura de pantalla Hide Main Window when capturing a new screenshot. Ocultar a xanela principal ao facer unha nova captura de pantalla. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Mostrar a xanela rrincipal despois dunha nova captura cando a xanela principal foi escondida ou minimizada. Force Generic Wayland (xdg-desktop-portal) Screenshot Forzar o modo xenérico Wayland (xdg-desktop-portal) de captura de pantalla Scale Generic Wayland (xdg-desktop-portal) Screenshots Escalar o modo xenérico Wayland (xdg-desktop-portal) de captura de pantalla Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Historial do Imgur Close Pechar Time Stamp Marca temporal Link Ligazón Delete Link Eliminar a ligazón ImgurUploader Upload to imgur.com finished! Rematou o envío a imgur.com! Received new token, trying upload again… Recibiuse un novo token, tentando cargar de novo… Imgur token has expired, requesting new token… O token de Imgur caducou, solicitando un novo token… ImgurUploaderSettings Force anonymous upload Forzar a carga anónima Always copy Imgur link to clipboard Copia sempre a ligazón Imgur no portapapeis Client ID ID do cliente Client Secret Segredo do cliente PIN PIN Enter imgur Pin which will be exchanged for a token. Introduce o Pin imgur que se trocará por un token. Get PIN Obter o PIN Get Token Obter token Imgur History Historial do Imgur Imgur Uploader Cargador de imgur Username Nome do usuario Waiting for imgur.com… Agardando por imgur.com… Imgur.com token successfully updated. O token de Imgur.com actualizouse con éxito. Imgur.com token update error. Erro de actualización do token de Imgur.com. After uploading open Imgur link in default browser Despois de cargar, abra a ligazón Imgur no navegador predeterminado Link directly to image Ligazón directa á imaxe Base Url: URL Base: Base url that will be used for communication with Imgur. Changing requires restart. URL base que se utilizará para a comunicación con Imgur. O cambio require reiniciar. Clear Token Limpar token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Non se puido abrir a imaxe Unable to open image from path %1 Non foi posíbel abrir a imaxe da ruta % 1 MainToolBar New Novo Delay in seconds between triggering and capturing screenshot. Atraso en segundos entre a activación e a captura de pantalla. s The small letter s stands for seconds. seg. Save Gardar Save Screen Capture to file system Gardar a captura de pantalla no sistema de ficheiros Copy Copiar Copy Screen Capture to clipboard Copiar as capturas de pantalla no portapapeis Tools Ferramentas Undo Desfacer Redo Refacer Crop Cortar Crop Screen Capture Cortar a captura de pantalla MainWindow Unsaved Sen gardar Upload Envío Print Imprimir Opens printer dialog and provide option to print image Abre o cadro de dialogo da impresora e fornece a opción para imprimir a imaxe Print Preview Vista previa da impresión Opens Print Preview dialog where the image orientation can be changed Abre o cadro de diálogo da vista previa de impresión onde se pode cambiar a orientación da imaxe Scale Escalar Quit Saír Settings Axustes &About &Sobre Open Abrir &Edit &Editar &Options &Opcións &Help &Axuda Add Watermark Engadir marca de auga Add Watermark to captured image. Multiple watermarks can be added. Engadir marca de auga á imaxe capturada. Pódense engadir varias marcas de auga. &File &Ficheiro Unable to show image Non se pode mostrar a imaxe Save As... Gardar como... Paste Pegar Paste Embedded Pegar incrustado Pin Fixar Pin screenshot to foreground in frameless window Fixar a captura de pantalla en primeiro plano nunha xanela sen marco No image provided but one was expected. Non se proporcionou ningunha imaxe pero agardábase unha. Copy Path Copiar ruta Open Directory Abrir directorio &View &Ver Delete Eliminar Rename Renomear Open Images Abrir imaxes Show Docks Mostrar Docks Hide Docks Ocultar Docks Copy as data URI Copiar como URI de datos Open &Recent Abrir &Recente Modify Canvas Modificar Canvas Upload triggerCapture to external source Carga triggerCapture a unha fonte externa Copy triggerCapture to system clipboard Copia triggerCapture no portapapeis do sistema Scale Image Escalar imaxe Rotate Rotar Rotate Image Rotar imaxe Actions Accións Image Files Ficheiros de imaxe Save All Close Window Cut OCR MultiCaptureHandler Save Gardar Save As Gardar como Open Directory Abrir directorio Copy Copiar Copy Path Copiar ruta Delete Eliminar Rename Renomear Save All NewCaptureNameProvider Capture Capturar OcrWindowCreator OCR Window %1 PinWindow Close Pechar Close Other Pechar outro Close All Pechar todo PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Predeterminado The directory where the plugins are located. Browse Explorar Name Nome Version Versión Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Imaxe renomeada Image Rename Failed Ocorreu un erro ao renomear a imaxe Rename image Renomear imaxe New filename: Novo nome de arquivo: Successfully renamed image to %1 Cambiouse correctamente o nome da imaxe a %1 Failed to rename image to %1 Non se puido cambiar o nome da imaxe a %1 SaveOperation Save As Gardar como All Files Todos os ficheiros Image Saved Imaxe gardada Saving Image Failed Erro ao gardar a imaxe Image Files Ficheiros de imaxe Saved to %1 Gardado en %1 Failed to save image to %1 Non se puido gardar a imaxe en %1 SaverSettings Automatically save new captures to default location Garda automaticamente as novas capturas na localización predeterminada Prompt to save before discarding unsaved changes Solicitar para gardar antes de descartar os cambios non gardados Remember last Save Directory Lembrar o último directorio onde se gardaron arquivos When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Cando estea activado, sobrescribirase o directorio de gardado almacenado na configuración co último directorio de gardado, para cada gardado. Capture save location and filename Captura a localización e o nome do ficheiro para gardar Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Os formatos admitidos son JPG, PNG e BMP. Se non se proporciona ningún formato, empregarase PNG como predeterminado. O nome de ficheiro pode conter os seguintes comodíns: - $Y, $M, $D para a data, $h, $m, $s para a hora ou $T para a hora en formato hhmmss. - Múltiples # consecutivos para o contador. #### dará como resultado 0001, a seguinte captura sería 0002. Browse Explorar Saver Settings Configuracións de gardado Capture save location Localización para gardar as capturas Default Predeterminado Factor Save Quality Calidade para gardar Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Especifique 0 para obter ficheiros pequenos comprimidos, 100 para ficheiros grandes sen comprimir. Non todos os formatos de imaxe admiten a gama completa, JPEG si. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Copiar a saída do script no portapapeis Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Camiño ao script que se chamará para cargalo. Durante a carga, o script chamarase coa ruta dun ficheiro png temporal como un único argumento. Browse Explorar Script Uploader Cargador de scripts Select Upload Script Selecciona o script para envio Stop when upload script writes to StdErr Parar cando o script de envio graba em StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Marca a carga como fallida cando o script escribe en StdErr. Sen esta configuración, os erros no script pasarán desapercibidos. Filter: Filtro: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Expresión RegEx. Copia só no portapapeis o que coincida coa expresión RegEx. Cando se omite, cópiase todo. SettingsDialog Settings Axustes OK Aceptar Cancel Cancelar Image Grabber Capturador de imaxes Imgur Uploader Cargador de imgur Application Aplicación Annotator Anotador HotKeys Atallos do teclado Uploader Cargador Script Uploader Script de envío Saver Gardador Stickers Adhesivos Snipping Area Ãrea de corte Tray Icon Icona da bandexa Watermark Marca de auga Actions Accións FTP Uploader Cargador FTP Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Cambia o tamaño do recto seleccionado usando as asas ou móveo arrastrando a selección. Use arrow keys to move the selection. Use as frechas para mover a selección. Use arrow keys while pressing CTRL to move top left handle. Use as frechas mentres preme CTRL para mover o manexo superior esquerdo. Use arrow keys while pressing ALT to move bottom right handle. Use as frechas mentres preme ALT para mover o manexo inferior dereito. This message can be disabled via settings. Esta mensaxe pódese desactivar mediante a configuración. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Fai clic e arrastra para seleccionar unha área rectangular ou preme ESC para saír. Hold CTRL pressed to resize selection after selecting. Mantén premido CTRL para cambiar o tamaño da selección despois de seleccionala. Hold CTRL pressed to prevent resizing after selecting. Mantén premido CTRL para evitar o cambio de tamaño despois de seleccionar. Operation will be canceled after 60 sec when no selection made. A operación cancelarase despois de 60 segundos cando non se realice ningunha selección. This message can be disabled via settings. Esta mensaxe pódese desactivar mediante a configuración. SnippingAreaSettings Freeze Image while snipping Conxelar a imaxe mentres se recorta When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Cando estea activado, conxelará o fondo mentres selecciona unha rexión rectangular. Tamén cambia o comportamento das capturas de pantalla atrasadas, con esta opción activada, o atraso ocorre antes de que se mostre a área de recorte e coa opción desactivada, o atraso ocorre despois de que se mostre a área de recorte. Esta función sempre está desactivada para Wayland e sempre habilitado para MacOs. Show magnifying glass on snipping area Amosar a lupa na área de recorte Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Amosar unha lupa para facer zoom na imaxe de fondo. Esta opción só funciona coa opción «Conxelar a imaxe mentres se recorta» activada. Show Snipping Area rulers Amosar regras na área de recorte Horizontal and vertical lines going from desktop edges to cursor on snipping area. Liñas horizontais e verticais que van dende os bordos do escritorio ata o cursor na área de recorte. Show Snipping Area position and size info Amosar a posición da área de recorte e a información do tamaño When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Cando non se preme o botón esquerdo do rato móstrase a posición, cando se preme o botón do rato, o tamaño da área seleccionada móstrase á esquerda e arriba da área capturada. Allow resizing rect area selection by default Permitir redimensionar a selección da área recta de forma predeterminada When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Cando estea activado, despois de seleccionar unha área recta, permitirá cambiar o tamaño da selección. Cando remate o cambio de tamaño, a selección pódese confirmar premendo Intro. Show Snipping Area info text Mostrar texto de información da área de recorte Snipping Area cursor color Cor do cursor da área de recorte Sets the color of the snipping area cursor. Establece a cor do cursor da área de recorte. Snipping Area cursor thickness Grosor do cursor da área de recorte Sets the thickness of the snipping area cursor. Establece o grosor do cursor da área de recorte. Snipping Area Ãrea de corte Snipping Area adorner color Cor do adorno da área de corte Sets the color of all adorner elements on the snipping area. Establece a cor de todos os elementos de adorno na área de recorte. Snipping Area Transparency Transparencia da área de corte Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa para a rexión non seleccionada na área de recorte. O número menor é máis transparente. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Arriba Down Abaixo Use Default Stickers Usar adhesivos predeterminados Sticker Settings Configuración de adhesivos Vector Image Files (*.svg) Arquivos de imaxe vectorial (*.svg) Add Engadir Remove Sacar Add Stickers Engadir adhesivos TrayIcon Show Editor Mostra Editor TrayIconSettings Use Tray Icon Usa a icona da bandexa When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Cando estea activado, engadirase unha icona da bandexa á barra de tarefas se o xestor de fiestras do SO o admite. O cambio require reiniciar. Minimize to Tray Minimizar a bandexa Start Minimized to Tray Iniciar minimizado na bandexa Close to Tray Pechar para a bandexa Show Editor Mostrar editor Capture Capturar Default Tray Icon action Acción predeterminada da icona da bandexa Default Action that is triggered by left clicking the tray icon. Acción predeterminada que se activa facendo clic co botón esquerdo na icona da bandexa. Tray Icon Settings Configuración da icona da bandexa Use platform specific notification service Use o servizo de notificación específico da plataforma When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Cando estea activado, empregarase o servizo de notificacións específicos da plataforma, se existen. O cambio require o reinicio para que teña efecto. Display Tray Icon notifications Mostrar notificacións da icona da bandexa UpdateWatermarkOperation Select Image Seleccionar imaxe Image Files Ficheiros de imaxe UploadOperation Upload Script Required Requírese o script de carga Please add an upload script via Options > Settings > Upload Script Engade un script de carga a través de Opcións > Configuración > Script de carga Capture Upload Subir captura You are about to upload the image to an external destination, do you want to proceed? Estás a piques de subir a imaxe a un destino externo, queres continuar? UploaderSettings Ask for confirmation before uploading Solicita confirmación antes de subir Uploader Type: Tipo de subida: Imgur Imgur Script Uploader Subir imaxe FTP VersionTab Version Versión Build Construción Using: Usando: WatermarkSettings Watermark Image Imaxe de marca de auga Update Actualizar Rotate Watermark Rotar a marca de auga When enabled, Watermark will be added with a rotation of 45° Cando estea activado, engadirase a marca de auga cunha rotación de 45° Watermark Settings Configuración da marca de auga ksnip-master/translations/ksnip_he.ts000066400000000000000000001647121457262621600204120ustar00rootroot00000000000000 AboutDialog About ×ודות. About ×ודות Version גרסה Author מחבר Close סגור Donate תרומה Contact צור קשר AboutTab License: רישיון: Screenshot and Annotation Tool כלי ×¦×™×œ×•× ×ž×¡×š והערות ActionSettingTab Name ×©× Shortcut קיצור דרך Clear Take Capture Include Cursor כלול סמן Delay השהייה s The small letter s stands for seconds. ש Capture Mode מצב לכידה Show image in Pin Window Copy image to Clipboard העתק תמונה ללוח Upload image העלה תמונה Open image parent directory פתיחת תיקיית התמונה Save image שמור תמונה Hide Main Window הסתר חלון ר×שי Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add הוסף Actions Settings הגדרות פעולות Action פעולה AddWatermarkOperation Watermark Image Required נדרשת תמונת סימן ×ž×™× Please add a Watermark Image via Options > Settings > Annotator > Update AnnotationSettings Smooth Painter Paths החלקת נתיבי צביעה When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Application Style Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Automatically copy new captures to clipboard Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs הסתרת ט××‘×™× ×וטומטית Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse לדפדף AuthorTab Contributors: Spanish Translation ×ª×¨×’×•× ×œ×¡×¤×¨×“×™×ª Dutch Translation ×ª×¨×’×•× ×œ×”×•×œ× ×“×™×ª Russian Translation ×ª×¨×’×•× ×œ×¨×•×¡×™×ª Norwegian BokmÃ¥l Translation ×ª×¨×’×•× ×œ× ×•×¨×•×•×’×™×ª French Translation ×ª×¨×’×•× ×œ×¦×¨×¤×ª×™×ª Polish Translation ×ª×¨×’×•× ×œ×¤×•×œ× ×™×ª Snap & Flatpak Support תמיכת Snap & Flatpak The Authors: המחברי×: CanDiscardOperation Warning - ×זהרה - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Password FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Close Time Stamp Link Delete Link ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Client Secret PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. Save Save Screen Capture to file system Copy Copy Screen Capture to clipboard Tools Undo Redo Crop Crop Screen Capture MainWindow Unsaved Upload Print Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Settings &About Open &Edit &Options &Help Add Watermark Add Watermark to captured image. Multiple watermarks can be added. &File Unable to show image Save As... Paste Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Save As Open Directory Copy Copy Path Delete Rename Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default ברירת מחדל The directory where the plugins are located. Browse לדפדף Name ×©× Version גרסה Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved Saving Image Failed Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Saver Settings Capture save location Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings OK Cancel Image Grabber Imgur Uploader Application Annotator HotKeys Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version Build Using: WatermarkSettings Watermark Image Update Rotate Watermark When enabled, Watermark will be added with a rotation of 45° Watermark Settings הגדרות סימן ×ž×™× ksnip-master/translations/ksnip_hr.ts000066400000000000000000002044301457262621600204170ustar00rootroot00000000000000 AboutDialog About Informacije About Informacije Version Verzija Author Autor Close Zatvori Donate Doniraj Contact Kontakt AboutTab License: Licenca: Screenshot and Annotation Tool Alat za snimanje ekrana i komentiranje ActionSettingTab Name Ime Shortcut PreÄac Clear Isprazni Take Capture Snimi sliku Include Cursor UkljuÄi kursor Delay Odgodi s The small letter s stands for seconds. s Capture Mode NaÄin snimanja Show image in Pin Window Prikaži sliku u prikvaÄenom prozoru Copy image to Clipboard Kopiraj sliku u meÄ‘uspremnik Upload image Prenesi sliku Open image parent directory Otvori nadreÄ‘enu mapu slike Save image Spremi sliku Hide Main Window Sakrij glavni prozor Global Globalno When enabled will make the shortcut available even when ksnip has no focus. Kada je aktivirano, preÄac će biti dostupan Äak i kada ksnip nema fokus. ActionsSettings Add Dodaj Actions Settings Postavke radnji Action Radnja AddWatermarkOperation Watermark Image Required Potrebna je slika vodenog žiga Please add a Watermark Image via Options > Settings > Annotator > Update Dodaj sliku vodenog žiga putem Opcije > Postavke > Komentari > Aktualiziraj AnnotationSettings Smooth Painter Paths ZaglaÄ‘ivanje crtanih staza When enabled smooths out pen and marker paths after finished drawing. Kad je aktivirano, zaglaÄ‘uje staze olovke i markera nakon crtanja. Smooth Factor Faktor zaglaÄ‘ivanja Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Povećanjem faktora zaglaÄ‘ivanja smanjit će se toÄnost olovke i markera, ali će povećati zaglaÄ‘ivanje. Annotator Settings Postavke komentara Remember annotation tool selection and load on startup Zapamti odabir alata za komentare i uÄitaj ga tijekom pokretanja programa Switch to Select Tool after drawing Item Prebaci na alat za biranje elemenata nakon crtanja elementa Number Tool Seed change updates all Number Items Mijenjanjem vrijednosti brojaÄa, aktualiziraju se svi brojevni elementi Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Deaktiviranjem ove opcije brojaÄ utjeÄe samo na nove elemente, ne i na postojeće. Na taj je naÄin moguće koristiti iste brojeve viÅ¡estruko. Canvas Color Boja platna Default Canvas background color for annotation area. Changing color affects only new annotation areas. Standardna boja pozadine platna za podruÄje komentara. Promjena boje utjeÄe samo na nova podruÄja komentara. Select Item after drawing Odabir element nakon crtanja With this option enabled the item gets selected after being created, allowing changing settings. Kad je ova opcija aktivirana, element se odabire nakon Å¡to se stvori i omogućuje mijenjanje postavki. Show Controls Widget Prikaži programÄić kontrola The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ProgramÄić kontrola sadrži gumbe za PoniÅ¡ti/Ponovi, Izreži, Skaliraj, Okreni i Promijeni platno. ApplicationSettings Capture screenshot at startup with default mode Snimi sliku ekrana prilikom pokretanja programa sa standardnim modusom Application Style Stil programa Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Postavlja stil programa koji odreÄ‘uje izgled suÄelja. Promjene stupaju na snagu nakon ponovnog pokretanja ksnipa. Application Settings Postavke programa Automatically copy new captures to clipboard Automatski kopiraj nove snimke u meÄ‘uspremnik Use Tabs Koristi kartice Change requires restart. Promjena zahtijeva ponovno pokretanje programa. Run ksnip as single instance Pokrenite samo jedan primjerak ksnipa Hide Tabbar when only one Tab is used. Sakrij traku kartica kad postoji samo jedna kartica. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Aktiviranjem ove opcije omogućuje se pokretanje samo jednog primjerka programa ksnip, a sva naknadna pokretanja programa proslijedit će svoje argumente prvom pokrenutom i zatim će se zatvoriti. Mijenjanje ove opcije zahtijeva ponovno pokretanje svih primjeraka. Remember Main Window position on move and load on startup Zapamti položaj glavnog prozora prilikom premjeÅ¡tanja i uÄitaj ga prilikom pokretanja programa Auto hide Tabs Automatski sakrij kartice Auto hide Docks Automatski sakrij ploÄe On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Prilikom pokretanja sakrij alatnu traku i postavke komentara. Vidljivost ploÄa može se promijeniti pomoću tipke tabulatora. Auto resize to content Automatski prilagodi veliÄinu sadržaju Automatically resize Main Window to fit content image. Automatski prilagodi veliÄinu glavnog prozora veliÄini slike sadržaja. Enable Debugging Aktiviraj ispravljanje greÅ¡aka Enables debug output written to the console. Change requires ksnip restart to take effect. Aktivira rezultat ispravljanje greÅ¡aka ispisan u konzoli. Promjena zahtijeva ponovno pokretanje ksnip-a da bi stupilo na snagu. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Mijenjanje veliÄine sadržaja je odgoda kako bi se upravljaÄu prozora omogućilo primanje novog sadržaja. U sluÄaju da glavni prozori nisu pravilno podeÅ¡eni na novi sadržaj, povećanje ovog kaÅ¡njenja moglo bi poboljÅ¡ati ponaÅ¡anje. Resize delay KaÅ¡njenje mijenjanja veliÄine Temp Directory Mapa meÄ‘uspremanja Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Mapa meÄ‘uspremanja koja se koristi za spremanje meÄ‘uspremljenih slika koje će se izbrisati nakon zatvaranja ksnipa. Browse Pregledaj AuthorTab Contributors: Doprinositelji: Spanish Translation Prijevod na Å¡panjolski Dutch Translation Prijevod na nizozemski Russian Translation Prijevod na ruski Norwegian BokmÃ¥l Translation Prijevod na norveÅ¡ki bokmÃ¥l French Translation Prijevod na francuski Polish Translation Prijevod na poljski Snap & Flatpak Support Snap i Flatpak podrÅ¡ka The Authors: Autori: CanDiscardOperation Warning - Upozorenje – The capture %1%2%3 has been modified. Do you want to save it? Snimka %1%2%3 je promijenjena. ŽeliÅ¡ li je spremiti? CaptureModePicker New Novo Draw a rectangular area with your mouse Nacrtaj pravokutno podruÄje pomoću miÅ¡a Capture full screen including all monitors Snimi cijeli ekran ukljuÄujući sve monitore Capture screen where the mouse is located Snimi ekran na mjestu gdje se nalazi miÅ¡ Capture window that currently has focus Snimi trenutaÄno aktivni prozor Capture that is currently under the mouse cursor Snimi ono Å¡to se nalazi ispod pokazivaÄa miÅ¡a Capture a screenshot of the last selected rectangular area Snimi sliku ekrana zadnjeg odabranog pravokutnog podruÄja Uses the screenshot Portal for taking screenshot Koristi portal slika ekrana za snimanje slike ekrana ContactTab Community Zajednica Bug Reports Prijave greÅ¡aka If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Ako imaÅ¡ opća pitanja, ideje ili ako jednostavno želiÅ¡ razgovarati o ksnipu,<br/>, pridruži se naÅ¡em %1 ili naÅ¡em %2 poslužitelju. Please use %1 to report bugs. Za prijavu greÅ¡aka koristi %1. CopyAsDataUriOperation Failed to copy to clipboard Neuspjelo kopiranje u meÄ‘uspremnik Failed to copy to clipboard as base64 encoded image. Neuspjelo kopiranje u meÄ‘uspremnik kao base64-kodiranu sliku. Copied to clipboard Kopirano u meÄ‘uspremnik Copied to clipboard as base64 encoded image. Kopirano u meÄ‘uspremnik kao base64-kodirana slika. DeleteImageOperation Delete Image IzbriÅ¡i sliku The item '%1' will be deleted. Do you want to continue? Izbrisat će se element „%1â€. ŽeliÅ¡ li nastaviti? DonateTab Donations are always welcome Donacije su uvijek dobrodoÅ¡le Donation Donacija ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip je neprofitabilan copyleft projekt slobodnog softvera i<br/>joÅ¡ uvijek ima neke troÅ¡kove koje treba pokriti,<br/>poput troÅ¡kova domene ili troÅ¡kova hardvera za viÅ¡eplatformsku podrÅ¡ku. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Ako želiÅ¡ pomoći ili ako samo želiÅ¡ cijeniti obavljeni posao<br/>slobodno poÄastiti programere pivom ili kavom %1ovdje%2. Become a GitHub Sponsor? ŽeliÅ¡ postati GitHub sponzor? Also possible, %1here%2. TakoÄ‘er moguće %1ovdje%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Dodaj nove radnje pritiskom gumba „Dodajâ€. EnumTranslator Rectangular Area Pravokutno podruÄje Last Rectangular Area Zadnje pravokutno podruÄje Full Screen (All Monitors) Cijeli ekran (svi monitori) Current Screen TrenutaÄni ekran Active Window Aktivni prozor Window Under Cursor Prozor ispod pokazivaÄa Screenshot Portal Portal slika ekrana FtpUploaderSettings Force anonymous upload. Prisili anoniman prijenos. Url URL Username KorisniÄko ime Password Lozinka FTP Uploader FTP prenositelj HandleUploadResultOperation Upload Successful Prijenos je uspio Unable to save temporary image for upload. Nije moguće spremiti privremenu sliku za prijenos. Unable to start process, check path and permissions. Nije moguće pokrenuti postupak. Provjeri stazu i dozvole. Process crashed Postupak prekinut zbog greÅ¡ke Process timed out. Postupak je prekoraÄio vrijeme. Process read error. GreÅ¡ka u postupku Äitanja. Process write error. GreÅ¡ka u postupku pisanja. Web error, check console output. Web-greÅ¡ka. Pregledaj rezultat u konzoli. Upload Failed Prijenos nije uspio Script wrote to StdErr. Skripta je zapisala u standardnu greÅ¡ku (StdErr). FTP Upload finished successfully. FTP prijenos je uspjeÅ¡no zavrÅ¡en. Unknown error. Nepoznata greÅ¡ka. Connection Error. GreÅ¡ka u vezi. Permission Error. GreÅ¡ka u dozvoli. Upload script %1 finished successfully. Prijenos skripta %1 uspjeÅ¡no zavrÅ¡en. Uploaded to %1 Preneseno na %1 HotKeySettings Enable Global HotKeys Aktiviraj globalne tipkovniÄke preÄace Capture Rect Area Snimi pravokutno podruÄje Capture Full Screen Snimi cijeli ekran Capture current Screen Snimi trenutaÄni ekran Capture active Window Snimi aktivni prozor Capture Window under Cursor Snimi prozor ispod pokazivaÄa Global HotKeys Globalni tipkovniÄki preÄaci Capture Last Rect Area Snimi zadnje pravokutno podruÄje Clear Isprazni Capture using Portal Snimi koristeći portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. TipkovniÄki preÄaci su trenutaÄno dostupni samo za Windows i X11. Deaktiviranjem ove opcije takoÄ‘er omogućuje preÄace radnji samo za ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Snimi pokazivaÄ miÅ¡a u sliku ekrana Should mouse cursor be visible on screenshots. Da li prikazati pokazivaÄ miÅ¡a u slikama ekrana. Image Grabber Snimanje slika Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GeneriÄke implementacije Waylanda koji koriste XDG-DESKTOP-PORTAL razliÄito upravljaju skaliranjem ekrana. Aktiviranjem ove opcije odredit će se trenutaÄno skaliranje ekrana i primijeniti na sliku ekrana u ksnipu. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME i KDE Plasma podržavaju vlastiti Wayland i generiÄke XDG-DESKTOP-PORTAL slike ekrana. Aktiviranjem ove opcije prisilit će KDE Plasma i GNOME da koriste XDG-DESKTOP-PORTAL slike ekrana. Mijenjanje ove opcije zahtijeva ponovno pokretanje ksnip-a. Show Main Window after capturing screenshot Pokaži glavni prozor nakon snimanja slike ekrana Hide Main Window during screenshot Sakrij glavni prozor tijekom snimanja slike ekrana Hide Main Window when capturing a new screenshot. Sakrij glavni prozor pri snimanju nove slike ekrana. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Prikaži glavni prozor nakon snimanja nove snimke ekrana kad je glavni prozor bio skriven ili smanjen. Force Generic Wayland (xdg-desktop-portal) Screenshot Prisili generiÄku wayland (xdg-desktop-portal) snimku ekrana Scale Generic Wayland (xdg-desktop-portal) Screenshots Promijeni veliÄinu generiÄke wayland (xdg-desktop-portal) snimke ekrana Implicit capture delay Implicitno kaÅ¡njenje snimanja This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Ova se odgoda koristi kad u korisniÄkom suÄelju odgoda nije odabrana. Time se omogućuje skrivanje ksnipa prije snimanja ekrana. Ova se vrijednost ne primjenjuje kada je ksnip već skriven u programsku traku. Smanjenje ove vrijednosti može imati uÄinak da glavni prozor ksnipa bude vidljiv na snimci ekrana. ImgurHistoryDialog Imgur History Imgur povijest Close Zatvori Time Stamp Vremenska oznaka Link Poveznica Delete Link IzbriÅ¡i poveznicu ImgurUploader Upload to imgur.com finished! Prijenos na imgur.com je zavrÅ¡en! Received new token, trying upload again… Primljen je novi token, pokuÅ¡aj ponovnog prijenosa … Imgur token has expired, requesting new token… Imgur token je istekao, Å¡alje se zahtijev se novim tokenom … ImgurUploaderSettings Force anonymous upload Prisili anonimni prijenos Always copy Imgur link to clipboard Uvijek kopiraj Imgur-poveznicu u meÄ‘uspremnik Client ID ID klijenta Client Secret Tajna klijenta PIN PIN Enter imgur Pin which will be exchanged for a token. UpiÅ¡i imgur pin koji će se zamijeniti za token. Get PIN Nabavi PIN Get Token Nabavi token Imgur History Imgur povijest Imgur Uploader Prijenos za Imgur Username KorisniÄko ime Waiting for imgur.com… ÄŒekanje na imgur.com … Imgur.com token successfully updated. Imgur.com token uspjeÅ¡no aktualiziran. Imgur.com token update error. GreÅ¡ka aktualiziranja Imgur.com tokena. After uploading open Imgur link in default browser Nakon prijenosa otvori poveznicu na Imgur u standardnom pregledniku Link directly to image Poveži izravno na sliku Base Url: Osnovni URL: Base url that will be used for communication with Imgur. Changing requires restart. Osnovni URL koji će se koristiti za komunikaciju s Imgurom. Promjena zahtijeva ponovno pokretanje programa. Clear Token PoniÅ¡ti token Upload title: Naslov preuzimanja: Upload description: Opis preuzimanja: LoadImageFromFileOperation Unable to open image Neuspjelo otvaranje slike Unable to open image from path %1 Neuspjelo otvaranje slike iz %1 MainToolBar New Novo Delay in seconds between triggering and capturing screenshot. ZadrÅ¡ka u sekundama izmeÄ‘u okidanja i snimanja slike ekrana. s The small letter s stands for seconds. s Save Spremi Save Screen Capture to file system Spremi snimku ekrana u datoteÄni sustav Copy Kopiraj Copy Screen Capture to clipboard Kopiraj snimku ekrana u meÄ‘uspremnik Tools Alati Undo PoniÅ¡ti Redo Ponovi Crop Obreži Crop Screen Capture Obreži snimku ekrana MainWindow Unsaved Nespremljeno Upload Prenesi Print IspiÅ¡i Opens printer dialog and provide option to print image Otvara dijaloÅ¡ki okvir pisaÄa i omogućuje ispisivanje slike Print Preview Pretprikaz ispisa Opens Print Preview dialog where the image orientation can be changed Otvara dijalog za pregled ispisa u kojem se može promijeniti orijentacija slike Scale Skaliraj Quit Zatvori program Settings Postavke &About &Informacije Open Otvori &Edit &Uredi &Options &Opcije &Help &Pomoć Add Watermark Dodaj vodeni žig Add Watermark to captured image. Multiple watermarks can be added. Dodaj vodeni žig snimljenoj slici. Moguće je dodati viÅ¡e vodenih žigova. &File &Datoteka Unable to show image Nije moguće prikazati sliku Save As... Spremi kao … Paste Umetni Paste Embedded Umetni ugraÄ‘eno Pin PrikvaÄi Pin screenshot to foreground in frameless window PrikvaÄi sliku ekrana naprijed u bezrubnom prozoru No image provided but one was expected. Nijedna slika nije zadana, ali oÄekuje se jedna. Copy Path Kopiraj stazu Open Directory Otvori direktorij &View &Prikaz Delete IzbriÅ¡i Rename Preimenuj Open Images Otvori slike Show Docks Prikaži ploÄe Hide Docks Sakrij ploÄe Copy as data URI Kopiraj kao URI podatke Open &Recent Otvori &nedavne Modify Canvas Promijeni platno Upload triggerCapture to external source Prenesi snimku ekrana u vanjski izvor Copy triggerCapture to system clipboard Kopiraj snimku ekrana u meÄ‘uspremnik sustava Scale Image Promijeni veliÄinu slike Rotate Okreni Rotate Image Okreni sliku Actions Radnje Image Files Datoteke slika Save All Spremi sve Close Window Zatvori prozor Cut Izreži OCR OCR MultiCaptureHandler Save Spremi Save As Spremi kao Open Directory Otvori direktorij Copy Kopiraj Copy Path Kopiraj stazu Delete IzbriÅ¡i Rename Preimenuj Save All Spremi sve NewCaptureNameProvider Capture Snimi OcrWindowCreator OCR Window %1 OCR prozor %1 PinWindow Close Zatvori Close Other Zatvori ostale Close All Zatvori sve PinWindowCreator OCR Window %1 OCR prozor %1 PluginsSettings Search Path Staza pretrage Default Standardno The directory where the plugins are located. Mapa gdje se nalaze dodaci. Browse Pregledaj Name Ime Version Verzija Detect Otkrij Plugin Settings Postavke dotadaka Plugin location Mjesto dotadaka ProcessIndicator Processing Obrada RenameOperation Image Renamed Slika je preimenovana Image Rename Failed Neuspjelo preimenovanje slike Rename image Preimenuj sliku New filename: Novo ime datoteke: Successfully renamed image to %1 Slika uspjeÅ¡no preimenovana u %1 Failed to rename image to %1 Neuspjelo preimenovanje slike u %1 SaveOperation Save As Spremi kao All Files Sve datoteke Image Saved Slika je spremljena Saving Image Failed Spremanje slike neuspjelo Image Files Datoteke slika Saved to %1 Spremljeno u %1 Failed to save image to %1 Neuspjelo spremanje slike u %1 SaverSettings Automatically save new captures to default location Automatski spremi nove snimke u standardno mjesto Prompt to save before discarding unsaved changes Zatraži spremanje prije odbacivanja nespremljenih promjena Remember last Save Directory Zapamti zadnji direktorij spremanja When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Kad je aktivirano, prepisat će mapu za spremanje u postavkama s najnovijom mapom za spremanje, za svako spremanje. Capture save location and filename Mjesto spremanja snimke i ime datoteke Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Podržani formati su JPG, PNG i BMP. Ako nije naveden nijedan format, standardno će se koristiti PNG. Ime datoteke može sadržavati sljedeće zamjenske znakove: - $Y, $M, $D za datum, $h, $m, $s za vrijeme ili $T za vrijeme u formatu „ hhmmssâ€. - ViÅ¡e uzastopnih znakova „#†za brojaÄ. „####†vraća 0001, slijedeće snimanje bit će 0002. Browse Pretraži Saver Settings Postavke spremanja Capture save location Mjesto spremanja snimke Default Standardno Factor Faktor Save Quality Kvaliteta spremanja Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Zadaj 0 za dobivanje male komprimirane datoteke, 100 za velike nekomprimirane datoteke. Neki formati slika ne podržavaju cijeli raspon, JPEG ga podržava. Overwrite file with same name PrepiÅ¡i istoimenu datoteku ScriptUploaderSettings Copy script output to clipboard Kopiraj rezultat skripta u meÄ‘uspremnik Script: Skripta: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Staza do skripta koji se poziva za prijenos. Tijekom prijenosa pozvat će se skripta sa stazom do privremene png datoteke kao jedan argument. Browse Pretraži Script Uploader Prijenos skriptom Select Upload Script Odaberi skripta za prenoÅ¡enje Stop when upload script writes to StdErr Prekini kad skripta prijenosa piÅ¡e u standardnu greÅ¡ku (StdErr) Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. OznaÄava prijenos kao neuspio, kad skripta piÅ¡e u standardnu greÅ¡ku (StdErr). Bez ove postavke greÅ¡ke u skriptu neće se primijetiti. Filter: Filtar: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. RegEx (regularni) izraz. Kopiraj u meÄ‘uspremnik samo ono Å¡to se poklapa s RegEx izrazom. Ako se izostavi, kopira se sve. SettingsDialog Settings Postavke OK U redu Cancel Prekini Image Grabber Snimanje slika Imgur Uploader Prijenos za Imgur Application Program Annotator Komentari HotKeys TipkovniÄki preÄaci Uploader Prijenos Script Uploader Skripta za prijenos Saver Spremanje Stickers Naljepnice Snipping Area PodruÄje izrezivanja Tray Icon Ikona u programskoj traci Watermark Vodeni žig Actions Radnje FTP Uploader FTP prenositelj Plugins Dodaci Search Settings... Pretraži postavke … SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Promijeni veliÄinu pravokutnog odabira pomoću ruÄki ili ga premjesti povlaÄenjem odabira. Use arrow keys to move the selection. Za premjeÅ¡tanje odabira koristi tipke sa strelicama. Use arrow keys while pressing CTRL to move top left handle. Za micanje gornje lijeve ruÄke pritisni tipku CTRL i koristi tipke sa strelicama. Use arrow keys while pressing ALT to move bottom right handle. Za micanje donje desne ruÄke pritisni tipku ALT i koristi tipke sa strelicama. This message can be disabled via settings. Ova se poruka može deaktivirati u postavkama. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Potvrdi odabir pritiskom tipke ENTER/RETURN ili dvostrukim pritiskom miÅ¡a bilo gdje. Abort by pressing ESC. Prekini pritiskom tipke ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Za biranje pravokutnog podruÄja pritisni-i-povuci miÅ¡a ili pritisni ESC za prekid. Hold CTRL pressed to resize selection after selecting. Za mijenjanje veliÄine odabira pritisni tipku CTRL i drži je pritisnutom. Hold CTRL pressed to prevent resizing after selecting. Za spreÄavanje mijenjanja veliÄine odabira pritisni tipku CTRL i drži je pritisnutom. Operation will be canceled after 60 sec when no selection made. Operacija će se prekinuti nakon 60 sekundi, ako se niÅ¡ta ne odabere. This message can be disabled via settings. Ova se poruka može deaktivirati u postavkama. SnippingAreaSettings Freeze Image while snipping Zamrzni sliku tijekom izrezivanja When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Kad je aktivirano, zamrznut će pozadinu tijekom biranja pravokutnog podruÄja. TakoÄ‘er mijenja trajanje zadrÅ¡ke prilikom snimanja ekrana. Kad je aktivirano, zadrÅ¡ka se dogaÄ‘a prije prikazivanja podruÄja izrezivanja. Kad deaktivirano, zadrÅ¡ka se dogaÄ‘a nakon prikazivanja podruÄja izrezivanja. Ova je funkcija uvijek deaktivirana za Wayland, a uvijek aktivirana za MacOS. Show magnifying glass on snipping area Pokaži povećalo u podruÄju izrezivanja Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Pokaži povećalo koje povećava prikaz slike pozadine. Ova opcija radi samo, kad je „Zamrzni sliku tijekom izrezivanja†aktivirano. Show Snipping Area rulers Pokaži ravnala za podruÄje izrezivanja Horizontal and vertical lines going from desktop edges to cursor on snipping area. Vodoravne i okomite crte, koje se protežu od rubova radne povrÅ¡ine do pokazivaÄa u podruÄju izrezivanja. Show Snipping Area position and size info Pokaži podatke ploložaja i veliÄine podruÄja izrezivanja When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Kad se lijeva tipka miÅ¡a ne pritisne, prikazuje se položaj. Kad se pritisne, veliÄina odabranog podruÄja prikazuje se lijevo iznad snimljenog podruÄja. Allow resizing rect area selection by default Standardno dozvoli mijenjanje veliÄine pravokutnog podruÄja When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Kad je aktivirano, nakon biranja pravokutnog podruÄja dozvoli mijenjanje veliÄine odabira. Promjena veliÄine odabira može se potvrditi pritiskom tipke return. Show Snipping Area info text Pokaži tekst informacija podruÄja izrezivanja Snipping Area cursor color Boja pokazivaÄa za oznaÄivanje podruÄja izrezivanja Sets the color of the snipping area cursor. Postavlja boju pokazivaÄa za oznaÄivanje podruÄja izrezivanja. Snipping Area cursor thickness Debljina pokazivaÄa za oznaÄavanje podruÄja izrezivanja Sets the thickness of the snipping area cursor. Postavlja debljinu pokazivaÄa za oznaÄivanje podruÄja izrezivanja. Snipping Area PodruÄje izrezivanja Snipping Area adorner color Ukrasna boja podruÄja izrezivanja Sets the color of all adorner elements on the snipping area. Postavlja boju svih ukrasnih elemenata u podruÄju izrezivanja. Snipping Area Transparency Prozirnost podruÄja izrezivanja Alpha for not selected region on snipping area. Smaller number is more transparent. Prozirnost za neodabrano podruÄje u podruÄju izrezivanja. Manji broj znaÄi veću prozirnost. Enable Snipping Area offset Aktiviraj odmak podruÄja rezanja When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Kad je aktivirano, primijenit će se konfigurirani odmak od položaja podruÄja rezanja koji je potreban kada položaj nije ispravno izraÄunat. Ovo je ponekad potrebno s aktiviranim skaliranjem ekrana. X X Y Y StickerSettings Up Gore Down Dolje Use Default Stickers Koristi standardne naljepnice Sticker Settings Postavke naljepnica Vector Image Files (*.svg) Datoteke vektorskih slika (*.svg) Add Dodaj Remove Ukloni Add Stickers Dodaj naljepnice TrayIcon Show Editor Prikaži ureÄ‘ivaÄ TrayIconSettings Use Tray Icon Koristi ikonu u programskoj traci When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Kad je aktivirano, dodaje ikonu za programsku traku u traku zadataka, ako OS Windows Manager to podržava. Promjena zahtijeva ponovno pokretanje programa. Minimize to Tray Smanji u programsku traku Start Minimized to Tray Pokreni smanjeno u programskoj traci Close to Tray Zatvori u programskoj traci Show Editor Prikaži ureÄ‘ivaÄ Capture Snimi Default Tray Icon action Standardna radnja ikone u programskoj traci Default Action that is triggered by left clicking the tray icon. Standardna radnja koja se izvrÅ¡ava pri pritiskanju ikone u programskoj traci. Tray Icon Settings Postavke ikone u programskoj traci Use platform specific notification service Koristi uslugu obavjeÅ¡tavanja platforme When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Kad je aktivirano, pokuÅ¡at će koristiti uslugu obavjeÅ¡tavanja platforme kad postoji. Zahtijeva ponovno pokretanje kako bi se promjena primijenila. Display Tray Icon notifications Prikaži obavijesti trake ikona UpdateWatermarkOperation Select Image Odaberi sliku Image Files Datoteke slika UploadOperation Upload Script Required Potrebna je skripta za prijenos Please add an upload script via Options > Settings > Upload Script Dodaj skripta za prijenos putem Opcije > Postavke > Skripta za prijenos Capture Upload Prijenos snimke You are about to upload the image to an external destination, do you want to proceed? Prenijet ćeÅ¡ sliku na vanjsko odrediÅ¡te. ŽeliÅ¡ li nastaviti? UploaderSettings Ask for confirmation before uploading Zatraži potvrdu prije prenoÅ¡enja Uploader Type: Vrsta prijenosa: Imgur Imgur Script Skripta Uploader Prijenos FTP FTP VersionTab Version Verzija Build Izgradnja Using: Koristi: WatermarkSettings Watermark Image Slika vodenog žiga Update Aktualiziraj Rotate Watermark Okreni vodeni žig When enabled, Watermark will be added with a rotation of 45° Kad je aktivirano, dodat će se vodeni žig okrenut za 45 stupnjeva Watermark Settings Postavke vodenog žiga ksnip-master/translations/ksnip_hu.ts000066400000000000000000001723171457262621600204320ustar00rootroot00000000000000 AboutDialog About Névjegy About Névjegy Version Verzió Author SzerzÅ‘ Close Bezár Donate Támogatás Contact Kapcsolat AboutTab License: Licenc: Screenshot and Annotation Tool KépernyÅ‘kép és megjegyzéskészítÅ‘ eszköz ActionSettingTab Name Név Shortcut Parancsikon Clear Töröl Take Capture Kép készítése Include Cursor Kurzort is Delay Késleltetés s The small letter s stands for seconds. mp Capture Mode Képkészítési mód Show image in Pin Window Kép mutatása a rögzített ablakban Copy image to Clipboard kép másolása vágólapra Upload image Kép feltöltése Open image parent directory Kép megnyitása szülÅ‘könyvtárban Save image Kép mentése Hide Main Window FÅ‘ablak elrejtése Global Teljes When enabled will make the shortcut available even when ksnip has no focus. Ha engedélyezve van, a parancsikon akkor is elérhetÅ‘vé teszi, ha a ksnip nem fókuszál. ActionsSettings Add Hozzáad Actions Settings Műveletek beállításai Action Művelet AddWatermarkOperation Watermark Image Required Vízjel-kép szükséges Please add a Watermark Image via Options > Settings > Annotator > Update Addj vízjelet-képet az Opciók> Beállítások> Kiemelés> Frissítés menüponttal AnnotationSettings Smooth Painter Paths Sima festÅ‘ útvonal When enabled smooths out pen and marker paths after finished drawing. Ha engedélyezve van, kiüríti a tollat és a jelölÅ‘ útvonalakat a rajz befejezése után. Smooth Factor Simasági faktor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. A simasági tényezÅ‘ növekedésével csökken a toll és a jelölÅ‘ pontossága, de simábbá teszi. Annotator Settings Kiemelés beállításai Remember annotation tool selection and load on startup Emlékezzen a megjegyzéskészítÅ‘ eszköz kiválasztására és betöltése indításkor Switch to Select Tool after drawing Item Váltson a Kiválasztó eszközre az elem rajzolása után Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode KépernyÅ‘ mentése program indításkor az alapértelmezett módon Application Style Alkalmazás stílusa Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Beállítja az alkalmazás stílusát, amely meghatározza a grafikus felhasználói felület megjelenését és hangulatát. A módosításhoz érvényesítéséhez a program újraindítása szükséges. Application Settings Alkalmazás beállítások Automatically copy new captures to clipboard Az új képernyÅ‘mentéseket automatikusan másolja a vágólapra Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Tallózás AuthorTab Contributors: KözreműködÅ‘k: Spanish Translation Spanyol fordítás Dutch Translation Holland fordítás Russian Translation Orosz fordítás Norwegian BokmÃ¥l Translation Norvég fordítás French Translation Francia fordítás Polish Translation Lengyel fordítás Snap & Flatpak Support The Authors: CanDiscardOperation Warning - Figyelem - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Új Draw a rectangular area with your mouse Rajzolj (kijelölÅ‘) területet az egérrel Capture full screen including all monitors A teljes képernyÅ‘ rögzítése, beleértve az összes monitort Capture screen where the mouse is located Aktuális képernyÅ‘ rögzítése, ahol az egér található Capture window that currently has focus Aktív ablak rögzítése, ahol a fókusz van Capture that is currently under the mouse cursor Az egérmutató alatt lévÅ‘ ablak rögzítése Capture a screenshot of the last selected rectangular area KépernyÅ‘kép rögzítése a legutoljára használt kijelölés szerint Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome Az adományokat mindig szívesen fogadjuk Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Terület Last Rectangular Area Legutoljára használt kijelölés Full Screen (All Monitors) Teljes képernyÅ‘ (minden monitor) Current Screen Aktuális képernyÅ‘ Active Window Aktív ablak Window Under Cursor Kurzor alatti ablak Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Felhasználónév Password FTP Uploader HandleUploadResultOperation Upload Successful Sikeres feltöltés Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Globális gyorsbillentyűk bekapcsolása Capture Rect Area Kijelölt terület rögzítése Capture Full Screen Teljes képernyÅ‘ rögzítése Capture current Screen Aktuális képernyÅ‘ rögzítése Capture active Window Aktív ablak rögzítése Capture Window under Cursor Kurzor alatti ablak rögzítése Global HotKeys Globális gyorsbillentyűk Capture Last Rect Area Legutoljára használt kijelölés szerinti rögzítés Clear Töröl Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Egérkurzor rögzítése a képernyÅ‘képen Should mouse cursor be visible on screenshots. Az egérkurzor látszódni fog a képernyÅ‘képen. Image Grabber Képlopás Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Imgur elÅ‘znény Close Bezár Time Stamp IdÅ‘ bélyegzÅ‘ Link Link Delete Link Link törlése ImgurUploader Upload to imgur.com finished! Az imgur.com-ra való feltöltés befejezÅ‘dött! Received new token, trying upload again… Új azonosító, próbáld meg újra feltölteni… Imgur token has expired, requesting new token… Az Imgur azonosító lejárt, igényelj egy újat… ImgurUploaderSettings Force anonymous upload Névtelen feltöltés kényszerítése Always copy Imgur link to clipboard Mindig másolja az Imgur linket a vágólapra Client ID Ügyfél ID Client Secret Ügyfél titkosító PIN PIN Enter imgur Pin which will be exchanged for a token. Ãrd be az imgur Pin kódot, ami egy azonosítóra lesz cserélve. Get PIN PIN beszerzése Get Token Azonosító beszerzése Imgur History Imgur elÅ‘zmény Imgur Uploader Imgur feltöltÅ‘ Username Felhasználónév Waiting for imgur.com… Várakozás az imgur.com-ra… Imgur.com token successfully updated. imgur.com azonosító sikeresen feltöltve. Imgur.com token update error. imgur.com azonosító feltöltésekor hiba. After uploading open Imgur link in default browser imgur link megnyitása a böngészÅ‘ben, feltöltés után Link directly to image Közvetlen link a képhez Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Új Delay in seconds between triggering and capturing screenshot. Késleltés a képernyÅ‘kép rögzítése elÅ‘tt másodpercben megadva. s The small letter s stands for seconds. mp Save Mentés Save Screen Capture to file system KépernyÅ‘kép mentés a rendszerre Copy Másolás Copy Screen Capture to clipboard KépernyÅ‘kép másolása a vágólapra Tools Eszközök Undo Visszavonás Redo Megismételés Crop körbevágás Crop Screen Capture KépernyÅ‘kép körbevágása MainWindow Unsaved Mentetlen Upload Feltöltés Print Nyomtatás Opens printer dialog and provide option to print image Megnyitja a nyomtató párbeszédpanelt, és lehetÅ‘séget biztosít a kép kinyomtatására Print Preview Nyomtatási elÅ‘nézet Opens Print Preview dialog where the image orientation can be changed Megnyitja a Nyomtatási elÅ‘nézet párbeszédpanelt, ahol a kép tájolása megváltoztatható Scale Lépték Quit Kilépés Settings Beállítások &About Névjegy Open Megnyitás &Edit Szerkesztés &Options Opciók &Help Súgó Add Watermark Vízjel hozzáadása Add Watermark to captured image. Multiple watermarks can be added. Vízjel hozzáadása a rögzített képhez. Töbszörös vízjelezés is lehetséges. &File Fájl Unable to show image Nem lehet a képet megjeleníteni Save As... Mentés mint... Paste Beillesztés Paste Embedded Beágyazott beillesztés Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Mentés Save As Mentés másként Open Directory Copy Másolás Copy Path Delete Rename Save All NewCaptureNameProvider Capture Képlopás OcrWindowCreator OCR Window %1 PinWindow Close Bezár Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default The directory where the plugins are located. Browse Tallózás Name Név Version Verzió Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As Mentés másként All Files Minden fájl Image Saved Kép mentve Saving Image Failed Kép mentése nem sikerült Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Az új képernyÅ‘mentéseket automatikusan mentse az alapértelmezett helyre Prompt to save before discarding unsaved changes A mentettlen módosítások elvetése elÅ‘tt kérdezzen rá a mentésre Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Mentés helye és fájlneve Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Tallózás Saver Settings Capture save location Rögzített kép mentésének helye Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Tallózás Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings Beállítások OK OK Cancel Mégse Image Grabber Képfogó Imgur Uploader Imgur feltöltÅ‘ Application Alkalmazás Annotator KiemelÅ‘ HotKeys Gyorsbillentyűk Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping Kép fagyasztása rögzítéskor When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Mutassa a nagyítót rögzítéskor Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Mutasson a nagyítót, ami nagyítja a háttérképet. Ez az opció csak akkor működik, ha a 'Kép fagyasztása rögzítéskor' engedélyezve van. Show Snipping Area rulers Mutassa a vonalzót a rögzítés területén Horizontal and vertical lines going from desktop edges to cursor on snipping area. Vízszintes és függÅ‘leges vonalak az asztal széleitÅ‘l a rögzítési területen lévÅ‘ kurzorig. Show Snipping Area position and size info Mutassa a rögzítési terület helyét és méretét When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Kurzor színe a rögzítés területén Sets the color of the snipping area cursor. Snipping Area cursor thickness Kurzor vastagsága a rögzítési területen Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add Hozzáad Remove Add Stickers TrayIcon Show Editor SzerkesztÅ‘ mutatása TrayIconSettings Use Tray Icon Tálcaikon használata When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Ha engedélyezve van, a tálcaikon rákerül a tálcára, ha az oprenszer ablakkezelÅ‘je támogatja ezt a funkciót. A változtatás érvenyesítéséhez újra kell indítani a programot. Minimize to Tray Kicsinyítés a tálcára Start Minimized to Tray Close to Tray Bezáráskor lehelyezés a tálcára Show Editor SzerkesztÅ‘ mutatása Capture Képlopás Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Kép kiválasztása Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading MegerÅ‘sítés kérése feltöltés elÅ‘tt Uploader Type: Imgur Script Uploader FTP VersionTab Version Verzió Build build Using: Felhasználó: WatermarkSettings Watermark Image Vízjel-kép Update Frissítés Rotate Watermark Vízjel forgatása When enabled, Watermark will be added with a rotation of 45° Ha engedélyezve van, a vízjel 45°-kal elforgatva lesz hozzáadva a képhez Watermark Settings Vízjel beállítások ksnip-master/translations/ksnip_id.ts000066400000000000000000002026761457262621600204140ustar00rootroot00000000000000 AboutDialog About Tentang About Tentang Version Versi Author Penulis Close Tutup Donate Donasi Contact Kontak AboutTab License: Lisensi: Screenshot and Annotation Tool Alat Tangkapan Layar dan Anotasi ActionSettingTab Name Nama Shortcut Pintasan Clear Bersihkan Take Capture Tangkap Include Cursor Sertakan Kursor Delay Jeda s The small letter s stands for seconds. dtk Capture Mode Mode Tangkapan Show image in Pin Window Tampilkan citra di Jendela Sematan Copy image to Clipboard Salin citra ke Papan klip Upload image Unggah citra Open image parent directory Buka direktori induk citra Save image Simpan citra Hide Main Window Sembunyikan Jendela Utama Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Tambah Actions Settings Pengaturan Tindakan Action Tindakan AddWatermarkOperation Watermark Image Required Dibutuhkan Citra Tanda Air Please add a Watermark Image via Options > Settings > Annotator > Update Mohon tambahkan sebuah Citra Tanda Air melalui Pilihan > Pengaturan > Penganotasi > Perbarui AnnotationSettings Smooth Painter Paths Haluskan Path Painter When enabled smooths out pen and marker paths after finished drawing. Saat dinyalakan, perhalus jalur pena dan spidol setelah selesai menggambar. Smooth Factor Faktor Penghalusan Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Menambah faktor penghalusan akan mengurangi akurasi untuk pena dan penanda, tetapi akan membuatnya lebih halus. Annotator Settings Pengaturan Penganotasi Remember annotation tool selection and load on startup Ingat pilihan alat anotasi dan muat pada saat mulai Switch to Select Tool after drawing Item Ganti ke Perkakas Pemilihan setelah selesai menggambar Number Tool Seed change updates all Number Items Bibit Alat Nomor mengubah pembaruan semua Item Nomor Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Mematikan opsi ini akan mengakibatkan perubahan benih alat nomor yang akan berefek hanya item baru tapi bukan item yang telah ada. Mematikan opsi ini memperbolehkan mempunyai nomor ganda. Canvas Color Warna Kanvas Default Canvas background color for annotation area. Changing color affects only new annotation areas. Warna latar belakang kanvas untuk area anotasi. Mengganti warna hanya memengaruhi area anotasi baru. Select Item after drawing Pilih butir setelah selesai menggambar With this option enabled the item gets selected after being created, allowing changing settings. Ketika pilihan ini nyala, butir diseleksi setelah dibuat, mengizinkan adanya perubahan pengaturan. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Tangkap layar pada awal mula dengan moda bawaan Application Style Gaya Aplikasi Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Menyetel gaya aplikasi yang menentukan tampilan GUI-nya. Perubahan ini membutuhkan ksnip mulai ulang agar berefek. Application Settings Pengaturan Aplikasi Automatically copy new captures to clipboard Secara otomatis menyalin tangkapan baru ke papan klip Use Tabs Gunakan Tab Change requires restart. Perubahan membutuhkan pemulaian ulang. Run ksnip as single instance Jalankan ksnip sebagai instansi tunggal Hide Tabbar when only one Tab is used. Sembunyikan Bilah Tab ketika hanya satu tab digunakan. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Mengaktifkan pilihan ini akan memungkinkan hanya satu instansi ksnip yang akan dijalankan, semua instansi lain dimulai setelah yang pertama akan meneruskan argumennya ke yang pertama lalu ditutup. Mengubah pilihan ini membutuhkan pemulaian baru dari semua instansi. Remember Main Window position on move and load on startup Ingat posisi Jendela Utama saat pemindahan dan pemuatan pada awal mula Auto hide Tabs Sembunyikan otomatis tab-tab Auto hide Docks Sembunyikan otomatis Galangan On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Saat memulai, sembunyikan Bilah Alat dan Pengaturan Anotasi. Kenampakan Galangan dapat diaktifkan dengan Tombol Tab. Auto resize to content Ganti ukuran otomatis ke konten Automatically resize Main Window to fit content image. Secara otomatis ganti ukuran Jendela Utama agar sesuai dengan citra konten. Enable Debugging Aktifkan Pengawakutuan Enables debug output written to the console. Change requires ksnip restart to take effect. Mengaktifkan keluaran pengawakutuan ditulis ke konsol. Perubahan memerlukan ksnip untuk mulai ulang agar berefek. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Mengubah ukuran konten adalah penundaan agar Pengelola Jendela menerima konten baru. Jika Jendela Utama tidak diatur dengan benar ke konten baru, meningkatkan penundaan ini dapat meningkatkan perilaku. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Telusuri AuthorTab Contributors: Penyumbang: Spanish Translation Terjemahan Bahasa Spanyol Dutch Translation Terjemahan Bahasa Belanda Russian Translation Terjemahan Bahasa Rusia Norwegian BokmÃ¥l Translation Terjemahan Bahasa BokmÃ¥l Norwegia French Translation Terjemahan Bahasa Perancis Polish Translation Terjemahan Bahasa Polandia Snap & Flatpak Support Dukungan Snap & Flatpak The Authors: Penulis: CanDiscardOperation Warning - Peringatan - The capture %1%2%3 has been modified. Do you want to save it? Tangkapan %1%2%3 telah diubah. Apakah Anda ingin menyimpannya? CaptureModePicker New Baru Draw a rectangular area with your mouse Buat area persegi dengan tetikus anda Capture full screen including all monitors Tangkap layar penuh dalam semua monitor Capture screen where the mouse is located Tangkap layar dimana mouse sekarang berada Capture window that currently has focus Tangkap jendela yang sekarang sedang fokus Capture that is currently under the mouse cursor Tangkap jendela dimana kursor sedang berada Capture a screenshot of the last selected rectangular area Tangkap tangkapan layar dari area persegi panjang yang terakhir dipilih Uses the screenshot Portal for taking screenshot Menggunakan Portal tangkapan layar untuk mengambil tangkapan layar ContactTab Community Komunitas Bug Reports Laporan Awakutu If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Jika Anda memiliki pertanyaan umum, gagasan atau hanya ingin berbicara tentang ksnip,<br/>silakan bergabung dengan %1 atau server %2 kami. Please use %1 to report bugs. Harap gunakan %1 untuk melaporkan awakutu. CopyAsDataUriOperation Failed to copy to clipboard Gagal menyalin ke papan klip Failed to copy to clipboard as base64 encoded image. Gagal menyalin ke papan klip sebagai citra yang disandikan base64. Copied to clipboard Tersalin ke papan klip Copied to clipboard as base64 encoded image. Tersalin ke papan klip sebagai citra yang disandikan base64. DeleteImageOperation Delete Image Hapus Citra The item '%1' will be deleted. Do you want to continue? Butir '%1' akan dihapus. Apakah Anda ingin melanjutkan? DonateTab Donations are always welcome Donasi selalu diterima Donation Donasi ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip adalah proyek perangkat lunak bebas copyleft yang tidak komersial, dan<br/>masih memiliki beberapa biaya yang harus ditanggung,<br/>seperti biaya domain atau biaya perangkat keras untuk dukungan lintas platform. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Jika Anda ingin membantu atau hanya ingin menghargai pekerjaan yang dilakukan<br/>dengan mentraktir pengembang bandrek atau kopi, Anda dapat melakukannya %1di sini%2. Become a GitHub Sponsor? Menjadi Sponsor GitHub? Also possible, %1here%2. Mungkin juga, %1di sini%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Tambahkan tindakan baru dengan menekan tombol tab 'Tambah'. EnumTranslator Rectangular Area Area Persegi Last Rectangular Area Area Persegi Terakhir Full Screen (All Monitors) Layar Penuh (Seluruh Monitor) Current Screen Layar Saat Ini Active Window Jendela Aktif Window Under Cursor Jendela Di Bawah Kursor Screenshot Portal Portal Tangkapan Layar FtpUploaderSettings Force anonymous upload. Paksa unggahan anonim. Url Url Username Nama pengguna Password Sandi FTP Uploader Pengunggah FTP HandleUploadResultOperation Upload Successful Unggahan Berhasil Unable to save temporary image for upload. Tidak dapat menyimpan citra sementara untuk pengunggahan. Unable to start process, check path and permissions. Tidak dapat memulai proses, periksa jalur dan izin. Process crashed Proses macet Process timed out. Waktu proses habis. Process read error. Galat membaca proses. Process write error. Galat menulis proses. Web error, check console output. Kesalahan web, periksa keluaran konsol. Upload Failed Unggahan Gagal Script wrote to StdErr. Skrip menulis ke StdErr. FTP Upload finished successfully. Unggahan FTP berhasil diselesaikan. Unknown error. Galat tak diketahui. Connection Error. Galat Sambungan. Permission Error. Galat Izin. Upload script %1 finished successfully. Unggahan skrip %1 berhasil diselesaikan. Uploaded to %1 Terunggah ke %1 HotKeySettings Enable Global HotKeys Aktifkan Tombol Pintas Umum Capture Rect Area Tangkap Area Persegi Capture Full Screen Tangkap Layar Penuh Capture current Screen Tangkap Layar saat ini Capture active Window Tangkap Jendela aktif Capture Window under Cursor Tangkap Jendela di bawah Kursor Global HotKeys Tombol Pintasan Umum Capture Last Rect Area Tangkap Area Persegi Terakhir Clear Bersihkan Capture using Portal Tangkap menggunakan Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Tombol Pintasan saat ini hanya didukung untuk Windows dan X11. Menonaktifkan pilihan ini juga membuat pintasan tindakan hanya ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Tangkap juga kursor tetikus pada hasil tangkapan Should mouse cursor be visible on screenshots. Apakah kursor tetikus perlu ditampilkan pada hasil tangkapan. Image Grabber Penangkap Citra Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Implementasi Wayland Generik yang menggunakan XDG-DESKTOP-PORTAL menangani penskalaan layar secara berbeda. Mengaktifkan pilihan ini akan menentukan penskalaan layar saat ini dan menerapkannya ke tangkapan layar di ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME dan KDE Plasma mendukung tangkapan layar Waylan dan XDG-DESKTOP-PORTAL Generik mereka sendiri. Mengaktifkan pilihan ini akan memaksa KDE Plasma dan GNOME untuk menggunakan tangkapan layar XDG-DESKTOP-PORTAL. Perubahan pada pilihan ini mengharuskan ksnip dimulai ulang. Show Main Window after capturing screenshot Tampilkan Jendela Utama setelah mengambil tangkapan layar Hide Main Window during screenshot Sembunyikan Jendela Utama selama penangkapan layar Hide Main Window when capturing a new screenshot. Sembunyikan Jendela Utama saat mengambil tangkapan layar baru. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Tampilkan Jendela Utama setelah mengambil tangkapan layar baru ketika Jendela Utama disembunyikan atau diminimalkan. Force Generic Wayland (xdg-desktop-portal) Screenshot Paksa Tangkapan Layar Wayland Generik (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots Skalakan Tangkapan Layar Wayland Generik (xdg-desktop-portal) Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Riwayat Imgur Close Tutup Time Stamp Cap Waktu Link Tautan Delete Link Hapus Tautan ImgurUploader Upload to imgur.com finished! Pengunggahan ke imgur,com sudah selesai! Received new token, trying upload again… Menerima token baru, mencoba mengunggah kembali… Imgur token has expired, requesting new token… Token Imgur telah kedaluwarsa, meminta token baru… ImgurUploaderSettings Force anonymous upload Paksa unggahan anonim Always copy Imgur link to clipboard Selalu salin alamat imgur ke papan klip Client ID ID Klien Client Secret Rahasia Klien PIN PIN Enter imgur Pin which will be exchanged for a token. Masukkan Pin imgur yang akan diubah menjadi token. Get PIN Dapatkan PIN Get Token Dapatkan Token Imgur History Riwayat imgur Imgur Uploader Pengunggah Imgur Username Nama pengguna Waiting for imgur.com… Menunggu imgur.com… Imgur.com token successfully updated. Token Imgur.com berhasil diperbarui. Imgur.com token update error. Ada kesalahan dalam pemutakhiran token imgur.com. After uploading open Imgur link in default browser Setelah mengunggah tautan Imgur terbuka di peramban baku Link directly to image Tautan langsung ke citra Base Url: Url Dasar: Base url that will be used for communication with Imgur. Changing requires restart. Url dasar yang akan digunakan untuk komunikasi dengan Imgur. Perubahan membutuhkan mulai ulang. Clear Token Bersihkan Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Tidak dapat membuka citra Unable to open image from path %1 Tidak dapat membuka citra dari %1 MainToolBar New Baru Delay in seconds between triggering and capturing screenshot. Jeda antara pemicu dan penangkapan citra dalam detik. s The small letter s stands for seconds. dtk Save Simpan Save Screen Capture to file system Simpan Hasil Tangkapan ke sistem file Copy Salin Copy Screen Capture to clipboard Salin Hasil Tangkapan ke clipboard Tools Alat-alat Undo Tak Jadi Redo Jadi Lagi Crop Pangkas Crop Screen Capture Pangkas Tangkapan Layar MainWindow Unsaved Belum Disimpan Upload Unggah Print Cetak Opens printer dialog and provide option to print image Buat dialog pencetakan dan pilihan untuk mencetak citra Print Preview Pratinjau Cetak Opens Print Preview dialog where the image orientation can be changed Buka dialog Pratinjau Cetak dimana orientasi citra bisa diubah Scale Skala Quit Keluar Settings Setelan &About Tent&ang Open Buka &Edit &Sunting &Options &Pilihan &Help &Bantuan Add Watermark Tambahkan Tanda Air Add Watermark to captured image. Multiple watermarks can be added. Tambahkan Tanda Air ke citra yang diambil. Tanda air yang banyak dapat ditambahkan. &File &Berkas Unable to show image Tidak dapat menampilkan citra Save As... Simpan Sebagai... Paste Tempel Paste Embedded Tempel Tertanam Pin Sematkan Pin screenshot to foreground in frameless window Sematkan tangkapan layar ke latar depan di jendela tanpa bingkai No image provided but one was expected. Tidak ada citra yang disediakan tetapi setidaknya ada satu. Copy Path Salin Jalur Open Directory Buka Direktori &View &Tampilan Delete Hapus Rename Ganti nama Open Images Buka Citra Show Docks Tampilkan Dermaga Hide Docks Sembunyikan Dermaga Copy as data URI Salin sebagai data URI Open &Recent Buka Te&rkini Modify Canvas Ubah Kanvas Upload triggerCapture to external source Unggah triggerCapture ke sumber eksternal Copy triggerCapture to system clipboard Salin triggerCapture ke papan klip sistem Scale Image Skalakan Citra Rotate Putar Rotate Image Putar Citra Actions Aksi Image Files Berkas-berkas Citra Save All Close Window Cut OCR MultiCaptureHandler Save Simpan Save As Simpan Sebagai Open Directory Buka Direktori Copy Salin Copy Path Salin Jalur Delete Hapus Rename Ubah nama Save All NewCaptureNameProvider Capture Tangkap OcrWindowCreator OCR Window %1 PinWindow Close Tutup Close Other Tutup Lainnya Close All Tutup Semua PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Baku The directory where the plugins are located. Browse Telusuri Name Nama Version Versi Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Citra Diganti Nama Image Rename Failed Penggantian Nama Citra Gagal Rename image Ganti nama citra New filename: Nama file baru: Successfully renamed image to %1 Berhasil mengganti nama citra menjadi %1 Failed to rename image to %1 Gagal mengganti nama citra ke %1 SaveOperation Save As Simpan Sebagai All Files Semua file Image Saved Citra Disimpan Saving Image Failed Gagal Menyimpan Citra Image Files Berkas-berkas Citra Saved to %1 Tersimpan ke %1 Failed to save image to %1 Gagal menyimpan citra ke %1 SaverSettings Automatically save new captures to default location Secara otomatis menyimpan tangkapan baru ke lokasi baku Prompt to save before discarding unsaved changes Konfirmasi dulu sebelum mengabaikan perubahan yang belum disimpan Remember last Save Directory Ingat Direktori Penyimpanan terakhir When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Saat dinyalakan akan menimpa direktori penyimpanan yang disimpan dalam pengaturan dengan direktori penyimpanan terbaru untuk setiap penyimpanan. Capture save location and filename Lokasi penyimpanan dan nama file hasil tangkapan Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Format yang didukung adalah JPG, PNG dan BMP. Jika tidak ada format yang disediakan, PNG akan digunakan sebagai format baku. Nama berkas dapat berisi wildcard berikut: - $Y, $M, $D untuk tanggal, $h, $m, $s untuk waktu, atau $T untuk waktu dalam format hhmmss. - Beberapa # berturut-turut sebagai penghitung. #### akan menghasilkan 0001, tangkapan berikutnya adalah 0002. Browse Telusuri Saver Settings Pengaturan Penyimpan Capture save location Lokasi penyimpanan tangkapan Default Baku Factor Faktor Save Quality Simpan Kualitas Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Tata nilai ke 0 untuk mendapatkan berkas terkompresi kecil, nilai 100 untuk berkas besar yang tidak terkompresi. Tidak semua format citra mendukung rentang penuh, sedangkan JPEG mendukungnya. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Salin keluaran skrip ke papan klip Script: Skrip: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Jalur ke skrip yang akan dipanggil untuk diunggah. Saat mengunggah skrip akan dipanggil dengan jalur ke berkas png sementara sebagai argumen tunggal. Browse Telusuri Script Uploader Pengunggah Skrip Select Upload Script Pilih Unggahan Skrip Stop when upload script writes to StdErr Berhenti ketika skrip unggah menulis ke StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Menandai unggahan sebagai gagal saat skrip menulis ke StdErr. Tanpa pengaturan ini, kesalahan dalam skrip tidak akan diketahui. Filter: Penyaring: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Ekspresi RegEx. Hanya salin ke papan klip yang cocok dengan Ekspresi RegEx. Ketika dihilangkan, semuanya akan disalin. SettingsDialog Settings Setelan OK OK Cancel Batalkan Image Grabber Penangkap Citra Imgur Uploader Pengunggah Imgur Application Aplikasi Annotator Penganotasi HotKeys Tombol Pintas Uploader Pengunggah Script Uploader Pengunggah Skrip Saver Penyimpan Stickers Stiker Snipping Area Area Pemotong Tray Icon Ikon Baki Watermark Tanda Air Actions Tindakan FTP Uploader Pengunggah FTP Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ubah ukuran persegi yang dipilih menggunakan pegangan atau pindahkan dengan menyeret pilihan. Use arrow keys to move the selection. Gunakan tombol panah untuk memindahkan pilihan. Use arrow keys while pressing CTRL to move top left handle. Gunakan tombol panah sambil menekan CTRL untuk memindahkan pegangan kiri atas. Use arrow keys while pressing ALT to move bottom right handle. Gunakan tombol panah sambil menekan ALT untuk memindahkan pegangan kanan bawah. This message can be disabled via settings. Pesan ini dapat dimatikan melalui pengaturan. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Klik dan Seret untuk memilih area persegi panjang atau tekan ESC untuk keluar. Hold CTRL pressed to resize selection after selecting. Tahan tekan CTRL untuk mengubah ukuran pilihan setelah memilih. Hold CTRL pressed to prevent resizing after selecting. Tahan tekan CTRL untuk mencegah pengubahan ukuran setelah memilih. Operation will be canceled after 60 sec when no selection made. Operasi akan dibatalkan setelah 60 detik jika tidak ada pilihan yang dibuat. This message can be disabled via settings. Pesan ini dapat dimatikan melalui pengaturan. SnippingAreaSettings Freeze Image while snipping Bekukan gambar saat memotong When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Saat dinyalakan akan membekukan latar belakang saat memilih wilayah persegi panjang. Hal ini juga mengubah perilaku tangkapan layar yang tertunda, dengan pilihan ini memungkinkan penundaan terjadi sebelum area pemotongan ditampilkan dan dengan pilihan dimatikan, penundaan terjadi setelah area pemotongan ditampilkan. Fitur ini selalu dimatikan untuk Wayland dan selalu diaktifkan untuk macOS. Show magnifying glass on snipping area Tampilkan kaca pembesar pada area snipping Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Menampilkan kaca pembesar yang akan membesarkan gambar latar belakang. Opsi ini hanya berlaku jika Bekukan Gambar saat snipping diaktifkan. Show Snipping Area rulers Tampilkan penggaris Area Snipping Horizontal and vertical lines going from desktop edges to cursor on snipping area. Garis vertikal dan horizontal dari pinggir desktop ke kursor pada area snipping. Show Snipping Area position and size info Tampilkan info posisi dan ukuran Area Snipping When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Ketika tombol kiri tetikus tidak ditekan, posisi ditampilkan, ketika tombol tetikus ditekan, ukuran area pilih ditampilkan di kiri dan di atas dari daerah yang ditangkap. Allow resizing rect area selection by default Izinkan pengubahan ukuran pemilihan area persegi secara baku When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Saat dinyalakan akan membuat setelah memilih area persegi, bisa melakukan pengubahan ukuran pemilihan. Setelah selesai mengubah ukuran pemilihan dapat dikonfirmasi dengan menekan ENTER/RETURN. Show Snipping Area info text Tampilkan teks informasi Area Pemotongan Snipping Area cursor color Warna kursor Area Snipping Sets the color of the snipping area cursor. Mengatur warna kursor area pemotongan. Snipping Area cursor thickness Tebal kursor Area Snipping Sets the thickness of the snipping area cursor. Mengatur ketebalan kursor area pemotongan. Snipping Area Area Pemotong Snipping Area adorner color Warna penghias Area Pemotongan Sets the color of all adorner elements on the snipping area. Mengatur warna semua elemen penghias pada area pemotongan. Snipping Area Transparency Transparansi Area Pemotongan Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa untuk wilayah yang tidak dipilih pada area pemotongan. Nilai yang lebih kecil berarti lebih transparan. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Atas Down Bawah Use Default Stickers Gunakan Stiker Default Sticker Settings Pengaturan Stiker Vector Image Files (*.svg) Berkas Citra Vektor (*.svg) Add Tambah Remove Hapus Add Stickers Tambah Stiker TrayIcon Show Editor Tampilkan Editor TrayIconSettings Use Tray Icon Gunakan Ikon Baki When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Saat dinyalakan akan menambahkan Ikon Baki ke Bilah Tugas jika Manajer Jendela OS mendukungnya. Perubahan membutuhkan mulai ulang. Minimize to Tray Kecilkan ke Baki Start Minimized to Tray Mulai Dikecilkan ke Baki Close to Tray Tutup ke Baki Show Editor Tampilkan Editor Capture Tangkap Default Tray Icon action Tindakan Ikon Baki baku Default Action that is triggered by left clicking the tray icon. Tindakan baku yang dipicu dengan mengklik kiri ikon baki. Tray Icon Settings Pengaturan Ikon Baki Use platform specific notification service Gunakan layanan pemberitahuan khusus platform When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Saat dinyalakan akan mencoba menggunakan layanan pemberitahuan khusus platform saat tersedia. Perubahan memerlukan mulai ulang untuk diterapkan. Display Tray Icon notifications Tampilkan pemberitahuan Ikon Baki UpdateWatermarkOperation Select Image Pilih Citra Image Files Berkas-berkas Citra UploadOperation Upload Script Required Dibutuhkan Skrip Unggah Please add an upload script via Options > Settings > Upload Script Silakan tambahkan skrip unggahan melalui Pilihan > Pengaturan> Skrip Unggahan Capture Upload Tangkap Unggahan You are about to upload the image to an external destination, do you want to proceed? Anda akan mengunggah gambar ke tujuan eksternal, apakah Anda ingin melanjutkan? UploaderSettings Ask for confirmation before uploading Tanya dulu sebelum mengunggah Uploader Type: Tipe Pengunggah: Imgur Imgur Script Skrip Uploader Pengunggah FTP FTP VersionTab Version Versi Build Build Using: Menggunakan: WatermarkSettings Watermark Image Citra Tanda Air Update Perbarui Rotate Watermark Putar Tanda Air When enabled, Watermark will be added with a rotation of 45° Saat dinyalakan, Tanda Air akan ditambahkan dengan putaran 45° Watermark Settings Pengaturan Tanda Air ksnip-master/translations/ksnip_it.ts000066400000000000000000002102351457262621600204220ustar00rootroot00000000000000 AboutDialog About Informazioni About Informazioni Version Versione Author Autore Close Chiudi Donate Dona Contact Contatto AboutTab License: Licenza: Screenshot and Annotation Tool Screenshot e Strumento di Annotazione ActionSettingTab Name Nome Shortcut Scorciatoia Clear Pulisci Take Capture Cattura Include Cursor Includi cursore Delay Ritardo s The small letter s stands for seconds. s Capture Mode Modalità di cattura Show image in Pin Window Mostra immagine nella finestra bloccata Copy image to Clipboard Copia l'immagine negli appunti Upload image Carica immagine Open image parent directory Apri la directory principale dell'immagine Save image Salva immagine Hide Main Window Nascondi finestra principale Global Globale When enabled will make the shortcut available even when ksnip has no focus. Quando abilitato, creerà il collegamento disponibile anche quando ksnip non ha focus. ActionsSettings Add Aggiungi Actions Settings Impostazioni delle azioni Action Azione AddWatermarkOperation Watermark Image Required Immagine filigrana necessaria Please add a Watermark Image via Options > Settings > Annotator > Update È necessario aggiungere un'immagine Filigrana tramite il menù Opzioni > Impostazioni > Annotatore > Aggiorna AnnotationSettings Smooth Painter Paths Smussa i tratti di pennello When enabled smooths out pen and marker paths after finished drawing. Se abilitato, smussa i tratti di penna e pennarello dopo che sono stati tracciati. Smooth Factor Fattore di smussamento Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Aumentando il fattore di morbidezza diminuirà precisione per penna e pennarello ma li renderà più lisci. Annotator Settings Impostazioni Annotatore Remember annotation tool selection and load on startup Ricorda la selezione dello strumento di annotazione e carica all'avvio Switch to Select Tool after drawing Item Passa allo strumento Seleziona dopo aver disegnato l'oggetto Number Tool Seed change updates all Number Items Una modifica al numero di partenza aggiorna tutti gli elementi numerati Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. La disabilitazione di questa opzione provoca modifiche allo strumento del numero ed influenza solo i nuovi elementi ma non gli elementi esistenti. La disabilitazione di questa opzione consente di avere numeri duplicati. Canvas Color Colore della tela Default Canvas background color for annotation area. Changing color affects only new annotation areas. Colore di sfondo predefinito della tela per l'area di annotazione. La modifica del colore ha effetto solo sulle nuove aree di annotazione. Select Item after drawing Seleziona l'oggetto dopo il disegno With this option enabled the item gets selected after being created, allowing changing settings. Con questa opzione abilitata l'elemento viene selezionato dopo essere stato creato, consentendo la modifica delle impostazioni. Show Controls Widget Mostra controlli Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Il widget dei controlli contiene i pulsanti Annulla/Ripeti, Ritaglia, Ridimensiona, Ruota e Modifica tela. ApplicationSettings Capture screenshot at startup with default mode Salva una schermata all'avvio usando la modalità di default Application Style Stile applicazione Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Imposta lo stile dell'applicazione: ciò definisce l'aspetto estetico dell'interfaccia. Questa impostazione richiede il riavvio. Application Settings Impostazioni Applicazione Automatically copy new captures to clipboard Copia automaticamente le nuove catture negli appunti Use Tabs Usa l'interfaccia con le schede Change requires restart. La modifica richiede il riavvio. Run ksnip as single instance Usa ksnip in una sola finestra Hide Tabbar when only one Tab is used. Nascondi la barra delle schede quando viene utilizzata una sola scheda. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Questa opzione consente solo l'avvio di una singola istanza di ksnip. Se vengono lanciate altre istanze, passeranno il loro argomenti al primo prima di fermarsi. Devi ricominciare tutte le istanze per abilitare o disabilitare questa opzione. Remember Main Window position on move and load on startup Ricorda la posizione della finestra principale durante lo spostamento e il caricamento all'avvio Auto hide Tabs Nascondi automaticamente le schede Auto hide Docks Nascondi automaticamente i dock On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. All'avvio nascondi la barra degli strumenti e le impostazioni delle annotazioni. La visibilità dei dock può essere attivata o disattivata con il tasto Tab. Auto resize to content Ridimensiona automaticamente al contenuto Automatically resize Main Window to fit content image. Ridimensiona automaticamente la finestra principale per adattarla all'immagine del contenuto. Enable Debugging Abilita il debug Enables debug output written to the console. Change requires ksnip restart to take effect. Abilita l'output di debug scritto nella console. La modifica richiede il riavvio di ksnip per avere effetto. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Il ridimensionamento al contenuto è un ritardo per consentire a Window Manager di ricevere il nuovo contenuto. Nel caso in cui la finestra principale non sia regolata correttamente al nuovo contenuto, aumentare questo ritardo potrebbe migliorare il comportamento. Resize delay Ridimensiona ritardo Temp Directory Directory temporanea Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Directory temporanea utilizzata per memorizzare immagini temporanee che verranno eliminato dopo la chiusura di ksnip. Browse Sfoglia AuthorTab Contributors: Collaboratori: Spanish Translation Traduzione in Spagnolo Dutch Translation Traduzione in Olandese Russian Translation Traduzione in Russo Norwegian BokmÃ¥l Translation Traduzione in BokmÃ¥l Norvegese French Translation Traduzione in Francese Polish Translation Traduzione in Polacco Snap & Flatpak Support Versione Snap & Flatpack The Authors: Gli autori: CanDiscardOperation Warning - Attenzione - The capture %1%2%3 has been modified. Do you want to save it? La cattura %1%2%3 è stata modificata Vuoi salvarla? CaptureModePicker New Nuovo Draw a rectangular area with your mouse Traccia un'area rettangolare con il mouse Capture a screenshot of the last selected rectangular area Cattura usando la ultima area rettangolare usata Capture full screen including all monitors Cattura di tutti gli schermi collegati Capture screen where the mouse is located Acquisisci lo schermo nella posizione del mouse Capture window that currently has focus Acquisisci la finestra attualmente in primo piano Capture that is currently under the mouse cursor Cattura ciò che si trova attualmente sotto il cursore del mouse Uses the screenshot Portal for taking screenshot Utilizza il portale screenshot per acquisire screenshot ContactTab Community Comunità Bug Reports Segnalazioni di bug If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Se hai domande generali, idee o semplicemente vuoi parlare di ksnip,<br/>unisciti al nostro server %1 o %2. Please use %1 to report bugs. Si prega di utilizzare %1 per segnalare gli errori. CopyAsDataUriOperation Failed to copy to clipboard Impossibile copiare negli appunti Failed to copy to clipboard as base64 encoded image. Impossibile copiare negli appunti come immagine codificata base64. Copied to clipboard Copiato negli appunti Copied to clipboard as base64 encoded image. Copiato negli appunti come immagine codificata base64. DeleteImageOperation Delete Image Elimina immagine The item '%1' will be deleted. Do you want to continue? L'elemento '%1' verrà eliminato. Vuoi continuare? DonateTab Donations are always welcome Le donazioni sono sempre ben accette Donation Donazione ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip è un progetto non redditizio di software libero con copyleft, e<br/>ha ancora alcuni costi che devono essere coperti,<br/>come i costi del dominio o i costi dell'hardware per il supporto multipiattaforma. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Se vuoi aiutare o semplicemente apprezzare il lavoro che viene fatto<br/> offrendo agli sviluppatori una birra o un caffè, puoi farlo %1here%2. Become a GitHub Sponsor? Diventare uno sponsor di GitHub? Also possible, %1here%2. Anche possibile, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Aggiungi nuove azioni premendo il pulsante della scheda "Aggiungi". EnumTranslator Rectangular Area Area rettangolare Last Rectangular Area Ultima area rettangolare Full Screen (All Monitors) Schermo intero (tutti i monitor) Current Screen Schermo corrente Active Window Finestra attiva Window Under Cursor Finestra sotto il cursore Screenshot Portal Portale schermate FtpUploaderSettings Force anonymous upload. Forza il caricamento anonimo. Url URL Username Nome utente Password Password FTP Uploader Uploader FTP HandleUploadResultOperation Upload Successful Il caricamento è andato a buon fine Unable to save temporary image for upload. Impossibile salvare l'immagine temporanea per il caricamento. Unable to start process, check path and permissions. Impossibile avviare il processo, controllare il percorso e le autorizzazioni. Process crashed Il processo si è interrotto Process timed out. Processo scaduto. Process read error. Errore in lettura del processo. Process write error. Errore in scrittura del processo. Web error, check console output. Errore Web, controlla l'output della console. Upload Failed Caricamento fallito Script wrote to StdErr. Lo script ha scritto su StdErr. FTP Upload finished successfully. Caricamento FTP terminato con successo. Unknown error. Errore sconosciuto. Connection Error. Errore di connessione. Permission Error. Errore di autorizzazione. Upload script %1 finished successfully. Caricamento dello script %1 terminato con successo. Uploaded to %1 Caricato su %1 HotKeySettings Enable Global HotKeys Abilita scorciatoie globali Capture Rect Area Acquisisci area rettangolare Capture Last Rect Area Acquisisci l'ultima area rettangolare Capture Full Screen Acquisisci l'intero schermo Capture current Screen Acquisisci lo Schermo attuale Capture active Window Acquisisci la finestra attiva Capture Window under Cursor Acquisisci la finestra sotto il Cursore Global HotKeys Scorciatoie Globali Clear Pulisci Capture using Portal Cattura usando il portale HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. I tasti di scelta rapida sono attualmente supportati solo per Windows e X11. La disabilitazione di questa opzione rende anche le scorciatoie di azione solo ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Includi il cursore del mouse nell'acquisizione schermo Should mouse cursor be visible on screenshots. Il cursore del mouse dovrebbe essere visibile su screenshot. Image Grabber Acquisizione di immagini Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Implementazioni generiche di Wayland che utilizzano XDG-DESKTOP-PORTAL gestiscono diversamente il ridimensionamento dello schermo. L'attivazione di questa opzione sarà determinare il ridimensionamento dello schermo corrente e applicarlo allo screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME e KDE Plasma supportano il proprio Wayland e gli screenshot generici di XDG-DESKTOP-PORTAL. Abilitare questa opzione forzerà KDE Plasma e GNOME per utilizzare gli screenshot di XDG-DESKTOP-PORTAL. La modifica di questa opzione richiede un riavvio di ksnip. Show Main Window after capturing screenshot Mostra la finestra principale dopo aver catturato lo screenshot Hide Main Window during screenshot Nascondi la finestra principale durante lo screenshot Hide Main Window when capturing a new screenshot. Nascondi la finestra principale durante l'acquisizione di un nuovo screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Mostra la finestra principale dopo aver catturato un nuovo screenshot quando la finestra principale era nascosta o ridotta a icona. Force Generic Wayland (xdg-desktop-portal) Screenshot Schermata di Force Generic Wayland (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots Schermate di Scale Generic Wayland (xdg-desktop-portal) Implicit capture delay Ritardo di cattura implicito This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Questo ritardo viene utilizzato quando non è stato selezionato alcun ritardo nell'UI, questo permette a ksnip di nascondersi prima di prendere uno screenshot. Questo valore non viene applicato quando ksnip era già minimizzato. Ridurre questo valore può avere l'effetto che la finestra principale di ksnip sia visibile sullo screenshot. ImgurHistoryDialog Imgur History Cronologia di Imgur Close Chiudi Time Stamp Data e ora Link Link Delete Link Cancella Link ImgurUploader Upload to imgur.com finished! Il caricamento su imgur.com è stato completato! Received new token, trying upload again… Ricevuto nuovo token,nuova prova di upload in corso… Imgur token has expired, requesting new token… Il token Imgur è scaduto, richiesta nuovo token in corso… ImgurUploaderSettings Force anonymous upload Forza caricamento anonimo After uploading open Imgur link in default browser Dopo aver caricato, apri il link Imgur nel browser predefinito Always copy Imgur link to clipboard Copia sempre il link Imgur negli Appunti Client ID ID Client Client Secret Client Secreto PIN PIN Enter imgur Pin which will be exchanged for a token. Inserisci il Pin imgur che verrà scambiato con un token. Get PIN Ottieni PIN Get Token Ottieni Token Imgur History Cronologia Imgur Imgur Uploader Carica Imgur Username Nome Utente Waiting for imgur.com… In attesa di imgur.com… Imgur.com token successfully updated. Token Imgur.com aggiornato correttamente. Imgur.com token update error. Errore di aggiornamento del token imgur.com. Link directly to image Link direttamente all'immagine Base Url: URL di base: Base url that will be used for communication with Imgur. Changing requires restart. URL di base che verrà utilizzato per la comunicazione con Imgur. La modifica richiede il riavvio. Clear Token Cancella token Upload title: Carica titolo: Upload description: Carica descrizione: LoadImageFromFileOperation Unable to open image Impossibile aprire l'immagine Unable to open image from path %1 Impossibile aprire l'immagine dal percorso %1 MainToolBar New Nuovo Delay in seconds between triggering and capturing screenshot. Ritardo in secondi tra l'attivazione e cattura screenshot. s The small letter s stands for seconds. s Save Salva Save Screen Capture to file system Salva Cattura Schermo nel file system Copy Copia Copy Screen Capture to clipboard Copia Cattura Schermo negli Appunti Undo Annulla Redo Rifai Crop Ritaglia Crop Screen Capture Ritaglia Cattura Schermo Tools Strumenti MainWindow Unable to show image Impossibile mostrare l'immagine Unsaved Non Salvato Upload Carica Print Stampa Opens printer dialog and provide option to print image Apre la finestra di dialogo della stampante e fornisci l'opzione per stampare l'immagine Print Preview Anteprima di Stampa Opens Print Preview dialog where the image orientation can be changed Apre la finestra di dialogo Anteprima di stampa in cui è possibile modificare l'orientamento dell'immagine Scale Scala Add Watermark Aggiungi Filigrana Add Watermark to captured image. Multiple watermarks can be added. Aggiungi filigrana all'immagine acquisita. È possibile aggiungere più filigrane. Quit Esci Settings Impostazioni &About Informazioni Open Apri &File FIle &Edit Modifica &Options Opzioni &Help Aiuto Save As... Salva Come... Paste Incolla Paste Embedded Incollaggio Incorporato Pin Blocca Pin screenshot to foreground in frameless window Blocca lo screenshot in primo piano nella finestra senza cornice No image provided but one was expected. Nessuna immagine fornita ma ne era prevista una. Copy Path Copia percorso Open Directory Apri directory &View &Vista Delete Cancella Rename Rinomina Open Images Apri immagini Show Docks Mostra Dock Hide Docks Nascondi Dock Copy as data URI Copia come dati URI Open &Recent Apri &Recenti Modify Canvas Modifica tela Upload triggerCapture to external source Carica l'acquisizione del trigger su una fonte esterna Copy triggerCapture to system clipboard Copia la cattura del trigger negli appunti di sistema Scale Image Scala immagine Rotate Ruota Rotate Image Ruota immagine Actions Azioni Image Files File immagine Save All Salva tutto Close Window Chiudi finestra Cut Taglia OCR OCR MultiCaptureHandler Save Salva Save As Salva Come Open Directory Apri directory Copy Copia Copy Path Copia percorso Delete Cancella Rename Rinomina Save All Salva tutto NewCaptureNameProvider Capture Cattura OcrWindowCreator OCR Window %1 Finestra OCR %1 PinWindow Close Chiudi Close Other Chiudi Altro Close All Chiudi Tutto PinWindowCreator OCR Window %1 Finestra OCR %1 PluginsSettings Search Path Percorso di ricerca Default Predefinito The directory where the plugins are located. La directory in cui si trovano i plugin. Browse Sfoglia Name Nome Version Versione Detect Rileva Plugin Settings Impostazioni dei plugin Plugin location Posizione del plugin ProcessIndicator Processing Elaborazione in corso RenameOperation Image Renamed Immagine rinominata Image Rename Failed Rinomina immagine non riuscita Rename image Rinomina immagine New filename: Nuovo nome file: Successfully renamed image to %1 Immagine rinominata con successo in %1 Failed to rename image to %1 Impossibile rinominare l'immagine in %1 SaveOperation Save As Salva Come All Files Tutti i FIle Image Saved Immagine Salvata Saving Image Failed Salvataggio Immagine Fallito Image Files File immagine Saved to %1 Salvato in %1 Failed to save image to %1 Impossibile salvare l'immagine in %1 SaverSettings Automatically save new captures to default location Salva automaticamente le nuove acquisizioni nella posizione predefinita Prompt to save before discarding unsaved changes Richiedi di salvare prima di eliminare le modifiche non salvate Remember last Save Directory Ricorda l'ultima directory di salvataggio When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Se abilitato, sovrascriverà la directory di salvataggio memorizzata nelle impostazioni con l'ultima directory di salvataggio, per ogni salvataggio. Capture save location and filename Directory di registrazione e nome del file Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. I formati supportati sono JPG, PNG e BMP. Se non viene fornito alcun formato, come impostazione predefinita verrà utilizzato PNG. Il nome del file può contenere i seguenti caratteri jolly: - $Y, $M, $D per la data, $h, $m, $s per l'ora o $T per l'ora in formato hhmmss. - Più # consecutivi per contatore. #### risulterà in 0001, la prossima acquisizione sarà 0002. Browse Sfoglia Saver Settings Impostazioni di risparmio Capture save location Cattura directory di registrazione Default Predefinito Factor Fattore Save Quality Qualità di registrazione Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Specificare 0 per ottenere file compressi di piccole dimensioni, 100 per file non compressi di grandi dimensioni. Non tutti i formati di immagine supportano l'intera gamma, JPEG lo fa. Overwrite file with same name Sovrascrivi il file con lo stesso nome ScriptUploaderSettings Copy script output to clipboard Copia l'output dello script negli appunti Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Percorso per lo script che verrà chiamato per il caricamento. Durante il caricamento verrà chiamato lo script con il percorso di un file png temporaneo come singolo argomento. Browse Sfoglia Script Uploader Caricatore di script Select Upload Script Seleziona carica script Stop when upload script writes to StdErr Interrompi quando lo script di invio scrive su StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Il caricamento verrà annotato come non riuscito se lo script ha scritto su StdErr. Se questa casella non è selezionata, gli errori di script passeranno inosservati. Filter: Filtro: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Espressione regolare (RegEx). Saranno solo le righe corrispondenti alla RegEx copiato negli appunti. Se non è definito alcun filtro, verranno copiate tutte le righe. SettingsDialog Settings Impostazioni OK OK Cancel Cancella Application Applicazione Image Grabber Acquisizione di immagini Imgur Uploader Carica su Imgur Annotator Annotatore HotKeys Tasti di scelta rapida Uploader Caricatore Script Uploader Caricatore di script Saver Registrazione Stickers Adesivi Snipping Area Area di taglio Tray Icon Icona della barra delle applicazioni Watermark Filigrana Actions Azioni FTP Uploader Uploader FTP Plugins Plugin Search Settings... Impostazioni di ricerca... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ridimensiona il rettangolo selezionato utilizzando le maniglie o spostalo trascinando la selezione. Use arrow keys to move the selection. Utilizzare i tasti freccia per spostare la selezione. Use arrow keys while pressing CTRL to move top left handle. Usa i tasti freccia mentre premi CTRL per spostare la maniglia in alto a sinistra. Use arrow keys while pressing ALT to move bottom right handle. Utilizzare i tasti freccia mentre si preme ALT per spostare la maniglia in basso a destra. This message can be disabled via settings. Questo messaggio può essere disabilitato tramite le impostazioni. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Confermare la selezione premendo ENTER/RETURN o facendo doppio clic con il mouse su un punto qualsiasi. Abort by pressing ESC. Interrompere premendo ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Fare clic e trascinare per selezionare un'area rettangolare o premere ESC per uscire. Hold CTRL pressed to resize selection after selecting. Tenere premuto CTRL per ridimensionare dopo la selezione. Hold CTRL pressed to prevent resizing after selecting. Tenere premuto CTRL per impedire il ridimensionamento dopo la selezione. Operation will be canceled after 60 sec when no selection made. L'operazione verrà annullata dopo 60 secondi in assenza di selezione. This message can be disabled via settings. Questo messaggio può essere disabilitato tramite le impostazioni. SnippingAreaSettings Freeze Image while snipping Blocca l'immagine durante l'acquisizione When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Quando abilitato bloccherà lo sfondo mentre si seleziona una regione rettangolare. Cambia anche il comportamento degli screenshot ritardati, con questo opzione abilitata il ritardo si verifica prima che venga mostrata l'area di cattura e con l'opzione disabilitata il ritardo si verifica dopo la visualizzazione dell'area di cattura. Questa funzione è sempre disabilitata per Wayland e sempre abilitata per MacOs. Show magnifying glass on snipping area Mostra la lente d'ingrandimento sull'area di cattura Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Mostra una lente d'ingrandimento che ingrandisce l'immagine di sfondo. Questa opzione funziona solo con 'Blocca immagine durante la cattura' abilitato. Show Snipping Area rulers Mostra righelli su area di cattura Horizontal and vertical lines going from desktop edges to cursor on snipping area. Mostra linee orizzontali e verticali dai bordi dello schermo al puntatore per facilitare l'inquadratura. Show Snipping Area position and size info Mostra le informazioni sulla posizione e sulla dimensione dell'area di cattura When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Quando il tasto sinistro del mouse non viene premuto la posizione viene mostrato, quando si preme il pulsante del mouse, la dimensione dell'area selezionata è mostrata a sinistra e sopra dalla zona catturata. Allow resizing rect area selection by default Consenti il ridimensionamento della selezione dell'area retta per impostazione predefinita When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Quando abilitato, dopo aver selezionato un area retta, consente di ridimensionare la selezione. Quando fatto il ridimensionamento la selezione può essere confermata premendo Invio. Show Snipping Area info text Mostra il testo delle informazioni sull'area di cattura Snipping Area cursor color Colore del cursore dell'area di cattura Sets the color of the snipping area cursor. Imposta il colore del cursore dell'area di cattura. Snipping Area cursor thickness Spessore cursore area di cattura Sets the thickness of the snipping area cursor. Imposta lo spessore del cursore dell'area di cattura. Snipping Area Area di cattura Snipping Area adorner color Colore ornamentale dell'area di cattura Sets the color of all adorner elements on the snipping area. Imposta il colore di tutti gli elementi ornamento sull'area di cattura. Snipping Area Transparency Trasparenza dell'area di cattura Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa per la regione non selezionata nell'area di cattura. Il numero più piccolo è più trasparente. Enable Snipping Area offset Abilita l'offset dell'area di ritaglio When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Se abilitato, applica l'offset configurato alla posizione dell'area di alla posizione dell'area di ritaglio, che è necessario quando la posizione non è calcolata correttamente. Questo è talvolta necessario con il ridimensionamento dello schermo abilitato. X X Y Y StickerSettings Up Su Down Giù Use Default Stickers Usa adesivi predefiniti Sticker Settings Impostazioni adesivo Vector Image Files (*.svg) File di immagini vettoriali (*.svg) Add Aggiungi Remove Rimuovi Add Stickers Aggiungi adesivi TrayIcon Show Editor Mostra editor TrayIconSettings Use Tray Icon Usa l'icona della barra delle applicazioni When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Quando abilitato aggiungerà un'icona della barra delle applicazioni alla barra delle applicazioni se il gestore di finestre del sistema operativo lo supporta. La modifica richiede il riavvio. Minimize to Tray Riduci a icona nella barra delle applicazioni Start Minimized to Tray Inizia in miniatura nella barra delle applicazioni Close to Tray Vicino alla barra delle applicazioni Show Editor Mostra editor Capture Cattura Default Tray Icon action Azione predefinita dell'icona della barra delle applicazioni Default Action that is triggered by left clicking the tray icon. Azione predefinita che viene attivata facendo clic con il tasto sinistro sull'icona della barra delle applicazioni. Tray Icon Settings Impostazioni dell'icona della barra delle applicazioni Use platform specific notification service Utilizza il servizio di notifica specifico della piattaforma When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Quando abilitato, proverà ad utilizzare la notifica specifica del servizio della piattaforma quando questa esiste. La modifica richiede il riavvio per avere effetto. Display Tray Icon notifications Visualizza notifiche dell'icona della barra delle applicazioni UpdateWatermarkOperation Select Image Seleziona immagine Image Files File immagine UploadOperation Upload Script Required È richiesto uno script di invio Please add an upload script via Options > Settings > Upload Script Aggiungi uno script di caricamento tramite Opzioni > Impostazioni > Carica script Capture Upload Cattura caricamento You are about to upload the image to an external destination, do you want to proceed? Stai per caricare l'immagine su una destinazione esterna, vuoi procedere? UploaderSettings Ask for confirmation before uploading Chiedi conferma prima di caricare Uploader Type: Tipo di caricamento: Imgur Imgur Script Script Uploader Caricamento FTP FTP VersionTab Version Versione Build Compilato Using: Utilizzando: WatermarkSettings Watermark Image Filigrana Immagine Update Aggiorna Rotate Watermark Ruota Filigrana When enabled, Watermark will be added with a rotation of 45° Se abilitato, la Filigrana verrà aggiunta con una rotazione di 45° Watermark Settings Impostazioni filigrana ksnip-master/translations/ksnip_ja.ts000066400000000000000000002133051457262621600204010ustar00rootroot00000000000000 AboutDialog About 情報: About 情報 Version ãƒãƒ¼ã‚¸ãƒ§ãƒ³ Author 開発 Close é–‰ã˜ã‚‹ Donate 寄付 Contact ãŠå•ã„åˆã‚ã› AboutTab License: ライセンス: Screenshot and Annotation Tool ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã¨æ³¨é‡ˆç”¨ãƒ„ール ActionSettingTab Name åå‰ Shortcut ショートカット Clear 消去 Take Capture キャプãƒãƒ£ãƒ¼ã‚’撮影 Include Cursor カーソルをå«ã‚ã‚‹ Delay é…å»¶ s The small letter s stands for seconds. ç§’ Capture Mode キャプãƒãƒ£ãƒ¼æ–¹æ³• Show image in Pin Window ピン留ã‚ã—ãŸç”»åƒã‚’表示 Copy image to Clipboard ç”»åƒã‚’クリップボードã«ã‚³ãƒ”ー Upload image ç”»åƒã‚’アップロード Open image parent directory ç”»åƒã®è¦ªãƒ•ォルダを開ã Save image ç”»åƒã‚’ä¿å­˜ Hide Main Window メインウィンドウをéžè¡¨ç¤º Global グローãƒãƒ« When enabled will make the shortcut available even when ksnip has no focus. 有効ã ã¨ã€ksnip ã«ãƒžã‚¦ã‚¹ãŒä¹—ã£ã¦ã„ãªãã¦ã‚‚ ショートカットãŒåˆ©ç”¨ã§ãã¾ã™ã€‚ ActionsSettings Add 追加 Actions Settings アクションã®è¨­å®š Action アクション AddWatermarkOperation Watermark Image Required ウォーターマーク画åƒãŒå¿…è¦ã§ã™ Please add a Watermark Image via Options > Settings > Annotator > Update 「オプション〠> 「設定〠> 「注釈〠> 「更新ã€ã§ã‚¦ã‚©ãƒ¼ã‚¿ãƒ¼ãƒžãƒ¼ã‚¯ç”»åƒã‚’追加ã—ã¦ãã ã•ã„ AnnotationSettings Smooth Painter Paths ãƒ‘ã‚¹ã®æç”»ã‚’æ»‘ã‚‰ã‹ã«ã™ã‚‹ When enabled smooths out pen and marker paths after finished drawing. 有効ã«ã™ã‚‹ã¨ã€ãƒšãƒ³ãƒ„ールやマーカーツール㧠線を引ã終ã‚ã£ãŸæ™‚ã«ã€ç·šã‚’滑らã‹ã«ã—ã¾ã™ã€‚ Smooth Factor 滑らã‹ä¿‚æ•° Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. 滑らã‹ä¿‚数を大ããã™ã‚‹ã¨ãƒšãƒ³ãƒ„ールやマーカー ツールã®ç²¾åº¦ãŒè½ã¡ã€ã‚ˆã‚Šä¸€å±¤æ»‘らã‹ã«ãªã‚Šã¾ã™ã€‚ Annotator Settings 注釈ã®è¨­å®š Remember annotation tool selection and load on startup é¸æŠžã—ãŸæ³¨é‡ˆãƒ„ールを記憶ã—ã¦èµ·å‹•時ã«èª­ã¿è¾¼ã‚€ Switch to Select Tool after drawing Item アイテムをæç”»ã—ãŸã‚‰é¸æŠžãƒ„ールã«åˆ‡ã‚Šæ›¿ãˆã‚‹ Number Tool Seed change updates all Number Items 番å·ãƒ„ールã®ã‚·ãƒ¼ãƒ‰ã®å‰²ã‚Šå½“ã¦ã‚’変更ã™ã‚‹ã¨ã™ã¹ã¦ã®ç•ªå·ã‚’æ›´æ–° Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. 無効ãªã‚‰ã€ç•ªå·ãƒ„ールã®å‰²ã‚Šå½“ã¦æ•°ã®å¤‰æ›´ã¯ã€ æ–°è¦ã®é …ç›®ã«ã ã‘影響ã—ã€æ—¢å­˜ã®é …ç›®ã«ã¯å½±éŸ¿ã—ã¾ã›ã‚“。 無効ãªã‚‰ã€é‡è¤‡ã—ãŸç•ªå·ã®å‰²ã‚Šå½“ã¦ã‚‚å¯èƒ½ã§ã™ã€‚ Canvas Color キャンãƒã‚¹ã®è‰² Default Canvas background color for annotation area. Changing color affects only new annotation areas. æ³¨é‡ˆé ˜åŸŸã®æ¨™æº–ã®ã‚­ãƒ£ãƒ³ãƒã‚¹ã®èƒŒæ™¯è‰²ã€‚ 色ã®å¤‰æ›´ã¯æ–°ã—ã„æ³¨é‡ˆé ˜åŸŸã«ã®ã¿å映ã•れã¾ã™ã€‚ Select Item after drawing æç”»å¾Œã«ã‚¢ã‚¤ãƒ†ãƒ ã‚’é¸æŠž With this option enabled the item gets selected after being created, allowing changing settings. 有効ãªã‚‰ã€ä½œæˆå¾Œã®ã‚¢ã‚¤ãƒ†ãƒ ãŒé¸æŠžã•れ 設定を変更ã§ãã¾ã™ã€‚ Show Controls Widget æ“作ウィジットを表示 The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. æ“作ウィジットã®ãƒœã‚¿ãƒ³ã¯ã€å…ƒã«æˆ»ã™/やり直㗠切り抜ãã€æ‹¡å¤§ç¸®å°ã€ã‚­ãƒ£ãƒ³ãƒã‚¹ä¿®æ­£ã§ã™ã€‚ ApplicationSettings Capture screenshot at startup with default mode èµ·å‹•æ™‚ã«æ—¢å®šã®ãƒ¢ãƒ¼ãƒ‰ã§ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’撮る Application Style アプリã®å¤–観 Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. GUI ã®è¦‹ãŸç›®ã‚’決ã‚るアプリã®ã‚¹ã‚¿ã‚¤ãƒ«ã‚’設定ã—ã¾ã™ã€‚ 変更㯠ksnip ã‚’å†èµ·å‹•ã™ã‚‹ã¨æœ‰åйã«ãªã‚Šã¾ã™ã€‚ Application Settings アプリケーションã®è¨­å®š Automatically copy new captures to clipboard è‡ªå‹•çš„ã«æ–°ã—ã„キャプãƒãƒ£ãƒ¼ã‚’クリップボードã«ã‚³ãƒ”ー Use Tabs タブを使用 Change requires restart. 変更ã«ã¯å†èµ·å‹•ãŒå¿…è¦ã§ã™ã€‚ Run ksnip as single instance ksnip ã‚’å˜ä¸€ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã¨ã—ã¦å®Ÿè¡Œ Hide Tabbar when only one Tab is used. タブãŒä¸€ã¤ã®æ™‚ã¯ã‚¿ãƒ–ãƒãƒ¼ã‚’éš ã—ã¾ã™ã€‚ Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. 有効ãªã‚‰ã€å®Ÿè¡Œã§ãã‚‹ ksnip ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã¯ä¸€ã¤ã ã‘ã«ãªã‚Š ä»–ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’èµ·å‹•ã™ã‚‹ã¨ã€èµ·å‹•済ã¿ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã« 引数を渡ã—ã¦çµ‚了ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ã“ã®ã‚ªãƒ—ション ã®å¤‰æ›´ã«ã¯ã€ã™ã¹ã¦ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã‚’終了ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ Remember Main Window position on move and load on startup メインウィンドウã®ä½ç½®ã‚’記憶ã—ã¦èµ·å‹•時ã«èª­ã¿è¾¼ã‚€ Auto hide Tabs タブを自動ã§éžè¡¨ç¤º Auto hide Docks ドックを自動ã§éžè¡¨ç¤º On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. 起動時ã«ã€ãƒ„ールãƒãƒ¼ã¨æ³¨é‡ˆã®è¨­å®šã‚’éžè¡¨ç¤ºã«ã—ã¾ã™ã€‚ ドックã®è¡¨ç¤ºã‚’ Tab キーã§åˆ‡ã‚Šæ›¿ãˆã§ãã¾ã™ã€‚ Auto resize to content コンテンツを自動ã§ãƒªã‚µã‚¤ã‚º Automatically resize Main Window to fit content image. コンテンツã®ç”»åƒã‚’メインウィンドウã«é©åˆã™ã‚‹ã‚ˆã†ã«è‡ªå‹•ã§ãƒªã‚µã‚¤ã‚ºã€‚ Enable Debugging デãƒãƒƒã‚° Enables debug output written to the console. Change requires ksnip restart to take effect. ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã«æ›¸ãè¾¼ã¾ã‚Œã‚‹ãƒ‡ãƒãƒƒã‚°ã®å‡ºåŠ›ã‚’æœ‰åŠ¹ã«ã—ã¾ã™ã€‚ 変更ã«ã¯ ksnip ã®å†èµ·å‹•ãŒå¿…è¦ã§ã™ã€‚ Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. コンテンツã®ãƒªã‚µã‚¤ã‚ºæ™‚ã«ã€æ–°ã—ã„コンテンツをウィンドウマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŒ å—ã‘å–ã‚‹ãŸã‚ã«é…å»¶ã•ã›ã¾ã™ã€‚メインウィンドウãŒã€æ–°ã—ã„コンテンツã«å¯¾ã—㦠正ã—ã調整ã•れã¦ã„ãªã„ãªã‚‰ã€é…延時間を増やã™ã¨æ”¹å–„ã•れる場åˆãŒã‚りã¾ã™ã€‚ Resize delay リサイズ時ã®é…å»¶ Temp Directory 一時フォルダ Temp directory used for storing temporary images that are going to be deleted after ksnip closes. 一時フォルダã¯ã€ä¸€æ™‚çš„ãªç”»åƒã®ä¿ç®¡ã«ä½¿ã‚れ ã“れ㯠ksnip ã‚’é–‰ã˜ã‚‹ã¨å‰Šé™¤ã•れã¾ã™ã€‚ Browse å‚ç…§ AuthorTab Contributors: 貢献者: Spanish Translation スペイン語訳 Dutch Translation オランダ語訳 Russian Translation ロシア語訳 Norwegian BokmÃ¥l Translation ノルウェー語 (ブークモール) 訳 French Translation フランス語訳 Polish Translation ãƒãƒ¼ãƒ©ãƒ³ãƒ‰èªžè¨³ Snap & Flatpak Support Snap 㨠Flatpak ã®ã‚µãƒãƒ¼ãƒˆ The Authors: 開発者: CanDiscardOperation Warning - 警告 - The capture %1%2%3 has been modified. Do you want to save it? キャプãƒãƒ£ãƒ¼ %1%2%3 ã¯å¤‰æ›´ã•れã¦ã„ã¾ã™ã€‚ ä¿å­˜ã—ã¾ã™ã‹ï¼Ÿ CaptureModePicker New æ–°è¦ Draw a rectangular area with your mouse マウスã§å››è§’ãé¸æŠžã—ã¾ã™ Capture a screenshot of the last selected rectangular area æœ€è¿‘é¸æŠžã—ãŸç¯„囲ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’キャプãƒãƒ£ãƒ¼ã—ã¾ã™ Capture full screen including all monitors ã™ã¹ã¦ã®ãƒ¢ãƒ‹ã‚¿ãƒ¼ã®å…¨ç”»é¢ã‚’キャプãƒãƒ£ãƒ¼ã—ã¾ã™ Capture screen where the mouse is located マウスカーソルãŒã‚ã‚‹ç”»é¢ã‚’キャプãƒãƒ£ãƒ¼ã—ã¾ã™ Capture window that currently has focus ç¾åœ¨ãƒ•ォーカスãŒã‚るウィンドウをキャプãƒãƒ£ãƒ¼ã—ã¾ã™ Capture that is currently under the mouse cursor ç¾åœ¨ãƒžã‚¦ã‚¹ã‚«ãƒ¼ã‚½ãƒ«ãŒã‚るウィンドウをキャプãƒãƒ£ãƒ¼ã—ã¾ã™ Uses the screenshot Portal for taking screenshot スクリーンショットã®å–å¾—ã«ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆç”¨ãƒãƒ¼ã‚¿ãƒ«ã‚’使用ã—ã¾ã™ ContactTab Community コミュニティ Bug Reports ãƒã‚°å ±å‘Š If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. 一般的ãªè³ªå•ã€ã‚¢ã‚¤ãƒ‡ã‚¢ã€å˜ã« ksnip ã«ã¤ã„ã¦è©±ã—ãŸã„ãªã‚‰<br/>%1 ã‚„ %2 サーãƒãƒ¼ã«å‚加ã—ã¦ãã ã•ã„。 Please use %1 to report bugs. ãƒã‚°å ±å‘Šã¯ %1 ã§è¡Œã£ã¦ãã ã•ã„。 CopyAsDataUriOperation Failed to copy to clipboard クリップボードã¸ã®ã‚³ãƒ”ーã«å¤±æ•— Failed to copy to clipboard as base64 encoded image. base64 エンコードã®ç”»åƒã¨ã—ã¦ã‚¯ãƒªãƒƒãƒ—ボードã«ã‚³ãƒ”ーã™ã‚‹ã®ã«å¤±æ•—。 Copied to clipboard クリップボードã«ã‚³ãƒ”ーã—ã¾ã—㟠Copied to clipboard as base64 encoded image. base64 エンコードã®ç”»åƒã¨ã—ã¦ã‚¯ãƒªãƒƒãƒ—ボードã«ã‚³ãƒ”ーã—ã¾ã—ãŸã€‚ DeleteImageOperation Delete Image ç”»åƒã‚’削除 The item '%1' will be deleted. Do you want to continue? '%1' を削除ã—ã¾ã™ã€‚ 続行ã—ã¾ã™ã‹ï¼Ÿ DonateTab Donations are always welcome 寄付ã¯ã„ã¤ã§ã‚‚大歓迎ã§ã™ Donation 寄付 ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip ã¯ã€éžå–¶åˆ©çš„ã§ã‚³ãƒ”ーレフトãªè‡ªç”±ã‚½ãƒ•トウェアã®ãƒ—ロジェクトã§ã€<br/>ドメインやクロスプラットフォーム対応用ã®ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãªã©<br/>å¿…è¦ãªè²»ç”¨ãŒã‚りã¾ã™ã€‚ If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. ã“ã®å–り組ã¿ã‚’手ä¼ã£ãŸã‚Šæ„Ÿè¬ã™ã‚‹ãŸã‚ã«ã€<br/>開発者ã«ãƒ“ールやコーヒーをãŠã”ã‚‹ã“ã¨ãŒã€%1ã“ã“%2ã‹ã‚‰å¯èƒ½ã§ã™ã€‚ Become a GitHub Sponsor? GitHub ã®ã‚¹ãƒãƒ³ã‚µãƒ¼ã«ãªã‚Šã¾ã›ã‚“ã‹ ? Also possible, %1here%2. %1ã“ã¡ã‚‰ã‹ã‚‰%2ã§ãã¾ã™ã€‚ EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. æ–°è¦ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã«ã¯ã€Œè¿½åŠ ã€ãƒœã‚¿ãƒ³ã‚’押ã—ã¾ã™ã€‚ EnumTranslator Rectangular Area é¸æŠžç¯„å›² Last Rectangular Area 最後ã®é¸æŠžç¯„囲 Full Screen (All Monitors) å…¨ç”»é¢ (ã™ã¹ã¦ã®ãƒ¢ãƒ‹ã‚¿ãƒ¼) Current Screen ç¾åœ¨ã®ç”»é¢ Active Window アクティブウィンドウ Window Under Cursor カーソルãŒã‚るウィンドウ Screenshot Portal スクリーンショット用ãƒãƒ¼ã‚¿ãƒ« FtpUploaderSettings Force anonymous upload. 強制的ã«åŒ¿åã§ã‚¢ãƒƒãƒ—ロード. Url URL Username ユーザーå Password パスワード FTP Uploader FTP アップローダー HandleUploadResultOperation Upload Successful ã‚¢ãƒƒãƒ—ãƒ­ãƒ¼ãƒ‰ã«æˆåŠŸ Unable to save temporary image for upload. アップロードã™ã‚‹ãŸã‚ã®ä¸€æ™‚ç”»åƒã‚’ä¿å­˜ã§ãã¾ã›ã‚“。 Unable to start process, check path and permissions. プロセスを起動ã§ãã¾ã›ã‚“ã€‚ãƒ‘ã‚¹ã¨æ¨©é™ã‚’確èªã—ã¦ãã ã•ã„。 Process crashed プロセスãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ã¾ã—㟠Process timed out. プロセスãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸã€‚ Process read error. プロセスã®èª­ã¿å–りエラーã§ã™ã€‚ Process write error. ãƒ—ãƒ­ã‚»ã‚¹ã®æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚ Web error, check console output. ウェブã®ã‚¨ãƒ©ãƒ¼ã§ã™ã€‚コンソールã®å‡ºåŠ›ã‚’ç¢ºèªã—ã¦ãã ã•ã„。 Upload Failed アップロードã«å¤±æ•— Script wrote to StdErr. スクリプト㌠StdErr ã«æ›¸ãè¾¼ã¿ã¾ã—ãŸã€‚ FTP Upload finished successfully. FTPã‚¢ãƒƒãƒ—ãƒ­ãƒ¼ãƒ‰ã¯æ­£å¸¸ã«å®Œäº†ã—ã¾ã—ãŸã€‚ Unknown error. 䏿˜Žã®ã‚¨ãƒ©ãƒ¼ã€‚ Connection Error. 接続エラー。 Permission Error. 権é™ã‚¨ãƒ©ãƒ¼ã€‚ Upload script %1 finished successfully. アップロードスクリプト %1 ã¯æ­£å¸¸ã«å®Œäº†ã—ã¾ã—ãŸã€‚ Uploaded to %1 %1 ã¸ã‚¢ãƒƒãƒ—ロード HotKeySettings Enable Global HotKeys グローãƒãƒ«ãƒ›ãƒƒãƒˆã‚­ãƒ¼ã‚’有効化 Capture Rect Area é¸æŠžç¯„å›²ã‚’ã‚­ãƒ£ãƒ—ãƒãƒ£ãƒ¼ Capture Last Rect Area 最後ã«é¸æŠžã—ãŸç¯„囲をキャプãƒãƒ£ãƒ¼ Capture Full Screen 全画é¢ã‚­ãƒ£ãƒ—ãƒãƒ£ãƒ¼ Capture current Screen ç¾åœ¨ã®ç”»é¢ã‚’キャプãƒãƒ£ãƒ¼ Capture active Window アクティブウィンドウをキャプãƒãƒ£ãƒ¼ Capture Window under Cursor カーソルãŒã‚るウィンドウをキャプãƒãƒ£ãƒ¼ Global HotKeys グローãƒãƒ«ãƒ›ãƒƒãƒˆã‚­ãƒ¼ Clear 消去 Capture using Portal Portal を使用ã—ã¦ã‚­ãƒ£ãƒ—ãƒãƒ£ãƒ¼ HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ç¾åœ¨ã€ãƒ›ãƒƒãƒˆã‚­ãƒ¼ã¯ Windows 㨠X11 ã§ã®ã¿å‹•作ã—ã¾ã™ã€‚ 無効ã«ã™ã‚‹ã¨ã€ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã‚­ãƒ¼ã‚‚ ksnip 用ã«ãªã‚Šã¾ã™ã€‚ ImageGrabberSettings Capture mouse cursor on screenshot マウスカーソルもキャプãƒãƒ£ãƒ¼ Should mouse cursor be visible on screenshots. スクリーンショットã«ãƒžã‚¦ã‚¹ã‚«ãƒ¼ã‚½ãƒ«ã‚’ 表示ã•ã›ãŸã„å ´åˆã¯æœ‰åйã«ã—ã¦ãã ã•ã„。 Image Grabber ç”»åƒå–å¾— Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. XDG-DESKTOP-PORTAL を使ㆠ一般 Wayland ã®å®Ÿè£…ã§ã¯ã€ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã® スケーリングを異ãªã‚‹æ–¹æ³•ã§å‡¦ç†ã—ã¾ã™ã€‚ 有効ã«ã™ã‚‹ã¨ã€ç¾åœ¨ã®ç”»é¢ã®ã‚¹ã‚±ãƒ¼ãƒªãƒ³ã‚°ã‚’決定ã—〠ãれを ksnip ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã«é©ç”¨ã—ã¾ã™ã€‚ GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME 㨠KDE Plasma ã¯ã€ç‹¬è‡ªã® Wayland 㨠一般 XDG-DESKTOP-PORTAL ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã«å¯¾å¿œã—ã¾ã™ã€‚ 有効ã«ã™ã‚‹ã¨ã€KDE Plasma 㨠GNOME ã¯å¼·åˆ¶çš„ã« XDG-DESKTOP-PORTAL ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’使用ã—ã¾ã™ã€‚ 変更ã«ã¯ã€ksnip ã®å†èµ·å‹•ãŒå¿…è¦ã§ã™ã€‚ Show Main Window after capturing screenshot スクリーンショット撮影後ã«ãƒ¡ã‚¤ãƒ³ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示 Hide Main Window during screenshot スクリーンショット撮影中ã¯ãƒ¡ã‚¤ãƒ³ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’éš ã™ Hide Main Window when capturing a new screenshot. æ–°ã—ã„スクリーンショットを撮る時ã«ãƒ¡ã‚¤ãƒ³ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’éžè¡¨ç¤ºã«ã—ã¾ã™ã€‚ Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. æ–°ã—ã„スクリーンショットã®ã‚­ãƒ£ãƒ—ãƒãƒ£å¾Œã€ メインウィンドウãŒéžè¡¨ç¤ºã‚„最å°åŒ–ãªã‚‰ãƒ¡ã‚¤ãƒ³ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‚’表示。 Force Generic Wayland (xdg-desktop-portal) Screenshot 一般 Wayland (xdg-desktop-portal) ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã‚’強制的ã«ä½¿ç”¨ Scale Generic Wayland (xdg-desktop-portal) Screenshots 一般 Wayland (xdg-desktop-portal) ã®ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã§å‡¦ç† Implicit capture delay è£œåŠ©ã®æ’®å½±é…å»¶ This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ã“ã®é…å»¶ã¯ã€UI ã®é…å»¶ãŒé¸æŠžã•れã¦ã„ãªã„ ã¨ãã«ä½¿ç”¨ã•れã¾ã™ã€‚スクリーンショット撮影å‰ã« ksnip ã‚’éžè¡¨ç¤ºã«ã—ã¾ã™ã€‚ksnip ãŒæ—¢ã«æœ€å°åŒ– ã•れã¦ã„れã°ã€ã“ã®å€¤ã¯é©ç”¨ã•れã¾ã›ã‚“。 値を減少ã™ã‚‹ã¨ã€ksnip ã®ãƒ¡ã‚¤ãƒ³ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ãŒ スクリーンショットã«è¡¨ç¤ºã•れã¾ã™ã€‚ ImgurHistoryDialog Imgur History Imgur ã®å±¥æ­´ Close é–‰ã˜ã‚‹ Time Stamp 日付 Link リンク Delete Link 削除用リンク ImgurUploader Upload to imgur.com finished! imgur.com ã¸ã®ã‚¢ãƒƒãƒ—ロードãŒå®Œäº†ï¼ Received new token, trying upload again… æ–°ã—ã„トークンをå—ã‘å–りã€ã‚¢ãƒƒãƒ—ロードå†è©¦è¡Œä¸­â€¦ Imgur token has expired, requesting new token… Imgur ãƒˆãƒ¼ã‚¯ãƒ³ã®æœŸé™åˆ‡ã‚Œã§ã™ã€‚æ–°ã—ã„ãƒˆãƒ¼ã‚¯ãƒ³ã‚’è¦æ±‚… ImgurUploaderSettings Force anonymous upload 強制的ãªåŒ¿åアップロード After uploading open Imgur link in default browser アップロード後 Imgur ã®ãƒªãƒ³ã‚¯ã‚’既定ã®ãƒ–ラウザーã§é–‹ã Always copy Imgur link to clipboard 常㫠Imgur ã®ãƒªãƒ³ã‚¯ã‚’クリップボードã«ã‚³ãƒ”ーã™ã‚‹ Client ID Client ID Client Secret Client Secret PIN PIN Enter imgur Pin which will be exchanged for a token. トークン変æ›ç”¨ã® Imgur PIN を入力ã—ã¦ãã ã•ã„。 Get PIN PIN ã‚’å–å¾— Get Token トークンをå–å¾— Imgur History Imgur ã®å±¥æ­´ Imgur Uploader Imgur アップローダー Username ユーザーå Waiting for imgur.com… imgur.com を待機… Imgur.com token successfully updated. Imgur.com ãƒˆãƒ¼ã‚¯ãƒ³ã®æ›´æ–°ã«æˆåŠŸã€‚ Imgur.com token update error. Imgur.com ãƒˆãƒ¼ã‚¯ãƒ³ã®æ›´æ–°ã‚¨ãƒ©ãƒ¼ã€‚ Link directly to image ç”»åƒã«ç›´æŽ¥ãƒªãƒ³ã‚¯ Base Url: ベース URL: Base url that will be used for communication with Imgur. Changing requires restart. Imgur ã¨ã®é€šä¿¡æ™‚ã«ä½¿ç”¨ã™ã‚‹ãƒ™ãƒ¼ã‚¹ URL ã§ã™ã€‚ 変更ã«ã¯å†èµ·å‹•ãŒå¿…è¦ã§ã™ã€‚ Clear Token トークンを消去 Upload title: アップロード時ã®é¡Œå: Upload description: アップロード時ã®èª¬æ˜Ž: LoadImageFromFileOperation Unable to open image ç”»åƒãŒé–‹ã‘ã¾ã›ã‚“ Unable to open image from path %1 以下ã®ãƒ‘スã®ç”»åƒã‚’é–‹ã‘ã¾ã›ã‚“ %1 MainToolBar New æ–°è¦ Delay in seconds between triggering and capturing screenshot. スクリーンショット撮影ã¾ã§ã® é…å»¶ç§’æ•°ã§ã™ã€‚ s The small letter s stands for seconds. ç§’ Save ä¿å­˜ Save Screen Capture to file system スクリーンキャプãƒãƒ£ãƒ¼ã‚’ファイルシステムã«ä¿å­˜ Copy コピー Copy Screen Capture to clipboard スクリーンキャプãƒãƒ£ãƒ¼ã‚’クリップボードã«ã‚³ãƒ”ー Undo å…ƒã«æˆ»ã™ Redo やり直㗠Crop 切り抜ã Crop Screen Capture スクリーンキャプãƒãƒ£ãƒ¼ã‚’切り抜ãã¾ã™ Tools ツール MainWindow Unable to show image ç”»åƒã‚’表示ã§ãã¾ã›ã‚“ Unsaved 未ä¿å­˜ Upload アップロード Print å°åˆ· Opens printer dialog and provide option to print image å°åˆ·ãƒ€ã‚¤ã‚¢ãƒ­ã‚°ã‚’é–‹ãç”»åƒå°åˆ·ã‚ªãƒ—ションをæä¾›ã—ã¾ã™ Print Preview å°åˆ·ãƒ—レビュー Opens Print Preview dialog where the image orientation can be changed ç”»åƒã®å‘ãを変更ã§ãã‚‹å°åˆ·ãƒ—レビューダイアログを開ãã¾ã™ Scale æ‹¡å¤§ç¸®å° Add Watermark ウォーターマークを追加 Add Watermark to captured image. Multiple watermarks can be added. キャプãƒãƒ£ãƒ¼ã—ãŸç”»åƒã«ã‚¦ã‚©ãƒ¼ã‚¿ãƒ¼ãƒžãƒ¼ã‚¯ã‚’追加ã—ã¾ã™ã€‚ウォーターマークã¯è¤‡æ•°è¿½åŠ ã§ãã¾ã™ã€‚ Quit 終了 Settings 設定 &About 情報(&A) Open é–‹ã &File ファイル(&F) &Edit 編集(&E) &Options オプション(&O) &Help ヘルプ(&H) Save As... åå‰ã‚’付ã‘ã¦ä¿å­˜... Paste 貼り付㑠Paste Embedded 貼り付㑠(埋ã‚è¾¼ã¿) Pin ピン留゠Pin screenshot to foreground in frameless window スクリーンショットを枠ã®ãªã„ウィンドウ内ã«å‰æ™¯ã¨ã—ã¦ãƒ”ン留ã‚ã—ã¾ã™ No image provided but one was expected. 想定ã•れる画åƒã®æä¾›ãŒã‚りã¾ã›ã‚“。 Copy Path パスをコピー Open Directory ディレクトリを開ã &View 表示(&V) Delete 削除 Rename åå‰ã‚’変更 Open Images ç”»åƒã‚’é–‹ã Show Docks ドックを表示 Hide Docks ドックを隠㙠Copy as data URI Data URI ã¨ã—ã¦ã‚³ãƒ”ー Open &Recent 最近使ã£ãŸãƒ•ァイル(&R) Modify Canvas キャンãƒã‚¹ã‚’修正 Upload triggerCapture to external source triggerCapture を外部ã®å‡ºåŠ›å…ˆã¸ã‚¢ãƒƒãƒ—ロード Copy triggerCapture to system clipboard triggerCapture をシステムã®ã‚¯ãƒªãƒƒãƒ—ボードã«ã‚³ãƒ”ー Scale Image ç”»åƒã®æ‹¡å¤§ç¸®å° Rotate 回転 Rotate Image ç”»åƒã‚’回転 Actions アクション Image Files ç”»åƒãƒ•ァイル Save All ã™ã¹ã¦ä¿å­˜ Close Window ウィンドウを閉ã˜ã‚‹ Cut 切り抜ã削除 OCR OCR MultiCaptureHandler Save ä¿å­˜ Save As åå‰ã‚’付ã‘ã¦ä¿å­˜ Open Directory ディレクトリを開ã Copy コピー Copy Path パスをコピー Delete 削除 Rename åå‰ã‚’変更 Save All ã™ã¹ã¦ä¿å­˜ NewCaptureNameProvider Capture キャプãƒãƒ£ãƒ¼ OcrWindowCreator OCR Window %1 OCR ウィンドウ %1 PinWindow Close é–‰ã˜ã‚‹ Close Other ã»ã‹ã‚’é–‰ã˜ã‚‹ Close All ã™ã¹ã¦é–‰ã˜ã‚‹ PinWindowCreator OCR Window %1 OCR ウィンドウ %1 PluginsSettings Search Path 検索ã™ã‚‹ãƒ‘ス Default 既定 The directory where the plugins are located. プラグインã®ã‚るディレクトリ。 Browse å‚ç…§ Name åå‰ Version ãƒãƒ¼ã‚¸ãƒ§ãƒ³ Detect 検出 Plugin Settings プラグインã®è¨­å®š Plugin location プラグインã®å ´æ‰€ ProcessIndicator Processing 処ç†ä¸­ RenameOperation Image Renamed ç”»åƒã®åå‰ã‚’変更ã—ã¾ã—㟠Image Rename Failed ç”»åƒã®åå‰ã‚’変更ã§ãã¾ã›ã‚“ã§ã—㟠Rename image ç”»åƒã®åå‰ã‚’変更 New filename: æ–°ã—ã„ファイルå: Successfully renamed image to %1 以下ã®ç”»åƒã®æ”¹åã«æˆåŠŸ %1 Failed to rename image to %1 以下ã®ç”»åƒã®æ”¹åã«å¤±æ•— %1 SaveOperation Save As åå‰ã‚’付ã‘ã¦ä¿å­˜ All Files ã™ã¹ã¦ã®ãƒ•ァイル Image Saved ç”»åƒã‚’ä¿å­˜ã—ã¾ã—㟠Saving Image Failed ç”»åƒã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—㟠Image Files ç”»åƒãƒ•ァイル Saved to %1 以下ã«ä¿å­˜ %1 Failed to save image to %1 以下ã¸ã®ä¿å­˜ã«å¤±æ•— %1 SaverSettings Automatically save new captures to default location è‡ªå‹•çš„ã«æ–°ã—ã„キャプãƒãƒ£ãƒ¼ã‚’既定ã®å ´æ‰€ã«ä¿å­˜ã™ã‚‹ Prompt to save before discarding unsaved changes 未ä¿å­˜ã®å¤‰æ›´ã‚’破棄ã™ã‚‹å‰ã«ä¿å­˜ã™ã‚‹ã‹ç¢ºèªã™ã‚‹ Remember last Save Directory 最後ã«ä¿å­˜ã—ãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’記憶ã™ã‚‹ When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. 有効ã«ã™ã‚‹ã¨ã€ä¿å­˜ã™ã‚‹ãŸã³ã« ä¿å­˜å…ˆã®è¨­å®šãŒä¸Šæ›¸ãã•れã¾ã™ã€‚ Capture save location and filename キャプãƒãƒ£ãƒ¼ã®ä¿å­˜å ´æ‰€ã¨ãƒ•ァイルå Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. JPGã€PNGã€BMP をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚ファイル形å¼ã‚’指定ã—ãªã„å ´åˆã¯ PNG ã«ãªã‚Šã¾ã™ã€‚ ファイルåã«ã¯æ¬¡ã®ãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰ã‚’å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™: - 日付: $Y, $M, $D, 時刻: $h, $m, $s, hhmmss å½¢å¼ã®æ™‚刻: $T - 番å·ã‚’表ã™é€£ç¶šã—㟠#。#### 㯠0001 ã«ç½®æ›ã•れã€0002 ã®ã‚ˆã†ã«å¢—加ã—ã¾ã™ã€‚ Browse å‚ç…§ Saver Settings ä¿å­˜è¨­å®š Capture save location キャプãƒãƒ£ãƒ¼ã®ä¿å­˜å ´æ‰€ Default 既定 Factor ä¿‚æ•° Save Quality ä¿å­˜å“質 Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. ファイルを圧縮ã—ã¦å°ã•ãã—ãŸã„å ´åˆã¯ 0 ã‚’ã€å¤§ããã¦ã‚‚éžåœ§ç¸®ã«ã—ãŸã„å ´åˆã¯ 100 を指定ã—ã¦ãã ã•ã„。 JPEG 以外ã®ç”»åƒå½¢å¼ã¯ 0 ã‹ã‚‰ 100 ã¾ã§ã®ç¯„囲をサãƒãƒ¼ãƒˆã—ã¦ã„ãªã„å ´åˆãŒã‚りã¾ã™ã€‚ Overwrite file with same name åŒåã®ãƒ•ァイルを上書ã ScriptUploaderSettings Copy script output to clipboard スクリプトã®å‡ºåŠ›ã‚’ã‚¯ãƒªãƒƒãƒ—ãƒœãƒ¼ãƒ‰ã«ã‚³ãƒ”ー Script: スクリプト: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. アップロード用ã®ã‚¹ã‚¯ãƒªãƒ—トã®ãƒ‘ス。スクリプトã¯ã€ã‚¢ãƒƒãƒ—ロード中㫠å˜ä¸€ã®ä¸€æ™‚ファイル (PNG) を引数ã¨ã—ã¦å‘¼ã³å‡ºã•れã¾ã™ã€‚ Browse å‚ç…§ Script Uploader スクリプトアップローダー Select Upload Script ã‚¢ãƒƒãƒ—ãƒ­ãƒ¼ãƒ‰ã‚¹ã‚¯ãƒªãƒ—ãƒˆã‚’é¸æŠž Stop when upload script writes to StdErr アップロードスクリプト㌠StdErr ã«æ›¸ã込んã ã‚‰åœæ­¢ Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. スクリプト㌠StdErr ã«æ›¸ã込む時ã«ã€ã‚¢ãƒƒãƒ—ロードã«å¤±æ•—ã—ãŸã¨ã—ã¦ãƒžãƒ¼ã‚¯ã—ã¾ã™ã€‚ ã“ã®è¨­å®šãŒãªã„ã¨ã‚¹ã‚¯ãƒªãƒ—ト内ã®ã‚¨ãƒ©ãƒ¼ã«æ°—付ã‘ã¾ã›ã‚“。 Filter: 絞り込ã¿: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. æ­£è¦è¡¨ç¾ã®å¼ã§ã™ã€‚ã“ã®æ­£è¦è¡¨ç¾ã«ä¸€è‡´ã™ã‚‹ã‚‚ã®ã®ã¿ã‚¯ãƒªãƒƒãƒ—ボードã«ã‚³ãƒ”ーã—ã¾ã™ã€‚ çœç•¥ã—ãŸå ´åˆã€ã™ã¹ã¦ã‚³ãƒ”ーã—ã¾ã™ã€‚ SettingsDialog Settings 設定 OK OK Cancel キャンセル Application アプリケーション Image Grabber ç”»åƒå–å¾— Imgur Uploader Imgur アップローダー Annotator 注釈 HotKeys ホットキー Uploader アップローダー Script Uploader スクリプトアップローダー Saver ä¿å­˜ Stickers ステッカー Snipping Area ç¯„å›²é¸æŠž Tray Icon トレイ アイコン Watermark ウォーターマーク Actions アクション FTP Uploader FTP アップローダー Plugins プラグイン Search Settings... 設定を検索... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. é¸æŠžç¯„å›²ã‚’ãƒªã‚µã‚¤ã‚ºã—ãŸã‚Šã€ãƒ‰ãƒ©ãƒƒã‚°ã—ã¦ç§»å‹•ã§ãã¾ã™ã€‚ Use arrow keys to move the selection. 矢å°ã‚­ãƒ¼ã§é¸æŠžç¯„囲を移動。 Use arrow keys while pressing CTRL to move top left handle. CTRL キーを押ã—ãªãŒã‚‰çŸ¢å°ã‚­ãƒ¼ã§ã€å·¦ä¸Šã‚’処ç†ã€‚ Use arrow keys while pressing ALT to move bottom right handle. ALT キーを押ã—ãªãŒã‚‰çŸ¢å°ã‚­ãƒ¼ã§ã€å³ä¸‹ã‚’処ç†ã€‚ This message can be disabled via settings. ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯è¨­å®šã‹ã‚‰ç„¡åйã«ã§ãã¾ã™ã€‚ Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. ENTER/RETURN キーã‹ã€ãƒžã‚¦ã‚¹ã‚’ダブルクリックã—ã¦é¸æŠžå†…容を確èªã€‚ Abort by pressing ESC. ESCキーã§ä¸­æ­¢ã€‚ SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. クリックã—ドラッグã§åˆ‡ã‚Šå–ã‚Šç¯„å›²ã‚’é¸æŠžã™ã‚‹ã‹ã€ESC キーã§çµ‚了。 Hold CTRL pressed to resize selection after selecting. CTRL キーを押ã™ã¨é¸æŠžå¾Œã«é¸æŠžç¯„囲を調整ã§ãã¾ã™ã€‚ Hold CTRL pressed to prevent resizing after selecting. CTRL キーを押ã™ã¨é¸æŠžå¾Œã®ãƒªã‚µã‚¤ã‚ºã‚’抑止ã—ã¾ã™ã€‚ Operation will be canceled after 60 sec when no selection made. ä½•ã‚‚é¸æŠžã—ãªã„ãªã‚‰ã€60ç§’å¾Œã«æ“作ã¯ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã™ã€‚ This message can be disabled via settings. ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸è¨­å®šã‹ã‚‰ç„¡åйã«ã§ãã¾ã™ã€‚ SnippingAreaSettings Freeze Image while snipping ç¯„å›²é¸æŠžç”»é¢ã‚’ç”»åƒã¨ã—ã¦ãƒ•リーズ When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. 有効ã«ã™ã‚‹ã¨ã€åˆ‡ã‚Šå–り範囲ã®é¸æŠžä¸­ã« ãã®èƒŒæ™¯ã¯ç”»åƒã¨ã—ã¦ãƒ•リーズã—ã¾ã™ã€‚ ã¾ãŸã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã‚·ãƒ§ãƒƒãƒˆã®é…延動作も 変更ã•れã¾ã™ã€‚ã“ã®ã‚ªãƒ—ã‚·ãƒ§ãƒ³ãŒæœ‰åйãªã‚‰ã€ 切りå–り範囲ãŒè¡¨ç¤ºã•れるå‰ã«é…å»¶ãŒç™ºç”Ÿã€‚ 無効ãªã‚‰ã€åˆ‡ã‚Šå–り範囲ã®è¡¨ç¤ºå¾Œã«é…å»¶ãŒç™ºç”Ÿã€‚ ã“ã®æ©Ÿèƒ½ã¯ Wayland ã§ã¯å¸¸ã«ç„¡åŠ¹åŒ–ã€ MacOSã§ã¯å¸¸ã«æœ‰åŠ¹åŒ–ã•れã¾ã™ã€‚ Show magnifying glass on snipping area ç¯„å›²é¸æŠžç”»é¢ã§æ‹¡å¤§é¡ã‚’表示 Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. 背景画åƒã‚’拡大ã™ã‚‹æ‹¡å¤§é¡ã‚’表示ã—ã¾ã™ã€‚ ã“ã®ã‚ªãƒ—ションã¯ã€Œç¯„å›²é¸æŠžç”»é¢ã§ç”»åƒã‚’ 固定ã€ãŒæœ‰åйãªå ´åˆã®ã¿å‹•作ã—ã¾ã™ã€‚ Show Snipping Area rulers ç¯„å›²é¸æŠžç”»é¢ã§ãƒ«ãƒ¼ãƒ©ãƒ¼ã‚’表示 Horizontal and vertical lines going from desktop edges to cursor on snipping area. マウスカーソルã‹ã‚‰ç”»é¢ç«¯ã¾ã§ 横線ã¨ç¸¦ç·šã‚’表示ã—ã¾ã™ã€‚ Show Snipping Area position and size info ç¯„å›²é¸æŠžç”»é¢ã§ã‚«ãƒ¼ã‚½ãƒ«ä½ç½®æƒ…å ±ã‚„é¸æŠžã‚µã‚¤ã‚ºæƒ…å ±ã‚’è¡¨ç¤º When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. マウスã®å·¦ãƒœã‚¿ãƒ³ã‚’押ã—ã¦ã„ãªã„å ´åˆã¯ カーソルã®ä½ç½®æƒ…å ±ãŒè¡¨ç¤ºã•ã‚Œã€æŠ¼ã—㦠ã„ã‚‹å ´åˆã¯é¸æŠžç¯„囲ã®é•·ã•ãŒè¡¨ç¤ºã•れ㾠ã™ã€‚ Allow resizing rect area selection by default 標準ã§é¸æŠžç¯„囲をリサイズ When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. 有効ãªã‚‰ã€ç¯„å›²é¸æŠžå¾Œã«ãã®ã‚µã‚¤ã‚ºã‚’ 変更ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ サイズ変更後㫠Return キーを 押ã™ã¨ç¢ºå®šã—ã¾ã™ã€‚ Show Snipping Area info text ç¯„å›²é¸æŠžç”¨ã®èª¬æ˜Ž Snipping Area cursor color ç¯„å›²é¸æŠžã‚«ãƒ¼ã‚½ãƒ«ã®è‰² Sets the color of the snipping area cursor. ç¯„å›²é¸æŠžã‚«ãƒ¼ã‚½ãƒ«ã®è‰²ã‚’指定ã—ã¾ã™ã€‚ Snipping Area cursor thickness ç¯„å›²é¸æŠžã‚«ãƒ¼ã‚½ãƒ«ã®å¤ªã• Sets the thickness of the snipping area cursor. ç¯„å›²é¸æŠžã‚«ãƒ¼ã‚½ãƒ«ã®å¤ªã•を指定ã—ã¾ã™ã€‚ Snipping Area ç¯„å›²é¸æŠž Snipping Area adorner color ç¯„å›²é¸æŠžã®è£…飾ã®è‰² Sets the color of all adorner elements on the snipping area. ç¯„å›²é¸æŠžæ™‚ã®è£…飾的ãªè¦ç´ ã® 色を指定ã—ã¾ã™ã€‚ Snipping Area Transparency ç¯„å›²é¸æŠžå¤–ã®é€æ˜Žåº¦ Alpha for not selected region on snipping area. Smaller number is more transparent. é¸æŠžç¯„å›²ä»¥å¤–ã®ã‚¢ãƒ«ãƒ•ァ値。 値ãŒå°ã•ã„ã»ã©é€æ˜Žã§ã™ã€‚ Enable Snipping Area offset é¸æŠžç¯„å›²ã®è£œæ­£ã‚’使用 When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. 有効ãªã‚‰ã€é¸æŠžç¯„囲ã«è¨­å®šã•れãŸè£œæ­£ãŒ é©ç”¨ã•れã¾ã™ã€‚ä½ç½®ãŒæ­£ã—ã計算ã•れãªã„ å ´åˆã«ä½¿ã„ã¾ã™ã€‚ ç”»é¢ã®æ‹¡å¤§ç¸®å°ãŒæœ‰åйãªå ´åˆã« å¿…è¦ã«ãªã‚‹ã“ã¨ãŒã‚りã¾ã™ã€‚ X 横 (X) Y 縦 (Y) StickerSettings Up 上㸠Down 下㸠Use Default Stickers 既定ã®ã‚¹ãƒ†ãƒƒã‚«ãƒ¼ã‚’使用ã™ã‚‹ Sticker Settings ステッカー設定 Vector Image Files (*.svg) ベクター画åƒãƒ•ァイル (*.svg) Add 追加 Remove 削除 Add Stickers ステッカーを追加 TrayIcon Show Editor エディターを表示 TrayIconSettings Use Tray Icon トレイアイコンを使用 When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. 有効ãªã‚‰ã€ã‚¿ã‚¹ã‚¯ãƒãƒ¼ã«ãƒˆãƒ¬ã‚¤ã‚¢ã‚¤ã‚³ãƒ³ã‚’追加ã—ã¾ã™ã€‚OS 㮠ウィンドウマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ãŒå¯¾å¿œã™ã‚‹ãªã‚‰å¯èƒ½ã§ã™ã€‚è¦å†èµ·å‹•。 Minimize to Tray 最å°åŒ–ã—ãŸã‚‰ãƒˆãƒ¬ã‚¤ã«æ ¼ç´ Start Minimized to Tray ãƒˆãƒ¬ã‚¤ã«æœ€å°åŒ–ã—ã¦èµ·å‹• Close to Tray ウィンドウを閉ã˜ãŸã‚‰ãƒˆãƒ¬ã‚¤ã«æ ¼ç´ Show Editor エディターを表示 Capture キャプãƒãƒ£ãƒ¼ Default Tray Icon action 標準ã®ãƒˆãƒ¬ã‚¤ã‚¢ã‚¤ã‚³ãƒ³ã®å‹•作 Default Action that is triggered by left clicking the tray icon. トレイアイコンを左クリックã—ãŸæ™‚ã®æ¨™æº–ã®å‹•作。 Tray Icon Settings トレイアイコンã®è¨­å®š Use platform specific notification service ãã®ãƒ—ラットフォームã®é€šçŸ¥ã‚µãƒ¼ãƒ“スを使用 When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. 有効ãªã‚‰ã€ãã®ãƒ—ラットフォーム固有ã®é€šçŸ¥ã‚µãƒ¼ãƒ“スãŒã‚れ㰠使用を試ã¿ã¾ã™ã€‚変更ã«ã¯å†èµ·å‹•ãŒå¿…è¦ã§ã™ã€‚ Display Tray Icon notifications トレイアイコンã®é€šçŸ¥ã‚’表示 UpdateWatermarkOperation Select Image ç”»åƒã‚’é¸æŠž Image Files ç”»åƒãƒ•ァイル UploadOperation Upload Script Required アップロードスクリプトãŒå¿…è¦ã§ã™ Please add an upload script via Options > Settings > Upload Script 「オプション〠> 「設定〠> 「アップロードスクリプトã€ã§ã‚¢ãƒƒãƒ—ロードスクリプトを追加ã—ã¦ãã ã•ã„ Capture Upload キャプãƒãƒ£ãƒ¼ã‚’アップロード You are about to upload the image to an external destination, do you want to proceed? 外部ã®å ´æ‰€ã«ç”»åƒã‚’アップロードã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚続行ã—ã¾ã™ã‹ï¼Ÿ UploaderSettings Ask for confirmation before uploading アップロードå‰ã«ç¢ºèªã™ã‚‹ Uploader Type: アップローダーã®ç¨®é¡ž: Imgur Imgur Script スクリプト Uploader アップローダー FTP FTP VersionTab Version ãƒãƒ¼ã‚¸ãƒ§ãƒ³ Build ビルド Using: 使用: WatermarkSettings Watermark Image ã‚¦ã‚©ãƒ¼ã‚¿ãƒ¼ãƒžãƒ¼ã‚¯ç”»åƒ Update æ›´æ–° Rotate Watermark ウォーターマークを傾ã‘ã‚‹ When enabled, Watermark will be added with a rotation of 45° 有効ã«ã™ã‚‹ã¨ã‚¦ã‚©ãƒ¼ã‚¿ãƒ¼ãƒžãƒ¼ã‚¯ãŒ45度傾ã„ãŸçŠ¶æ…‹ã«ãªã‚Šã¾ã™ Watermark Settings ウォーターマークã®è¨­å®š ksnip-master/translations/ksnip_ko.ts000066400000000000000000001647631457262621600204350ustar00rootroot00000000000000 AboutDialog About About Version Author ì €ìž Close 닫기 Donate 기부 Contact AboutTab License: ë¼ì´ì„¼ìФ Screenshot and Annotation Tool ActionSettingTab Name ì´ë¦„ Shortcut 단축키 Clear Take Capture 캡처하기 Include Cursor 커서 í¬í•¨ Delay s The small letter s stands for seconds. Capture Mode 캡처 모드 Show image in Pin Window í•€ì— ì´ë¯¸ì§€ 표시 Copy image to Clipboard í´ë¦½ë³´ë“œë¡œ ì´ë¯¸ì§€ 복사 Upload image ì´ë¯¸ì§€ 업로드 Open image parent directory Save image ì´ë¯¸ì§€ 저장 Hide Main Window Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add 추가 Actions Settings Action AddWatermarkOperation Watermark Image Required ì›Œí„°ë§ˆí¬ ì´ë¯¸ì§€ í•„ìš” Please add a Watermark Image via Options > Settings > Annotator > Update 옵션> 설정> 주ì„> ì—…ë°ì´íŠ¸ë¥¼ 통해 워터 ë§ˆí¬ ì´ë¯¸ì§€ë¥¼ 추가하십시오 AnnotationSettings Smooth Painter Paths When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Application Style Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Automatically copy new captures to clipboard Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse AuthorTab Contributors: 기여ìž: Spanish Translation 스페ì¸ì–´ 번역 Dutch Translation 네ëœëž€ë“œì–´ 번역 Russian Translation 러시아어 번역 Norwegian BokmÃ¥l Translation ë…¸ë¥´ì›¨ì´ ë¶€í¬ëª°ì–´ 번역 French Translation 프랑스어 번역 Polish Translation í´ëž€ë“œì–´ 번역 Snap & Flatpak Support Snap & Flatpak ì§€ì› The Authors: CanDiscardOperation Warning - 경고 - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Password FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Close 닫기 Time Stamp Link Delete Link ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Client Secret PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. Save Save Screen Capture to file system Copy Copy Screen Capture to clipboard Tools Undo Redo Crop Crop Screen Capture MainWindow Unsaved Upload Print Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Settings &About Open &Edit &Options &Help Add Watermark Add Watermark to captured image. Multiple watermarks can be added. &File Unable to show image Save As... Paste Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Save As Open Directory Copy Copy Path Delete Rename Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close 닫기 Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default The directory where the plugins are located. Browse Name ì´ë¦„ Version Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved Saving Image Failed Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Saver Settings Capture save location Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings OK Cancel Image Grabber Imgur Uploader Application Annotator HotKeys Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add 추가 Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version Build Using: WatermarkSettings Watermark Image Update Rotate Watermark When enabled, Watermark will be added with a rotation of 45° Watermark Settings ksnip-master/translations/ksnip_nl.ts000066400000000000000000002034661457262621600204270ustar00rootroot00000000000000 AboutDialog About Over About Over Version Versie Author Auteur Close Sluiten Donate Doneren Contact Contact opnemen AboutTab License: Licentie: Screenshot and Annotation Tool Schermfoto- en aantekeningsprogramma ActionSettingTab Name Naam Shortcut Sneltoets Clear Wissen Take Capture Schermfoto maken Include Cursor Cursor tonen op schermfoto Delay Wachttijd s The small letter s stands for seconds. s Capture Mode Modus Show image in Pin Window Schermfoto tonen op overzichtsvenster Copy image to Clipboard Schermfoto kopiëren naar klembord Upload image Schermfoto uploaden Open image parent directory Bijbehorende map openen Save image Schermfoto opslaan Hide Main Window Hoofdvenster verbergen Global Globaal When enabled will make the shortcut available even when ksnip has no focus. Schakel in om de sneltoets ook te gebruiken als ksnip niet actief is. ActionsSettings Add Toevoegen Actions Settings Actie-instellingen Action Actie AddWatermarkOperation Watermark Image Required Watermerkafbeelding vereist Please add a Watermark Image via Options > Settings > Annotator > Update Voeg een watermerkafbeelding toe via Opties --> Instellingen --> Aantekeningen --> Bijwerken AnnotationSettings Smooth Painter Paths Gladvegen When enabled smooths out pen and marker paths after finished drawing. Schakel dit in om pen- en markeerstrepen na afloop glad te vegen. Smooth Factor Gladveegfactor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Het verhogen van de factor vermindert de precisie, maar maakt pen- en markeerstrepen gladder. Annotator Settings Aantekeningsinstellingen Remember annotation tool selection and load on startup Aantekeningsgereedschap onthouden en laden na opstarten Switch to Select Tool after drawing Item Overschakelen naar selectiegereedschap na tekenen Number Tool Seed change updates all Number Items Getalwijziging werkt alle items met getallen bij Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Schakel deze optie uit om alleen nieuwe items en niet ook bestaande items te wijzigen. Hierdoor zijn duplicaten mogelijk. Canvas Color Canvaskleur Default Canvas background color for annotation area. Changing color affects only new annotation areas. De standaard achtergrondkleur van het aantekeningsgebied. Dit is alleen van toepassing op nieuwe aantekeningsgebieden. Select Item after drawing Item selecteren na tekenen With this option enabled the item gets selected after being created, allowing changing settings. Schakel in om een item te selecteren nadat het getekend is, zodat de instellingen ervan kunnen worden aangepast. Show Controls Widget Bedieningspaneel tonen The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Toon een bedieningspaneel met knoppen voor ongedaan maken/herhalen, bijsnijden, draaien, etc. ApplicationSettings Capture screenshot at startup with default mode Schermfoto vastleggen met standaardmodus bij opstarten Application Style Programmastijl Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Hiermee bepaal je het uiterlijk van het programma. Herstart ksnip om de wijzigingen toe te passen. Application Settings Programma-instellingen Automatically copy new captures to clipboard Nieuwe schermfoto's automatisch kopiëren naar klembord Use Tabs Tabbladen gebruiken Change requires restart. Herstart om de wijzigingen toe te passen. Run ksnip as single instance Slechts één ksnip-proces toestaan Hide Tabbar when only one Tab is used. Verberg de tabbladbalk als er één tabblad geopend is. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Schakel deze optie in om slechts één ksnip-proces toe te staan. Alle hierna gestarte processen geven opdrachten door aan het eerste en worden daarna afgesloten. Herstart alle ksnip-processen om deze wijziging toe te passen. Remember Main Window position on move and load on startup Automatisch opstarten met vorige schermpositie van hoofdvenster Auto hide Tabs Tabbladen automatisch verbergen Auto hide Docks Panelen automatisch verbergen On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Verberg bij het opstarten de werkbalk- en aantekeningsinstellingen. Ze kunnen dan worden getoond/verborgen met de Tab-toets. Auto resize to content Automatisch aanpassen aan inhoud Automatically resize Main Window to fit content image. Pas de afmetingen van het hoofdvenster automatisch aan aan de schermfoto. Enable Debugging Foutopsporing inschakelen Enables debug output written to the console. Change requires ksnip restart to take effect. Schrijft foutopsporingsinformatie weg naar een terminalvenster. Herstart ksnip om de wijziging toe te passen. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. De wachttijd omtrent herschalen naar inhoud geldt voor de vensterbeheerder. Als het hoofdvenster niet goed wordt aangepast aan de nieuwe inhoud, dan kan deze wachttijd het gedrag verbeteren. Resize delay Grootte-aanpassingsvertraging Temp Directory Tijdelijke map Temp directory used for storing temporary images that are going to be deleted after ksnip closes. De tijdelijke map waarin schermfoto's worden opgeslagen die verwijderd gaan worden na het afsluiten. Browse Bladeren AuthorTab Contributors: Bijdragers: Spanish Translation Spaanse vertaling Dutch Translation Nederlandse vertaling Russian Translation Russische vertaling Norwegian BokmÃ¥l Translation Noorse (BokmÃ¥l) vertaling French Translation Franse vertaling Polish Translation Poolse vertaling Snap & Flatpak Support Snap- en Flatpak-ondersteuning The Authors: De makers: CanDiscardOperation Warning - Waarschuwing - The capture %1%2%3 has been modified. Do you want to save it? De schermfoto, %1%2%3, is bewerkt. Wil je deze opslaan? CaptureModePicker New Nieuw Draw a rectangular area with your mouse Teken een rechthoekig gebied met je cursor Capture full screen including all monitors Leg het volledige scherm vast op alle beeldschermen Capture screen where the mouse is located Maak een schermfoto van het scherm waarop de cursor is Capture window that currently has focus Maak een schermfoto van het momenteel gefocuste venster Capture that is currently under the mouse cursor Maak een schermfoto van het venster onder de cursor Capture a screenshot of the last selected rectangular area Maak een schermfoto van het laatst geselecteerde rechthoekige gebied Uses the screenshot Portal for taking screenshot Gebruik het schermfotoportaal om een schermfoto te maken ContactTab Community Gemeenschap Bug Reports Bugmeldingen If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Als je vragen hebt, ideeën wilt delen of gewoon even een praatje wilt maken, <br/>neem dan deel aan onze %1- of %2-server. Please use %1 to report bugs. Meld bugs op %1. CopyAsDataUriOperation Failed to copy to clipboard Kopiëren naar klembord mislukt Failed to copy to clipboard as base64 encoded image. Het kopiëren naar het klembord als base64-versleutelde schermfoto is mislukt. Copied to clipboard Gekopieerd naar klembord Copied to clipboard as base64 encoded image. Gekopieerd naar het klembord als base64-versleutelde schermfoto. DeleteImageOperation Delete Image Schermfoto verwijderen The item '%1' will be deleted. Do you want to continue? ‘%1’ wordt verwijderd. Weet je zeker dat je wilt doorgaan? DonateTab Donations are always welcome Donaties zijn altijd welkom Donation Doneren ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip is een vrij softwareproject zonder winstoogmerk. Er zijn echter<br/>kosten die moeten worden gedekt,<br/>zoals domeinnaamkosten en hardware voor platform-onafhankelijke ondersteuning. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Als je wilt helpen of je waardering wilt tonen<br/>door de ontwikkelaars te trakteren op een biertje of kopje koffie, dan kan dat via %1deze pagina%2. Become a GitHub Sponsor? GitHub-sponsor worden? Also possible, %1here%2. Dat kan ook, namelijk via %1deze pagina%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Voeg nieuwe acties toe door de knop ‘Toevoegen’ aan te klikken. EnumTranslator Rectangular Area Rechthoekig gebied Last Rectangular Area Vorig rechthoekig gebied Full Screen (All Monitors) Volledig scherm (alle beeldschermen) Current Screen Huidig scherm Active Window Actief venster Window Under Cursor Venster onder cursor Screenshot Portal Schermfotoportaal FtpUploaderSettings Force anonymous upload. Dwing anoniem uploaden af. Url URL Username Gebruikersnaam Password Wachtwoord FTP Uploader FTP-upload HandleUploadResultOperation Upload Successful Schermfoto geüpload Unable to save temporary image for upload. De tijdelijke schermfoto, nodig voor het uploaden, kan niet worden opgeslagen. Unable to start process, check path and permissions. Het proces kan niet worden gestart. Controleer de locatie en toegangsrechten. Process crashed Het proces is gecrasht Process timed out. Het proces is verlopen. Process read error. Leesfout. Process write error. Schrijffout. Web error, check console output. Netwerkfout. Controleer de opdrachtvensteruitvoer. Upload Failed Uploaden mislukt Script wrote to StdErr. Het script is weggeschreven naar StdErr. FTP Upload finished successfully. De ftp-upload is afgerond. Unknown error. Onbekende fout. Connection Error. Verbindingsfout. Permission Error. Rechtenfout. Upload script %1 finished successfully. ‘%1’ is uitgevoerd. Uploaded to %1 Geüpload naar %1 HotKeySettings Enable Global HotKeys Algemene sneltoetsen inschakelen Capture Rect Area Rechthoekig gebied vastleggen Capture Full Screen Volledig scherm vastleggen Capture current Screen Huidige scherm vastleggen Capture active Window Actief scherm vastleggen Capture Window under Cursor Venster onder cursor vastleggen Global HotKeys Algemene sneltoetsen Capture Last Rect Area Vorig rechthoekig gebied vastleggen Clear Wissen Capture using Portal Vastleggen met portaal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Sneltoetsen worden momenteel alleen ondersteund op Windows en X11. Schakel deze optie uit om de actiesneltoetsen alleen te gebruiken binnen KSnip. ImageGrabberSettings Capture mouse cursor on screenshot Cursor vastleggen bij maken van schermfoto Should mouse cursor be visible on screenshots. Of de cursor zichtbaar moet zijn op schermfoto's. Image Grabber Vastleggen Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Algemene Wayland-implementaties die XDG DESKTOP PORTAL gebruiken, handelen beeldgroottes allemaal anders af. Met deze optie wordt de huidige beeldgrootte bepaald en toegepast op de schermfoto in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME en KDE Plasma ondersteunen zowel hun eigen Wayland-implementatie als die van de algemene XDG-DESKTOP-PORTAL. Schakel deze optie in om KDE Plasma en GNOME XDG-DESKTOP-PORTAL te laten gebruiken voor het maken van schermfoto's. Herstart ksnip om de wijziging toe te passen. Show Main Window after capturing screenshot Hoofdvenster tonen na maken van schermfoto Hide Main Window during screenshot Hoofdvenster verbergen tijdens maken van schermfoto Hide Main Window when capturing a new screenshot. Verberg het hoofdvenster tijdens het maken van een schermfoto. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Toon het hoofdvenster na het maken van een schermfoto als het hoofdvenster verborgen of geminimaliseerd is. Force Generic Wayland (xdg-desktop-portal) Screenshot Algemene Wayland (xdg-desktop-portal)-schermfoto afdwingen Scale Generic Wayland (xdg-desktop-portal) Screenshots Algemene Wayland (xdg-desktop-portal)-schermfoto's schalen Implicit capture delay Wachttijd This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Deze wachttijd wordt gebruikt als er geen andere wachttijd is ingesteld op het hoofdvenster. Hierdoor wordt ksnip verborgen alvorens een schermfoto te maken. Deze waarde wordt genegeerd als ksnip reeds geminimaliseerd is. Let op: door het verlagen van de waarde wordt het hoofdvenster mogelijk op de schermfoto getoond. ImgurHistoryDialog Imgur History Imgur-geschiedenis Close Sluiten Time Stamp Tijdstempel Link Link Delete Link Link verwijderen ImgurUploader Upload to imgur.com finished! De schermfoto is geüpload naar imgur.com! Received new token, trying upload again… Nieuwe toegangssleutel ontvangen; bezig met opnieuw uploaden… Imgur token has expired, requesting new token… Imgur-toegangssleutel verlopen; bezig met aanvragen van nieuwe… ImgurUploaderSettings Force anonymous upload Anoniem uploaden Always copy Imgur link to clipboard Imgur-link altijd kopiëren naar klembord Client ID Client-id Client Secret Client-geheim PIN Pincode Enter imgur Pin which will be exchanged for a token. Voer de imgur-pincode in. Deze wordt omgeruild voor een toegangssleutel. Get PIN Pincode ophalen Get Token Toegangssleutel ophalen Imgur History Imgur-geschiedenis Imgur Uploader Imgur-uploader Username Gebruikersnaam Waiting for imgur.com… Bezig met wachten op imgur.com… Imgur.com token successfully updated. De imgur.com-toegangssleutel is bijgewerkt. Imgur.com token update error. Fout tijdens bijwerken van imgur.com-toegangssleutel. After uploading open Imgur link in default browser Imgur-link na uploaden openen in standaardbrowser Link directly to image Directe link naar foto Base Url: Basis-url: Base url that will be used for communication with Imgur. Changing requires restart. De basis-url voor communicatie met Imgur. Herstart om de wijzigingen toe te passen. Clear Token Toegangssleutel wissen Upload title: Uploadnaam: Upload description: Uploadbeschrijving: LoadImageFromFileOperation Unable to open image Kan schermfoto niet openen Unable to open image from path %1 De schermfoto uit ‘%1’ kan niet worden geopend MainToolBar New Nieuw Delay in seconds between triggering and capturing screenshot. De wachttijd tussen het aanroepen en vastleggen van een schermfoto, in seconden. s The small letter s stands for seconds. s Save Opslaan Save Screen Capture to file system Schermfoto lokaal opslaan Copy Kopiëren Copy Screen Capture to clipboard Schermfoto kopiëren naar klembord Tools Hulpmiddelen Undo Ongedaan maken Redo Opnieuw uitvoeren Crop Bijsnijden Crop Screen Capture Schermfoto bijsnijden MainWindow Unsaved Niet-opgeslagen Upload Uploaden Print Afdrukken Opens printer dialog and provide option to print image Afdrukvenster openen om de schermfoto af te drukken Print Preview Afdrukvoorbeeld Opens Print Preview dialog where the image orientation can be changed Afdrukvoorbeeld openen zodat de oriëntatie kan worden aangepast Scale Grootte aanpassen Quit Afsluiten Settings Instellingen &About &Over Open Openen &Edit B&ewerken &Options &Opties &Help &Hulp Add Watermark Watermerk toevoegen Add Watermark to captured image. Multiple watermarks can be added. Voorzie de schermfoto van een watermerk. Je kunt meerdere watermerken toevoegen. &File &Bestand Unable to show image Kan schermfoto niet tonen Save As... Opslaan als… Paste Plakken Paste Embedded Ingesloten plakken Pin Vastmaken Pin screenshot to foreground in frameless window Schermfoto vastmaken aan voorgrond van naadloos venster No image provided but one was expected. Er werd een foto verwacht, maar niks opgegeven. Copy Path Locatie kopiëren Open Directory Map openen &View &Bekijken Delete Verwijderen Rename Naam wijzigen Open Images Schermfoto's openen Show Docks Panelen tonen Hide Docks Panelen verbergen Copy as data URI Kopiëren als gegevensuri Open &Recent &Recent bestand openen Modify Canvas Canvas aanpassen Upload triggerCapture to external source Schermfoto uploaden naar externe dienst Copy triggerCapture to system clipboard Schermfoto kopiëren naar klembord Scale Image Afmetingen aanpassen Rotate Draaien Rotate Image Foto draaien Actions Acties Image Files Afbeeldingsbestanden Save All Alles opslaan Close Window Venster sluiten Cut Knippen OCR Ocr MultiCaptureHandler Save Opslaan Save As Opslaan als Open Directory Map openen Copy Kopiëren Copy Path Locatie kopiëren Delete Verwijderen Rename Naam wijzigen Save All Alles opslaan NewCaptureNameProvider Capture Vastleggen OcrWindowCreator OCR Window %1 Ocr-venster %1 PinWindow Close Sluiten Close Other Anderen sluiten Close All Alles sluiten PinWindowCreator OCR Window %1 Ocr-venster %1 PluginsSettings Search Path Zoeklocatie Default Standaard The directory where the plugins are located. De map met de plug-ins. Browse Bladeren Name Naam Version Versie Detect Automatisch vaststellen Plugin Settings Plug-in-instellingen Plugin location Plug-inlocatie ProcessIndicator Processing Bezig met verwerken… RenameOperation Image Renamed De fotonaam is gewijzigd Image Rename Failed Naamswijziging mislukt Rename image Fotonaam wijzigen New filename: Nieuwe bestandsnaam: Successfully renamed image to %1 De afbeeldingsnaam is gewijzigd in ‘%1’ Failed to rename image to %1 De naam van ‘%1’ kan niet worden gewijzigd SaveOperation Save As Opslaan als All Files Alle bestanden Image Saved De schermfoto is opgeslagen Saving Image Failed Kan schermfoto niet opslaan Image Files Afbeeldingsbestanden Saved to %1 Opgeslagen in %1 Failed to save image to %1 De afbeelding kan niet worden opgeslagen in %1 SaverSettings Automatically save new captures to default location Nieuwe schermfoto's automatisch opslaan op standaardlocatie Prompt to save before discarding unsaved changes Altijd vragen om aanpassingen op te slaan Remember last Save Directory Recentste opslagmap onthouden When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Schakel in om de opslagmap uit de instellingen te vervangen door de recentste opslagmap. Capture save location and filename Opslaglocatie en bestandsnaam Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Ondersteunde bestandsformaten: JPG, PNG en BMP. Als je geen formaat opgeeft, dan wordt PNG gebruikt. De bestandsnaam mag de volgende jokertekens bevatten: - $Y, $M, $D voor datum, $h, $m, $s voor tijd, of $T voor tijd in de opmaak ‘uummss’. - Gebruik # voor optelling. Voorbeeld: #### geeft 0001, met als opvolger 0002. Browse Bladeren Saver Settings Opslaginstellingen Capture save location Opslaglocatie Default Standaard Factor Factor Save Quality Opslagkwaliteit Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Geef 0 op om bestanden met lage compressie te verkrijgen en 100 voor bestanden met hoge compressie. Niet alle formaten ondersteunen det volledige bereik, maar jpeg wel. Overwrite file with same name Bestand met dezelfde naam overschrijven ScriptUploaderSettings Copy script output to clipboard Scriptuitvoer kopiëren naar klembord Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Locatie van het script dat moet worden gebruikt bij het uploaden. Tijdens het uploaden wordt dit script aangeroepen op de locatie van de tijdelijke png. Browse Bladeren Script Uploader Script-uploader Select Upload Script Uploadscript kiezen Stop when upload script writes to StdErr Stoppen als uploadscript is weggeschreven naar StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Markeert de upload als ‘mislukt’ als het script wordt weggeschreven naar StdErr. Schakel uit om scriptfouten te negeren. Filter: Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Reguliere uitdrukking. Kopieer alleen tekst naar het klembord die hiermee overeenkomt. Sla over om álles te kopiëren. SettingsDialog Settings Instellingen OK Oké Cancel Annuleren Image Grabber Vastleggen Imgur Uploader Imgur-uploader Application Programma Annotator Aantekeningen HotKeys Sneltoetsen Uploader Uploader Script Uploader Script-uploader Saver Opslaan Stickers Stickers Snipping Area Vastleggebied Tray Icon Systeemvakpictogram Watermark Watermerk Actions Acties FTP Uploader FTP-upload Plugins Plug-ins Search Settings... Zoekinstellingen… SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Pas de grootte van het selectiegebied aan door de handgrepen te verschuiven of de selectie te verplaatsen. Use arrow keys to move the selection. Gebruik de pijltjestoetsen om de selectie te verplaatsen. Use arrow keys while pressing CTRL to move top left handle. Houd de Ctrl-toets ingedrukt en druk op de pijltjestoetsen om het bovenste linkerhandvat te verplaatsen. Use arrow keys while pressing ALT to move bottom right handle. Houd de Alt-toets ingedrukt en druk op de pijltjestoetsen om het onderste rechterhandvat te verplaatsen. This message can be disabled via settings. Dit bericht kan in de instellingen worden uitgeschakeld. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Bevestig de selectie door op de entertoets te drukken of te dubbelklikken. Abort by pressing ESC. Breek af door op Esc te drukken. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Klik en sleep om een rechthoekig gebied te selecteren of druk op Esc om af te breken. Hold CTRL pressed to resize selection after selecting. Houd na het selecteren Ctrl ingedrukt om het gebied te verkleinen/vergroten. Hold CTRL pressed to prevent resizing after selecting. Houd na het selecteren Ctrl ingedrukt om vergroten/verkleinen te voorkomen. Operation will be canceled after 60 sec when no selection made. De handeling wordt na 60 sec. inactiviteit afgebroken. This message can be disabled via settings. Dit bericht kan in de instellingen worden uitgeschakeld. SnippingAreaSettings Freeze Image while snipping Schermfoto bevriezen tijdens vastleggen When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Schakel in om de achtergrond te bevriezen tijdens het selecteren van een rechthoekig gebied. Dit verandert tevens het gedrag van vertraagde schermfoto's: de wachttijd vindt plaats vóórdat het selectiegebied wordt getoond. Deze optie is altijd uitgeschakeld op Wayland en altijd ingeschakeld op macOS. Show magnifying glass on snipping area Vergrootglas tonen op vastleggebied Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Toont een vergrootglas om in te zoomen op de achtergrondafbeelding. Deze optie werkt alleen als ‘Schermfoto bevriezen tijdens vastleggen’ is ingeschakeld. Show Snipping Area rulers Linialen tonen op vastleggebied Horizontal and vertical lines going from desktop edges to cursor on snipping area. Horizontale en verticale lijnen die lopen vanaf de schermranden naar de cursor op het vastleggebied. Show Snipping Area position and size info Positie- en afmetingsinformatie tonen op vastleggebied When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Als de linkermuisknop niet wordt ingedrukt, wordt de positie getoond. Als de knop wél wordt ingedrukt, wordt de grootte van het selectiegebied links en bovenaan getoond. Allow resizing rect area selection by default Vergroten/Verkleinen van selectiegebied toestaan When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Schakel in om de afmetingen van het gebied van een rechthoekige selectie aan te passen. Druk na het aanpassen op Enter om op te slaan. Show Snipping Area info text Informatietekst tonen op vastleggebied Snipping Area cursor color Cursorkleur binnen vastleggebied Sets the color of the snipping area cursor. Stel de kleur in van de cursor op het vastleggebied. Snipping Area cursor thickness Cursordikte binnen vastleggebied Sets the thickness of the snipping area cursor. Stel de dikte in van de cursor op het vastleggebied. Snipping Area Vastleggebied Snipping Area adorner color Versierkleur van vastleggebied Sets the color of all adorner elements on the snipping area. Stelt de kleur in van versierde elementen in het vastleggebied. Snipping Area Transparency Doorzichtigheid van vastleggebied Alpha for not selected region on snipping area. Smaller number is more transparent. De alfawaarde van niet-geselecteerde gebieden in het selectiegebied. Lager = doorzichtiger. Enable Snipping Area offset Verschuiving van vastleggebied gebruiken When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Schakel in om de ingestelde verschuiving toe te passen op het vastleggebied als de positie onjuist wordt berekend. Deze functie is in sommige gevallen vereist. X X Y Y StickerSettings Up Omhoog Down Omlaag Use Default Stickers Standaardstickers gebruiken Sticker Settings Stickerinstellingen Vector Image Files (*.svg) Vector-afbeeldingsbestanden (*.svg) Add Toevoegen Remove Verwijderen Add Stickers Stickers toevoegen TrayIcon Show Editor Bewerker tonen TrayIconSettings Use Tray Icon Systeemvakpictogram gebruiken When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Schakel dit in om, als je vensterbeheerder dit ondersteunt, een systeemvakpictogram te gebruiken. Herstart om de wijziging toe te passen. Minimize to Tray Minimaliseren naar systeemvak Start Minimized to Tray Geminimaliseerd in systeemvak opstarten Close to Tray Sluiten naar systeemvak Show Editor Bewerker tonen Capture Vastleggen Default Tray Icon action Standaard systeemvakpictogramactie Default Action that is triggered by left clicking the tray icon. De standaardactie na het klikken op het systeemvakpictogram. Tray Icon Settings Systeemvakinstellingen Use platform specific notification service Systeemmeldingen tonen When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Schakel in om, indien mogelijk, systeemmeldingen te tonen. Herstart KSnip om de wijziging toe te passen. Display Tray Icon notifications Systeemvakmeldingen tonen UpdateWatermarkOperation Select Image Foto kiezen Image Files Afbeeldingsbestanden UploadOperation Upload Script Required Uploadscript vereist Please add an upload script via Options > Settings > Upload Script Voeg een uploadscript toe via Opties --> Instellingen --> Uploadscript Capture Upload Schermfoto uploaden You are about to upload the image to an external destination, do you want to proceed? Je staat op het punt om een schermfoto te uploaden. Wil je doorgaan? UploaderSettings Ask for confirmation before uploading Vragen alvorens te uploaden Uploader Type: Soort upload: Imgur Imgur Script Script Uploader Uploader FTP FTP VersionTab Version Versie Build Bouwsel Using: Gebruikmakend van: WatermarkSettings Watermark Image Watermerkafbeelding Update Bijwerken Rotate Watermark Watermerk draaien When enabled, Watermark will be added with a rotation of 45° Gebruik deze optie om een watermerk toe te voegen dat 45° gedraaid is Watermark Settings Watermerkinstellingen ksnip-master/translations/ksnip_no.ts000066400000000000000000001712071457262621600204270ustar00rootroot00000000000000 AboutDialog About Om About Om Version Versjon Author Utvikler Close Lukk Donate Doner Contact AboutTab License: Lisens: Screenshot and Annotation Tool ActionSettingTab Name Shortcut Clear Tøm Take Capture Include Cursor Delay s The small letter s stands for seconds. s Capture Mode Show image in Pin Window Copy image to Clipboard Upload image Open image parent directory Save image Hide Main Window Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Legg til Actions Settings Action AddWatermarkOperation Watermark Image Required Vannmerkingsbilde kreves Please add a Watermark Image via Options > Settings > Annotator > Update Legg til et vannmerkingsbilde via Valg → Innstillinger → Undertekster → Oppdater AnnotationSettings Smooth Painter Paths Myk ut tegningsstrøk When enabled smooths out pen and marker paths after finished drawing. Myker ut penn og markørstrøk etter utført tegning. Smooth Factor Utmykiningsfaktor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Økning av utmykingsfaktoren vil senke nøyaktigheten for penn og markør, men vil gjøre dem mykere. Annotator Settings Undertekstingsinnstillinger Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Utfør skjermavbildning ved oppstart i forvalgt modus Application Style Programstil Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Setter programstilen som definerer utseende og oppførsel for bruker- grensesnittet. Endringer krever omstart av ksnip. Application Settings Programinnstillinger Automatically copy new captures to clipboard Kopier nye avbildninger til utklippstavle automatisk Use Tabs Bruk faner Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Utforsk AuthorTab Contributors: Bidragsytere: Spanish Translation Spansk oversettelse Dutch Translation Nederlandsk oversettelse Russian Translation Russisk oversettelse Norwegian BokmÃ¥l Translation BokmÃ¥lsoversettelse French Translation Fransk oversettelse Polish Translation Polsk oversettelse Snap & Flatpak Support Snap og Flatpak -støtte The Authors: CanDiscardOperation Warning - Advarsel - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Ny Draw a rectangular area with your mouse Tegn et rektangulært omrÃ¥de med musen din Capture full screen including all monitors Avbild hele skjermen pÃ¥ tvers av alle monitorer Capture screen where the mouse is located Avbild skjerm der pekeren befinner seg Capture window that currently has focus Avbild vindu som er i fokus Capture that is currently under the mouse cursor Avbild det som er under musepekeren Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image Slett bilde The item '%1' will be deleted. Do you want to continue? Elementet «%1» vil bli slettet. Ønsker du Ã¥ fortsette? DonateTab Donation Donasjon Donations are always welcome Donasjoner er alltid velkomne ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Rektangulært omrÃ¥de Last Rectangular Area Full Screen (All Monitors) Fullskjermsvisning (alle skjermer) Current Screen NÃ¥værende skjerm Active Window Aktivt vindu Window Under Cursor Vindu under peker Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Brukernavn Password FTP Uploader HandleUploadResultOperation Upload Successful Opplastet Unable to save temporary image for upload. Unable to start process, check path and permissions. Kunne ikke starte prosess, sjekk sti og tilganger. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear Tøm Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Ta med peker Should mouse cursor be visible on screenshots. Hvorvidt pekeren tas med pÃ¥ skjermavbildninger. Image Grabber Bildehenter Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Imgur-historikk Close Lukk Time Stamp Tidsstempel Link Lenke Delete Link Slett lenke ImgurUploader Upload to imgur.com finished! Opplastet til imgur.com. Received new token, trying upload again… Mottok nytt symbol, forsøker opplasting igjen… Imgur token has expired, requesting new token… Imgur-symbol utløpt, forespør nytt… ImgurUploaderSettings Force anonymous upload Tving anonym opplasting Always copy Imgur link to clipboard Alltid kopier Imgur-lenke til utklippstavle Client ID Klient-ID Client Secret Klient-hemmelighet PIN PIN Enter imgur Pin which will be exchanged for a token. Skriv inn Imgur-PIN brukt til utveksling for symbol Get PIN Hent PIN Get Token Hent symbol Imgur History Imgur-historikk Imgur Uploader Imgur-opplaster Username Brukernavn Waiting for imgur.com… Venter pÃ¥ imgur.com… Imgur.com token successfully updated. Imgur.com-symbol oppdatert. Imgur.com token update error. Imgur.com-symboloppdateringsfeil. After uploading open Imgur link in default browser Etter opplasting, Ã¥pne Imgur-lenke i forvalgt nettleser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Ny Delay in seconds between triggering and capturing screenshot. Forsinkelse i sekunder mellom utløsing og avbildning av skjerm. s The small letter s stands for seconds. s Save Lagre Save Screen Capture to file system Lagre skjermavbildning til filsystem Copy Kopier Copy Screen Capture to clipboard Kopier skjermavbildning til utklippstavle Tools Verktøy Undo Angre Redo Gjenta Crop Beskjær Crop Screen Capture Beskjær skjermavbildning MainWindow Unsaved Ulagret Upload Last opp Print Skriv ut Opens printer dialog and provide option to print image Ã…pner utskriftsdialogvindu og gir mulighet til Ã¥ skrive ut bilde Print Preview UtskriftsforhÃ¥ndsvisning Opens Print Preview dialog where the image orientation can be changed Ã…pner utskriftsforhÃ¥ndsvisningsdialogvindu der sideretning kan endres Scale Skaler Quit Avslutt Settings Innstillinger &About &Om Open Ã…pne &Edit &Rediger &Options &Valg &Help &Hjelp Add Watermark Legg til vannmerke Add Watermark to captured image. Multiple watermarks can be added. Legg til vannmerke til innhentet bilde. Flere vannmerker kan legges til. &File &Fil Unable to show image Klarte ikke Ã¥ vise bilde Save As... Lagre som … Paste Lim inn Paste Embedded Pin Fest Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Kopier sti Open Directory Ã…pne mappe &View &Vis Delete Slett Rename Gi nytt navn Open Images Ã…pne bilder Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Lagre Save As Lagre som Open Directory Ã…pne mappe Copy Kopier Copy Path Kopier sti Delete Slett Rename Gi nytt navn Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close Lukk Close Other Close All Lukk alle PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Forvalg The directory where the plugins are located. Browse Utforsk Name Version Versjon Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image Gi bilde nytt navn New filename: Nytt filnavn: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As Lagre som All Files Alle filer Image Saved Bilde lagret Saving Image Failed Kunne ikke lagre bilde Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Forespør lagring før forkasting av ulagrede endringer Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Lagringssted og filnavn for skjermavbildning Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Utforsk Saver Settings Capture save location Avbildningslagringssted Default Forvalg Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Kopier skriptutdata til utklippstavle Script: Skript: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Utforsk Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings Innstillinger OK OK Cancel Avbryt Image Grabber Bildehenter Imgur Uploader Imgur-opplaster Application Program Annotator Undertekster HotKeys Uploader Opplaster Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping Frys bildet under tilpasning When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Vis forstørrelsesglass i tilpasningsomrÃ¥de Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Vis et forstørrelsesglass som forstørrer inn i bakgrunnsbildet. Dette valget fungerer med "Frys bilde under tilpasning" pÃ¥skrudd. Show Snipping Area rulers Vis linjaler for tilpasningsomrÃ¥de Horizontal and vertical lines going from desktop edges to cursor on snipping area. Vann- og loddrette linjer som gÃ¥r fra skrivebordets kanter til pekeren i tilpasningsomrÃ¥det. Show Snipping Area position and size info Vis posisjon og størrelsesinfo for tilpasningsomrÃ¥de When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Pekerfarge for tilpasningsomrÃ¥de Sets the color of the snipping area cursor. Snipping Area cursor thickness Pekertykkelse for tilpasningsomrÃ¥de Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add Legg til Remove Fjern Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon Bruk systemkurvsikon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Minimer til systemkurven Start Minimized to Tray Close to Tray Lukk til systemkurven Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Velg bilde Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Forespør bekreftelse før opplasting Uploader Type: Imgur Script Skript Uploader Opplaster FTP VersionTab Version Versjon Build Bygg Using: Bruker: WatermarkSettings Watermark Image Vannmerkingsbilde Update Oppdater Rotate Watermark Roter vannmerke When enabled, Watermark will be added with a rotation of 45° Legger til vannmere rotert 45° Watermark Settings ksnip-master/translations/ksnip_pl.ts000066400000000000000000002064501457262621600204250ustar00rootroot00000000000000 AboutDialog About O programie About O programie Version Wersja Author Autor Close Zamknij Donate Wspomóż Contact Kontakt AboutTab License: Licencja: Screenshot and Annotation Tool Zrzuty ekranu i narzÄ™dzie adnotacji ActionSettingTab Name Nazwa Shortcut Skrót Clear Wyczyść Take Capture Przechwyć Include Cursor UwzglÄ™dnij kursor Delay Opóźnij s The small letter s stands for seconds. s Capture Mode Tryb przechwytywania Show image in Pin Window Pokaż obraz w oknie Pin Copy image to Clipboard Kopiuj obraz do schowka Upload image PrzeÅ›lij obraz Open image parent directory Otwórz nadrzÄ™dny katalog obrazu Save image Zapisz obraz Hide Main Window Ukryj główne okno Global Globalne When enabled will make the shortcut available even when ksnip has no focus. Włączenie tej opcji spowoduje, że skrót bÄ™dzie dostÄ™pny nawet wtedy, gdy ksnip nie ma ostroÅ›ci. ActionsSettings Add Dodaj Actions Settings Ustawienia dziaÅ‚aÅ„ Action DziaÅ‚anie AddWatermarkOperation Watermark Image Required Wymagany obraz znaku wodnego Please add a Watermark Image via Options > Settings > Annotator > Update Dodaj obraz znaku wodnego, wybierajÄ…c Opcje > Ustawienia > Adnotacje > Aktualizuj AnnotationSettings Smooth Painter Paths WygÅ‚adzaj linie rysunkowe When enabled smooths out pen and marker paths after finished drawing. Po włączeniu wygÅ‚adza linie pióra i Å›cieżki znaczników po zakoÅ„czeniu rysowania. Smooth Factor Współczynnik wygÅ‚adzania Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. ZwiÄ™kszenie współczynnika wygÅ‚adzania spowoduje zmniejszenie dokÅ‚adnoÅ›ci pióra i markera ale uczyni je bardziej gÅ‚adkimi. Annotator Settings Ustawienia adnotacji Remember annotation tool selection and load on startup ZapamiÄ™taj wybór narzÄ™dzia do adnotacji i zaÅ‚aduj go podczas uruchamiania Switch to Select Tool after drawing Item Przejdź do opcji Wybierz narzÄ™dzie po narysowaniu elementu Number Tool Seed change updates all Number Items NarzÄ™dzie Zmiana Numeracji aktualizuje wszystkie ponumerowane pozycje Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Wyłączenie tej opcji powoduje zmiany narzÄ™dzia numeracji. Dotyczy tylko nowych elementów i nie wpÅ‚ywa na już istniejÄ…ce elementy. Wyłączenie tej opcji spowoduje zduplikowanie numerów. Canvas Color Kolor płótna Default Canvas background color for annotation area. Changing color affects only new annotation areas. DomyÅ›lny kolor tÅ‚a obszaru roboczego dla obszaru adnotacji. Zmiana koloru wpÅ‚ywa tylko na nowe obszary adnotacji. Select Item after drawing Wybierz element po narysowaniu With this option enabled the item gets selected after being created, allowing changing settings. Po włączeniu tej opcji element jest zaznaczany po utworzeniu, co pozwala na zmianÄ™ ustawieÅ„. Show Controls Widget Pokaż widżet Sterowanie The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Widżet Sterowanie zawiera opcje Cofnij/Ponów, Przyciski Kadruj, Skaluj, Obróć i Modyfikuj obszar roboczy. ApplicationSettings Capture screenshot at startup with default mode Przechwyć zrzut ekranu przy uruchamianiu w trybie domyÅ›lnym Application Style Styl aplikacji Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Ustawia styl aplikacji, który definiuje wyglÄ…d i dziaÅ‚anie interfejsu GUI. Zmiana wymaga ponownego uruchomienia ksnip, aby odniosÅ‚a skutek. Application Settings Ustawienia aplikacji Automatically copy new captures to clipboard Automatycznie kopiuj nowe zrzuty do schowka Use Tabs Użyj zakÅ‚adek Change requires restart. Zmiana wymaga ponownego uruchomienia. Run ksnip as single instance Uruchom ksnip jako pojedynczÄ… instancjÄ™ Hide Tabbar when only one Tab is used. Ukryj pasek zakÅ‚adek, gdy używana jest tylko jedna karta. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Włączenie tej opcji pozwoli na uruchomienie tylko jednej instancji ksnip, wszystkie inne instancje uruchomione po pierwszym uruchomieniu przekażą ich argumenty do pierwszego uruchomienia i zostanÄ… zamkniÄ™te. Zmiana tej opcji wymaga ponownego uruchomienia wszystkich instancji. Remember Main Window position on move and load on startup ZapamiÄ™taj pozycjÄ™ okna głównego podczas przenoszenia i Å‚adowania przy starcie Auto hide Tabs Ukryj automatycznie ZakÅ‚adki Auto hide Docks Ukryj automatycznie Doki On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Po uruchomieniu ukryj pasek narzÄ™dzi i ustawienia adnotacji. widoczność Doków można przełączać za pomocÄ… klawisza Tab. Auto resize to content Dostosuj rozmiar do zawartoÅ›ci Automatically resize Main Window to fit content image. Automatyczna zmiana rozmiaru okna głównego w celu dopasowania do zawartoÅ›ci obrazu. Enable Debugging Włącz debugowanie Enables debug output written to the console. Change requires ksnip restart to take effect. Włącza debugowanie danych wyjÅ›ciowych zapisanych w konsoli. Zmiana wymaga ponownego uruchomienia programu ksnip. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Zmiana rozmiaru zawartoÅ›ci jest opóźnione, aby umożliwić menedżerowi okien odebranie nowej zawartoÅ›ci. W przypadku, gdy główne okno nie jest poprawnie dostosowane do nowej zawartoÅ›ci, zwiÄ™kszenie tego opóźnienia może poprawić zachowanie. Resize delay Zmiana rozmiaru opóźnienia Temp Directory Katalog Temp Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Katalog Temp sÅ‚uży do przechowywania tymczasowych obrazów, które zostanÄ… usuniÄ™te po zamkniÄ™ciu programu ksnip. Browse PrzeglÄ…daj AuthorTab Contributors: Współtwórcy: Spanish Translation TÅ‚umaczenie na jÄ™zyk hiszpaÅ„ski Dutch Translation TÅ‚umaczenie na jÄ™zyk niderlandzki Russian Translation TÅ‚umaczenie na jÄ™zyk rosyjski Norwegian BokmÃ¥l Translation TÅ‚umaczenie na jÄ™zyk norweski BokmÃ¥l French Translation TÅ‚umaczenie na jÄ™zyk francuski Polish Translation TÅ‚umaczenie na jÄ™zyk polski Snap & Flatpak Support ObsÅ‚uga Snap & Flatpak The Authors: Autorzy: CanDiscardOperation Warning - Ostrzeżenie - The capture %1%2%3 has been modified. Do you want to save it? Zrzut z ekranu %1%2%3 zostaÅ‚ zmodyfikowany. Chcesz go zapisać? CaptureModePicker New Nowy Draw a rectangular area with your mouse Narysuj myszkÄ… prostokÄ…tny obszar Capture full screen including all monitors Przechwyć peÅ‚ny ekran, w tym wszystkie monitory Capture screen where the mouse is located Przechwyć ekran, na którym znajduje siÄ™ myszka Capture window that currently has focus Przechwyć okno, które aktualnie jest aktywne Capture that is currently under the mouse cursor Przechwyć okno, które jest aktualnie pod kursorem myszy Capture a screenshot of the last selected rectangular area Wykonaj zrzut ekranu z ostatnio wybranym prostokÄ…tnym obszarem Uses the screenshot Portal for taking screenshot Wykorzystuje portal do robienia zrzutów ekranu ContactTab Community SpoÅ‚eczność Bug Reports ZgÅ‚aszanie błędów If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. JeÅ›li masz ogólne pytania, pomysÅ‚y lub po prostu chcesz porozmawiać o programie ksnip,<br/>dołącz do naszego serwisu %1 lub %2. Please use %1 to report bugs. Użyj %1, aby zgÅ‚osić błędy. CopyAsDataUriOperation Failed to copy to clipboard Nieudane kopiowanie do schowka Failed to copy to clipboard as base64 encoded image. Nie udaÅ‚o siÄ™ skopiować do schowka obrazu zakodowanego w base64. Copied to clipboard Skopiowano do schowka Copied to clipboard as base64 encoded image. Skopiowano do schowka jako obraz zakodowany base64. DeleteImageOperation Delete Image UsuÅ„ Obraz The item '%1' will be deleted. Do you want to continue? Element '%1' zostanie usuniÄ™ty. Czy chcesz kontynuować? DonateTab Donations are always welcome Darowizny sÄ… zawsze mile widziane Donation Wspomóż ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip jest niedochodowym projektem wolnego oprogramowania objÄ™tego licencjÄ… typu copylefted <br/> i nadal ma pewne koszty, które trzeba pokryć, takie jak koszty domeny lub koszty sprzÄ™tu<br/> do obsÅ‚ugi wielu platform. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. JeÅ›li chcesz pomóc lub po prostu chcesz docenić wykonywanÄ… pracÄ™ czÄ™stujÄ…c programistów<br/> piwem lub kawÄ…, możesz to zrobić %1tutaj%2. Become a GitHub Sponsor? Czy możesz być sponsorem GitHub? Also possible, %1here%2. Możliwe również, %1tutaj%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Dodaj nowe dziaÅ‚ania, naciskajÄ…c przycisk "Dodaj". EnumTranslator Rectangular Area Obszar prostokÄ…tny Last Rectangular Area Ostatni obszar prostokÄ…tny Full Screen (All Monitors) PeÅ‚ny ekran (wszystkie monitory) Current Screen Bieżący ekran Active Window Aktywne okno Window Under Cursor Okno pod kursorem Screenshot Portal Portal zrzutu ekranu FtpUploaderSettings Force anonymous upload. WymuÅ› anonimowe wysyÅ‚anie. Url Adres URL Username Nazwa użytkownika Password HasÅ‚o FTP Uploader PrzesyÅ‚anie protokoÅ‚em FTP HandleUploadResultOperation Upload Successful PrzesyÅ‚anie zakoÅ„czone pomyÅ›lnie Unable to save temporary image for upload. Nie można zapisać tymczasowego obrazu do przesÅ‚ania. Unable to start process, check path and permissions. Nie można uruchomić procesu, sprawdź Å›cieżkÄ™ i uprawnienia. Process crashed Proces ulegÅ‚ awarii Process timed out. Przekroczono limit czasu procesu. Process read error. Błąd odczytu procesu. Process write error. Błąd zapisu procesu. Web error, check console output. Błąd sieciowy, sprawdź dane wyjÅ›ciowe konsoli. Upload Failed PrzesyÅ‚anie nie powiodÅ‚o siÄ™ Script wrote to StdErr. Skrypt wysÅ‚any do StdErr. FTP Upload finished successfully. PrzesyÅ‚anie protokoÅ‚em FTP zakoÅ„czyÅ‚o siÄ™ pomyÅ›lnie. Unknown error. Nieznany błąd. Connection Error. Błąd połączenia. Permission Error. Błąd uprawnieÅ„. Upload script %1 finished successfully. PrzesyÅ‚anie skryptu %1 zakoÅ„czone pomyÅ›lnie. Uploaded to %1 PrzesÅ‚ano do %1 HotKeySettings Enable Global HotKeys Włącz globalne klawisze skrótu Capture Rect Area Przechwyć obszar prostokÄ…tny Capture Full Screen Przechwyć peÅ‚ny ekran Capture current Screen Przechwyć bieżący ekran Capture active Window Przechwyć aktywne okno Capture Window under Cursor Przechwyć okno pod kursorem Global HotKeys Globalne skróty klawiszowe Capture Last Rect Area Przechwyć ostatni obszar prostokÄ…tny Clear Wyczyść Capture using Portal Przechwyć za pomocÄ… Portalu HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Skróty klawiszowe sÄ… obecnie obsÅ‚ugiwane tylko dla systemów Windows i X11. Wyłączenie tej opcji spowoduje, że skróty akcji bÄ™dÄ… obsÅ‚ugiwane tylko przez program ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Przechwyć kursor myszy na zrzucie ekranu Should mouse cursor be visible on screenshots. Jesli kursor myszy powinien być widoczny na zrzutach ekranu. Image Grabber Przechwyć obraz Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Rodzajowe wdrożenia Wayland, które używajÄ… XDG-DESKTOP-PORTAL obsÅ‚ugujÄ… skalowanie ekranu w inny sposób. Włączenie tej opcji okreÅ›li bieżące skalowanie ekranu i zastosuje je do zrzutu ekranu w ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME i KDE Plasma obsÅ‚ugujÄ… wÅ‚asny Wayland oraz zrzuty ekranu Generic XDG-DESKTOP-PORTAL. Włączenie tej opcji wymusi KDE Plasma i GNOME do korzystania ze zrzutów ekranu XDG-DESKTOP-PORTAL. Zmiana tej opcji wymaga ponownego uruchomienia ksnip. Show Main Window after capturing screenshot Pokaż okno główne po przechwyceniu zrzutu ekranu Hide Main Window during screenshot Ukryj okno główne podczas zrzutu ekranu Hide Main Window when capturing a new screenshot. Ukryj okno główne podczas przechwytywania nowego zrzutu ekranu. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Pokaż okno główne po zrobieniu nowego zrzutu ekranu kiedy główne okno byÅ‚o ukryte lub zminimalizowane. Force Generic Wayland (xdg-desktop-portal) Screenshot WymuÅ› zrzut ekranu poprzez generyczny podsystem Wayland (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots Skaluj ogólne zrzuty ekranu Wayland (xdg-desktop-portal) Implicit capture delay Opóźnienie przechwytywania niejawnego This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Opóźnienie jest używane, gdy w interfejsie użytkownika nie wybrano żadnego opóźnienia. Pozwala to ksnip ukryć siÄ™ przed wykonaniem zrzutu. Wartość ta nie jest stosowana, gdy ksnip zostaÅ‚ już zminimalizowany. Zmniejszenie tej wartoÅ›ci może spowodować, że główne okno ksnip bÄ™dzie widoczne na zrzucie ekranu. ImgurHistoryDialog Imgur History Historia Imgur Close Zamknij Time Stamp Czas Link Link Delete Link UsuÅ„ link ImgurUploader Upload to imgur.com finished! PrzesyÅ‚anie do imgur.com zakoÅ„czone! Received new token, trying upload again… Otrzymano nowy token, próbujÄ™ przesÅ‚ać ponownie… Imgur token has expired, requesting new token… Token Imgur wygasÅ‚, żądanie nowego tokena… ImgurUploaderSettings Force anonymous upload WymuÅ› anonimowe przesyÅ‚anie Always copy Imgur link to clipboard Zawsze kopiuj link Imgur do schowka Client ID Identyfikator klienta Client Secret Szyfrowanie klienta PIN PIN Enter imgur Pin which will be exchanged for a token. Wpisz Pin imgur, który zostanie wymieniony na token. Get PIN Uzyskaj PIN Get Token Uzyskaj Token Imgur History Historia Imgur Imgur Uploader PrzeÅ›lij do Imgur Username Nazwa użytkownika Waiting for imgur.com… Czekam na imgur.com… Imgur.com token successfully updated. Token Imgur.com zostaÅ‚ pomyÅ›lnie zaktualizowany. Imgur.com token update error. Błąd aktualizacji tokena Imgur.com. After uploading open Imgur link in default browser Po zaÅ‚adowaniu otwórz link Imgur w domyÅ›lnej przeglÄ…darce Link directly to image BezpoÅ›redni link do obrazu Base Url: Bazowy adres URL: Base url that will be used for communication with Imgur. Changing requires restart. Bazowy adres URL, który bÄ™dzie używany do komunikacji z Imgur. Zmiana adresu wymaga ponownego uruchomienia. Clear Token Wyczyść token Upload title: TytuÅ‚ przesyÅ‚anego zrzutu: Upload description: Opis przesyÅ‚anego zrzutu: LoadImageFromFileOperation Unable to open image Nie można otworzyć obrazu Unable to open image from path %1 Nie można otworzyć obrazu ze Å›cieżki %1 MainToolBar New Nowy Delay in seconds between triggering and capturing screenshot. Opóźnienie w sekundach pomiÄ™dzy wywoÅ‚aniem i wykonaniem zrzutu ekranu. s The small letter s stands for seconds. s Save Zapisz Save Screen Capture to file system Zapisz zrzut ekranu w systemie plików Copy Kopiuj Copy Screen Capture to clipboard Skopiuj zrzut ekranu do schowka Tools NarzÄ™dzia Undo Cofnij Redo Ponów Crop Kadruj Crop Screen Capture Kadruj zrzut ekranu MainWindow Unsaved Niezapisane Upload WyÅ›lij Print Drukuj Opens printer dialog and provide option to print image Otwiera okno dialogowe drukarki i umożliwia drukowanie obrazu Print Preview PodglÄ…d wydruku Opens Print Preview dialog where the image orientation can be changed Otwiera okno dialogowe PodglÄ…du wydruku, w którym można zmienić orientacjÄ™ obrazu Scale Skaluj Quit ZakoÅ„cz Settings Ustawienia &About &O programie Open Otwórz &Edit &Edytuj &Options &Opcje &Help &Pomoc Add Watermark Dodaj znak wodny Add Watermark to captured image. Multiple watermarks can be added. Dodaj znak wodny do przechwyconego obrazu. Można dodać wiele znaków wodnych. &File &Plik Unable to show image Nie można wyÅ›wietlić obrazu Save As... Zapisz jako... Paste Wklej Paste Embedded Wklej Osadź Pin Pin Pin screenshot to foreground in frameless window Przypnij zrzut ekranu do pierwszego planu w oknie bez ramek No image provided but one was expected. Nie dostarczono żadnego obrazu, ale można siÄ™ byÅ‚o go spodziewać. Copy Path Kopiuj Å›cieżkÄ™ Open Directory Otwórz katalog &View &Widok Delete UsuÅ„ Rename ZmieÅ„ nazwÄ™ Open Images Otwórz obraz Show Docks Pokaż Doki Hide Docks Ukryj Doki Copy as data URI Kopiuj jako dane URI Open &Recent Ostatnio &otwierane Modify Canvas Modyfikacja płótna Upload triggerCapture to external source PrzeÅ›lij trigerCapture do zewnÄ™trznego źródÅ‚a Copy triggerCapture to system clipboard Kopiuj triggerCapture do schowka systemowego Scale Image Skaluj obraz Rotate Obróć Rotate Image Obróć obraz Actions DziaÅ‚ania Image Files Pliki obrazów Save All Zapisz wszystko Close Window Zamknij okno Cut Przytnij OCR OCR MultiCaptureHandler Save Zapisz Save As Zapisz jako Open Directory Otwórz katalog Copy Kopiuj Copy Path Kopiuj Å›cieżkÄ™ Delete UsuÅ„ Rename ZmieÅ„ nazwÄ™ Save All Zapisz wszystko NewCaptureNameProvider Capture Zrzut ekranu OcrWindowCreator OCR Window %1 Okno OCR %1 PinWindow Close Zamknij Close Other Zamknij inne Close All Zamknij wszystko PinWindowCreator OCR Window %1 Okno OCR %1 PluginsSettings Search Path Szukaj Å›cieżki Default DomyÅ›lnie The directory where the plugins are located. Katalog, w którym znajdujÄ… siÄ™ wtyczki. Browse PrzeglÄ…daj Name Nazwa Version Wersja Detect Wykryj Plugin Settings Ustawienia wtyczki Plugin location Lokalizacja wtyczki ProcessIndicator Processing Przetwarzanie RenameOperation Image Renamed Zmiana nazwy obrazu Image Rename Failed Zmiana nazwy obrazu nie powiodÅ‚a siÄ™ Rename image ZmieÅ„ nazwÄ™ obrazu New filename: Nowa nazwa pliku: Successfully renamed image to %1 PomyÅ›lnie zmieniono nazwÄ™ obrazu na %1 Failed to rename image to %1 Nie można zmienić nazwy obrazu na %1 SaveOperation Save As Zapisz jako All Files Wszystkie Pliki Image Saved Obraz zostaÅ‚ zapisany Saving Image Failed Zapisywanie obrazu nie powiodÅ‚o siÄ™ Image Files Pliki obrazów Saved to %1 Zapisano w %1 Failed to save image to %1 Nie udaÅ‚o siÄ™ zapisać obrazu w %1 SaverSettings Automatically save new captures to default location Zapisz automatycznie nowe zrzuty w domyÅ›lnej lokalizacji Prompt to save before discarding unsaved changes Pytaj czy zapisać przed odrzuceniem niezapisanych zmian Remember last Save Directory ZapamiÄ™taj ostatni katalog zapisywania When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Po włączeniu tej opcji nadpisze zapisany w ustawieniach katalog najnowszym katalogiem zapisu, dla każdego zapisu. Capture save location and filename Lokalizacja zapisu i nazwa pliku Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. ObsÅ‚ugiwane formaty to JPG, PNG i BMP. JeÅ›li format nie zostanie podany, domyÅ›lnie zostanie użyty format PNG. Nazwa pliku może zawierać nastÄ™pujÄ…ce symbole wieloznaczne: - $Y, $M, $D dla daty, $h, $m, $s dla czasu lub $T dla czasu w formacie ggmmss. - Wiele kolejnych znaków # dla licznika. #### da w wyniku 0001, nastÄ™pne przechwycenie to 0002. Browse PrzeglÄ…daj Saver Settings Zapisz ustawienia Capture save location Zapisz zrzut ekranu w lokalizacji Default DomyÅ›lna Factor Współczynnik Save Quality Jakość zapisu Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Podaj 0, aby uzyskać maÅ‚e pliki skompresowane, 100 dla dużych plików nieskompresowanych. Nie wszystkie formaty obrazów obsÅ‚ugujÄ… peÅ‚ny zakres, JPEG obsÅ‚uguje peÅ‚ny zakres. Overwrite file with same name ZastÄ…p plik o tej samej nazwie ScriptUploaderSettings Copy script output to clipboard Kopiuj dane wyjÅ›ciowe skryptu do schowka Script: Skrypt: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Åšcieżka do skryptu, który zostanie wywoÅ‚any w celu przesÅ‚ania. Podczas przesyÅ‚ania skrypt zostanie wywoÅ‚any ze Å›cieżkÄ… do tymczasowego pliku png jako pojedynczym argumentem. Browse PrzeglÄ…daj Script Uploader PrzesyÅ‚anie z użyciem skryptu Select Upload Script Wybierz skrypt do przesÅ‚ania Stop when upload script writes to StdErr Zatrzymaj skrypt i użyj stderr, aby zapisać wszystkie komunikaty o błędach Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Oznacza przesyÅ‚anie jako zakoÅ„czone niepowodzeniem, gdy skrypt zapisuje do StdErr. Bez tego ustawienia błędy w skrypcie pozostanÄ… niezauważone. Filter: Filtr: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Wyrażenie RegEx. Kopiuj do schowka tylko to, co pasuje do wyrażenia RegEx. W przypadku pominiÄ™cia wszystko jest kopiowane. SettingsDialog Settings Ustawienia OK OK Cancel Anuluj Image Grabber Przechwyć obraz Imgur Uploader PrzeÅ›lij do Imgur Application Aplikacja Annotator Adnotacje HotKeys Skróty klawiszowe Uploader PrzesyÅ‚anie Script Uploader PrzesyÅ‚anie z użyciem skryptu Saver Zapisywanie Stickers Naklejki Snipping Area Obszar wycinania Tray Icon Ikona w zasobniku Watermark Znak wodny Actions DziaÅ‚ania FTP Uploader PrzeÅ›lij protokoÅ‚em FTP Plugins Wtyczki Search Settings... Ustawienia wyszukiwania... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ponownie wybierz rozmiar wybranego prostokÄ…ta za pomocÄ… uchwytów lub przesuÅ„ go, przeciÄ…gajÄ…c zaznaczenie. Use arrow keys to move the selection. Użyj klawiszy strzaÅ‚ek, aby przesunąć zaznaczenie. Use arrow keys while pressing CTRL to move top left handle. Użyj klawiszy strzaÅ‚ek, naciskajÄ…c klawisz CTRL, aby przesunąć lewy górny uchwyt. Use arrow keys while pressing ALT to move bottom right handle. Użyj klawiszy strzaÅ‚ek, jednoczeÅ›nie naciskajÄ…c ALT, aby przesunąć prawy dolny uchwyt. This message can be disabled via settings. Ten komunikat można wyłączyć w ustawieniach. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Potwierdź wybór, naciskajÄ…c ENTER/RETURN lub klikajÄ…c dwukrotnie myszkÄ… w dowolnym miejscu. Abort by pressing ESC. Przerwij, naciskajÄ…c ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Kliknij i przeciÄ…gnij, aby wybrać prostokÄ…tny obszar, lub naciÅ›nij klawisz ESC, aby zakoÅ„czyć pracÄ™. Hold CTRL pressed to resize selection after selecting. Przytrzymaj wciÅ›niÄ™ty klawisz CTRL, aby zmienić rozmiar zaznaczenia po wybraniu. Hold CTRL pressed to prevent resizing after selecting. Przytrzymaj wciÅ›niÄ™ty klawisz CTRL, aby zapobiec zmianie rozmiaru po wybraniu. Operation will be canceled after 60 sec when no selection made. Operacja zostanie anulowana po 60 sekundach, gdy żaden wybór nie zostanie dokonany. This message can be disabled via settings. Ten komunikat można wyłączyć w ustawieniach. SnippingAreaSettings Freeze Image while snipping Zablokuj obraz podczas wycinania When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Po włączeniu tej opcji zamraża tÅ‚o, podczas wybierania prostokÄ…tnego obszaru. Zmienia również zachowanie opóźnionych zrzutów ekranu, z tym że przy opcji włączonej opóźnienie nastÄ™puje przed wyÅ›wietleniem obszaru wycinania, a z opcjÄ… wyłączonÄ… opóźnienie nastÄ™puje po wyÅ›wietleniu obszaru wycinania. Ta funkcja jest zawsze wyłączona dla Wayland i zawsze włączone dla MacOs. Show magnifying glass on snipping area Pokaż lupÄ™ w obszarze wycinania Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. WyÅ›wietla lupÄ™, która pozwala powiÄ™kszyć obraz tÅ‚a. Ta opcja dziaÅ‚a tylko z włączonÄ… funkcjÄ… "Zamrażaj obraz podczas przycinania". Show Snipping Area rulers Pokaż linijki obszaru wycinania Horizontal and vertical lines going from desktop edges to cursor on snipping area. Linie poziome i pionowe przechodzÄ…ce od krawÄ™dzi pulpitu do kursora w obszarze wycinania. Show Snipping Area position and size info Pokaż poÅ‚ożenie i rozmiar obszaru wycinania When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Gdy lewy przycisk myszy nie jest wciÅ›niÄ™ty pozycja jest wyÅ›wietlana, po naciÅ›niÄ™ciu przycisku myszy wielkość wybranego obszaru jest wyÅ›wietlana po lewej stronie i powyżej przechwyconego obszaru. Allow resizing rect area selection by default DomyÅ›lnie zezwalaj na zmianÄ™ rozmiaru zaznaczenia obszaru prostokÄ…tnego When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Po włączeniu tej opcji, po zaznaczeniu prostokÄ…tnego obszaru, pozwoli na zmianÄ™ rozmiaru zaznaczenia. Po zakoÅ„czeniu zmiany rozmiaru można potwierdzić wybór naciskajÄ…c wstecz. Show Snipping Area info text Pokaż tekst informacyjny o obszarze wycinania Snipping Area cursor color Kolor kursora obszaru wycinania Sets the color of the snipping area cursor. Ustawia kolor kursora obszaru wycinania. Snipping Area cursor thickness Grubość kursora obszaru wycinania Sets the thickness of the snipping area cursor. Ustawia grubość kursora obszaru wycinania. Snipping Area Obszar wycinania Snipping Area adorner color Ozdobny kolor obszaru przechwytywania Sets the color of all adorner elements on the snipping area. Ustawia kolor wszystkich elementów ozdobnych w obszarze wycinania. Snipping Area Transparency Przezroczystość obszaru wycinania Alpha for not selected region on snipping area. Smaller number is more transparent. Przezroczystość nie wybranego regionu w obszarze wycinania. Im mniejsza liczba, tym obszar bardziej przezroczysty. Enable Snipping Area offset Włącz przesuniÄ™cie obszaru wycinania When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Po włączeniu zostanie zastosowane skonfigurowane przesuniÄ™cie do pozycji Obszar wycinania, który jest wymagany, gdy pozycja nie jest poprawnie obliczona. Czasami jest to wymagane przy włączonym skalowaniu ekranu. X X Y Y StickerSettings Up PrzesuÅ„ w górÄ™ Down PrzesuÅ„ w dół Use Default Stickers Użyj domyÅ›lnych naklejek Sticker Settings Ustawienia naklejek Vector Image Files (*.svg) Pliki obrazu wektorowego (*.svg) Add Dodaj Remove UsuÅ„ Add Stickers Dodaj naklejkÄ™ TrayIcon Show Editor Pokaż edytor TrayIconSettings Use Tray Icon Użyj ikony z zasobnika When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Po włączeniu doda ikonÄ™ do zasobnika paska zadaÅ„, jeÅ›li obsÅ‚uguje go Menedżer okien systemu operacyjnego. Zmiana wymaga ponownego uruchomienia. Minimize to Tray Minimalizuj do zasobnika Start Minimized to Tray Uruchom zminimalizowany do zasobnika Close to Tray Zamknij do zasobnika Show Editor Pokaż Edytor Capture Zrzut ekranu Default Tray Icon action DomyÅ›lna akcja ikony zasobnika Default Action that is triggered by left clicking the tray icon. DomyÅ›lna Akcja, która jest uruchamiana przez klikniÄ™cie lewym przyciskiem myszy ikony zasobnika. Tray Icon Settings Ustawienia ikony zasobnika Use platform specific notification service Skorzystaj z usÅ‚ugi powiadomieÅ„ specyficznej dla platformy When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Gdy włączone, bÄ™dzie próbowaÅ‚ używać powiadomieÅ„ specyficznych dla platformy jeÅ›li taka istnieje. Zmiana wymaga ponownego uruchomienia, aby zaczęła obowiÄ…zywać. Display Tray Icon notifications WyÅ›wietl ikony powiadomieÅ„ w zasobniku UpdateWatermarkOperation Select Image Wybierz obraz Image Files Pliki obrazów UploadOperation Upload Script Required Wymagany skrypt do przesÅ‚ania Please add an upload script via Options > Settings > Upload Script Aby przesÅ‚ać wykorzystujÄ…c skrypt należy wybrać Opcje > Ustawienia > PrzesyÅ‚anie z użyciem skryptu Capture Upload PrzeÅ›lij zrzut You are about to upload the image to an external destination, do you want to proceed? Masz zamiar przesÅ‚ać obraz do zewnÄ™trznego miejsca docelowego, chcesz kontynuować? UploaderSettings Ask for confirmation before uploading PoproÅ› o potwierdzenie przed przesÅ‚aniem Uploader Type: Typ przesyÅ‚ania: Imgur Imgur Script Skrypt Uploader PrzesyÅ‚anie FTP FTP VersionTab Version Wersja Build Kompilacja Using: Z użyciem: WatermarkSettings Watermark Image Obraz znaku wodnego Update Aktualizuj Rotate Watermark Obróć znak wodny When enabled, Watermark will be added with a rotation of 45° Po włączeniu tej funkcji znak wodny zostanie dodany z obróceniem o 45 ° Watermark Settings Ustawienia znaku wodnego ksnip-master/translations/ksnip_pt.ts000066400000000000000000002043411457262621600204320ustar00rootroot00000000000000 AboutDialog About Sobre About Sobre Version Versão Author Autor Close Fechar Donate Doar Contact Contacto AboutTab License: Licença: Screenshot and Annotation Tool Ferramenta de Captura de Imagem e Edição ActionSettingTab Name Nome Shortcut Atalho Clear Apagar Take Capture Fazer Captura Include Cursor Incluir Cursor Delay Atraso s The small letter s stands for seconds. s Capture Mode Modo de Captura Show image in Pin Window Mostrar imagem na janela de pinada Copy image to Clipboard Copiar imagem para a área de transferência Upload image Enviar Imagem Open image parent directory Abrir o diretório da imagem Save image Salvar imagem Hide Main Window Esconder Janela Principal Global Global When enabled will make the shortcut available even when ksnip has no focus. Quando ativado fará o atalho disponível mesmo quando ksnip não tem o foco. ActionsSettings Add Adicionar Actions Settings Configurações de Ações Action Ação AddWatermarkOperation Watermark Image Required Imagem para marca d'água é necessária Please add a Watermark Image via Options > Settings > Annotator > Update Adicione uma imagem de marca d'água em: Opções > Configurações > Editor > Selecionar AnnotationSettings Smooth Painter Paths Suavizar Traços When enabled smooths out pen and marker paths after finished drawing. Quando ativado, suaviza a caneta e o marcador após finalizar o desenho. Smooth Factor Fator de suavização Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Incrementar o fator de suavização diminuirá a precisão da caneta e do marcador, mas irá torná-los mais suaves. Annotator Settings Configurações do Editor Remember annotation tool selection and load on startup Lembre-se da ferramenta selecionada e carregue na inicialização Switch to Select Tool after drawing Item Mudar para ferramenta de seleção após desenhar o item Number Tool Seed change updates all Number Items Mudança na Ferramenta atualiza todos os itens número Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Desativar esta opção causa mudanças na ferramenta número para afetar apenas novos itens, mas não os itens existentes. Desativar esta opção permite ter números duplicados. Canvas Color Cor de fundo do ecrã Default Canvas background color for annotation area. Changing color affects only new annotation areas. Cor de fundo padrão do ecrã para a área de anotação. Alterar a cor afeta apenas novas áreas de anotação. Select Item after drawing Escolher o item após desenhar With this option enabled the item gets selected after being created, allowing changing settings. Com esta opção ativa, o item fica selecionado após ser criado, permitindo alterar as configurações. Show Controls Widget Mostrar widget de controles The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Capturar ecrã ao iniciar, usando o modo por omissão Application Style Estilo da Aplicação Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Define o estilo da aplicação que determina a aparência da interface gráfica. Requer reiniciar o ksnip para aplicar as mudanças. Application Settings Configurações da Aplicação Automatically copy new captures to clipboard Automaticamente copiar novas capturas para a área de transferência Use Tabs Usar Abas Change requires restart. A mudança requer reinicialização. Run ksnip as single instance Executar o ksnip como instância única Hide Tabbar when only one Tab is used. Ocultar barra de abas quando apenas uma guia for usada. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Ativar esta opção permitirá que apenas uma instância do ksnip funcione, todas as outras instâncias iniciadas após a primeira passarão os argumentos dele para a primeira e fechar. Alterar esta opção requer um novo início de todas as instâncias. Remember Main Window position on move and load on startup Lembre-se da posição da janela principal ao mover e carregar na inicialização Auto hide Tabs Ocultar abas automaticamente Auto hide Docks Auto ocultar Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Na inicialização, oculte as configurações de barra de ferramentas e anotações. A visibilidade das Docks pode ser alternada com a tecla Tab. Auto resize to content Redimensionar automaticamente para o conteúdo Automatically resize Main Window to fit content image. Redimensionar automaticamente a janela principal para se ajustar a imagem. Enable Debugging Ativar depuração Enables debug output written to the console. Change requires ksnip restart to take effect. Ativa a saída de depuração gravada no console. A mudança requer o reinício do ksnip para ter efeito. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Atraso para redimensionar conteúdo permite que o gestor de janelas receba um novo conteúdo, caso a janela principal não esteja ajustada corretamente ao novo conteúdo, aumentar esse atraso pode melhorar o comportamento. Resize delay Temp Directory Diretório temporário Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse Selecionar AuthorTab Contributors: Contribuidores: Spanish Translation Tradução para Espanhol Dutch Translation Tradução para Holandês Russian Translation Tradução para Russo Norwegian BokmÃ¥l Translation Tradução para Norueguês BokmÃ¥l French Translation Tradução para Francês Polish Translation Tradução para Polonês Snap & Flatpak Support Suporte a Snap e Flatpak The Authors: Autores: CanDiscardOperation Warning - Aviso - The capture %1%2%3 has been modified. Do you want to save it? A captura %1%2%3 foi modificada. Deseja salvá-la? CaptureModePicker New Novo Draw a rectangular area with your mouse Desenhar uma área retangular com o rato Capture full screen including all monitors Capturar ecrã inteiro incluindo todos os monitores Capture screen where the mouse is located Capturar o ecrã onde o rato está localizado Capture window that currently has focus Capturar a janela que atualmente está com o foco Capture that is currently under the mouse cursor Capturar o que está atualmente sob o cursor do rato Capture a screenshot of the last selected rectangular area Realizar uma captura de ecrã da última área retangular selecionada Uses the screenshot Portal for taking screenshot Usar o portal de captura de ecrã para fazer a captura do ecrã ContactTab Community Comunidade Bug Reports Registo de Problemas If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Se tiver dúvidas gerais, idéias ou apenas quiser falar sobre o ksnip, <br/> por favor entre em nosso servidor% 1 ou% 2. Please use %1 to report bugs. Por favor, use %1 para relatar bugs. CopyAsDataUriOperation Failed to copy to clipboard Falha ao copiar para a área de transferência Failed to copy to clipboard as base64 encoded image. Falha ao copiar para a área de transferência como imagem codificada em base64. Copied to clipboard Copiado para a área de transferência Copied to clipboard as base64 encoded image. Copiado para a área de transferência como imagem codificada em base64. DeleteImageOperation Delete Image Apagar imagem The item '%1' will be deleted. Do you want to continue? O item '%1' será apagado. Deseja continuar? DonateTab Donations are always welcome Doações são sempre bem-vindas Donation Doação ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip é um projeto de software copyleft livre sem fins lucrativos e <br/> ainda tem alguns custos que precisam ser cobertos, <br/> como custos de domínio ou custos de hardware para suporte de plataforma cruzada. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Se quiser ajudar ou apenas apreciar o trabalho que está sendo feito <br/> oferecendo uma cerveja ou café aos programadores, pode fazer isso% 1aqui% 2. Become a GitHub Sponsor? Tornar-se um patrocinador do GitHub? Also possible, %1here%2. Também é possível, %1aqui%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Adicionar novas ações a pressionar o botão da guia 'Adicionar'. EnumTranslator Rectangular Area Ãrea retangular Last Rectangular Area Última Ãrea Retangular Full Screen (All Monitors) Ecrã cheio (Todos os monitores) Current Screen Ecrã atual Active Window Janela Ativa Window Under Cursor Janela Sob o Cursor Screenshot Portal Portal de captura do ecrã FtpUploaderSettings Force anonymous upload. Forçar envio anônimo. Url Url Username Nome de utilizador Password Palavra-passe FTP Uploader Enviador FTP HandleUploadResultOperation Upload Successful Upload bem sucedido Unable to save temporary image for upload. Não foi possível salvar a imagem temporária para upload. Unable to start process, check path and permissions. Não foi possível iniciar o processo, verifique o caminho e as permissões. Process crashed Processo travado Process timed out. O tempo limite do processo expirou. Process read error. Erro no processo de leitura. Process write error. Erro no processo de gravação. Web error, check console output. Erro na Web, verifique a saída do console. Upload Failed Falha no upload Script wrote to StdErr. Script escrito para StdErr. FTP Upload finished successfully. FTP Envio concluído com sucesso. Unknown error. Erro desconhecido. Connection Error. Erro de conexão. Permission Error. Erro de permissão. Upload script %1 finished successfully. O script de envio %1 foi concluído com sucesso. Uploaded to %1 Enviado para %1 HotKeySettings Enable Global HotKeys Ativar as teclas de atalho globais Capture Rect Area Captura de Ãrea retangular Capture Full Screen Captura do ecrã cheio Capture current Screen Captura do ecrã atual Capture active Window Captura da Janela ativa Capture Window under Cursor Captura da Janela sob o rato Global HotKeys Teclas de Atalho Globais Capture Last Rect Area Captura da Última área retangular Clear Apagar Capture using Portal Capturar utilizando Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. As HotKeys são atualmente suportadas apenas em Windows e X11. Desativar esta opção também faz com que os atalhos de ação sejam apenas ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Capturar o cursor do rato na captura de ecrã Should mouse cursor be visible on screenshots. O cursor do rato estará visível nas capturas de ecrã. Image Grabber Captura de Imagem Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Implementações genéricas do Wayland que utilizam o XDG-DESKTOP-PORTAL lidam com o dimensionamento do ecrã de forma diferente. Ativar esta opção irá determinar a escala atual do ecrã e aplicar isso à captura do ecrã no ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME e KDE Plasma suportam as próprias capturas do ecrã do Wayland e Generic XDG-DESKTOP-PORTAL. Ativar esta opção irá forçar o KDE Plasma e o GNOME a usar as capturas do XDG-DESKTOP-PORTAL. A alteração desta opção exige que o ksnip seja reiniciado. Show Main Window after capturing screenshot Exibir janela principal após capturar o ecrã Hide Main Window during screenshot Ocultar a janela principal durante a captura do ecrã Hide Main Window when capturing a new screenshot. Ocultar a janela principal ao capturar uma nova imagem. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Mostrar a Janela Principal após uma nova captura quando a Janela Principal foi escondida ou minimizada. Force Generic Wayland (xdg-desktop-portal) Screenshot Forçar Wayland genérico (xdg-desktop-portal) capturar de ecrã Scale Generic Wayland (xdg-desktop-portal) Screenshots Escalar Wayland genérico (xdg-desktop-portal) para capturas de ecrã Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Histórico do Imgur Close Fechar Time Stamp Registro de Data e Hora Link Link Delete Link Apagar Link ImgurUploader Upload to imgur.com finished! Upload para imgur.com concluído! Received new token, trying upload again… Novo token recebido , tentando fazer o upload novamente… Imgur token has expired, requesting new token… O token Imgur expirou, solicitando novo token… ImgurUploaderSettings Force anonymous upload Forçar upload anônimo Always copy Imgur link to clipboard Sempre copiar o link Imgur para a área de transferência Client ID Client ID Client Secret Segredo do cliente PIN PIN Enter imgur Pin which will be exchanged for a token. Digite imgur Pin, que será trocado por um token. Get PIN Obter PIN Get Token Obter Token Imgur History Histórico do Imgur Imgur Uploader Histórico do Imgur Username Nome de utilizador Imgur.com token successfully updated. Token Imgur.com atualizado com sucesso. Imgur.com token update error. Erro na atualização do token Imgur.com. Waiting for imgur.com… Aguardando imgur.com… After uploading open Imgur link in default browser Depois do upload, abrir link do Imgur no navegador padrão Link directly to image Link direto para a imagem Base Url: Url base: Base url that will be used for communication with Imgur. Changing requires restart. Url base que será usado para comunicação com Imgur. Mudança requer reinicialização. Clear Token Limpar Token Upload title: Ficheiro do envio Upload description: Descrição do envio LoadImageFromFileOperation Unable to open image Incapaz de abrir a imagem Unable to open image from path %1 Incapaz de abrir a imagem do caminho %1 MainToolBar New Novo Delay in seconds between triggering and capturing screenshot. Atraso em segundos entre o acionamento e captura de ecrã. s The small letter s stands for seconds. s Save Salvar Save Screen Capture to file system Gravar captura de ecrã para o sistema de ficheiros Copy Copiar Copy Screen Capture to clipboard Copiar captura de ecrã para a área de transferência Tools Ferramentas Undo Desfazer Redo Refazer Crop Recortar Crop Screen Capture Recortar captura de ecrã MainWindow Unsaved Não salvo Upload Upload Print Imprimir Opens printer dialog and provide option to print image Abrir caixa de diálogo da impressão e fornecer as opções de impressão Print Preview Visualizar impressão Opens Print Preview dialog where the image orientation can be changed Abrir caixa de diálogo Visualizar impressão, onde a orientação da imagem pode ser alterada Scale Redimensionar Quit Sair Settings Configurações &About &Sobre Open Abrir &Edit &Editar &Options &Opções &Help Aj&uda Add Watermark Adicionar marca d'água Add Watermark to captured image. Multiple watermarks can be added. Adicionar marca d'água à imagem capturada. Várias marcas d'água podem ser adicionadas. &File &Arquivo Unable to show image Não foi possível exibir a imagem Save As... Salvar como... Paste Colar Paste Embedded Colar incorporado Pin Fixar Pin screenshot to foreground in frameless window Fixar captura de ecrã em primeiro plano na janela sem moldura No image provided but one was expected. Nenhuma imagem fornecida, mas uma era esperada. Copy Path Copiar caminho Open Directory Abrir diretório &View &Exibir Delete Apagar Rename Renomear Open Images Abrir Imagens Show Docks Exibir Docks Hide Docks Ocultar Docks Copy as data URI Copiar como URI de dados Open &Recent Aberto &Recente Modify Canvas Modificar fundo do ecrã Upload triggerCapture to external source Carregar triggerCapture para fonte externa Copy triggerCapture to system clipboard Copiar o triggerCaptura para a área de transferência do sistema Scale Image Escala de Imagem Rotate Rotacionar Rotate Image Rotacionar Imagem Actions Ações Image Files Ficheiros de imagem Save All Gravar tudo Close Window Fechar janela Cut Cortar OCR MultiCaptureHandler Save Salvar Save As Salvar como Open Directory Abrir Diretório Copy Copiar Copy Path Copiar caminho Delete Apagar Rename Renomear Save All Gravar tudo NewCaptureNameProvider Capture Imagem OcrWindowCreator OCR Window %1 PinWindow Close Fechar Close Other Fechar Outros Close All Fechar Todos PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Padrão The directory where the plugins are located. Browse Selecionar Name Nome Version Versão Detect Detetar Plugin Settings Preferências de Plug-in Plugin location ProcessIndicator Processing A processar RenameOperation Image Renamed Imagem Renomeada Image Rename Failed Falhou ao renomear imagem Rename image Renomear imagem New filename: Novo nome do ficheiro: Successfully renamed image to %1 Imagem renomeada com sucesso para %1 Failed to rename image to %1 Falha ao mudar o nome da imagem para %1 SaveOperation Save As Salvar como All Files Todos os ficheiros Image Saved Imagem salva Saving Image Failed Falha ao salvar imagem Image Files Ficheiros de imagem Saved to %1 Salvo em %1 Failed to save image to %1 Falha ao gravar a imagem em %1 SaverSettings Automatically save new captures to default location Automaticamente salvar novas capturas para o diretório padrão Prompt to save before discarding unsaved changes Avisar para salvar antes de descartar um trabalho não salvo Remember last Save Directory Lembrar o último diretório onde os arquivos foram salvos When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Quando ativado, substituirá o diretório de "salvamento" armazenado nas configurações para o diretório mais recente onde foi salvo, isso para cada vez que usar o comando salvar. Capture save location and filename Local e nome do ficheiro para gravar a captura Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Os formatos suportados são JPG, PNG e BMP. Se nenhum formato for fornecido, o PNG será usado como padrão. O nome do arquivo pode conter os seguintes curingas: - $Y, $M, $D para data, $h, $m, $s para hora ou $T para hora no formato hhmmss. - # múltiplos consecutivos para contador. #### resultará em 0001, a próxima captura será 0002. Browse Selecionar Saver Settings Configurações para Salvar arquivos Capture save location Local para salvar a captura Default Padrão Factor Fator Save Quality Qualidade para salvar Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Indique 0 para obter pequenos ficheiros compactados, 100 para grandes ficheiros não compactados. Nem todos os formatos de imagem têm suporte a todos os intervalos, o JPEG suporta. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Copiar saída do script para a área de transferência Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Caminho para o script que será chamado para upload. Durante o upload, o script será chamado com o caminho para um ficheiro png temporário como um único argumento. Browse Selecionar Script Uploader Script de Uploader Select Upload Script Selecione o Script para Upload Stop when upload script writes to StdErr Parar quando o script de upload é gravado no StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Marca o upload como malsucedido quando o script grava no StdErr. Sem essa configuração, os erros no script não serão notados. Filter: Filtro: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Expressão RegEx. Apenas copie para a área de transferência aquilo que corresponda à expressão RegEx. Quando omitido, tudo é copiado. SettingsDialog Settings Configurações OK OK Cancel Cancelar Application Aplicação Image Grabber Captura de Imagem Imgur Uploader Serviço Imgur Annotator Editor HotKeys Teclas de Atalho Uploader Enviador Script Uploader Script de Uploader Saver Salvar Stickers Adesivos Snipping Area Ãrea Retangular Tray Icon Ãcone da bandeja Watermark Marca d'água Actions Ações FTP Uploader Enviador de FTP Plugins Plug-ins Search Settings... Buscar Preferências... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Redimensione o retângulo selecionado a usar as alças ou mova-o a arrastar a seleção. Use arrow keys to move the selection. Use as setas para mover a seleção. Use arrow keys while pressing CTRL to move top left handle. Use as seta enquanto pressiona CTRL para mover a alça superior esquerda. Use arrow keys while pressing ALT to move bottom right handle. Use as teclas de seta enquanto pressiona ALT para mover a alça inferior direita. This message can be disabled via settings. Esta mensagem pode ser desativada nas configurações. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. Cancelar ao pressionar ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Clique e arraste para selecionar uma área retangular ou pressione ESC para sair. Hold CTRL pressed to resize selection after selecting. Mantenha CTRL pressionado para redimensionar a seleção após selecionar. Hold CTRL pressed to prevent resizing after selecting. Mantenha CTRL pressionado para evitar o redimensionamento após selecionar. Operation will be canceled after 60 sec when no selection made. A operação será cancelada após 60 segundos quando nenhuma seleção for feita. This message can be disabled via settings. Esta mensagem pode ser desativada nas configurações. SnippingAreaSettings Freeze Image while snipping Congelar imagem ao capturar área retangular When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Quando ativado irá congelar o fundo enquanto a selecionar uma área retangular. Também muda o comportamento de capturas do ecrã atrasadas, com esta opção ativada o atraso acontece antes da área retangular ser exibida e com a opção desativada o atraso acontece depois que a área retangular é exibida. Este recurso está sempre desativado para Wayland e sempre ativado para MacOs. Show magnifying glass on snipping area Exibir lupa ao capturar área retangular Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Exibir uma lupa que mostra zoom na imagem de fundo. Esta opção só funciona com 'Congelar imagem ao capturar área retangular' ativada. Show Snipping Area rulers Exibir réguas ao capturar área retangular Horizontal and vertical lines going from desktop edges to cursor on snipping area. Uma linha horizontal e vertical será exibida antes de iniciar a captura de uma área retangular. Show Snipping Area position and size info Exibir posição e tamanho ao capturar área retangular When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Quando o botão esquerdo do rato não é pressionado a posição é exibida, quando o botão do rato é pressionado, o tamanho da área selecionada é exibido à esquerda e acima da área capturada. Allow resizing rect area selection by default Permitir redimensionamento da seleção da área retangular por padrão When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Quando ativado, após selecionar uma área retangular, permite redimensionar a seleção. Quando realizado o redimensionamento a seleção pode ser confirmada a pressionar Enter. Show Snipping Area info text Mostrar texto de informação para área retangular Snipping Area cursor color Cor do cursor ao capturar área retangular Sets the color of the snipping area cursor. Define a cor do cursor da área retangular. Snipping Area cursor thickness Espessura do cursor ao capturar área retangular Sets the thickness of the snipping area cursor. Define a espessura do cursor da área retangular. Snipping Area Ãrea Retangular Snipping Area adorner color Cor das bordas da área de recorte Sets the color of all adorner elements on the snipping area. Define a cor de todos as bordas na área de retangular. Snipping Area Transparency Transparência da área retangular Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa para região não selecionada na área retangular. O número menor é mais transparente. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X X Y Z StickerSettings Up Subir Down Descer Use Default Stickers Usar adesivos padrão Sticker Settings Configurações de Adesivos Vector Image Files (*.svg) Ficheiros de imagem vetorial (*.svg) Add Adicionar Remove Remover Add Stickers Adicionar adesivos TrayIcon Show Editor Exibir Editor TrayIconSettings Use Tray Icon Usar ícone da bandeja When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Quando ativado, adiciona um ícone de bandeja na barra de tarefas, se o gestor de janelas do SO oferecer suporte. A mudança requer reinicialização. Minimize to Tray Minimizar para a Bandeja Start Minimized to Tray Iniciar Minimizado na Bandeja Close to Tray Fechar para a Bandeja Show Editor Exibir Editor Capture Capturar Default Tray Icon action Ação padrão do ícone da bandeja Default Action that is triggered by left clicking the tray icon. Ação padrão que é disparada a clicar com o botão esquerdo do rato no ícone da bandeja. Tray Icon Settings Configurações do ícone da bandeja Use platform specific notification service Usar o serviço de notificação específico da plataforma When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Quando ativado, tentará usar o serviço de notificação específico da plataforma, quando tal existir. A mudança requer reinicialização para ter efeito. Display Tray Icon notifications Exibir notificações do ícone da bandeja UpdateWatermarkOperation Select Image Selecione uma imagem Image Files Ficheiros de imagem UploadOperation Upload Script Required Script de Upload Requerido Please add an upload script via Options > Settings > Upload Script Adicione um script de upload em Opções> Configurações> Script de Uploader Capture Upload Capturar Upload You are about to upload the image to an external destination, do you want to proceed? Você está prestes a enviar a imagem para um destino externo. Deseja continuar? UploaderSettings Ask for confirmation before uploading Confirmar antes de fazer o upload Uploader Type: Tipo de Uploader: Imgur Imgur Script Script Uploader Enviador FTP FTP VersionTab Version Versão Build Compilação Using: Utilizando: WatermarkSettings Watermark Image Imagem de marca d'água Update Atualizar Rotate Watermark Girar marca d'água When enabled, Watermark will be added with a rotation of 45° Quando ativado, a marca d'água será adicionada com rotação de 45º Watermark Settings Configurações de Marca d'água ksnip-master/translations/ksnip_pt_BR.ts000066400000000000000000001723721457262621600210250ustar00rootroot00000000000000 AboutDialog About Sobre About Sobre Version Versão Author Autor Close Fechar Donate Doar Contact Contato AboutTab License: Licença: Screenshot and Annotation Tool Ferramenta de captura de tela e anotação ActionSettingTab Name Nome Shortcut Atalho Clear Limpar Take Capture Fazer Captura Include Cursor Incluir Cursor Delay Atraso s The small letter s stands for seconds. s Capture Mode Modo de Captura Show image in Pin Window Mostrar imagem na janela de pinada Copy image to Clipboard Copiar imagem para a área de transferência Upload image Enviar Imagem Open image parent directory Abrir o diretório da imagem Save image Salvar imagem Hide Main Window Ocultar Janela Principal ActionsSettings Add Adicionar Actions Settings Configurações de Ações Action Ação AddWatermarkOperation Watermark Image Required Marca d'água Obrigatória Please add a Watermark Image via Options > Settings > Annotator > Update Por favor, adicione uma marca d'água em: Opções > Configurações > Editor > Atualizar AnnotationSettings Smooth Painter Paths Suavizar Traços When enabled smooths out pen and marker paths after finished drawing. Quando ativado, suaviza a caneta e o marcador após finalizar o desenho. Smooth Factor Fator de Suavização Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Incrementar o fator de suavização diminuirá a precisão da caneta e do marcador, mas irá torná-los mais suaves. Annotator Settings Configurações do Editor Remember annotation tool selection and load on startup Lembrar da ferramenta de anotação selecionada e carregue na inicialização Switch to Select Tool after drawing Item Mudar para ferramenta de seleção após desenhar o item Number Tool Seed change updates all Number Items Mudança na Ferramenta atualiza todos os itens número Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Desativar esta opção causa mudanças na ferramenta número para afetar apenas novos itens, mas não os itens existentes. Desativar esta opção permite ter números duplicados. Canvas Color Cor de fundo da Tela Default Canvas background color for annotation area. Changing color affects only new annotation areas. Cor de fundo padrão da tela para a área de anotação. Alterar a cor afeta apenas novas áreas de anotação. Select Item after drawing Selecione o item após o desenho With this option enabled the item gets selected after being created, allowing changing settings. Com esta opção habilitada, o item é selecionado após ter sido criado, permitindo a alteração de configurações. ApplicationSettings Capture screenshot at startup with default mode Capturar a tela ao iniciar utilizando o modo padrão de captura Application Style Estilo da Aplicação Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Define o estilo da aplicação que determina a aparência da interface gráfica. Requer reiniciar o ksnip para aplicar as mudanças. Application Settings Configurações da Aplicação Automatically copy new captures to clipboard Automaticamente copiar novas capturas para a área de transferência Use Tabs Usar Abas Change requires restart. A mudança requer reinicialização. Run ksnip as single instance Executar o ksnip como instância única Remember Main Window position on move and load on startup Lembrar da posição da janela principal ao mover e carregar na inicialização Hide Tabbar when only one Tab is used. Ocultar a barra de abas quando apenas uma aba for usada. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Ativar esta opção permitirá que apenas uma instância do ksnip funcione, todas as outras instâncias iniciadas após a primeira passarão seus argumentos para a primeira e fechar. Alterar esta opção requer um novo início de todas as instâncias. Auto hide Tabs Ocultar abas automaticamente Auto hide Docks Auto ocultar Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Na inicialização, oculte as configurações de barra de ferramentas e anotações. A visibilidade das Docks pode ser alternada com a tecla Tab. Auto resize to content Redimensionar automaticamente para o conteúdo Automatically resize Main Window to fit content image. Redimensionar automaticamente a janela principal para se ajustar a imagem. Enable Debugging Habilitar depuração Enables debug output written to the console. Change requires ksnip restart to take effect. Ativa a saída de depuração gravada no console. A mudança requer o reinício do ksnip para ter efeito. Resize to content delay Atraso para redimensionar conteúdo Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Atraso para redimensionar conteúdo permite que o gerenciador de janelas receba um novo conteúdo, caso a janela principal não esteja ajustada corretamente ao novo conteúdo, aumentar esse atraso pode melhorar o comportamento. AuthorTab Contributors: Contribuidores: Spanish Translation Tradução para Espanhol Dutch Translation Tradução para Holandês Russian Translation Tradução para Russo Norwegian BokmÃ¥l Translation Tradução para Norueguês BokmÃ¥l French Translation Tradução para Francês Polish Translation Tradução para Polonês The Authors: Autores: Snap & Flatpak Support Suporte para Snap e Flatpak CanDiscardOperation Warning - Aviso - The capture %1%2%3 has been modified. Do you want to save it? A captura %1%2%3 foi modificada. Deseja salvá-la? CaptureModePicker New Novo Draw a rectangular area with your mouse Desenhar uma área retangular com o mouse Capture full screen including all monitors Capturar tela inteira incluindo todos os monitores Capture screen where the mouse is located Capturar a tela onde o mouse está localizado Capture window that currently has focus Capturar a janela em foco Capture that is currently under the mouse cursor Capturar o que está sob o cursor do mouse Capture a screenshot of the last selected rectangular area Realizar uma captura de tela da última área retangular selecionada Uses the screenshot Portal for taking screenshot Usa o portal de captura de tela para obter a imagem ContactTab Community Comunidade Bug Reports Relatório de erros If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Se você tiver dúvidas gerais, idéias ou apenas quiser falar sobre o ksnip, <br/> por favor entre em nosso servidor %1 ou %2. Please use %1 to report bugs. Por favor, use %1 para relatar bugs. CopyAsDataUriOperation Failed to copy to clipboard Falha ao copiar para a área de transferência Failed to copy to clipboard as base64 encoded image. Falha ao copiar para a área de transferência como imagem codificada em base64. Copied to clipboard Copiado para a área de transferência Copied to clipboard as base64 encoded image. Copiado para a área de transferência como imagem codificada em base64. DeleteImageOperation Delete Image Excluir imagem The item '%1' will be deleted. Do you want to continue? O item '%1' será excluído. Deseja continuar? DonateTab Donations are always welcome Doações são sempre bem-vindas Donation Doação ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip é um projeto de software copyleft livre sem fins lucrativos, e <br/> ainda tem alguns custos que precisam ser cobertos, <br/> como custos de domínio ou custos de hardware para suporte de plataforma cruzada. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Se você quiser ajudar ou apenas apreciar o trabalho que está sendo feito <br/> oferecendo uma cerveja ou café aos desenvolvedores, você pode fazer isso% 1aqui% 2. Become a GitHub Sponsor? Tornar-se um patrocinador do GitHub? Also possible, %1here%2. Também é possível, %1aqui%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Adicionar novas ações pressionando o botão da guia 'Adicionar'. EnumTranslator Rectangular Area Ãrea retangular Last Rectangular Area Última Ãrea Retangular Full Screen (All Monitors) Tela cheia (Todos os monitores) Current Screen Tela atual Active Window Janela Ativa Window Under Cursor Janela Sob o Cursor Screenshot Portal Portal de captura de tela FtpUploaderSettings Force anonymous upload. Forçar upload anônimo. Url Url Username Nome de usuário Password Senha FTP Uploader Uploader FTP HandleUploadResultOperation Upload Successful Enviado com Sucesso Unable to save temporary image for upload. Não foi possível salvar a imagem temporária para envio. Unable to start process, check path and permissions. Não foi possível iniciar o processo, verifique o caminho e as permissões. Process crashed Processo travado Process timed out. O tempo limite do processo expirou. Process read error. Erro no processo de leitura. Process write error. Erro no processo de gravação. Web error, check console output. Erro na Web, verifique a saída do console. Upload Failed Falha no envio Script wrote to StdErr. Script escrito para StdErr. FTP Upload finished successfully. FTP Upload concluído com sucesso. Unknown error. Erro desconhecido. Connection Error. Erro de conexão. Permission Error. Erro de permissão. Upload script %1 finished successfully. O script de upload% 1 foi concluído com sucesso. Uploaded to %1 Enviado para% 1 HotKeySettings Enable Global HotKeys Ativar as teclas de atalho globais Capture Rect Area Captura de Ãrea retangular Capture Full Screen Captura da Tela cheia Capture current Screen Captura da Tela atual Capture active Window Captura da Janela ativa Capture Window under Cursor Captura da Janela sob o mouse Global HotKeys Teclas de Atalho Globais Capture Last Rect Area Captura da Última área retangular Clear Apagar Capture using Portal Capturar usando o Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Atualmente, as teclas de atalho são suportadas apenas para Windows e X11. Desabilitar esta opção também torna os atalhos de ação apenas no ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Capturar o cursor do mouse na captura de tela Should mouse cursor be visible on screenshots. O cursor do mouse estará visível nas capturas de tela. Image Grabber Captura de Imagem Show Main Window after capturing screenshot Mostrar janela principal após a captura da tela GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME e KDE Plasma suportam suas próprias capturas de tela do Wayland e Generic XDG-DESKTOP-PORTAL. Ativar esta opção irá forçar o KDE Plasma e o GNOME a usar as capturas do XDG-DESKTOP-PORTAL. A alteração desta opção exige que o ksnip seja reiniciado. Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Implementações genéricas do Wayland que utilizam o XDG-DESKTOP-PORTAL lidam com o dimensionamento de tela de forma diferente. Ativar esta opção irá determinar a escala atual da tela e aplicar isso à captura de tela no ksnip. Hide Main Window during screenshot Ocultar a janela principal durante a captura da imagem Hide Main Window when capturing a new screenshot. Ocultar a janela principal ao capturar uma nova imagem. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Mostrar a Janela Principal após capturar uma nova imagem quando a Janela Principal for ocultada ou minimizada. Force Generic Wayland (xdg-desktop-portal) Screenshot Forçar Wayland genérico (xdg-desktop-portal) capturar de tela Scale Generic Wayland (xdg-desktop-portal) Screenshots Escalar Wayland genérico (xdg-desktop-portal) para capturas de tela ImgurHistoryDialog Imgur History Histórico do Imgur Close Fechar Time Stamp Registro de Data e Hora Link Link Delete Link Excluir Link ImgurUploader Upload to imgur.com finished! Envio para imgur.com concluído! Received new token, trying upload again… Novo token recebido, tentando enviar novamente… Imgur token has expired, requesting new token… O token Imgur expirou, solicitando novo token… ImgurUploaderSettings Force anonymous upload Forçar envio anônimo Always copy Imgur link to clipboard Sempre copiar o link de Imgur para a área de transferência Client ID Client ID Client Secret Client Secret PIN PIN Enter imgur Pin which will be exchanged for a token. Digite o Pin do imgur Pin, que será trocado por um token. Get PIN Obter PIN Get Token Obter Token Imgur History Histórico do Imgur Imgur Uploader Uploader do Imgur Username Nome de usuário Waiting for imgur.com… Aguardando imgur.com… Imgur.com token successfully updated. Token Imgur.com atualizado com sucesso. Imgur.com token update error. Erro na atualização do token Imgur.com. After uploading open Imgur link in default browser Depois de enviar, abrir link do Imgur no navegador padrão Link directly to image Link direto para a imagem Base Url: Url base: Base url that will be used for communication with Imgur. Changing requires restart. Url base que será usado para comunicação com Imgur. Mudança requer reinicialização. Clear Token Limpar Token LoadImageFromFileOperation Unable to open image Incapaz de abrir a imagem Unable to open image from path %1 Incapaz de abrir a imagem do caminho %1 MainToolBar New Novo Delay in seconds between triggering and capturing screenshot. Atraso em segundos entre o acionamento e captura de tela. s The small letter s stands for seconds. s Save Salvar Save Screen Capture to file system Salvar captura de tela nos arquivos Copy Copiar Copy Screen Capture to clipboard Copiar captura de tela para a área de transferência Tools Ferramentas Undo Desfazer Redo Refazer Crop Recortar Crop Screen Capture Recortar captura de tela MainWindow Unsaved Não salvo Upload Enviar Print Imprimir Opens printer dialog and provide option to print image Abrir caixa de diálogo da impressão e fornecer as opções de impressão Print Preview Visualizar impressão Opens Print Preview dialog where the image orientation can be changed Abrir caixa de diálogo Visualizar impressão, onde a orientação da imagem pode ser alterada Scale Redimensionar Quit Sair Settings Configurações &About &Sobre Open Abrir &Edit &Editar &Options &Opções &Help Aj&uda Add Watermark Adicionar marca d'água Add Watermark to captured image. Multiple watermarks can be added. Adicionar marca d'água à imagem capturada. Várias marcas d'água podem ser adicionadas. &File &Arquivo Unable to show image Não foi possível exibir a imagem Save As... Salvar como... Paste Colar Paste Embedded Colar Aqui No image provided but one was expected. Nenhuma imagem fornecida, mas uma era esperada. Copy Path Copiar caminho Rename Renomear Open Directory Abrir pasta Pin Pinar Pin screenshot to foreground in frameless window Pinar a captura de tela no primeiro plano de uma janela sem moldura Delete Excluir &View &Exibir Open Images Abrir imagens Show Docks Exibir Docks Hide Docks Ocultar Docks Copy as data URI Copiar como URI de dados Open &Recent Aberto &Recente Modify Canvas Modificar fundo de tela Upload triggerCapture to external source Carregar captura para fonte externa Copy triggerCapture to system clipboard Copiar captura para a área de transferência do sistema Scale Image Escala de Imagem Rotate Rotacionar Rotate Image Rotacionar Imagem Actions Ações Image Files Arquivos de imagem MultiCaptureHandler Save Salvar Save As Salvar como Rename Renomear Open Directory Abrir pasta Copy Copiar Copy Path Copiar caminho Delete Excluir NewCaptureNameProvider Capture Imagem PinWindow Close Fechar Close Other Fechar outro Close All Fechar tudo PinWindowHandler Pin Window %1 Pinar janela %1 RenameOperation Image Renamed Imagem renomeada Image Rename Failed Ocorreu um erro ao renomear a imagem Rename image Renomear imagem New filename: Novo nome do arquivo: Successfully renamed image to %1 Imagem renomeada com sucesso para% 1 Failed to rename image to %1 Falha ao mudar o nome da imagem para% 1 SaveOperation Save As Salvar como All Files Todos os arquivos Image Saved Imagem salva Saving Image Failed Falha ao salvar imagem Image Files Arquivos de imagem Saved to %1 Salvo em% 1 Failed to save image to %1 Falha ao salvar a imagem em% 1 SaverSettings Automatically save new captures to default location Automaticamente salvar novas capturas na pasta padrão Prompt to save before discarding unsaved changes Avisar para salvar antes de descartar um trabalho não salvo Remember last Save Directory Lembrar a Última Pasta Salva When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Quando ativado, substituirá a pasta armazenada nas configurações pela pasta mais recente salva, toda vez que salvar. Capture save location and filename Local e nome do arquivo para salvar a captura Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Os formatos suportados são JPG, PNG e BMP. Se nenhum formato for fornecido, o PNG será usado como padrão. O nome do arquivo pode conter os seguintes curingas: - $Y, $M, $D para data, $h, $m, $s para hora ou $T para hora no formato hhmmss. - # múltiplos consecutivos para contador. #### resultará em 0001, a próxima captura será 0002. Browse Selecionar Saver Settings Configurações para Salvar arquivos Capture save location Local para salvar a captura Default Padrão Factor Fator Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Indique 0 para obter pequenos arquivos compactados, 100 para grandes arquivos não compactados. Nem todos os formatos de imagem têm suporte a todos os intervalos, o JPEG suporta. Save Quality Qualidade para salvar ScriptUploaderSettings Copy script output to clipboard Copiar saída do script para a área de transferência Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Caminho para o script que será chamado para upload. Durante o upload, o script será chamado com o caminho para um arquivo png temporário como um único argumento. Browse Selecionar Script Uploader Script de Uploader Select Upload Script Selecione o Script para Envio Stop when upload script writes to StdErr Parar quando o script de upload é gravado no StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Marca o upload como falha quando o script escreve em StdErr. Sem essa configuração, os erros no script passarão despercebidos. Filter: Filtro: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Expressão Regulares. Copie para a área de transferência apenas o que corresponde à expressão RegEx. Quando omitido, tudo é copiado. SettingsDialog Settings Configurações OK OK Cancel Cancelar Image Grabber Captura de Imagem Imgur Uploader Uploader Imgur Application Aplicação Annotator Editor HotKeys Teclas de Atalho Uploader Carregador Script Uploader Script de Uploader Saver Salvar Stickers Figurinhas Snipping Area Ãrea Retangular Tray Icon Ãcone da bandeja Watermark Marca d'água Actions Ações FTP Uploader Uploader FTP SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Redimensione o retângulo selecionado usando as alças ou mova-o arrastando a seleção. Use arrow keys to move the selection. Use as setas para mover a seleção. Use arrow keys while pressing CTRL to move top left handle. Use as seta enquanto pressiona CTRL para mover a alça superior esquerda. Use arrow keys while pressing ALT to move bottom right handle. Use as teclas de seta enquanto pressiona ALT para mover a alça inferior direita. Confirm selection by pressing ENTER/RETURN or abort by pressing ESC. Confirmar a seleção pressionando ENTER/RETURN ou aborte pressionando ESC. This message can be disabled via settings. Esta mensagem pode ser desativada nas configurações. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Clique e arraste para selecionar uma área retangular ou pressione ESC para sair. Hold CTRL pressed to resize selection after selecting. Mantenha CTRL pressionado para redimensionar a seleção após selecionar. Hold CTRL pressed to prevent resizing after selecting. Mantenha CTRL pressionado para evitar o redimensionamento após selecionar. Operation will be canceled after 60 sec when no selection made. A operação será cancelada após 60 segundos quando nenhuma seleção for feita. This message can be disabled via settings. Esta mensagem pode ser desativada nas configurações. SnippingAreaSettings Freeze Image while snipping Congelar imagem ao capturar área retangular When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Quando ativado irá congelar o fundo enquanto selecionando uma área retangular. Também muda o comportamento de capturas de tela atrasadas, com esta opção habilitada o atraso acontece antes da área retangular ser exibida e com a opção desativada o atraso acontece depois que a área retangular é exibida. Este recurso está sempre desabilitado para Wayland e sempre habilitado para MacOs. Show magnifying glass on snipping area Exibir lupa ao capturar área retangular Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Exibir uma lupa que mostra zoom na imagem de fundo. Esta opção só funciona com 'Congelar imagem ao capturar área retangular' habilitada. Show Snipping Area rulers Exibir réguas ao capturar área retangular Horizontal and vertical lines going from desktop edges to cursor on snipping area. Uma linha horizontal e vertical será exibida antes de iniciar a captura de uma área retangular. Show Snipping Area position and size info Exibir posição e tamanho ao capturar área retangular When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Quando o botão esquerdo do mouse não é pressionado a posição é exibida, quando o botão do mouse é pressionado, o tamanho da área selecionada é exibido à esquerda e acima da área capturada. Allow resizing rect area selection by default Permitir redimensionamento da seleção da área retangular por padrão When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Quando ativado, após selecionar uma área retangular, permite redimensionar a seleção. Quando realizado o redimensionamento a seleção pode ser confirmada pressionando Enter. Show Snipping Area info text Mostrar texto de informação para área retangular Snipping Area cursor color Cor do cursor ao capturar área retangular Sets the color of the snipping area cursor. Define a cor do cursor da área retangular. Snipping Area cursor thickness Espessura do cursor ao capturar área retangular Sets the thickness of the snipping area cursor. Define a espessura do cursor da área retangular. Snipping Area Ãrea Retangular Snipping Area adorner color Cor das bordas da área de recorte Sets the color of all adorner elements on the snipping area. Define a cor de todos as bordas na área de retangular. Snipping Area Transparency Transparência da área retangular Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa para região não selecionada na área retangular. O número menor é mais transparente. StickerSettings Up Subir Down Descer Use Default Stickers Usar Figurinhas Padrão Sticker Settings Configurações de Figurinhas Vector Image Files (*.svg) Arquivos de Imagem Vetorial (*.svg) Add Adicionar Remove Remover Add Stickers Adicionar Figurinhas TrayIcon Show Editor Exibir Editor TrayIconSettings Use Tray Icon Usar ícone da bandeja When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Quando ativado, adiciona um ícone de bandeja na barra de tarefas, se o gerenciador de janelas do SO oferecer suporte. A mudança requer reinicialização. Minimize to Tray Minimizar para a Bandeja Start Minimized to Tray Iniciar Minimizado na Bandeja Close to Tray Fechar para a Bandeja Show Editor Exibir Editor Capture Capturar Default Tray Icon action Ação padrão do ícone da bandeja Default Action that is triggered by left clicking the tray icon. Ação padrão que é disparada clicando com o botão esquerdo do mouse no ícone da bandeja. Tray Icon Settings Configurações do ícone da bandeja Use platform specific notification service Usar o serviço de notificação específico da plataforma When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Quando ativado, tentará usar o serviço de notificação específico da plataforma, quando tal existir. A mudança requer reinicialização para ter efeito. Display Tray Icon notifications Exibir notificações do ícone da bandeja UpdateWatermarkOperation Select Image Selecione uma imagem Image Files Arquivos de imagem UploadOperation Upload Script Required Script de Upload Requerido Please add an upload script via Options > Settings > Upload Script Adicione um script de envio em Opções> Configurações> Script de Envio Capture Upload Capturar Envio You are about to upload the image to an external destination, do you want to proceed? Você está prestes a enviar a imagem para um destino externo. Deseja continuar? UploaderSettings Ask for confirmation before uploading Confirmar antes de enviar Uploader Type: Tipo de Uploader: Imgur Imgur Script Script Uploader Carregador FTP FTP VersionTab Version Versão Build Compilação Using: Utilizando: WatermarkSettings Watermark Image Imagem de marca d'água Update Atualizar Rotate Watermark Girar marca d'água When enabled, Watermark will be added with a rotation of 45° Quando ativado, a marca d'água será adicionada com rotação de 45º Watermark Settings Configurações de Marca d'água ksnip-master/translations/ksnip_ro.ts000066400000000000000000001676271457262621600204460ustar00rootroot00000000000000 AboutDialog About Despre About Despre Version Versiune Author Autor Close ÃŽnchide Donate Donează Contact Contact AboutTab License: Licență: Screenshot and Annotation Tool Unealtă pentru capturi de ecran È™i adnotări ActionSettingTab Name Denumire Shortcut Scurtătură Clear Curăță Take Capture Fă o captură Include Cursor Include cursorul Delay ÃŽntârziere s The small letter s stands for seconds. s Capture Mode Regim captură Show image in Pin Window Copy image to Clipboard Copiază imaginea în clipboard Upload image ÃŽncarcă imaginea Open image parent directory Deschide dosarul părinte al imaginii Save image Salvează imaginea Hide Main Window Ascunde fereastra principală Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Adaugă Actions Settings Configurări acÈ›iune Action AcÈ›iune AddWatermarkOperation Watermark Image Required Imagine-filigran necesară Please add a Watermark Image via Options > Settings > Annotator > Update AdăugaÈ›i o imagine-filigran în OpÈ›iuni > Configurări > Adnotator > Actualizează AnnotationSettings Smooth Painter Paths NetezeÈ™te căile pictorului When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Factor de netezime Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Configurări adnotator Remember annotation tool selection and load on startup Èšine minte selecÈ›ia uneltei de adnotare È™i încarc-o la lansare Switch to Select Tool after drawing Item Schimbă la unealta de selecÈ›ie după desenarea elementului Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Culoare canava Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing Alege elementul după desenare With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Fă o captură la pornire cu regimul implicit Application Style Stil aplicaÈ›ie Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Configurări aplicaÈ›ie Automatically copy new captures to clipboard Copiază automat noua captură în clipboard Use Tabs FoloseÈ™te file Change requires restart. Schimbarea necesită repornire. Run ksnip as single instance Rulează KSnip ca instanță unică Hide Tabbar when only one Tab is used. Ascunde bara de file când e folosită doar o filă. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Èšine minte poziÈ›ia ferestrei principale la mutare È™i încarc-o la lansare Auto hide Tabs Ascunde filele automat Auto hide Docks Ascunde andocările automat On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Redimensionează automat la conÈ›inut Automatically resize Main Window to fit content image. Redimensionează automat fereastra principală să se potrivească cu conÈ›inutul. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse RăsfoieÈ™te AuthorTab Contributors: Contribuitori: Spanish Translation Traducere spaniolă Dutch Translation Traducere olandeză Russian Translation Traducere rusă Norwegian BokmÃ¥l Translation Traducere norvegiană BokmÃ¥l French Translation Traducere franceză Polish Translation Traducere poloneză Snap & Flatpak Support Suport pentru Snap È™i Flatpak The Authors: Autorii: CanDiscardOperation Warning - Avertisment – The capture %1%2%3 has been modified. Do you want to save it? Captura %1%2%3 a fost modificată. DoriÈ›i să o salvaÈ›i? CaptureModePicker New Nou Draw a rectangular area with your mouse DesenaÈ›i o zonă dreptunghiulară cu mausul Capture full screen including all monitors Capturează ecran complet incluzând toate monitoarele Capture screen where the mouse is located Capturează ecranul pe care e mausul Capture window that currently has focus Capturează fereastra care e focalizată acum Capture that is currently under the mouse cursor Capturează ce e acum sub cursorul mausului Capture a screenshot of the last selected rectangular area Fă o captură a ultimei zone dreptunghiulare alese Uses the screenshot Portal for taking screenshot ContactTab Community Comunitate Bug Reports Rapoarte de defecte If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Copierea în clipboard a eÈ™uat Failed to copy to clipboard as base64 encoded image. Copierea în clipboard ca imagine codată cu base64 a eÈ™uat. Copied to clipboard Copiat în clipboard Copied to clipboard as base64 encoded image. Copiat în clipboard ca imagine codată cu base64. DeleteImageOperation Delete Image Șterge imaginea The item '%1' will be deleted. Do you want to continue? Elementul „%1†va fi È™ters. DoriÈ›i să continuaÈ›i? DonateTab Donations are always welcome DonaÈ›iile sunt binevenite mereu Donation DonaÈ›ie ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. AdăugaÈ›i acÈ›iuni noi apăsând pe butonul „Adaugă†de pe filă. EnumTranslator Rectangular Area Zonă dreptunghiulară Last Rectangular Area Ultima zonă dreptunghiulară Full Screen (All Monitors) Ecran complet (toate monitoarele) Current Screen Ecranul actual Active Window Fereastra activă Window Under Cursor Fereastra de sub cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Utilizator Password FTP Uploader HandleUploadResultOperation Upload Successful ÃŽncărcare reuÈ™ită Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Procesul a eÈ™uat Process timed out. Procesul a expirat. Process read error. Process write error. Web error, check console output. Upload Failed ÃŽncărcarea a eÈ™uat Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Activează scurtături globale Capture Rect Area Capture Full Screen Capturează ecran complet Capture current Screen Capturează ecranul actual Capture active Window Capturează fereastra activă Capture Window under Cursor Capturează fereastra de sub cursor Global HotKeys Scurtături globale Capture Last Rect Area Clear Curăță Capture using Portal Capturează folosind Portalul HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Capturează cursorul mausului Should mouse cursor be visible on screenshots. Image Grabber Acaparator de imagini Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Arată fereastra principală după capturare Hide Main Window during screenshot Ascunde fereastra principală în timpul capturării Hide Main Window when capturing a new screenshot. Ascunde fereastra principală în timpul capturării ecranului. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Istoric Imgur Close ÃŽnchide Time Stamp Ștampilă temporală Link Legătură Delete Link Șterge legătura ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload ForÈ›ează încărcare anonimă Always copy Imgur link to clipboard Copiază mereu legătura Imgur în clipboard Client ID Id. client Client Secret Secret client PIN PIN Enter imgur Pin which will be exchanged for a token. Get PIN ObÈ›ine PIN-ul Get Token ObÈ›ine jetonul Imgur History Istoric Imgur Imgur Uploader ÃŽncărcător Imgur Username Utilizator Waiting for imgur.com… Se aÈ™teaptă imgur.com… Imgur.com token successfully updated. Jeton imgur.com actualizat cu succes. Imgur.com token update error. Eroare la actualizarea jetonului imgur.com. After uploading open Imgur link in default browser Link directly to image Leagă direct la imagine Base Url: URL de bază: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Curăță jetonul Upload title: Upload description: LoadImageFromFileOperation Unable to open image Nu s-a putut deschide imaginea Unable to open image from path %1 Nu s-a putut deschide imaginea de la calea %1 MainToolBar New Nou Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. s Save Salvează Save Screen Capture to file system Salvează captura ecranului în sistemul de fiÈ™iere Copy Copiază Copy Screen Capture to clipboard Copiază captura de ecran în clipboard Tools Unelte Undo Desfă Redo Refă Crop Decupează Crop Screen Capture Decupează captura de ecran MainWindow Unsaved Nesalvat Upload ÃŽncarcă Print TipăreÈ™te Opens printer dialog and provide option to print image Print Preview Previzualizare tipărire Opens Print Preview dialog where the image orientation can be changed Scale Scalează Quit Termină Settings Configurări &About &Despre Open Deschide &Edit &Editare &Options &OpÈ›iuni &Help &Ajutor Add Watermark Adaugă filigran Add Watermark to captured image. Multiple watermarks can be added. &File &FiÈ™ier Unable to show image Nu s-a putut arăta imaginea Save As... Salvează ca… Paste LipeÈ™te Paste Embedded Pin Fixează Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Copiază calea Open Directory Deschide dosar &View &Vizualizare Delete Șterge Rename RedenumeÈ™te Open Images Deschide imagini Show Docks Arată andocări Hide Docks Ascunde andocări Copy as data URI Copiază datele ca URI Open &Recent Deschide &recent Modify Canvas Modifică canavaua Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Scalează imaginea Rotate RoteÈ™te Rotate Image RoteÈ™te imaginea Actions AcÈ›iuni Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Salvează Save As Salvează ca Open Directory Deschide dosar Copy Copiază Copy Path Copiază calea Delete Șterge Rename RedenumeÈ™te Save All NewCaptureNameProvider Capture Captură OcrWindowCreator OCR Window %1 PinWindow Close ÃŽnchide Close Other ÃŽnchide celelalte Close All ÃŽnchide toate PinWindowCreator OCR Window %1 PluginsSettings Search Path Default Implicit The directory where the plugins are located. Browse RăsfoieÈ™te Name Denumire Version Versiune Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Imagine redenumită Image Rename Failed Redenumirea imaginii a eÈ™uat Rename image RedenumeÈ™te imaginea New filename: Denumire nouă: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As Salvează ca All Files Toate fiÈ™ierele Image Saved Imagine salvată Saving Image Failed Salvarea imaginii a eÈ™uat Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory Èšine minte ultimul dosar de salvare When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse RăsfoieÈ™te Saver Settings Capture save location Locul salvării capturilor Default Implicit Factor Factor Save Quality Calitate salvare Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse RăsfoieÈ™te Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: Filtru: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings Configurări OK Bine Cancel Renunță Image Grabber Acaparator de imagini Imgur Uploader ÃŽncărcător Imgur Application AplicaÈ›ie Annotator Adnotator HotKeys Scurtături Uploader ÃŽncărcător Script Uploader Saver Stickers Autocolante Snipping Area Zona tăieturii Tray Icon Pictogramă în tavă Watermark Filigran Actions AcÈ›iuni FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Acest mesaj poate fi dezactivat în configurări. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. Acest mesaj poate fi dezactivat în configurări. SnippingAreaSettings Freeze Image while snipping ÃŽngheață imaginea la tăiere When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Arată lupa pe zona tăieturii Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Zona tăieturii Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency TransparenÈ›a zonei tăieturii Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa pentru regiunea nealeasă în zona tăieturii. Numerele mai mici sunt mai transparente. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Sus Down Jos Use Default Stickers FoloseÈ™te autocolante implicite Sticker Settings Configurări autocolante Vector Image Files (*.svg) FiÈ™iere cu imagini vectoriale (*.svg) Add Adaugă Remove Elimină Add Stickers Adaugă autocolante TrayIcon Show Editor Arată redactorul TrayIconSettings Use Tray Icon FoloseÈ™te pictogramă în tavă When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Când e activată, va adăuga o pictogramă în tava de sistem dacă gestionarul de ferestre o susÈ›ine. Modificarea necesită repornire. Minimize to Tray Minimizează în tavă Start Minimized to Tray PorneÈ™te minimizat în tavă Close to Tray ÃŽnchide în tavă Show Editor Arată redactorul Capture Captură Default Tray Icon action AcÈ›iune implicită pentru pictograma din tavă Default Action that is triggered by left clicking the tray icon. AcÈ›iune implicită declanÈ™ată la clic stâng pe pictograma din tavă. Tray Icon Settings Configurări pictogramă în tavă Use platform specific notification service FoloseÈ™te serviciu de notificare specific platformei When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Când e activat, se va încerca folosirea serviciului de notificare specific platformei, dacă există. Modificarea necesită o repornire pentru a intra în vigoare. Display Tray Icon notifications UpdateWatermarkOperation Select Image Alege imaginea Image Files UploadOperation Upload Script Required Script de încărcare necesar Please add an upload script via Options > Settings > Upload Script AdăugaÈ›i un script de încărcare în OpÈ›iuni > Configurări > Script de încărcare Capture Upload ÃŽncărcare captură You are about to upload the image to an external destination, do you want to proceed? SunteÈ›i pe cale să încărcaÈ›i imaginea pe o destinaÈ›ie externă, doriÈ›i să continuaÈ›i? UploaderSettings Ask for confirmation before uploading Cere confirmare înainte de a încărca Uploader Type: Tip încărcător: Imgur Imgur Script Script Uploader ÃŽncărcător FTP VersionTab Version Versiune Build Construire Using: Folosind: WatermarkSettings Watermark Image Imagine filigran Update Actualizează Rotate Watermark RoteÈ™te filigranul When enabled, Watermark will be added with a rotation of 45° La activare, filigranul va fi adăugat cu rotaÈ›ie de 45° Watermark Settings Configurări filigran ksnip-master/translations/ksnip_ru.ts000066400000000000000000002345231457262621600204420ustar00rootroot00000000000000 AboutDialog About О приложении About О приложении Version ВерÑÐ¸Ñ Author Ðвтор Close Закрыть Donate Пожертвовать Contact Контакты AboutTab License: ЛицензиÑ: Screenshot and Annotation Tool ИнÑтрумент Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¸ Ð°Ð½Ð½Ð¾Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñнимков Ñкрана ActionSettingTab Name Ð˜Ð¼Ñ Shortcut Ярлык Clear ОчиÑтить Take Capture Сделать Ñнимок Ñкрана Include Cursor Включить курÑор Delay Задержка s The small letter s stands for seconds. Ñ Capture Mode Режим Ñнимка Ñкрана Show image in Pin Window Показать изображение в закреплённом окне Copy image to Clipboard Скопировать изображение в буфер обмена Upload image Выгрузить изображение на внешний реÑÑƒÑ€Ñ Open image parent directory Открыть Ñодержащий изображение каталог Save image Сохранить изображение Hide Main Window Скрыть оÑновное окно Global Общее When enabled will make the shortcut available even when ksnip has no focus. При включении Ñделает горÑчие клавиши доÑтупными, даже еÑли ksnip не в фокуÑе. ActionsSettings Add Добавить Actions Settings ÐаÑтройки дейÑтвий Action ДейÑтвие AddWatermarkOperation Watermark Image Required ТребуетÑÑ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ водÑного знака Please add a Watermark Image via Options > Settings > Annotator > Update ПожалуйÑта, добавьте изображение водÑного знака через Опции > ÐаÑтройки > Параметры риÑÐ¾Ð²Ð°Ð½Ð¸Ñ > УÑтановить водÑной знак/логотип AnnotationSettings Smooth Painter Paths Сглаживание When enabled smooths out pen and marker paths after finished drawing. При включении Ñглаживает киÑть поÑле Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€Ð¸ÑованиÑ. Smooth Factor КоÑффициент Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Увеличение коÑффициента ÑÐ³Ð»Ð°Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÑƒÐ¼ÐµÐ½ÑŒÑˆÐ¸Ñ‚ точноÑть ручки и маркера, но Ñделает их более плавными. Annotator Settings Параметры риÑÐ¾Ð²Ð°Ð½Ð¸Ñ Remember annotation tool selection and load on startup Запомнить выбор инÑтрумента аннотации и запуÑтить его при загрузке Switch to Select Tool after drawing Item ПереключитьÑÑ Ð½Ð° выбор инÑтрумента поÑле риÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ñлемента Number Tool Seed change updates all Number Items Изменение нумератора обновит вÑе нумерованные Ñлементы Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Отключение данной опции приведёт к раÑпроÑтранению изменений нумератора только на новые Ñлементы, но не на уже ÑущеÑтвующие. Отключение опции разрешит дублирование номеров. Canvas Color Цвет фона Default Canvas background color for annotation area. Changing color affects only new annotation areas. Цвет фона по умолчанию Ð´Ð»Ñ Ð¾Ð±Ð»Ð°Ñти аннотаций. Изменение цвета повлиÑет только на новые аннотации. Select Item after drawing Выбирать Ñлемент поÑле отриÑовки With this option enabled the item gets selected after being created, allowing changing settings. При включении опции Ñлемент будет автоматичеÑки выбиратьÑÑ Ð¿Ð¾Ñле ÑозданиÑ, позволÑÑ Ð¼ÐµÐ½Ñть параметры. Show Controls Widget Показать панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Панель ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñодержит кнопки Ðазад/Вперед, Обрезать, МаÑштабировать, Повернуть и Изменить полотно. ApplicationSettings Capture screenshot at startup with default mode Делать Ñкриншот при запуÑке Application Style Стиль окон Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. УÑтанавливает Ñтиль программы, который определÑет внешний вид GUI. Ðеобходимо перезапуÑтить ksnip, чтобы Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ñтупили в Ñилу. Application Settings ОÑновные наÑтройки Automatically copy new captures to clipboard ÐвтоматичеÑки копировать новые Ñкриншоты в буфер обмена Use Tabs ИÑпользовать вкладки Change requires restart. Изменение требует перезапуÑка. Run ksnip as single instance ЗапуÑкать только один ÑкземплÑÑ€ ksnip Hide Tabbar when only one Tab is used. Скрыть панель вкладок, еÑли иÑпользуетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ одна вкладка. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Включение Ñтой опции позволит запуÑкать только один ÑкземплÑÑ€ ksnip, вÑе оÑтальные запуÑкаемые ÑкземплÑры передадут аргументы первому. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼ новый запуÑк вÑех ÑкземплÑров. Remember Main Window position on move and load on startup Запомнить положение главного окна при перемещении и воÑÑтановить при загрузке Auto hide Tabs ÐвтоматичеÑки Ñкрывать вкладки Auto hide Docks ÐвтоматичеÑки Ñкрывать панели On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Скрывать панель инÑтрументов и наÑтройки Ð°Ð½Ð½Ð¾Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸ запуÑке. ВидимоÑть панелей можно переключать клавишей Tab. Auto resize to content ÐвтоматичеÑки маÑштабировать под Ñодержимое Automatically resize Main Window to fit content image. ÐвтоматичеÑки маÑштабировать главное окно под размер Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² нём. Enable Debugging Включить отладку Enables debug output written to the console. Change requires ksnip restart to take effect. Включает вывод отладочной информации в конÑоль. Ð”Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼ перезапуÑк ksnip. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. МаÑштабирование под Ñодержимое выполнÑетÑÑ Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹, позволÑÑ Ð¾ÐºÐ¾Ð½Ð½Ð¾Ð¼Ñƒ менеджеру получить новое Ñодержимое. Увеличение данной задержки может помочь, еÑли главное окно автоматичеÑки маÑштабируетÑÑ Ð¿Ð¾Ð´ Ñодержимое некорректно. Resize delay Задержка Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° Temp Directory Временный каталог Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Временный каталог иÑпользуетÑÑ Ð´Ð»Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… изображений, которые будут удалены поÑле Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ñ ksnip. Browse Обзор AuthorTab Contributors: Соавторы: Spanish Translation перевод на иÑпанÑкий Dutch Translation перевод на нидерландÑкий Russian Translation перевод на руÑÑкий Norwegian BokmÃ¥l Translation перевод на норвежÑкий букмол French Translation перевод на французÑкий Polish Translation перевод на польÑкий Snap & Flatpak Support Поддержка Snap и Flatpak The Authors: Ðвторы: CanDiscardOperation Warning - Внимание - The capture %1%2%3 has been modified. Do you want to save it? Снимок %1%2%3 был изменён. Хотите Ñохранить его? CaptureModePicker New Создать Draw a rectangular area with your mouse Выделите мышкой прÑмоугольную облаÑть Capture full screen including all monitors Сделать Ñкриншот вÑего Ñкрана Ñо вÑех мониторов Capture screen where the mouse is located Сделать Ñкриншот Ñкрана, на котором раÑположен курÑор мыши Capture window that currently has focus Сделать Ñнимок текущего окна Capture that is currently under the mouse cursor Сделать Ñкриншот окна, на котором раÑположен курÑор мыши Capture a screenshot of the last selected rectangular area Сделать Ñкриншот поÑледней выделенной облаÑти Uses the screenshot Portal for taking screenshot ИÑпользовать screenshot Portal Ð´Ð»Ñ Ñнимков Ñкрана ContactTab Community СообщеÑтво Bug Reports Ð¡Ð¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибках If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. ПриÑоединÑйтеÑÑŒ к нашим %1 или %2 Ñерверам,<br/>еÑли у Ð²Ð°Ñ ÐµÑть вопроÑÑ‹, идеи или проÑто хотите поговорить о ksnip. Please use %1 to report bugs. ИÑпользуйте, пожалуйÑта, %1 Ð´Ð»Ñ Ñообщений об ошибках. CopyAsDataUriOperation Failed to copy to clipboard Ðе удалоÑÑŒ Ñкопировать в буфер обмена Failed to copy to clipboard as base64 encoded image. Ðе удалоÑÑŒ Ñкопировать изображение в буфер обмена в виде base64-кода. Copied to clipboard Скопировано в буфер обмена Copied to clipboard as base64 encoded image. Изображение Ñкопировано в буфер обмена в виде base64-кода. DeleteImageOperation Delete Image Удалить изображение The item '%1' will be deleted. Do you want to continue? Элемент "%1" будет удален. Хотите продолжить? DonateTab Donations are always welcome ÐŸÐ¾Ð¶ÐµÑ€Ñ‚Ð²Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ñегда приветÑтвуютÑÑ Donation Пожертвование ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip&nbsp;&mdash; Ñто некоммерчеÑкий проект Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ иÑходным кодом, но<br/>проект вÑÑ‘ равно требует Ð¿Ð¾ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… затрат,<br/>таких как оплата домена или инÑтрументов кроÑÑ-платформенной поддержки. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. ЕÑли вы хотите помочь или проÑто хотите оценить проделанную работу,<br/>угоÑтив разработчиков пивом или кофе, можете Ñделать Ñто %1здеÑÑŒ%2. Become a GitHub Sponsor? Стать ÑпонÑором на GitHub? Also possible, %1here%2. Также можете, %1здеÑÑŒ%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Добавьте новые дейÑÑ‚Ð²Ð¸Ñ Ð½Ð°Ð¶Ð°Ñ‚Ð¸ÐµÐ¼ на вкладке кнопки «Добавить». EnumTranslator Rectangular Area ПрÑÐ¼Ð¾ÑƒÐ³Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть Last Rectangular Area ПоÑледнÑÑ Ð¿Ñ€ÑÐ¼Ð¾ÑƒÐ³Ð¾Ð»ÑŒÐ½Ð°Ñ Ð¾Ð±Ð»Ð°Ñть Full Screen (All Monitors) ПолноÑкранный режим (вÑе мониторы) Current Screen Текущий Ñкран Active Window Ðктивное окно Window Under Cursor Окно под курÑором мыши Screenshot Portal Портал Ñкриншота FtpUploaderSettings Force anonymous upload. ÐÐ½Ð¾Ð½Ð¸Ð¼Ð½Ð°Ñ Ð²Ñ‹Ð³Ñ€ÑƒÐ·ÐºÐ°. Url URL-Ð°Ð´Ñ€ÐµÑ Username Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Password Пароль FTP Uploader Выгрузка на FTP HandleUploadResultOperation Upload Successful УÑпешно выгружено Unable to save temporary image for upload. Ðе удалоÑÑŒ Ñохранить временное изображение Ð´Ð»Ñ Ð²Ñ‹Ð³Ñ€ÑƒÐ·ÐºÐ¸. Unable to start process, check path and permissions. Ðе удалоÑÑŒ запуÑтить процеÑÑ, проверьте путь и права доÑтупа. Process crashed ПроцеÑÑ Ð°Ð²Ð°Ñ€Ð¸Ð¹Ð½Ð¾ завершилÑÑ Process timed out. Ð’Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа иÑтекло. Process read error. Ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа. Process write error. Ошибка запиÑи процеÑÑа. Web error, check console output. Ошибка Ñети, проверьте вывод конÑоли. Upload Failed Выгрузка не удалаÑÑŒ Script wrote to StdErr. Скрипт напиÑал в Ñтандартный вывод ошибок. FTP Upload finished successfully. Выгрузка на FTP-Ñервер уÑпешно завершена. Unknown error. ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°. Connection Error. Ошибка подключениÑ. Permission Error. Ошибка прав доÑтупа. Upload script %1 finished successfully. Скрипт выгрузки %1 завершилÑÑ ÑƒÑпешно. Uploaded to %1 Выгружено на %1 HotKeySettings Enable Global HotKeys Включить глобальные горÑчие клавиши (не работает в Wayland) Capture Rect Area Снимок выделенной облаÑти Capture Full Screen Снимок вÑего Ñкрана Capture current Screen Снимок текущего Ñкрана Capture active Window Снимок активного окна Capture Window under Cursor Снимок окна под курÑором мыши Global HotKeys ГорÑчие клавиши Capture Last Rect Area Снимок поÑледней облаÑти Clear ОчиÑтить Capture using Portal Захват Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ портала HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ГорÑчие клавиши поддерживаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в Windows и X11. При отключении данной опции ÑÐ¾Ñ‡ÐµÑ‚Ð°Ð½Ð¸Ñ ÐºÐ»Ð°Ð²Ð¸Ñˆ будут работать только в ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Показывать курÑор мыши на Ñнимке Ñкрана Should mouse cursor be visible on screenshots. Должен ли быть виден курÑор мыши во Ð²Ñ€ÐµÐ¼Ñ Ñнимка Ñкрана. Image Grabber ÐаÑтройки захвата Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Общие реализации Wayland, иÑпользующие XDG-DESKTOP-PORTAL, реализуют маÑштабирование по-разному. Включение Ñтой опции приведет к определению маÑштаба текущего Ñкрана и применению его к Ñкриншоту в ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME и KDE Plasma поддерживают ÑобÑтвенные методы Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñкриншотов в Wayland и Generic XDG-DESKTOP-PORTAL. Включение Ñтой опции заÑтавит KDE Plasma и GNOME иÑпользовать Ñкриншоты метода XDG-DESKTOP-PORTAL. Изменение Ñтой опции требует перезапуÑка ksnip. Show Main Window after capturing screenshot Показать главное окно поÑле Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñнимка Ñкрана Hide Main Window during screenshot Скрыть главное окно во Ð²Ñ€ÐµÐ¼Ñ Ñнимка Ñкрана Hide Main Window when capturing a new screenshot. Скрыть главное окно при захвате нового Ñнимка Ñкрана. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Показать оÑновное окно поÑле Ð²Ñ‹Ð¿Ð¾Ð»ÐµÐ½ÐµÐ½Ð¸Ñ Ñнимка, еÑли оно было Ñкрыто или Ñвёрнуто. Force Generic Wayland (xdg-desktop-portal) Screenshot ИÑпользовать Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñкриншота в Wayland базовый метод (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots МаÑштабировать Ñкриншоты, полученные базовым методом Wayland (xdg-desktop-portal) Implicit capture delay Ð¡ÐºÑ€Ñ‹Ñ‚Ð°Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ° захвата This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Эта задержка иÑпользуетÑÑ Ð¿Ñ€Ð¸ отÑутÑтвии обычной, что позволÑет ksnip ÑкрытьÑÑ Ð´Ð¾ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñнимка. Ðе иÑпользуетÑÑ, еÑли окно ksnip Ñвёрнуто. Уменьшение Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ привеÑти к отображению оÑновного окна ksnip на Ñнимке. ImgurHistoryDialog Imgur History ИÑÑ‚Ð¾Ñ€Ð¸Ñ Imgur Close Закрыть Time Stamp Ð’Ñ€ÐµÐ¼Ñ Link СÑылка Delete Link СÑылка на удаление ImgurUploader Upload to imgur.com finished! Выгрузка на imgur.com завершена! Received new token, trying upload again… Получен новый токен, Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° выгрузки… Imgur token has expired, requesting new token… Срок дейÑÑ‚Ð²Ð¸Ñ Ñ‚Ð¾ÐºÐµÐ½Ð° иÑтек, запрашиваетÑÑ Ð½Ð¾Ð²Ñ‹Ð¹ токен… ImgurUploaderSettings Force anonymous upload ФорÑировать анонимную выгрузку Always copy Imgur link to clipboard Копировать ÑÑылку в буфер обмена Client ID ID клиента Client Secret Секретный ключ клиента PIN PIN-код Enter imgur Pin which will be exchanged for a token. Введите PIN-код Ñ Imgur, который будет заменен на токен. Get PIN Получить PIN Get Token Получить токен Imgur History ИÑÑ‚Ð¾Ñ€Ð¸Ñ Imgur Imgur Uploader Выгрузка на Imgur Username Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Waiting for imgur.com… Ожидание imgur.com… Imgur.com token successfully updated. Imgur.com: токен был обновлен. Imgur.com token update error. Imgur.com: ошибка во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð¾ÐºÐµÐ½Ð°. After uploading open Imgur link in default browser ПоÑле выгрузки открыть ÑÑылку Imgur в браузере по умолчанию Link directly to image ПрÑÐ¼Ð°Ñ ÑÑылка на изображение Base Url: Базовый URL: Base url that will be used for communication with Imgur. Changing requires restart. Базовый URL, иÑпользуемый Ð´Ð»Ñ ÑвÑзи Ñ Imgur. Изменение потребует перезапуÑка. Clear Token ОчиÑтить токен Upload title: Ðазвание загруженного: Upload description: ОпиÑание загруженного: LoadImageFromFileOperation Unable to open image Ðевозможно открыть изображение Unable to open image from path %1 Ðевозможно открыть изображение %1 MainToolBar New Создать Delay in seconds between triggering and capturing screenshot. Задержка в Ñекундах перед тем, как будет Ñделан Ñнимок Ñкрана. s The small letter s stands for seconds. Ñ Save Сохранить Save Screen Capture to file system Сохранить Ñнимок Ñкрана в файловой ÑиÑтеме Copy Копировать Copy Screen Capture to clipboard Копировать Ñнимок Ñкрана в буфер обмена Tools ИнÑтрументы Undo Отменить Redo Вернуть Crop Обрезать Crop Screen Capture Обрезать Ñнимок Ñкрана MainWindow Unsaved Ðе Ñохранено Upload Выгрузить на внешний реÑÑƒÑ€Ñ Print Печать Opens printer dialog and provide option to print image Открывает диалоговое окно принтера Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð¿Ñ†Ð¸Ð¹ печати Print Preview ПредпроÑмотр печати Opens Print Preview dialog where the image orientation can be changed Открыть предварительный проÑмотр раÑпечатки, в котором можно изменить ориентацию Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Scale Изменить размер Quit Выход Settings ÐаÑтройки &About &О приложении Open Открыть &Edit &Редактировать &Options &Опции &Help &Помощь Add Watermark Добавить водÑной знак/логотип Add Watermark to captured image. Multiple watermarks can be added. Добавить водÑнной знак/логотип. Можно добавить неÑколько. &File &Файл Unable to show image Ðевозможно показать изображение Save As... Сохранить как… Paste Ð’Ñтавить Paste Embedded Ð’Ñтавить интегрированным Pin Закрепить Pin screenshot to foreground in frameless window Закрепить Ñнимок Ñкрана на переднем плане в безрамочном окне No image provided but one was expected. Ðикакого Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ было, но его ожидали увидеть. Copy Path Скопировать путь Open Directory Открыть каталог файла &View &ПроÑмотр Delete Удалить Rename Переименовать Open Images Открытое изображение Show Docks Показать панели Hide Docks Скрыть панели Copy as data URI Скопировать в виде «data: URI» Open &Recent &ПоÑледние файлы Modify Canvas Изменить фон Upload triggerCapture to external source Передать Ñнимок Ñкрана на внешний реÑÑƒÑ€Ñ Copy triggerCapture to system clipboard Скопировать Ñнимок в ÑиÑтемный буфер обмена Scale Image МаÑштабировать изображение Rotate Повернуть Rotate Image Повернуть изображение Actions ДейÑÑ‚Ð²Ð¸Ñ Image Files Файлы изображений Save All Сохранить вÑе Close Window Закрыть окно Cut Вырезать OCR РаÑпознавание Ñимволов MultiCaptureHandler Save Сохранить Save As Сохранить как Open Directory Открыть раÑположение Copy Копировать Copy Path Скопировать путь Delete Удалить Rename Переименовать Save All Сохранить вÑе NewCaptureNameProvider Capture Снимок OcrWindowCreator OCR Window %1 Окно раÑпознавание Ñимволов %1 PinWindow Close Закрыть Close Other Закрыть оÑтальные Close All Закрыть вÑе PinWindowCreator OCR Window %1 Окно раÑÐ¿Ð¾Ð·Ð½Ð°Ð²Ð°Ð½Ð¸Ñ Ñ‚ÐµÐºÑта %1 PluginsSettings Search Path Путь поиÑка Default По умолчанию The directory where the plugins are located. Каталог, в котором раÑположены плагины. Browse Обзор Name Ð˜Ð¼Ñ Version ВерÑÐ¸Ñ Detect Определить Plugin Settings ÐаÑтройки плагина Plugin location РаÑположение плагина ProcessIndicator Processing Обработка RenameOperation Image Renamed Изображение переименовано Image Rename Failed Ðе удалоÑÑŒ переименовать изображение Rename image Переименовать изображение New filename: Ðовое Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°: Successfully renamed image to %1 Изображение уÑпешно переименовано в %1 Failed to rename image to %1 Ðе удалоÑÑŒ переименовать изображение в %1 SaveOperation Save As Сохранить как All Files Ð’Ñе файлы Image Saved Изображение Ñохранено Saving Image Failed Ошибка во Ð²Ñ€ÐµÐ¼Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Image Files Файлы изображений Saved to %1 Сохранено в %1 Failed to save image to %1 Ðе удалоÑÑŒ Ñохранить изображение в %1 SaverSettings Automatically save new captures to default location ÐвтоматичеÑки ÑохранÑть новые Ñнимки в папку по умолчанию Prompt to save before discarding unsaved changes Выводить диалог ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ перед отменой Remember last Save Directory Запоминать поÑледний каталог ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. При включении каждый раз будет перезапиÑыватьÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³ Ð´Ð»Ñ ÑохранениÑ, указанный в наÑтройках, на поÑледний иÑпользуемый. Capture save location and filename МеÑто ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñнимков и название файла Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Поддерживаемые форматы: JPG, PNG и BMP. ЕÑли формат не указан, будет выбран PNG как по умолчанию. Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° может Ñодержать Ñледующие подÑтановочные знаки: - $Y, $M, $D Ð´Ð»Ñ Ð´Ð°Ñ‚Ñ‹, $h, $m, $s Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸, или $T Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ в формате hhmmss. - ИÑпользуйте многократно # Ð´Ð»Ñ Ñчётчиков. #### приведет к результату 0001, Ñледующий Ñнимок будет 0002. Browse Обзор Saver Settings ÐаÑтройки ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Capture save location МеÑто ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñнимка Default По умолчанию Factor Уровень Save Quality КачеÑтво ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Укажите 0 Ð´Ð»Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÑŒÑˆÐµÐ³Ð¾ ÑжатиÑ, 100 Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… файлов Ñ Ð½Ð°Ð¸Ð»ÑƒÑ‡ÑˆÐ¸Ð¼ качеÑтвом. Ðе вÑе форматы изображений поддерживают полный диапазон, но JPEG поддерживает. Overwrite file with same name ПерезапиÑать файл Ñ Ñ‚ÐµÐ¼ же именем ScriptUploaderSettings Copy script output to clipboard Копировать вывод Ñкрипта в буфер обмена Script: Скрипт: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Путь к Ñкрипту, вызываемому Ð´Ð»Ñ Ð²Ñ‹Ð³Ñ€ÑƒÐ·ÐºÐ¸. Ð’ процеÑÑе выгрузки Ñкрипт будет вызван Ñ Ð¿ÑƒÑ‚Ñ‘Ð¼ к временному PNG-файлу, в качеÑтве единÑтвенного аргумента. Browse Обзор Script Uploader Выгрузка через Ñкрипт Select Upload Script Выбрать Ñкрипт выгрузки Stop when upload script writes to StdErr ОÑтановить, еÑли Ñкрипт выгрузки напишет в Ñтандартный поток ошибок Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Отметит выгрузку как неудачную, еÑли Ñкрипт напишет в Ñтандартный поток ошибок. Без Ñтой опции ошибки Ñкрипта будут проигнорированы. Filter: Фильтр: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. РегулÑрное выражение. Ð’ буфер обмена будет Ñкопировано только то, что удовлетворÑет Ñтому выражению. ЕÑли не задано, будет Ñкопировано вÑÑ‘. SettingsDialog Settings ÐаÑтройки OK Сохранить Cancel Отменить Image Grabber Захват Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Imgur Uploader Выгрузка на Imgur Application Приложение Annotator Параметры риÑÐ¾Ð²Ð°Ð½Ð¸Ñ HotKeys ГорÑчие клавиши Uploader Выгрузка Script Uploader Выгрузка через Ñкрипт Saver Сохранение Stickers Стикеры Snipping Area Зона обрезки Tray Icon Значок в трее Watermark ВодÑной знак Actions ДейÑÑ‚Ð²Ð¸Ñ FTP Uploader FTP-загрузчик Plugins Плагины Search Settings... ПоиÑк в наÑтройках... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. МаÑштабируйте прÑмоугольник выделениÑ, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼Ð°Ñ€ÐºÐµÑ€Ñ‹, или двигайте его, перетаÑÐºÐ¸Ð²Ð°Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð½ÑƒÑŽ обраÑть. Use arrow keys to move the selection. ИÑпользуйте клавиши-Ñтрелки Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð½Ð¾Ð¹ облаÑти. Use arrow keys while pressing CTRL to move top left handle. Ð£Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ Ctrl, иÑпользуйте клавиши-Ñтрелки Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð»ÐµÐ²Ð¾Ð³Ð¾ верхнего маркера. Use arrow keys while pressing ALT to move bottom right handle. Ð£Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ Alt, иÑпользуйте клавиши-Ñтрелки Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¾Ð³Ð¾ нижнего маркера. This message can be disabled via settings. Это Ñообщение может быть отключено через наÑтройки. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Подтвердите выбор, нажав ENTER/RETURN или дважды нажав мышью в любом меÑте. Abort by pressing ESC. Можно прервать, нажав ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Ðажмите и перемещайте Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° прÑмоугольной облаÑти, или нажмите ESC Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð°. Hold CTRL pressed to resize selection after selecting. Зажмите CTRL Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð° поÑле выбора зоны. Hold CTRL pressed to prevent resizing after selecting. ОÑтавлÑйте CTRL нажатым Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð¾Ð½Ñ‹ поÑле выбора. Operation will be canceled after 60 sec when no selection made. ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ отменена через 60 Ñекунд, еÑли не будет Ñделано выбора. This message can be disabled via settings. Это Ñообщение может быть отключено через наÑтройки. SnippingAreaSettings Freeze Image while snipping Заблокировать выделенную облаÑть при Ñнимке When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. При включении задний фон блокируетÑÑ Ð¾Ñ‚ изменений в процеÑÑе Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð±Ð»Ð°Ñти захвата. Также менÑетÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ Ñнимков Ñкрана Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¾Ð¹, при включенной опции задержка включаетÑÑ Ð´Ð¾ захвата облаÑти обрезки, а при выключенной опции задержка проиÑходит поÑле захвата облаÑти. Эта Ð¾Ð¿Ñ†Ð¸Ñ Ð²Ñегда отключена Ð´Ð»Ñ Wayland и вÑегда включена Ð´Ð»Ñ macOS. Show magnifying glass on snipping area Показывать лупу во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Показывает лупу во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð±Ð»Ð°Ñти. Эта Ð¾Ð¿Ñ†Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°ÐµÑ‚ только при включенной опции «Заморозить выделенную облаÑть». Show Snipping Area rulers Показывать линии Ð´Ð»Ñ Ð·Ð¾Ð½Ñ‹ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Horizontal and vertical lines going from desktop edges to cursor on snipping area. Показывает горизонтальные и вертикальные пунктирные линии от краёв Ñкрана к зоне выделениÑ. Show Snipping Area position and size info Показывать координаты и размер зоны When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. ЕÑли Ð»ÐµÐ²Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши не нажата - положение отображаетÑÑ, при нажатии кнопки мыши размер выбранной облаÑти отображаетÑÑ Ð² левом верхнему углу захватываемой зоны. Allow resizing rect area selection by default Разрешить изменение размера Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. ПозволÑет изменить вручную размеры зоны поÑле выделениÑ. Ð”Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½Ñ‘Ð½Ð½Ñ‹Ñ… размеров необходимо нажать кнопку Enter. Show Snipping Area info text Показывать подÑказки в зоне Ñкриншота Snipping Area cursor color Цвет курÑора зоны Ñкриншота Sets the color of the snipping area cursor. Задаёт цвет курÑора Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° облаÑти обрезки. Snipping Area cursor thickness Толщина курÑора облаÑти обрезки Sets the thickness of the snipping area cursor. Задаёт толщину курÑора облаÑти обрезки. Snipping Area Зона обрезки Snipping Area adorner color Цвет Ð´ÐµÐºÐ¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð¾Ð½Ñ‹ обрезки Sets the color of all adorner elements on the snipping area. Задаёт цвет вÑех декоративных Ñлементов зоны обрезки. Snipping Area Transparency ПрозрачноÑть зоны обрезки Alpha for not selected region on snipping area. Smaller number is more transparent. ПрозрачноÑть невыделенной облаÑти в зоне обрезки Меньше значение — больше прозрачноÑть. Enable Snipping Area offset Включить Ñмещение зоны обрезки When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. ЕÑли включено, заданное Ñмещение будет применÑтьÑÑ Ðº позиции зоны обрезки. ИÑпользуйте, еÑли Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÑетÑÑ Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð¾, например при активном маÑштабировании Ñкрана. X X Y Y StickerSettings Up Вверх Down Вниз Use Default Stickers ИÑпользовать Ñтикеры по умолчанию Sticker Settings ÐаÑтройки Ñтикеров Vector Image Files (*.svg) Файлы векторных изображений (*.svg) Add Добавить Remove Удалить Add Stickers Добавить Ñтикеры TrayIcon Show Editor Показать редактор TrayIconSettings Use Tray Icon Показывать значок в трее When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. При включении добавит значок в трей панели задач, еÑли оконный менеджер ОС Ñто поддерживает. Изменение требует перезапуÑка приложениÑ. Minimize to Tray Сворачивать в трей Start Minimized to Tray ЗапуÑкать Ñвёрнутым в трей Close to Tray Сворачивать в трей при закрытии Show Editor Показать редактор Capture Снимок Default Tray Icon action ДейÑтвие по умолчанию Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐºÐ° в трее Default Action that is triggered by left clicking the tray icon. ДейÑтвие по умолчанию, вызываемое нажатием левой кнопкой мыши на значок в трее. Tray Icon Settings ÐаÑтройки значка в трее Use platform specific notification service ИÑпользовать ÑиÑтемную Ñлужбу уведомлений When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. При включении будет иÑпользоватьÑÑ ÑиÑÑ‚ÐµÐ¼Ð½Ð°Ñ Ñлужба уведомлений, еÑли Ñ‚Ð°ÐºÐ¾Ð²Ð°Ñ ÑущеÑтвует. Ð”Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð±Ñ…Ð¾Ð´Ð¸Ð¼ перезапуÑк. Display Tray Icon notifications Отображать ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð·Ð½Ð°Ñ‡ÐºÐ° в ÑиÑтемном лотке UpdateWatermarkOperation Select Image Выбрать изображение Image Files Файлы изображений UploadOperation Upload Script Required Ðеобходим Ñкрипт выгрузки Please add an upload script via Options > Settings > Upload Script ПожалуйÑта, добавьте Ñкрипт выгрузки через Опции > ÐаÑтройки > Выгрузка через Ñкрипт Capture Upload Выгрузка Ñнимка Ñкрана на внешний реÑÑƒÑ€Ñ You are about to upload the image to an external destination, do you want to proceed? Ð’Ñ‹ ÑобираетеÑÑŒ выгрузить изображение на внешний реÑурÑ, хотите продолжить? UploaderSettings Ask for confirmation before uploading Запрашивать подтверждение перед выгрузкой Uploader Type: Тип выгрузки: Imgur Imgur Script Скрипт Uploader Выгрузка на внешний реÑÑƒÑ€Ñ FTP FTP VersionTab Version ВерÑÐ¸Ñ Build Сборка Using: Программа иÑпользует: WatermarkSettings Watermark Image ВодÑной знак Update Обновить Rotate Watermark Повернуть водÑной знак When enabled, Watermark will be added with a rotation of 45° При включении водÑной знак будет добавлен Ñ Ð¿Ð¾Ð²Ð¾Ñ€Ð¾Ñ‚Ð¾Ð¼ на 45° Watermark Settings ÐаÑтройки водÑного знака ksnip-master/translations/ksnip_si.ts000066400000000000000000001754431457262621600204340ustar00rootroot00000000000000 AboutDialog About පිළිබඳව About පිළිබඳව Version අනුවà·à¶¯à¶º Author කර්තෘ Close වසන්න Donate පරිත්â€à¶ºà·à¶œ Contact සබඳතà·à·€ AboutTab License: බලපත්â€à¶»à¶º: Screenshot and Annotation Tool ActionSettingTab Name නම Shortcut කෙටිමග Clear හිස් කරන්න Take Capture ග්â€à¶»à·„ණය කරන්න Include Cursor ඊතලය සහිතව Delay à¶´à·Šâ€à¶»à¶¸à·à¶¯à¶º s The small letter s stands for seconds. à¶­à¶­à·Š. Capture Mode ග්â€à¶»à·„à¶« à¶´à·Šâ€à¶»à¶šà·à¶»à¶º Show image in Pin Window Copy image to Clipboard පසුරුපුවරුවට අනුරුව à¶´à·’à¶§à¶´à¶­à·Š කරන්න Upload image උඩුගත කරන්න Open image parent directory Save image අනුරුව සුරකින්න Hide Main Window à¶´à·Šâ€à¶»à¶°à·à¶± කවුළුව සඟවන්න Global à¶œà·à¶½à·“ය When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add à¶‘à¶šà¶­à·” කරන්න Actions Settings à¶šà·Šâ€à¶»à·’යමà·à¶»à·Šà¶œ à·ƒà·à¶šà·ƒà·”ම Action à¶šà·Šâ€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œà¶º AddWatermarkOperation Watermark Image Required Please add a Watermark Image via Options > Settings > Annotator > Update AnnotationSettings Smooth Painter Paths When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Annotator Settings Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Application Style Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings යෙදුමේ à·ƒà·à¶šà·ƒà·”ම් Automatically copy new captures to clipboard Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging නිදොස්කරණය සබල කරන්න Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory à¶­à·à·€à¶šà·à¶½à·’à¶š à¶±à·à¶¸à·à·€à¶½à·’ය Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse පිරික්සන්න AuthorTab Contributors: සහදà·à¶ºà¶šà¶ºà·’න්: Spanish Translation ස්පà·à¶¤à·Šà¶¤ පරිවර්තනය Dutch Translation ලන්දේසි පරිවර්තනය Russian Translation රුසියà·à¶±à·” පරිවර්තනය Norwegian BokmÃ¥l Translation à¶±à·à¶»à·Šà·€à·“ජියà·à¶±à·” බොක්මà·à¶½à·Š පරිවර්තනය French Translation à¶´à·Šâ€à¶»à¶‚෠පරිවර්තනය Polish Translation à¶´à·à¶½à¶±à·Šà¶­ පරිවර්තනය Snap & Flatpak Support ස්නà·à¶´à·Š සහ ෆ්ලà·à¶§à·Šà¶´à·à¶šà·Š සහà·à¶º The Authors: කතුවරු: CanDiscardOperation Warning - අවවà·à¶¯à¶ºà¶ºà·’ - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New නව Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community à¶´à·Šâ€à¶»à¶¢à·à·€ Bug Reports දà·à·‚ à·€à·à¶»à·Šà¶­à· If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard පසුරුපුවරුවට à¶´à·’à¶§à¶´à¶­à·Š වීමට අසමත් විය Failed to copy to clipboard as base64 encoded image. base64 ආකේතිත අනුරුවක් ලෙස පසුරුපුවරුවට à¶´à·’à¶§à¶´à¶­à·Š වීමට අසමත් විය. Copied to clipboard පසුරුපුවරුවට à¶´à·’à¶§à¶´à¶­à·Š විය Copied to clipboard as base64 encoded image. base64 ආකේතිත අනුරුවක් ලෙස පසුරුපුවරුවට à¶´à·’à¶§à¶´à¶­à·Š විය. DeleteImageOperation Delete Image අනුරුව මකන්න The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome පරිත්â€à¶ºà·à¶œ à·ƒà·à¶¸à·€à·’ටම පිළිගනු à¶½à·à¶¶à·š Donation පරිත්â€à¶ºà·à¶œ ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area සෘජුකà·à¶«à·à·ƒà·Šâ€à¶» à¶´à·Šâ€à¶»à¶¯à·šà·à¶º Last Rectangular Area අන්තිම සෘජුකà·à¶«à·à·ƒà·Šâ€à¶» පෙදෙස Full Screen (All Monitors) පූර්ණ තිරය (සියළු දර්à·à¶š) Current Screen වත්මන් තිරය Active Window සක්â€à¶»à·“ය කවුළුව Window Under Cursor Screenshot Portal තිරසේය෠ද්වà·à¶»à¶º FtpUploaderSettings Force anonymous upload. à¶¶à¶½à·à¶­à·Šà¶¸à¶š නිර්නà·à¶¸à·’à¶š උඩුගත කිරීම. Url à¶’.à·ƒ.නි. Username පරිà·à·Šâ€à¶»à·“ලක à¶±à·à¶¸à¶º Password මුරපදය FTP Uploader HandleUploadResultOperation Upload Successful උඩුගත වීම à·ƒà·à¶»à·Šà¶®à¶šà¶ºà·’ Unable to save temporary image for upload. උඩුගත කිරීමට අනුරුව à¶­à·à·€à¶šà·à¶½à·’à¶šà·€ සුරà·à¶šà·“මට නොහà·à¶šà·’යි. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed උඩුගත වීම à¶…à·ƒà·à¶»à·Šà¶®à¶šà¶ºà·’ Script wrote to StdErr. FTP Upload finished successfully. Unknown error. නොදන්න෠දà·à·‚යකි. Connection Error. සම්බන්ධතà·à·€à¶ºà·š දà·à·‚යකි. Permission Error. අවසර දà·à·‚යකි. Upload script %1 finished successfully. Uploaded to %1 %1 වෙත උඩුගත විය HotKeySettings Enable Global HotKeys à¶œà·à¶½à·“ය උණුසුම් යතුර සබල කරන්න Capture Rect Area Capture Full Screen පූර්ණ තිරය ග්â€à¶»à·„ණය Capture current Screen වත්මන් තිරය ග්â€à¶»à·„ණය Capture active Window සක්â€à¶»à·’ය කවුළුව ග්â€à¶»à·„ණය Capture Window under Cursor Global HotKeys à¶œà·à¶½à·“ය උණුසුම් යතුරු Capture Last Rect Area Clear හිස් කරන්න Capture using Portal ද්වà·à¶»à¶º à¶·à·à·€à·’තයෙන් ග්â€à¶»à·„ණය HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot තිරසේයà·à·€ අතරතුර à¶´à·Šâ€à¶»à¶°à·à¶± කවුළුව සඟවන්න Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Imgur ඉතිහà·à·ƒà¶º Close වසන්න Time Stamp Link සබà·à¶³à·’ය Delete Link සබà·à¶³à·’ය මකන්න ImgurUploader Upload to imgur.com finished! Imgur.com වෙත උඩුගත කිරීම අවසන්! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload à¶¶à¶½à·à¶­à·Šà¶¸à¶š නිර්නà·à¶¸à·’à¶š උඩුගත කිරීම Always copy Imgur link to clipboard à·ƒà·à¶¸à·€à·’ටම Imgur සබà·à¶³à·’ය පසුරුපුවරුවට à¶´à·’à¶§à¶´à¶­à·Š කරන්න Client ID අනුග්â€à¶»à·à·„කයේ à·„à·à¶³à·”නුම Client Secret අනුග්â€à¶»à·à·„කයේ රහස PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur ඉතිහà·à·ƒà¶º Imgur Uploader Username පරිà·à·Šâ€à¶»à·“ලක à¶±à·à¶¸à¶º Waiting for imgur.com… Imgur.com සඳහ෠රà·à¶³à·™à¶¸à·’න්… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image අනුරුව විවෘත කිරීමට නොහà·à¶šà·’යි Unable to open image from path %1 %1 මà·à¶»à·Šà¶œà¶ºà·™à¶±à·Š අනුරුව විවෘත කිරීමට නොහà·à¶šà·’යි MainToolBar New නව Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. à¶­à¶­à·Š. Save සුරකින්න Save Screen Capture to file system Copy à¶´à·’à¶§à¶´à¶­à¶šà·Š Copy Screen Capture to clipboard Tools මෙවලම් Undo පෙරසේ Redo පසුසේ Crop à¶šà¶´à·Šà¶´à·à¶¯à·”à·€ Crop Screen Capture MainWindow Unsaved නොසුරà·à¶šà·’ Upload උඩුගත කරන්න Print මුද්â€à¶»à¶«à¶º කරන්න Opens printer dialog and provide option to print image Print Preview මුද්â€à¶»à¶« පෙරදසුන Opens Print Preview dialog where the image orientation can be changed Scale පරිමà·à¶«à¶±à¶º Quit ඉවත් වන්න Settings à·ƒà·à¶šà·ƒà·”ම් &About &පිළිබඳව Open අරින්න &Edit &සංස්කරණය &Options &විකල්ප &Help &à¶‹à¶´à¶šà·à¶» Add Watermark දිය සලකුණ යොදන්න Add Watermark to captured image. Multiple watermarks can be added. &File &ගොනුව Unable to show image අනුරුව පෙන්වීමට නොහà·à¶šà·’යි Save As... මෙලෙස සුරකින්න... Paste අලවන්න Paste Embedded à¶šà·à·€à·à¶¯à·Šà¶¯à·“ම අලවන්න Pin අමුණන්න Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path මà·à¶»à·Šà¶œà¶ºà·š à¶´à·’à¶§à¶´à¶­à¶šà·Š Open Directory à¶±à·à¶¸à·à·€à¶½à·’ය අරින්න &View &දà·à¶šà·Šà¶¸ Delete මකන්න Rename à¶±à·à·€à¶­ නම් කරන්න Open Images අනුරූප අරින්න Show Docks Hide Docks Copy as data URI දත්ත à¶’.à·ƒ.à·„. (URI) ලෙස à¶´à·’à¶§à¶´à¶­à¶šà·Š Open &Recent මෑත දෑ අරින්න Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image අනුරුව පරිමà·à¶±à¶«à¶º Rotate කරකවන්න Rotate Image අනුරුව කරකවන්න Actions à¶šà·Šâ€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œ Image Files අනුරූ ගොනු Save All සියල්ල සුරකින්න Close Window කවුළුව වසන්න Cut කපන්න OCR MultiCaptureHandler Save සුරකින්න Save As මෙලෙස සුරකින්න Open Directory à¶±à·à¶¸à·à·€à¶½à·’ය අරින්න Copy à¶´à·’à¶§à¶´à¶­à·Š කරන්න Copy Path මà·à¶»à·Šà¶œà¶ºà·š à¶´à·’à¶§à¶´à¶­à¶šà·Š Delete මකන්න Rename à¶±à·à·€à¶­ නම් කරන්න Save All සියල්ල සුරකින්න NewCaptureNameProvider Capture ග්â€à¶»à·„ණය OcrWindowCreator OCR Window %1 PinWindow Close වසන්න Close Other අනෙක්ව෠වසන්න Close All සියල්ල වසන්න PinWindowCreator OCR Window %1 OCR කවුළු %1 PluginsSettings Search Path සෙà·à¶ºà¶± මà·à¶»à·Šà¶œà¶º Default පෙරනිමි The directory where the plugins are located. පේනු තිබෙන à¶±à·à¶¸à·à·€à¶½à·’ය. Browse පිරික්සන්න Name නම Version අනුවà·à¶¯à¶º Detect à¶…à¶±à·à·€à¶»à¶«à¶º Plugin Settings පේනු à·ƒà·à¶šà·ƒà·”ම් Plugin location පේනුවේ ස්ථà·à¶±à¶º ProcessIndicator Processing RenameOperation Image Renamed අනුරුව නම් කෙරිණි Image Rename Failed අනුරුව නම් කිරීමට අසමත් විය Rename image අනුරුව යළි නම් කරන්න New filename: ගොනුවේ නව à¶±à·à¶¸à¶º: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As මෙලෙස සුරකින්න All Files සියළුම ගොනු Image Saved අනුරුව සුරà·à¶šà·’à¶«à·’ Saving Image Failed අනුරුව සුරà·à¶šà·“මට අසමත් විය Image Files අනුරූ ගොනු Saved to %1 %1 වෙත සුරà·à¶šà·’à¶«à·’ Failed to save image to %1 SaverSettings Automatically save new captures to default location නව තිරසේය෠ස්වයංක්â€à¶»à·’යව පෙරනිමි ස්ථà·à¶±à¶ºà·š සුරකින්න Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename තිරසේය෠සුරà·à¶šà·™à¶± ස්ථà·à¶±à¶º හ෠ගොනුවේ නම Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse පිරික්සන්න Saver Settings සුරà·à¶šà·“මේ à·ƒà·à¶šà·ƒà·”ම් Capture save location තිරසේය෠සුරà·à¶šà·™à¶± ස්ථà·à¶±à¶º Default පෙරනිමි Factor Save Quality සුරà·à¶šà·™à¶± ගුණත්â€à·€à¶º Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse පිරික්සන්න Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: පෙරහන: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings à·ƒà·à¶šà·ƒà·”ම් OK හරි Cancel අවලංගු කරන්න Image Grabber Imgur Uploader Application යෙදුම Annotator HotKeys උණුසුම් යතුරු Uploader Script Uploader Saver සුරà·à¶šà·”ම Stickers ඇඳිරූප Snipping Area Tray Icon Watermark දිය සලකුණ Actions à¶šà·Šâ€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œ FTP Uploader Plugins පේනු Search Settings... à·ƒà·à¶šà·ƒà·”ම් සොයන්න... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. à·ƒà·à¶šà·ƒà·”ම් හරහ෠මෙම පණිවිඩය à¶…à¶¶à¶½ à¶šà·… à·„à·à¶šà·’ය. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. à·ƒà·à¶šà·ƒà·”ම් හරහ෠මෙම පණිවිඩය à¶…à¶¶à¶½ à¶šà·… à·„à·à¶šà·’ය. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up ඉහළට Down à¶´à·„à·…à¶§ Use Default Stickers පෙරනිමි ඇඳිරූප යොදà·à¶œà¶±à·Šà¶± Sticker Settings ඇඳිරූප à·ƒà·à¶šà·ƒà·”ම් Vector Image Files (*.svg) Add à¶‘à¶šà¶­à·” කරන්න Remove ඉවත් කරන්න Add Stickers ඇඳිරූප à¶‘à¶šà·Š කරන්න TrayIcon Show Editor සංස්කරකය පෙන්වන්න TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor සංස්කරකය පෙන්වන්න Capture ග්â€à¶»à·„ණය Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image අනුරුවක් à¶­à·à¶»à¶±à·Šà¶± Image Files අනුරූ ගොනු UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version අනුවà·à¶¯à¶º Build à¶­à·à¶±à·“ම Using: à¶·à·à·€à·’තයෙන්: WatermarkSettings Watermark Image Update යà·à·€à¶­à·Šà¶šà·à¶½ Rotate Watermark දිය සලකුණ කරකවන්න When enabled, Watermark will be added with a rotation of 45° Watermark Settings දිය සලකුණු à·ƒà·à¶šà·ƒà·”ම් ksnip-master/translations/ksnip_sl.ts000066400000000000000000001647641457262621600204430ustar00rootroot00000000000000 AboutDialog About About Version RazliÄica Author Avtor Close Zapri Donate Licenca Contact Kontakt AboutTab License: Licenca Screenshot and Annotation Tool ActionSettingTab Name Ime Shortcut Bližnjica Clear PoÄisti Take Capture Include Cursor Delay Zakasnitev s The small letter s stands for seconds. s Capture Mode NaÄin zajema Show image in Pin Window Copy image to Clipboard Kopiraj sliko v odložiÅ¡Äe Upload image Open image parent directory Odprite nadrejeni imenik slik Save image Shrani sliko Hide Main Window Skrij glavno okno Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add Dodaj Actions Settings Nastavitve dejanj Action Dejanje AddWatermarkOperation Watermark Image Required Please add a Watermark Image via Options > Settings > Annotator > Update AnnotationSettings Smooth Painter Paths When enabled smooths out pen and marker paths after finished drawing. Smooth Factor Stopnja glajenja Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. PoveÄanje stopnje glajenja bo zmanjÅ¡alo natanÄnost za pero in marker, ampak jih bo naredilobolj gladke. Annotator Settings Remember annotation tool selection and load on startup Switch to Select Tool after drawing Item Po risanju predmeta preklopite na Izberi orodje Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Barva platna Default Canvas background color for annotation area. Changing color affects only new annotation areas. Select Item after drawing Izberite element po risanju With this option enabled the item gets selected after being created, allowing changing settings. Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode Application Style Slog aplikacije Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Application Settings Nastavitve aplikacije Automatically copy new captures to clipboard Samodejno kopiranje novih posnetkov v odložiÅ¡Äe Use Tabs Change requires restart. Run ksnip as single instance Hide Tabbar when only one Tab is used. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Remember Main Window position on move and load on startup Auto hide Tabs Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content Automatically resize Main Window to fit content image. Enable Debugging Enables debug output written to the console. Change requires ksnip restart to take effect. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse AuthorTab Contributors: Spanish Translation Dutch Translation Russian Translation Norwegian BokmÃ¥l Translation French Translation Polish Translation Snap & Flatpak Support The Authors: CanDiscardOperation Warning - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Draw a rectangular area with your mouse Capture full screen including all monitors Capture screen where the mouse is located Capture window that currently has focus Capture that is currently under the mouse cursor Capture a screenshot of the last selected rectangular area Uses the screenshot Portal for taking screenshot ContactTab Community Bug Reports If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Please use %1 to report bugs. CopyAsDataUriOperation Failed to copy to clipboard Failed to copy to clipboard as base64 encoded image. Copied to clipboard Copied to clipboard as base64 encoded image. DeleteImageOperation Delete Image The item '%1' will be deleted. Do you want to continue? DonateTab Donations are always welcome Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. EnumTranslator Rectangular Area Last Rectangular Area Full Screen (All Monitors) Current Screen Active Window Window Under Cursor Screenshot Portal FtpUploaderSettings Force anonymous upload. Url Username Password FTP Uploader HandleUploadResultOperation Upload Successful Unable to save temporary image for upload. Unable to start process, check path and permissions. Process crashed Process timed out. Process read error. Process write error. Web error, check console output. Upload Failed Script wrote to StdErr. FTP Upload finished successfully. Unknown error. Connection Error. Permission Error. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Capture Rect Area Capture Full Screen Capture current Screen Capture active Window Capture Window under Cursor Global HotKeys Capture Last Rect Area Clear PoÄisti Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Should mouse cursor be visible on screenshots. Image Grabber Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Hide Main Window when capturing a new screenshot. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Close Zapri Time Stamp Link Delete Link ImgurUploader Upload to imgur.com finished! Received new token, trying upload again… Imgur token has expired, requesting new token… ImgurUploaderSettings Force anonymous upload Always copy Imgur link to clipboard Client ID Client Secret PIN Enter imgur Pin which will be exchanged for a token. Get PIN Get Token Imgur History Imgur Uploader Username Waiting for imgur.com… Imgur.com token successfully updated. Imgur.com token update error. After uploading open Imgur link in default browser Link directly to image Base Url: Base url that will be used for communication with Imgur. Changing requires restart. Clear Token Upload title: Upload description: LoadImageFromFileOperation Unable to open image Unable to open image from path %1 MainToolBar New Delay in seconds between triggering and capturing screenshot. s The small letter s stands for seconds. s Save Save Screen Capture to file system Copy Copy Screen Capture to clipboard Tools Undo Redo Crop Crop Screen Capture MainWindow Unsaved Upload Print Opens printer dialog and provide option to print image Print Preview Opens Print Preview dialog where the image orientation can be changed Scale Quit Settings &About Open &Edit &Options &Help Add Watermark Add Watermark to captured image. Multiple watermarks can be added. &File Unable to show image Save As... Paste Paste Embedded Pin Pin screenshot to foreground in frameless window No image provided but one was expected. Copy Path Open Directory &View Delete Rename Open Images Show Docks Hide Docks Copy as data URI Open &Recent Modify Canvas Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Rotate Rotate Image Actions Image Files Save All Close Window Cut OCR MultiCaptureHandler Save Save As Open Directory Copy Copy Path Delete Rename Save All NewCaptureNameProvider Capture OcrWindowCreator OCR Window %1 PinWindow Close Zapri Close Other Close All PinWindowCreator OCR Window %1 PluginsSettings Search Path Default The directory where the plugins are located. Browse Name Ime Version RazliÄica Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed Image Rename Failed Rename image New filename: Successfully renamed image to %1 Failed to rename image to %1 SaveOperation Save As All Files Image Saved Saving Image Failed Image Files Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Prompt to save before discarding unsaved changes Remember last Save Directory When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Saver Settings Capture save location Default Factor Save Quality Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard Script: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Script Uploader Select Upload Script Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. SettingsDialog Settings OK Cancel Image Grabber Imgur Uploader Application Annotator HotKeys Uploader Script Uploader Saver Stickers Snipping Area Tray Icon Watermark Actions FTP Uploader Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. This message can be disabled via settings. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Hold CTRL pressed to prevent resizing after selecting. Operation will be canceled after 60 sec when no selection made. This message can be disabled via settings. SnippingAreaSettings Freeze Image while snipping When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Show Snipping Area rulers Horizontal and vertical lines going from desktop edges to cursor on snipping area. Show Snipping Area position and size info When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Sets the color of the snipping area cursor. Snipping Area cursor thickness Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up Down Use Default Stickers Sticker Settings Vector Image Files (*.svg) Add Dodaj Remove Add Stickers TrayIcon Show Editor TrayIconSettings Use Tray Icon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Minimize to Tray Start Minimized to Tray Close to Tray Show Editor Capture Default Tray Icon action Default Action that is triggered by left clicking the tray icon. Tray Icon Settings Use platform specific notification service When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications UpdateWatermarkOperation Select Image Image Files UploadOperation Upload Script Required Please add an upload script via Options > Settings > Upload Script Capture Upload You are about to upload the image to an external destination, do you want to proceed? UploaderSettings Ask for confirmation before uploading Uploader Type: Imgur Script Uploader FTP VersionTab Version RazliÄica Build Using: WatermarkSettings Watermark Image Update Rotate Watermark When enabled, Watermark will be added with a rotation of 45° Watermark Settings ksnip-master/translations/ksnip_sv.ts000066400000000000000000002032561457262621600204430ustar00rootroot00000000000000 AboutDialog About Om About Om Version Version Author Utvecklare Close Stäng Donate Donera Contact Kontakt AboutTab License: Licens: Screenshot and Annotation Tool Skärmklipps- och anteckningsverktyg ActionSettingTab Name Namn Shortcut Genväg Clear Rensa Take Capture Ta skärmklipp Include Cursor Inkludera muspekare Delay Fördröjning s The small letter s stands for seconds. s Capture Mode Skärmklippsläge Show image in Pin Window Visa bilden i ett fäst fönster Copy image to Clipboard Kopiera bilden till urklipp Upload image Ladda upp bilden Open image parent directory Öppna bildens överordnade mapp Save image Spara bilden Hide Main Window Dölj huvudfönstret Global Systemövergripande When enabled will make the shortcut available even when ksnip has no focus. Aktivering gör genvägen tillgänglig även när ksnip inte har fokus. ActionsSettings Add Lägg till Actions Settings Ã…tgärdsinställningar Action Ã…tgärd AddWatermarkOperation Watermark Image Required Vattenstämpelbild krävs Please add a Watermark Image via Options > Settings > Annotator > Update Lägg till en vattenstämpel via Alternativ > Inställningar > Anteckningar > Uppdatera AnnotationSettings Smooth Painter Paths Utjämna ritade objekt When enabled smooths out pen and marker paths after finished drawing. Vid aktivering utjämnas penn- och markeringsstreck efter avslutad ritning. Smooth Factor Utjämningsfaktor Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Ökad utjämningsfaktor minskar precisionen för penna och markör, men gör dem mjukare. Annotator Settings Anteckningsinställningar Remember annotation tool selection and load on startup Kom ihÃ¥g val av ritverktyg och läs in vid uppstart Switch to Select Tool after drawing Item Växla för att välja verktyg efter att ett objekt ritats Number Tool Seed change updates all Number Items Ändring i numreringsverktyget uppdaterar alla nummerposter Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Inaktivering av det här alternativet innebär att numreringsverktyget pÃ¥verkar endast nya objekt men inte befintliga. Inaktivering lÃ¥ter dig använda dubblettnummer. Canvas Color Färg pÃ¥ arbetsytan Default Canvas background color for annotation area. Changing color affects only new annotation areas. Standardfärg pÃ¥ arbetsytan i anteckningsomrÃ¥det. Ändring av färgen pÃ¥verkar bara nya anteckningsomrÃ¥den. Select Item after drawing Markera objekt efter ritning With this option enabled the item gets selected after being created, allowing changing settings. Med det här alternativet aktiverat, markeras objektet efter att det skapats, vilket gör det möjligt att ändra inställningar. Show Controls Widget Visa kontrollwidget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Kontrollwidgeten innehÃ¥ller knappar för Ã…ngra/Upprepa, Beskär, Skala, Rotera och Ändra arbetsytan. ApplicationSettings Capture screenshot at startup with default mode Ta skärmklipp vid uppstart med standardläget Application Style Programstil Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Anger programstilen, vilket definierar utseende och känsla i GUI. Ändringar tillämpas efter omstart av ksnip. Application Settings Programinställningar Automatically copy new captures to clipboard Kopiera automatiskt nya skärmklipp till urklipp Use Tabs Använd flikar Change requires restart. Ändring kräver omstart. Run ksnip as single instance Kör ksnip som enskild instans Hide Tabbar when only one Tab is used. Dölj flikfältet när endast en flik används. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Om du aktiverar detta alternativ kan endast en ksnip-instans köras, alla instanser som startas efter den första, kommer att skicka sina argument vidare till den första och sedan avslutas. Om det här alternativet ändras mÃ¥ste alla öppna instanser startas om. Remember Main Window position on move and load on startup Kom ihÃ¥g huvudfönstrets position vid förflyttning och läs in vid programstart Auto hide Tabs Dölj flikar automatiskt Auto hide Docks Dölj dockor automatiskt On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Dölj verktygsfält och noteringsinställningar vid uppstart. Dockors synlighet kan växlas med Tab-tangenten. Auto resize to content Storleksändra automatiskt efter innehÃ¥ll Automatically resize Main Window to fit content image. Ändra automatiskt storleken pÃ¥ huvudfönstret för att passa bilden. Enable Debugging Aktivera felsökning Enables debug output written to the console. Change requires ksnip restart to take effect. Aktiverar felsökningsutdata i konsolen. ksnip mÃ¥ste startas om för att ändringen skall tillämpas. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Storleksändring till innehÃ¥ll är en fördröjning för att fönsterhanteraren skall kunna ta emot det nya innehÃ¥llet. Om huvudfönstret inte är korrekt inställt till det nya innehÃ¥llet, kan en ökning av denna fördröjning förbättra beteendet. Resize delay Fördröjning av storleksändring Temp Directory Temp-katalog Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Temp-katalog för att lagra tillfälliga bilder som kommer att raderas när ksnip stängs. Browse Bläddra AuthorTab Contributors: Medverkande: Spanish Translation Spansk översättning Dutch Translation Nederländsk översättning Russian Translation Rysk översättning Norwegian BokmÃ¥l Translation Norsk (BokmÃ¥l) översättning French Translation Fransk översättning Polish Translation Polsk översättning Snap & Flatpak Support Snap- & Flatpak-stöd The Authors: Upphovsmän: CanDiscardOperation Warning - Varning! - The capture %1%2%3 has been modified. Do you want to save it? Klippet %1%2%3 har ändrats. Vill du spara det? CaptureModePicker New Nytt Draw a rectangular area with your mouse Dra upp ett rektangulärt omrÃ¥de med musen Capture full screen including all monitors Avbildar hela skärmen, samtliga skärmar inkluderade Capture screen where the mouse is located Avbildar skärmen där muspekaren befinner sig Capture window that currently has focus Avbildar det fönster som har fokus Capture that is currently under the mouse cursor Avbildar fönstret under muspekaren Capture a screenshot of the last selected rectangular area Tar ett skärmklipp av senast markerade rektangulära omrÃ¥de Uses the screenshot Portal for taking screenshot Använder skärmklippsportalen för att ta skärmdump ContactTab Community Gemenskap Bug Reports Felrapporter If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Om du har allmänna frÃ¥gor, idéer eller bara vill prata om ksnip,<br/>kan du ansluta till vÃ¥r %1- eller %2-server. Please use %1 to report bugs. Använd %1 för att rapportera fel. CopyAsDataUriOperation Failed to copy to clipboard Kunde inte kopiera till urklipp Failed to copy to clipboard as base64 encoded image. Kunde inte kopiera till urklipp som base64-kodad bild. Copied to clipboard Kopierat till urklipp Copied to clipboard as base64 encoded image. Kopierat till urklipp som base64-kodad bild. DeleteImageOperation Delete Image Ta bort bild The item '%1' will be deleted. Do you want to continue? "%1" kommer att tas bort. Vill du fortsätta? DonateTab Donations are always welcome Donationer är alltid välkomna Donation Donation ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip är ett icke-vinstdrivande copyleft-projekt för fri programvara, och<br/>har fortfarande vissa kostnader som mÃ¥ste täckas,<br/>som domänkostnader eller hÃ¥rdvarukostnader för plattformsoberoende stöd. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Om du vill hjälpa till eller bara uppskatta det arbete som görs<br/>genom att bjuda utvecklarna pÃ¥ en öl eller en kopp kaffe kan du göra det %1här%2. Become a GitHub Sponsor? Vill du bli en GitHub-sponsor? Also possible, %1here%2. Det är ocksÃ¥ möjligt, %1här%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Lägg till nya Ã¥tgärder genom att trycka pÃ¥ "Lägg till". EnumTranslator Rectangular Area Rektangulärt omrÃ¥de Last Rectangular Area Senaste rektangulära omrÃ¥de Full Screen (All Monitors) Helskärm (Alla skärmar) Current Screen Aktuell skärm Active Window Aktivt fönster Window Under Cursor Fönster under muspekaren Screenshot Portal Skärmklippsportal FtpUploaderSettings Force anonymous upload. Tvinga fram anonym uppladdning. Url URL Username Användarnamn Password Lösenord FTP Uploader FTP-uppladdare HandleUploadResultOperation Upload Successful Uppladdning slutförd Unable to save temporary image for upload. Kan inte spara temporär bild för uppladdning. Unable to start process, check path and permissions. Det gick inte att starta processen, kontrollera sökväg och behörigheter. Process crashed Processen kraschade Process timed out. Tidsgränsen för processen överskreds. Process read error. Läsfel i processen. Process write error. Skrivfel i processen. Web error, check console output. Webbfel, kontrollera utdata i konsolen. Upload Failed Uppladdning misslyckades Script wrote to StdErr. Skript skrev till StdErr. FTP Upload finished successfully. FTP-uppladdningen har slutförts. Unknown error. Okänt fel. Connection Error. Anslutningsfel. Permission Error. Behörighetsfel. Upload script %1 finished successfully. Uppladdningsskriptet %1 har slutförts. Uploaded to %1 Uppladdat till %1 HotKeySettings Enable Global HotKeys Aktivera systemövergripande snabbtangenter Capture Rect Area Avbilda rektangulärt omrÃ¥de Capture Full Screen Avbilda helskärm Capture current Screen Avbilda aktuell skärm Capture active Window Avbilda aktivt fönster Capture Window under Cursor Avbilda fönster under muspekare Global HotKeys Systemövergripande snabbtangenter Capture Last Rect Area Avbilda senaste rektangulära omrÃ¥de Clear Rensa Capture using Portal Klipp ut med hjälp av Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Snabbtangenter stöds för närvarande endast av Windows och X11. Inaktivering av detta alternativ gör ocksÃ¥ Ã¥tgärdsgenvägar till endast ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Ta med muspekaren i skärmklipp Should mouse cursor be visible on screenshots. Om muspekaren skall vara synlig i skärmklipp. Image Grabber OmrÃ¥desklipp Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Inbyggda Wayland-implementeringar som använder XDG-DESKTOP-PORTAL hanterar skärmskalning olikt. Aktivering av detta alternativ kommer avgöra aktuell skärmskalning och tillämpa det pÃ¥ skärmklipp i ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME och KDE Plasma stödjer det egna Wayland och inbyggda XDG-DESKTOP-PORTAL-skärmklipp. Om alternativet aktiveras kommer KDE Plasma och GNOME att använda XDG-DESKTOP-PORTAL-skärmklipp. Ändring i det här alternativet kräveratt ksnip startas om. Show Main Window after capturing screenshot Visa huvudfönstret efter utfört skärmklipp Hide Main Window during screenshot Dölj huvudfönstret under skärmklipp Hide Main Window when capturing a new screenshot. Dölj huvudfönstret när du tar ett nytt skärmklipp. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Visa huvudfönstret efter att ha tagit ett nytt skärmklipp, när huvudfönstret var dolt eller minimerat. Force Generic Wayland (xdg-desktop-portal) Screenshot Tvinga generisk Wayland (xdg-desktop-portal) Skärmdump Scale Generic Wayland (xdg-desktop-portal) Screenshots Skala Generic Wayland (xdg-desktop-portal) Skärmdumpar Implicit capture delay Implicit klippfördröjning This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Denna fördröjning används när ingen fördröjning har valts i UI, det gör att ksnip kan döljas innan det tar ett skärmklipp. Det här värdet används inte när ksnip redan är minimerad. Att minska det här värdet kan fÃ¥ effekten att ksnips huvudfönster syns pÃ¥ skärmklippet. ImgurHistoryDialog Imgur History Imgur-historik Close Stäng Time Stamp Tidsstämpel Link Länk Delete Link Ta bort länk ImgurUploader Upload to imgur.com finished! Uppladdning till imgur.com slutförd! Received new token, trying upload again… Tog emot ny token. Försöker ladda upp igen… Imgur token has expired, requesting new token… Imgur-token har upphört att gälla. Ber om ny token… ImgurUploaderSettings Force anonymous upload Tvinga fram anonym uppladdning Always copy Imgur link to clipboard Kopiera alltid Imgur-länk till urklipp Client ID Klient-ID Client Secret Klienthemlighet PIN PIN Enter imgur Pin which will be exchanged for a token. Ange Imgur PIN-kod, vilken byts mot en token. Get PIN Hämta PIN Get Token Hämta token Imgur History Imgur-historik Imgur Uploader Imgur-uppladdare Username Användarnamn Waiting for imgur.com… Väntar pÃ¥ imgur.com… Imgur.com token successfully updated. Imgur.com-token uppdaterades. Imgur.com token update error. Imgur.com-token uppdateringsfel. After uploading open Imgur link in default browser Öppna Imgur-länken i standardwebbläsare efter uppladdning Link directly to image Länka direkt till bilden Base Url: Grundläggande URL: Base url that will be used for communication with Imgur. Changing requires restart. Grundläggande URL som används för kommunikation med Imgur. Ändring kräver omstart. Clear Token Rensa token Upload title: Uppladdningsnamn: Upload description: Uppladdningsbeskrivning: LoadImageFromFileOperation Unable to open image Kan inte öppna bilden Unable to open image from path %1 Kan inte öppna bild frÃ¥n sökvägen %1 MainToolBar New Nytt Delay in seconds between triggering and capturing screenshot. Fördröjning i sekunder mellan utlösning och själva skärmklippet. s The small letter s stands for seconds. s Save Spara Save Screen Capture to file system Spara skärmklippet Copy Kopiera Copy Screen Capture to clipboard Kopiera skärmklippet till urklipp Tools Verktyg Undo Ã…ngra Redo Upprepa Crop Beskär Crop Screen Capture Beskär skärmklippet MainWindow Unsaved Osparad Upload Ladda upp Print Skriv ut Opens printer dialog and provide option to print image Öppnar en utskriftsdialog visar alternativen för utskrift Print Preview Förhandsgranskning Opens Print Preview dialog where the image orientation can be changed Öppnar en förhandsvisning av utskriften där bildorienteringen kan ändras Scale Skala Quit Avsluta Settings Inställningar &About &Om Open Öppna &Edit &Redigera &Options A&lternativ &Help &Hjälp Add Watermark Lägg till vattenstämpel Add Watermark to captured image. Multiple watermarks can be added. Lägg en vattenstämpel pÃ¥ skärmklippet. Flera vattenstämplar kan infogas. &File &Arkiv Unable to show image Kan inte visa bilden Save As... Spara som... Paste Klistra in Paste Embedded Klistra in inbäddat Pin Fäst Pin screenshot to foreground in frameless window Fäst skärmklipp i förgrunden i ramlöst fönster No image provided but one was expected. Ingen bild tillgänglig, men en var förväntad. Copy Path Kopiera sökväg Open Directory Öppna mapp &View &Visa Delete Ta bort Rename Byt namn Open Images Öppna bilder Show Docks Visa dockor Hide Docks Dölj dockor Copy as data URI Kopiera som data-URI Open &Recent Öppna &tidigare Modify Canvas Ändra arbetsyta Upload triggerCapture to external source Ladda upp skärmklipp till extern källa Copy triggerCapture to system clipboard Kopiera skärmklipp till systemets urklipp Scale Image Skala bild Rotate Rotera Rotate Image Rotera bild Actions Ã…tgärder Image Files Bildfiler Save All Spara alla Close Window Stäng fönster Cut Klipp ut OCR OCR MultiCaptureHandler Save Spara Save As Spara som Open Directory Öppna mapp Copy Kopiera Copy Path Kopiera sökväg Delete Ta bort Rename Byt namn Save All Spara alla NewCaptureNameProvider Capture Klipp OcrWindowCreator OCR Window %1 OCR-fönster %1 PinWindow Close Stäng Close Other Stäng övriga Close All Stäng alla PinWindowCreator OCR Window %1 OCR-fönster %1 PluginsSettings Search Path Sökväg Default Standard The directory where the plugins are located. Katalog där insticksprogrammen finns. Browse Bläddra Name Namn Version Version Detect Identifiera Plugin Settings Insticksinställningar Plugin location Plats för insticksprogrammet ProcessIndicator Processing Bearbetar RenameOperation Image Renamed Bilden har bytt namn Image Rename Failed Kunde inte byta namn Rename image Byt namn pÃ¥ bilden New filename: Nytt filnamn: Successfully renamed image to %1 Bildnamnet har ändrats till %1 Failed to rename image to %1 Kunde inte att byta namn pÃ¥ bilden till %1 SaveOperation Save As Spara som All Files Alla filer Image Saved Bild sparad Saving Image Failed Kunde inte spara bilden Image Files Bildfiler Saved to %1 Sparat till %1 Failed to save image to %1 Kunde inte att spara bilden till %1 SaverSettings Automatically save new captures to default location Spara automatiskt nya skärmklipp till standardplatsen Prompt to save before discarding unsaved changes FrÃ¥ga om att spara, innan osparade ändringar kasseras Remember last Save Directory Kom ihÃ¥g senaste lagringsmappen When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Vid aktivering kommer den i inställningarna sparade lagringsmappen att skrivas över med senaste lagringsmappen, varje gÃ¥ng nÃ¥got sparas. Capture save location and filename Klipplagringsplats och filnamn Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Formaten som stöds är JPG, PNG och BMP. Om inget format anges används PNG som standard. Filnamn kan innehÃ¥lla följande jokertecken: - $Y, $M, $D för datum, $h, $m, $s för tid eller $T för tid i hhmmss-format. - Flera pÃ¥ varandra följande # för räknare. #### kommer att resultera i 0001, nästa klipp blir 0002. Browse Bläddra Saver Settings Inställningar för lagring Capture save location Klipplagringsplats Default Standard Factor Faktor Save Quality Lagringskvalitet Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Ange 0 för att erhÃ¥lla smÃ¥ komprimerade filer, 100 för stora okomprimerade filer. Alla bildformat stödjer inte hela intervallet, det gör JEPG. Overwrite file with same name Skriv över filen med samma namn ScriptUploaderSettings Copy script output to clipboard Kopiera skriptutdata till urklipp Script: Skript: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Sökväg till det skript som kommer att anropas för uppladdning. Under uppladdningen kommer skriptet att anropas med sökvägen till en temporär png-fil som enskilt argument. Browse Bläddra Script Uploader Uppladdare för skript Select Upload Script Välj uppladdningsskript Stop when upload script writes to StdErr Stoppa när uppladdningsskript skriver till StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Markerar uppladdning som misslyckad när skript skriver till StdErr. Utan den här inställningen visas inga fel i skriptet. Filter: Filter: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. RegEx-uttryck. Kopiera endast till urklipp, vad som matchar RegEx-uttrycket. När detta utelämnas kopieras allt. SettingsDialog Settings Inställningar OK OK Cancel Avbryt Image Grabber Klippverktyg Imgur Uploader Imgur-uppladdare Application Program Annotator Ritverktyg HotKeys Snabbtangenter Uploader Uppladdare Script Uploader Uppladdare för skript Saver Lagring Stickers Dekaler Snipping Area KlippomrÃ¥de Tray Icon Systemfältsikon Watermark Vattenstämpel Actions Ã…tgärder FTP Uploader FTP-uppladdare Plugins Insticksprogram Search Settings... Sökinställningar... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Ändra storlek pÃ¥ markerad rektangel med hjälp av handtagen eller flytta den genom att dra markeringen. Use arrow keys to move the selection. Använd piltangenter för att flytta markeringen. Use arrow keys while pressing CTRL to move top left handle. Använd CTRL+piltangenter för att flytta handtaget i vänster överkant. Use arrow keys while pressing ALT to move bottom right handle. Använd ALT+piltangenter för att flytta handtaget i höger underkant. This message can be disabled via settings. Detta meddelande kan inaktiveras i inställningarna. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Bekräfta valet genom att trycka pÃ¥ ENTER/RETUR eller dubbelklicka med musen nÃ¥gonstans. Abort by pressing ESC. Avbryt genom att trycka ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Klicka och dra för att markera ett rektangulärt omrÃ¥de eller tryck ESC för att avsluta. Hold CTRL pressed to resize selection after selecting. HÃ¥ll CTRL nedtryckt för att ändra storlek pÃ¥ markeringen. Hold CTRL pressed to prevent resizing after selecting. HÃ¥ll CTRL nedtryckt för att förhindra storlekändring efter markering. Operation will be canceled after 60 sec when no selection made. Ã…tgärden avbryts efter 60 sekunder, om ingen markering gjorts. This message can be disabled via settings. Detta meddelande kan inaktiveras i inställningarna. SnippingAreaSettings Freeze Image while snipping Frys bilden under klipp When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Vid aktivering fryses bakgrunden medan ett rektangulärt omrÃ¥de markeras. Det ändrar ocksÃ¥ beteendet för fördröjt skärmklipp. Med detta alternativ aktiverat, sker fördröjningen innan klippomrÃ¥det visas och med alternativet avaktiverat, sker fördröjningen efter klippomrÃ¥det visas. Denna funktion är alltid inaktiverad för Wayland och alltid aktiverad för MacOS. Show magnifying glass on snipping area Visa förstoringsglas pÃ¥ klippomrÃ¥de Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Visa ett förstoringsglas som zoomar in i bakgrundsbilden. Detta alternativ fungerar endast när "Frys bilden under klipp" är aktiverat. Show Snipping Area rulers Visa linjaler pÃ¥ klippomrÃ¥det Horizontal and vertical lines going from desktop edges to cursor on snipping area. Horisontella och vertikala linjer gÃ¥r frÃ¥n skrivbordskanten till markören i klippomrÃ¥det. Show Snipping Area position and size info Visa klippomrÃ¥desplacering och storleksinformation When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. När vänster musknapp inte hÃ¥lls ner, visas positionen. När musknappen hÃ¥lls ner, visas storleken pÃ¥ markerat omrÃ¥de till vänster och över klippomrÃ¥det. Allow resizing rect area selection by default TillÃ¥t storleksändring av rektangelomrÃ¥de som standard When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Vid aktivering kommer en rektangulär omrÃ¥desmarkering att kunna storleksändras. När storleksändringen slutförts kan den tillämpas genom att trycka Retur. Show Snipping Area info text Visa informationstext för klippomrÃ¥de Snipping Area cursor color Färg pÃ¥ klippomrÃ¥desmarkören Sets the color of the snipping area cursor. Anger färgen pÃ¥ markören för klippomrÃ¥det. Snipping Area cursor thickness Tjocklek pÃ¥ klippomrÃ¥desmarkören Sets the thickness of the snipping area cursor. Anger tjockleken pÃ¥ klippomrÃ¥dets markör. Snipping Area KlippomrÃ¥de Snipping Area adorner color KlippomrÃ¥dets prydnadsfärg Sets the color of all adorner elements on the snipping area. Ställer in färgen pÃ¥ alla prydnadselement i klippomrÃ¥det. Snipping Area Transparency KlippomrÃ¥dets transparens Alpha for not selected region on snipping area. Smaller number is more transparent. Alfa för icke markerad region pÃ¥ klippomrÃ¥det. Lägre siffra är mer transparens. Enable Snipping Area offset Aktivera förskjutning av klippomrÃ¥de When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Vid aktivewring tillämpas den konfigurerade förskjutning till positionen för klippomrÃ¥det som krävs när positionen inte är korrekt beräknad. Detta krävs ibland när skärmskalning är aktiverad. X X Y Y StickerSettings Up Upp Down Ner Use Default Stickers Använda standarddekaler Sticker Settings Dekalinställningar Vector Image Files (*.svg) Vektorbilder (*.svg) Add Lägg till Remove Ta bort Add Stickers Lägg till dekaler TrayIcon Show Editor Visa redigerare TrayIconSettings Use Tray Icon Använd systemfältsikon When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Vid aktivering läggs en ikon till i systemfältet, om operativsystemet stödjer det. Ändring kräver omstart. Minimize to Tray Minimera till systemfältet Start Minimized to Tray Starta minimerad i systemfältet Close to Tray Stäng till systemfältet Show Editor Visa redigerare Capture Klipp Default Tray Icon action StandardÃ¥tgärd för systemfältsikon Default Action that is triggered by left clicking the tray icon. StandardÃ¥tgärd som utlöses genom att vänsterklicka pÃ¥ systemfältsikonen. Tray Icon Settings Inställningar för systemfältsikon Use platform specific notification service Använd plattformsspecifik aviseringstjänst When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Vid aktivering försöker ksnip använda plattformsspecifik avisering när sÃ¥dan finnes. Ändring kräver omstart för att tillämpas. Display Tray Icon notifications Visa systemfältsaviseringar UpdateWatermarkOperation Select Image Välj bild Image Files Bildfiler UploadOperation Upload Script Required Uppladdningsskript krävs Please add an upload script via Options > Settings > Upload Script Lägg till ett uppladdningsskript via Alternativ> Inställningar>Uppladdningsskript Capture Upload Skärmklippsuppladdning You are about to upload the image to an external destination, do you want to proceed? Du hÃ¥ller pÃ¥ att ladda upp bilden till en extern destination, vill du fortsätta? UploaderSettings Ask for confirmation before uploading Bekräfta före uppladdning Uploader Type: Uppladdartyp: Imgur Imgur Script Skript Uploader Uppladdare FTP FTP VersionTab Version Version Build Kompilering Using: Använder: WatermarkSettings Watermark Image Vattenstämpel Update Uppdatera Rotate Watermark Rotera vattenstämpel When enabled, Watermark will be added with a rotation of 45° Vid aktivering, roteras vattenstämpeln 45° Watermark Settings Vatenstämpelinställningar ksnip-master/translations/ksnip_tr.ts000066400000000000000000001636621457262621600204460ustar00rootroot00000000000000 AboutDialog About Hakkında About Hakkında Version Sürüm Author Yazar Close Kapat Donate Bağış Contact İletiÅŸim AboutTab License: Lisans: Screenshot and Annotation Tool Ekran Görüntüsü ve Ek Açıklama Aracı ActionSettingTab Name Ad Shortcut Kısayol Clear Temizle Take Capture Ekran Görüntüsü Al Include Cursor İmleci Dahil Et Delay Gecikme s The small letter s stands for seconds. sn Capture Mode Yakalama Modu Show image in Pin Window Görüntüyü Sabit Pencerede Göster Copy image to Clipboard Görüntüyü Panoya Kopyala Upload image Görüntü Yükle Open image parent directory Görüntü üst dizinini aç Save image Görüntüyü Kaydet Hide Main Window Ana Pencereyi Gizle ActionsSettings Add Ekle Actions Settings Eylem Ayarları Action Eylem AddWatermarkOperation Watermark Image Required Filigran Resmi Gerekli Please add a Watermark Image via Options > Settings > Annotator > Update Lüffen Seçenekler > Ayarlar > Ek Açıklama > Güncelle ile bir Filigran Resmi ekleyin AnnotationSettings Smooth Painter Paths Boyama Yollarını YumuÅŸat When enabled smooths out pen and marker paths after finished drawing. EtkinleÅŸtirildiÄŸinde, çizim bittikten sonra kalem ve iÅŸaretleme yollarını yumuÅŸatır. Smooth Factor YumuÅŸatma Çarpanı Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. YumuÅŸatma çarpanını artırmak, kalem ve iÅŸaretleyici için hassasiyeti azaltır ancak daha düzgün hale getirir. Annotator Settings Ek Açıklama Ayarları Remember annotation tool selection and load on startup Ek açıklama aracı seçimini hatırla ve baÅŸlangıçta yükle Switch to Select Tool after drawing Item Ögeyi çizdikten sonra Araç Seçimine geç Number Tool Seed change updates all Number Items Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Canvas Color Tuval Rengi Default Canvas background color for annotation area. Changing color affects only new annotation areas. Açıklama alanı için öntanımlı Tuval arka plan rengi. Rengin deÄŸiÅŸtirilmesi yalnızca yeni açıklama alanlarını etkiler. Select Item after drawing Çizdikden sonra Ögeyi seç With this option enabled the item gets selected after being created, allowing changing settings. Bu seçenek etkinleÅŸtirildiÄŸinde, öge oluÅŸturulduktan sonra seçilir ve ayarların deÄŸiÅŸtirilmesine izin verilir. ApplicationSettings Capture screenshot at startup with default mode Uygulama baÅŸlarken varsayılan kipte ekran görüntüsünü yakala Application Style Uygulama Tarzı Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Grafiksel arayüzün görünümünü ve uygulamanın temasını ayarlar. DeÄŸiÅŸiklik sonrası ksnip'in yeniden baÅŸlatılması gerekir. Application Settings Uygulama Ayarları Automatically copy new captures to clipboard Yeni kayıtları otomatik olarak panoya kopyala Use Tabs Sekmeleri Kullan Change requires restart. DeÄŸiÅŸiklik yeniden baÅŸlatmayı gerektirir. Run ksnip as single instance Ksnip tek örnek olarak çalışsın Hide Tabbar when only one Tab is used. Yalnızca tek sekme kullanıldığında, sekme çubuÄŸunu gizle. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Bu seçeneÄŸin etkinleÅŸtirilmesi, yalnızca bir ksnip örneÄŸinin çalışmasına izin verir, ilkinden sonra baÅŸlatılan diÄŸer tüm örnekler argümanlarını birinciye iletecek ve kapanacaktır. Bu seçeneÄŸin deÄŸiÅŸtirilmesi, tüm örneklerin yeniden baÅŸlatılmasını gerektirir. Remember Main Window position on move and load on startup Auto hide Tabs Sekmeleri otomatik gizle Auto hide Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. Auto resize to content İçeriÄŸe göre otomatik yeniden boyutlandır Automatically resize Main Window to fit content image. İçerik görüntüsüne sığması için Ana Pencereyi otomatik olarak yeniden boyutlandır. Enable Debugging Hata Ayıklamayı EtkinleÅŸtir Enables debug output written to the console. Change requires ksnip restart to take effect. Hata ayıklama çıktısının konsola yazdırılmasını etkinleÅŸtirir. DeÄŸiÅŸikliÄŸin etkili olması için ksnip'in yeniden baÅŸlatılması gerekir. Resize to content delay İçeriÄŸe göre yeniden boyutlandırma gecikmesi Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. AuthorTab Contributors: Katkıda bulunanlar: Spanish Translation İspanyolca Çeviri Dutch Translation Felemenkçe Çeviri Russian Translation Rusça Çeviri Norwegian BokmÃ¥l Translation Norveççe BokmÃ¥l Çeviri French Translation Fransızca Çeviri Polish Translation Lehçe Çeviri Snap & Flatpak Support Snap & Flatpak DesteÄŸi The Authors: Yazarlar: CanDiscardOperation Warning - Uyarı - The capture %1%2%3 has been modified. Do you want to save it? CaptureModePicker New Yeni Draw a rectangular area with your mouse Farenizle dikdörtgen bir alan çizin Capture full screen including all monitors Tüm ekranlar dahil tam ekran görüntü yakalama Capture screen where the mouse is located Farenin bulunduÄŸu ekranı yakalayın Capture window that currently has focus Odaklanılan mevcut pencereyi yakala Capture that is currently under the mouse cursor Fare imlecinin altında olanı yakala Capture a screenshot of the last selected rectangular area Son seçilen dikdörtgen alanın ekran görüntüsünü yakala Uses the screenshot Portal for taking screenshot Ekran görüntüsü almak için ekran görüntüsü portalını kullanır ContactTab Community Topluluk Bug Reports Hata Bildirimleri If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Genel sorularınız, fikirleriniz varsa veya sadece ksnip hakkında konuÅŸmak istiyorsanız,<br/>lütfen %1 veya %2 sunucumuza katılın. Please use %1 to report bugs. Hataları bildirmek için lütfen %1 kullanın. CopyAsDataUriOperation Failed to copy to clipboard Panoya kopyalanamadı Failed to copy to clipboard as base64 encoded image. Base64 ile kodlanmış görüntü olarak panoya kopyalanamadı. Copied to clipboard Panoya kopyalandı Copied to clipboard as base64 encoded image. Base64 ile kodlanmış görüntü olarak panoya kopyalandı. DeleteImageOperation Delete Image Görüntüyü Sil The item '%1' will be deleted. Do you want to continue? '%1' ögesi silinecek. Devam etmek istiyor musunuz? DonateTab Donations are always welcome Donation Bağış ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Become a GitHub Sponsor? GitHub Sponsoru Olun? Also possible, %1here%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. 'Ekle' sekmesi düğmesine basarak yeni eylemler ekleyin. EnumTranslator Rectangular Area Dikdörtgen Alan Last Rectangular Area Son Dikdörtgen Alan Full Screen (All Monitors) Tam Ekran (Tüm Ekranlar) Current Screen Geçerli Ekran Active Window Etkin Pencere Window Under Cursor İmlecin Altındaki Pencere Screenshot Portal Ekran Görüntüsü Portalı FtpUploaderSettings Force anonymous upload. Anonim yüklemeyi zorla. Url URL Username Kullanıcı Adı Password Parola FTP Uploader FTP Yükleyicisi HandleUploadResultOperation Upload Successful Karşıya Yükleme BaÅŸarılı Unable to save temporary image for upload. Karşıya yüklemek için geçici görüntü kaydedilemiyor. Unable to start process, check path and permissions. İşlem baÅŸlatılamıyor, yolu ve izinleri gözden geçirin. Process crashed İşlem çöktü Process timed out. İşlem zaman aşımına uÄŸradı. Process read error. İşlem okuma hatası. Process write error. İşlem yazma hatası. Web error, check console output. Web hatası, konsol çıktısını denetleyin. Upload Failed Karşıya Yükleme BaÅŸarısız Oldu Script wrote to StdErr. FTP Upload finished successfully. FTP Karşıya Yüklemesi baÅŸarıyla tamamlandı. Unknown error. Bilinmeyen hata. Connection Error. BaÄŸlantı Hatası. Permission Error. İzin Hatası. Upload script %1 finished successfully. Uploaded to %1 HotKeySettings Enable Global HotKeys Genel Kısayol TuÅŸlarını EtkinleÅŸtir Capture Rect Area Capture Full Screen Bütün Ekrani Kaydet Capture current Screen Åžuanki Ekrani Kaydet Capture active Window Etkin pencereyi yakala Capture Window under Cursor Imlecin Altındaki Ekranı Kaydet Global HotKeys Genel Kısayol TuÅŸları Capture Last Rect Area Son Seçimi Kaydet Clear Temizle Capture using Portal HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ImageGrabberSettings Capture mouse cursor on screenshot Ekran görüntüsünde fare imlecini yakala Should mouse cursor be visible on screenshots. Ekran görüntüsünde fare imleci gözükür. Image Grabber Görüntü Yakalayıcı Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. Show Main Window after capturing screenshot Hide Main Window during screenshot Ekran görüntüsü sırasında ana pencereyi gizle Hide Main Window when capturing a new screenshot. Yeni bir ekran görüntüsü yakalarken ana pencereyi gizle. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Force Generic Wayland (xdg-desktop-portal) Screenshot Scale Generic Wayland (xdg-desktop-portal) Screenshots ImgurHistoryDialog Imgur History Imgur GeçmiÅŸi Close Kapat Time Stamp Zaman Damgası Link BaÄŸlantı Delete Link BaÄŸlantıyı Sil ImgurUploader Upload to imgur.com finished! imgur.com adresine yükleme tamamlandı! Received new token, trying upload again… Yeni belirteç alındı, tekrar yüklenmeye çalışılıyor… Imgur token has expired, requesting new token… Imgur belirtecinin süresi doldu, yeni belirteç isteniyor… ImgurUploaderSettings Force anonymous upload Anonim yüklemeyi zorla Always copy Imgur link to clipboard Imgur baÄŸlantısını her zaman panoya kopyala Client ID İstemci KimliÄŸi Client Secret İstemci Parolası PIN PIN Enter imgur Pin which will be exchanged for a token. Bir belirteçle deÄŸiÅŸtirilecek olan imgur PIN'ini girin. Get PIN PIN Al Get Token Belirteç Al Imgur History Imgur GeçmiÅŸi Imgur Uploader Imgur Yükleyicisi Username Kullanıcı Adı Waiting for imgur.com… Imgur.com bekleniyor… Imgur.com token successfully updated. Imgur.com belirteci baÅŸarıyla güncellendi. Imgur.com token update error. Imgur.com belirteç güncelleme hatası. After uploading open Imgur link in default browser Yüklenme gerçekleÅŸtikten sonra Imgur linkini varsayılan tarayıcı ile aç Link directly to image Base Url: Temel URL: Base url that will be used for communication with Imgur. Changing requires restart. Imgur ile iletiÅŸim için kullanılacak temel URL. DeÄŸiÅŸtirmek yeniden baÅŸlatmayı gerektirir. Clear Token Belirteci Temizle LoadImageFromFileOperation Unable to open image Resim açılamıyor Unable to open image from path %1 MainToolBar New Yeni Delay in seconds between triggering and capturing screenshot. Tetiklemeden sonra saniye cinsinden gecikir ve ekran görüntüsünü yakalanır. s The small letter s stands for seconds. sn Save Kaydet Save Screen Capture to file system Yakalanan ekran görüntüsünü dosya sistemine kaydet Copy Kopyala Copy Screen Capture to clipboard Yakalanan ekran görüntüsünü panoya kopyala Tools Araçlar Undo Geri Redo İleri Crop Kırp Crop Screen Capture Yakalanan Ekran Görüntüsünü Kırp MainWindow Unsaved KaydedilmemiÅŸ Upload Karşıya yükle Print Yazdır Opens printer dialog and provide option to print image Yazıcı iletiÅŸim kutusunu açar ve görüntü yazdırma seçeneÄŸi sunar Print Preview Yazdırma Önizleme Opens Print Preview dialog where the image orientation can be changed Resim yönünün deÄŸiÅŸtirilebileceÄŸi Baskı Önizleme iletiÅŸim penceresini açar Scale Ölçekle Quit Kapat Settings Ayarlar &About &Hakkında Open Aç &Edit &Düzenle &Options &Seçenekler &Help &Yardım Add Watermark Fligran ekle Add Watermark to captured image. Multiple watermarks can be added. &File D&osya Unable to show image Resim gösterilemiyor Save As... Farklı Kaydet... Paste Yapıştır Paste Embedded Gömülü Yapıştır Pin Sabitle Pin screenshot to foreground in frameless window No image provided but one was expected. Görüntü saÄŸlanmadı, ancak bir tane bekleniyordu. Copy Path Hedefi Kopyala Open Directory Dizini Aç &View &Görünüm Delete Sil Rename Yeniden Adlandır Open Images Show Docks Hide Docks Copy as data URI Veri URI'si olarak kopyala Open &Recent Modify Canvas Tuvali DeÄŸiÅŸtir Upload triggerCapture to external source Copy triggerCapture to system clipboard Scale Image Görüntüyü Ölçekle Rotate Döndür Rotate Image Görüntüyü Döndür Actions Eylemler Image Files Görüntü Dosyaları MultiCaptureHandler Save Kaydet Save As Farklı Kaydet Open Directory Dizini Aç Copy Kopyala Copy Path Hedefi Kopyala Delete Sil Rename Yeniden Adlandır NewCaptureNameProvider Capture Yakala PinWindow Close Kapat Close Other DiÄŸerlerini Kapat Close All Tümünü Kapat PinWindowHandler Pin Window %1 RenameOperation Image Renamed Görüntü Yeniden Adlandırıldı Image Rename Failed Görüntü Yeniden Adlandırılamadı Rename image Görüntüyü yeniden adlandır New filename: Yeni dosya adı: Successfully renamed image to %1 Görüntü, %1 olarak baÅŸarıyla yeniden adlandırıldı Failed to rename image to %1 Görüntü, %1 olarak yeniden adlandırılamadı SaveOperation Save As Farklı Kaydet All Files Tüm Dosyalar Image Saved Görüntü Kaydedildi Saving Image Failed Görüntü Kaydedilemedi Image Files Görüntü Dosyaları Saved to %1 Failed to save image to %1 SaverSettings Automatically save new captures to default location Varsayılan noktaya otomatik olarak kaydet Prompt to save before discarding unsaved changes KaydedilmemiÅŸ deÄŸiÅŸiklikleri iptal etmeden önce, kaydetmek için uyar Remember last Save Directory Son kayıt dizinini hatırla When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Capture save location and filename Yakalanan görüntüyü kaydetme konumu ve dosya adı Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Browse Gözat Saver Settings Kaydedici Ayarları Capture save location Görüntü yakalama kayıt konumu Default Varsayılan Factor Çarpan Save Quality Kayıt Kalitesi Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Küçük sıkıştırılmış dosyalar elde etmek için 0, büyük sıkıştırılmamış dosyalar için 100 belirtin. Tüm görüntü biçimleri tam aralığı desteklemez, JPEG destekler. ScriptUploaderSettings Copy script output to clipboard Betik çıktısını panoya kopyala Script: Betik: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. Browse Gözat Script Uploader Yükleyici Kodu Select Upload Script Karşıya Yükleme BetiÄŸi Seç Stop when upload script writes to StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Filter: Filtre: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Düzenli İfade. Panoya yalnızca düzenli ifadeyle eÅŸleÅŸenleri kopyala. BoÅŸ bırakıldığında, her ÅŸey kopyalanır. SettingsDialog Settings Ayarlar OK Tamam Cancel İptal Image Grabber Görüntü Yakalayıcı Imgur Uploader Imgur Yükleyici Application Uygulama Annotator HotKeys Kısayol TuÅŸları Uploader Yükleyici Script Uploader Yükleyici Kodu Saver Kaydedici Stickers Etiketler Snipping Area Ekran Alıntısı Alanı Tray Icon Tepsi Simgesi Watermark Filigran Actions Eylemler FTP Uploader FTP Yükleyicisi SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Use arrow keys to move the selection. Seçimi taşımak için ok tuÅŸlarını kullanın. Use arrow keys while pressing CTRL to move top left handle. Use arrow keys while pressing ALT to move bottom right handle. Confirm selection by pressing ENTER/RETURN or abort by pressing ESC. This message can be disabled via settings. Bu mesaj ayarlar aracılığıyla devre dışı bırakılabilir. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. Hold CTRL pressed to resize selection after selecting. Seçtikten sonra seçimi yeniden boyutlandırmak için CTRL'yi basılı tutun. Hold CTRL pressed to prevent resizing after selecting. Seçtikten sonra yeniden boyutlandırmayı önlemek için CTRL'yi basılı tutun. Operation will be canceled after 60 sec when no selection made. Herhangi bir seçim yapılmadığında 60 saniye sonra iÅŸlem iptal edilecektir. This message can be disabled via settings. Bu mesaj ayarlar aracılığıyla devre dışı bırakılabilir. SnippingAreaSettings Freeze Image while snipping Seçim yaparken arka alanı dondur When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Show magnifying glass on snipping area Seçim alanında büyüteç göster Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Arkaplan görüntüsüne yakınlaÅŸtırma yapan bir büyüteç gösterilir. Bu seçenek yalnızca 'Seçim yaparken arka alanı dondur' etkinken çalışır. Show Snipping Area rulers Seçim Alanı cetvellerini göster Horizontal and vertical lines going from desktop edges to cursor on snipping area. Seçim yaparken dikey ve yatay cetvellerin gösterilmesini saÄŸlar. Show Snipping Area position and size info Seçim alanı konumu ve boyut bilgisini göster When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Allow resizing rect area selection by default When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Show Snipping Area info text Snipping Area cursor color Seçim Alanı imleç rengi Sets the color of the snipping area cursor. Snipping Area cursor thickness Seçim Alanı imleç kalınlığı Sets the thickness of the snipping area cursor. Snipping Area Snipping Area adorner color Sets the color of all adorner elements on the snipping area. Snipping Area Transparency Alpha for not selected region on snipping area. Smaller number is more transparent. StickerSettings Up Yukarı Down AÅŸağı Use Default Stickers Varsayılan Etiketi Kullan Sticker Settings Etiket Ayarları Vector Image Files (*.svg) Vektör Görüntü Dosyaları (*.svg) Add Ekle Remove Kaldır Add Stickers TrayIcon Show Editor Düzenleyiciyi Göster TrayIconSettings Use Tray Icon Tepsi Simgesi Kullan When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. EtkinleÅŸtirildiÄŸinde, iÅŸletim sisteminin pencere yöneticisi destekliyorsa görev çubuÄŸuna bir tepsi simgesi ekleyecektir. DeÄŸiÅŸiklik yeniden baÅŸlatma gerektirir. Minimize to Tray Tepsi Simgesi Durumuna Küçült Start Minimized to Tray Tepsi Simgesi Durumuna Küçültülmüş Olarak BaÅŸlat Close to Tray Tepsi Simgesi Durumuna Kapat Show Editor Düzenleyiciyi Göster Capture Yakala Default Tray Icon action Öntanımlı Tepsi Simgesi Eylemi Default Action that is triggered by left clicking the tray icon. Tepsi simgesine sol tıklandığında tetiklenen öntanımlı eylem. Tray Icon Settings Tepsi Simgesi Ayarları Use platform specific notification service Platforma özel bildirim hizmetini kullan When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Display Tray Icon notifications Tepsi Simgesi bildirimlerini görüntüle UpdateWatermarkOperation Select Image Görüntü Seç Image Files Görüntü Dosyaları UploadOperation Upload Script Required Karşıya Yükleme BetiÄŸi Gerekli Please add an upload script via Options > Settings > Upload Script Lütfen Seçenekler > Ayarlar > Karşıya Yükleme BetiÄŸi yoluyla bir karşıya yükleme betiÄŸi ekleyin Capture Upload Yüklemi Kaydet You are about to upload the image to an external destination, do you want to proceed? Resmi harici konuma yüklemek üzerisiniz, devam etmek istiyormusunuz? UploaderSettings Ask for confirmation before uploading Karşıya yüklemeden önce onay iste Uploader Type: Karşıya Yükleyici Türü: Imgur Imgur Script Betik Uploader Karşıya Yükleyici FTP FTP VersionTab Version Sürüm Build İnÅŸa Using: Kullanım: WatermarkSettings Watermark Image Filigran Resmi Update Güncelle Rotate Watermark Filigrani Döndür When enabled, Watermark will be added with a rotation of 45° EtkinleÅŸtirildiÄŸinde, filigran 45 derece açıyla eklenecektir. Watermark Settings Filigran Ayarları ksnip-master/translations/ksnip_uk.ts000066400000000000000000002413621457262621600204320ustar00rootroot00000000000000 AboutDialog About Про програму About Про програму Version ВерÑÑ–Ñ Author Ðвтор Close Закрити Donate Підтримати Contact Зв'Ñзок AboutTab License: ЛіцензіÑ: Screenshot and Annotation Tool Програма Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð° Ð°Ð½Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² вікон ActionSettingTab Name Ðазва Shortcut Ð¡ÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Clear ОчиÑтити Take Capture Зробити знімок Include Cursor Разом із вказівником Delay Затримка s The small letter s stands for seconds. Ñ Capture Mode Режим Ð·Ð½Ñ–Ð¼Ð°Ð½Ð½Ñ Show image in Pin Window Показати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñƒ пришпиленому вікні Copy image to Clipboard Копіювати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾ буфера обміну даними Upload image Вивантажити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Open image parent directory Відкрити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñƒ батьківÑькому каталозі Save image Зберегти Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Hide Main Window Приховати головне вікно Global Загальне When enabled will make the shortcut available even when ksnip has no focus. Якщо позначено, ÑкороченнÑм можна буде кориÑтуватиÑÑ, навіть Ñкщо ksnip не перебуває у фокуÑÑ–. ActionsSettings Add Додати Actions Settings Параметри дій Action Ð”Ñ–Ñ AddWatermarkOperation Watermark Image Required Потрібне Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð¾Ð´Ñного знаку Please add a Watermark Image via Options > Settings > Annotator > Update Будь лаÑка, додайте водÑний знак за допомогою пункту Параметри → ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ â†’ Ðнотатор → Оновити AnnotationSettings Smooth Painter Paths Згладжувати намальовані контури When enabled smooths out pen and marker paths after finished drawing. Якщо позначено, згладжувати лінії, Ñкі намальовано пером або маркером, піÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¼Ð°Ð»ÑŽÐ²Ð°Ð½Ð½Ñ. Smooth Factor Коефіцієнт Ð·Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. Ð—Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ ÐºÐ¾ÐµÑ„Ñ–Ñ†Ñ–Ñ”Ð½Ñ‚Ð° Ð·Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼ÐµÐ½ÑˆÐ¸Ñ‚ÑŒ чіткіÑть ліній, залишених пером чи маркером, але зробить Ñ—Ñ…
 плавнішими. Annotator Settings ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð½Ð¾Ñ‚Ð°Ñ‚Ð¾Ñ€Ð° Remember annotation tool selection and load on startup Запам'Ñтовувати вибраний заÑіб Ð°Ð½Ð¾Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ– завантажувати його піÑÐ»Ñ Ð·Ð°Ð¿ÑƒÑку Switch to Select Tool after drawing Item ПіÑÐ»Ñ Ð¼Ð°Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ð¾Ð±'єкта перемкнутиÑÑ Ð½Ð° заÑіб Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Number Tool Seed change updates all Number Items Зміна у заÑобі Ð¿ÐµÑ€ÐµÐ½ÑƒÐ¼ÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð½Ð¾Ð²Ð»ÑŽÑ” уÑÑ– запиÑи номерів Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. Якщо цей пункт не буде позначено, зміни у заÑобі Ð½ÑƒÐ¼ÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ ÑтоÑуватимутьÑÑ Ð»Ð¸ÑˆÐµ нових запиÑів, Ñ– не ÑтоÑуватимутьÑÑ Ð½Ð°Ñвних. Якщо пункт не буде позначено, також можлива поÑва дублікатів номерів. Canvas Color Колір полотна Default Canvas background color for annotation area. Changing color affects only new annotation areas. Типовий колір тла полотна Ð´Ð»Ñ Ð¾Ð±Ð»Ð°Ñті анотацій. Зміна кольору ÑтоÑуватиметьÑÑ Ð»Ð¸ÑˆÐµ нових облаÑтей анотацій. Select Item after drawing Позначити елемент піÑÐ»Ñ Ð¼Ð°Ð»ÑŽÐ²Ð°Ð½Ð½Ñ With this option enabled the item gets selected after being created, allowing changing settings. Якщо цей пункт буде позначено, програма позначатиме елемент піÑÐ»Ñ Ð¹Ð¾Ð³Ð¾ ÑтвореннÑ, надаючи змогу змінити його параметри. Show Controls Widget Показати віджет ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. Ðа віджеті ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÐ¾Ð²Ð°Ð½Ð¾ кнопки СкаÑуваннÑ/ПовтореннÑ, ОбрізаннÑ, МаÑштабуваннÑ, ÐžÐ±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° Зміни полотна. ApplicationSettings Capture screenshot at startup with default mode Захоплювати знімок піÑÐ»Ñ Ð·Ð°Ð¿ÑƒÑку у типовому режимі Application Style Стиль вікна програми Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. Ð’Ñтановлює Ñтиль вікна програми, Ñкий визначає Ñ—Ñ— виглÑд. Щоб Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½Ð¸Ð»Ð¾ÑÑ, перезапуÑтіть ksnip. Application Settings Параметри програми Automatically copy new captures to clipboard Ðвтоматично копіювати нові знімки до буферу обміну Use Tabs ВикориÑтовувати вкладки Change requires restart. ÐÐ°Ð±ÑƒÑ‚Ñ‚Ñ Ð·Ð¼Ñ–Ð½Ð°Ð¼Ð¸ чинноÑті потребує перезапуÑку. Run ksnip as single instance ЗапуÑкати ksnip у режимі єдиного екземплÑра Hide Tabbar when only one Tab is used. Ховати панель вкладок, Ñкщо викориÑтано лише одну вкладку. Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. Якщо позначити цей пункт, запуÑкатиметьÑÑ Ð»Ð¸ÑˆÐµ один екземплÑÑ€ ksnip. УÑÑ– інші запущені екземплÑри проÑто передаватимуть Ñвої аргументи першому екземплÑру Ñ– завершуватимуть роботу. Зміна Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° Ð´Ð»Ñ Ð½Ð°Ð±ÑƒÑ‚Ñ‚Ñ Ñ‡Ð¸Ð½Ð½Ð¾Ñті потребуватиме перезапуÑку уÑÑ–Ñ… екземплÑрів. Remember Main Window position on move and load on startup Запам'Ñтати Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ð¾Ð»Ð¾Ð²Ð½Ð¾Ð³Ð¾ вікна Ñ– відновлювати його піÑÐ»Ñ Ð·Ð°Ð¿ÑƒÑку Auto hide Tabs Ðвтоматично ховати вкладки Auto hide Docks Ðвтоматично ховати панелі On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. ПіÑÐ»Ñ Ð·Ð°Ð¿ÑƒÑку приховати панель інÑтрументів Ñ– параметри анотацій. ВидиміÑтю бічних панелей можна керувати за допомогою клавіші Tab. Auto resize to content Ðвтоматичний розмір за вміÑтом Automatically resize Main Window to fit content image. Ðвтоматично змінювати розміри головного вікна за зображеннÑм-вміÑтом. Enable Debugging Увімкнути діагноÑтику Enables debug output written to the console. Change requires ksnip restart to take effect. Вмикає діагноÑтичне Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð´Ð¾ конÑолі. Ð”Ð»Ñ Ð½Ð°Ð±ÑƒÑ‚Ñ‚Ñ Ð·Ð¼Ñ–Ð½Ð°Ð¼Ð¸ чинноÑті Ñлід перезапуÑтити ksnip. Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. Зміна розмірів за вміÑтом затримуєтьÑÑ Ð· метою ÑƒÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð·Ð°Ñобу ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–ÐºÐ½Ð°Ð¼Ð¸ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ вміÑту. Якщо головне вікно не коригуєтьÑÑ Ð·Ð° новим вміÑтом, Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ð·Ð°Ñ‚Ñ€Ð¸Ð¼ÐºÐ¸ може поліпшити Ñитуацію. Resize delay Затримка зміни розмірів Temp Directory ТимчаÑовий каталог Temp directory used for storing temporary images that are going to be deleted after ksnip closes. ТимчаÑовий каталог викориÑтовують Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ñ‚Ð¸Ð¼Ñ‡Ð°Ñових зображень, Ñкі буде вилучено піÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ ksnip. Browse Вибрати AuthorTab Contributors: УчаÑники розробки: Spanish Translation Переклад Ñ–ÑпанÑькою Dutch Translation Переклад голландÑькою Russian Translation Переклад роÑійÑькою Norwegian BokmÃ¥l Translation Переклад норвезькою (букмол) French Translation Переклад французькою Polish Translation Переклад польÑькою Snap & Flatpak Support Підтримка Snap & Flatpak The Authors: Ðвтори: CanDiscardOperation Warning - ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ â€” The capture %1%2%3 has been modified. Do you want to save it? Захоплене Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ %1%2%3 було змінено. Хочете його зберегти? CaptureModePicker New Створити Draw a rectangular area with your mouse Виділіть мишкою прÑмокутну облаÑть Capture full screen including all monitors Зробити знімок уÑього екрана з уÑÑ–Ñ… моніторів Capture screen where the mouse is located Зробити знімок екрана, на Ñкому розташовано вказівник миші Capture window that currently has focus Зробити знімок ÑфокуÑованого вікна Capture that is currently under the mouse cursor Зробити знімок вікна, на Ñкому розташовано вказівник миші Capture a screenshot of the last selected rectangular area Зробити знімок оÑтанньої позначеної прÑмокутної облаÑті Uses the screenshot Portal for taking screenshot ВикориÑтовує портал знімків вікон Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ° ContactTab Community Спільнота Bug Reports Звіти щодо вад If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. Якщо у Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ»Ð¸ Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ характеру, ідеї, або ви проÑто хочете поговорити про ksnip,<br/>будь лаÑка, долучайтеÑÑ Ð´Ð¾ нашого каналу %1 або нашого Ñервера %2. Please use %1 to report bugs. Будь лаÑка, ÑкориÑтайтеÑÑ Ñторінкою %1 Ð´Ð»Ñ Ð·Ð²Ñ–Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ вад. CopyAsDataUriOperation Failed to copy to clipboard Ðе вдалоÑÑ Ñкопіювати до буфера Failed to copy to clipboard as base64 encoded image. Ðе вдалоÑÑ Ñкопіювати до буфера дані Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñƒ кодуванні base64. Copied to clipboard Скопійовано до буфера Copied to clipboard as base64 encoded image. Скопійовано до буфера Ñк Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñƒ кодуванні base64. DeleteImageOperation Delete Image Вилучити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ The item '%1' will be deleted. Do you want to continue? Ð—Ð°Ð¿Ð¸Ñ Â«%1» буде вилучено. Хочете виконати цю дію? DonateTab Donations are always welcome Пожертви завжди вітаютьÑÑ Donation Пожертва ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip Ñ” неприбутковим вільним відкритим проєктом із розробки програмного забезпеченнÑ, але<br/>має певні Ñупутні витрати,<br/>зокрема, має платити за домен та Ð¾Ð±Ð»Ð°Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ¸ роботи на багатьох апаратних платформах. If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. Якщо ви хочете допомогти або проÑто вважаєте за потрібне віддÑчити за виконану роботу,<br/>надавши розробникам можливіÑть випити пива або кави, ви можете підтримати проєкт %1тут%2. Become a GitHub Sponsor? Станете ÑпонÑором GitHub? Also possible, %1here%2. Також можна підтримати %1тут%2. EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. Ðові дії можна додати натиÑканнÑм кнопки «Додати». EnumTranslator Rectangular Area ПрÑмокутна ділÑнка Last Rectangular Area ОÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ñмокутна ділÑнка Full Screen (All Monitors) Повноекранний режим (уÑÑ– монітори) Current Screen Поточний екран Active Window Ðктивне вікно Window Under Cursor Вікно під вказівником Screenshot Portal Портал знімків вікон FtpUploaderSettings Force anonymous upload. ПримуÑове анонімне вивантаженнÑ. Url ÐдреÑа Username КориÑтувач Password Пароль FTP Uploader Вивантажувач FTP HandleUploadResultOperation Upload Successful УÑпішне Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Unable to save temporary image for upload. Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ тимчаÑове Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ. Unable to start process, check path and permissions. Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити процеÑ. Перевірте шлÑÑ… Ñ– права доÑтупу. Process crashed Ðварійне Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑу Process timed out. Перевищено Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… від процеÑу. Process read error. Помилка під Ñ‡Ð°Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… з процеÑу. Process write error. Помилка під Ñ‡Ð°Ñ Ñпроби запиÑати дані до процеÑу. Web error, check console output. Помилка із мережею, ознайомтеÑÑ Ñ–Ð· виведеними до конÑолі даними. Upload Failed Ðевдала Ñпроба Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Script wrote to StdErr. Скрипт запиÑано до StdErr. FTP Upload finished successfully. Ð’Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° FTP уÑпішно завершено. Unknown error. Ðевідома помилка. Connection Error. Помилка з'єднаннÑ. Permission Error. Помилка із правами доÑтупу. Upload script %1 finished successfully. Скрипт Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ %1 завершив роботу уÑпішно. Uploaded to %1 Вивантажено до %1 HotKeySettings Enable Global HotKeys Увімкнути глобальні гарÑчі клавіші Capture Rect Area ЗнÑти прÑмокутну облаÑть Capture Full Screen ЗнÑти веÑÑŒ екран Capture current Screen ЗнÑти поточний екран Capture active Window ЗнÑти активне вікно Capture Window under Cursor ЗнÑти вікно під курÑором Global HotKeys Глобальні гарÑчі клавіші Capture Last Rect Area ЗнÑти оÑтанню прÑмокутну облаÑть Clear ОчиÑтити Capture using Portal Захопити за допомогою порталу HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. Підтримку клавіатурних Ñкорочень у поточній верÑÑ–Ñ— передбачено лише Ð´Ð»Ñ Windows Ñ– X11. ЗнÑÑ‚Ñ‚Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð· цього пункту обмежує клавіатурні ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð»Ð¸ÑˆÐµ ksnip. ImageGrabberSettings Capture mouse cursor on screenshot Показувати вказівник миші на знімку Should mouse cursor be visible on screenshots. Чи має бути показано вказівник миші на знімках. Image Grabber Ð—Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. Типові реалізації Wayland, Ñкі викориÑтовують XDG-DESKTOP-PORTAL, оброблÑють маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐºÑ€Ð°Ð½Ð° інакше. Ð’Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ параметра призведе до Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐºÑ€Ð°Ð½Ð° Ñ– заÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¹Ð¾Ð³Ð¾ до знімка у ksnip. GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. У GNOME Ñ– Плазмі KDE передбачено влаÑні заÑоби ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² Wayland та типових знімків XDG-DESKTOP-PORTAL. Якщо позначити цей пункт, програма примуÑово викориÑтовуватиме у Плазмі KDE Ñ– GNOME знімки XDG-DESKTOP-PORTAL. Ð”Ð»Ñ Ð½Ð°Ð±ÑƒÑ‚Ñ‚Ñ Ñ‡Ð¸Ð½Ð½Ð¾Ñті цим параметром ksnip Ñлід перезапуÑтити. Show Main Window after capturing screenshot Показувати головне вікно піÑÐ»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ° Hide Main Window during screenshot Ховати головне вікно під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ° Hide Main Window when capturing a new screenshot. Ховати головне вікно під Ñ‡Ð°Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ°. Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. Показати головне вікно піÑÐ»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ°, Ñкщо головне вікно було приховано або згорнуто. Force Generic Wayland (xdg-desktop-portal) Screenshot ПримуÑово типовий знімок вікна Wayland (xdg-desktop-portal) Scale Generic Wayland (xdg-desktop-portal) Screenshots МаÑштабовані загальні знімки вікон Wayland (xdg-desktop-portal) Implicit capture delay ÐеÑвна затримка Ð·Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. Цю затримку буде викориÑтано, Ñкщо затримку не було вибрано в інтерфейÑÑ– кориÑтувача. Ð¦Ñ Ð·Ð°Ñ‚Ñ€Ð¸Ð¼ÐºÐ° надає змогу приховувати ksnip перед ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ°. Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ буде заÑтоÑовано, Ñкщо ksnip вже мінімізовано. Ðадмірне Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ðµ призвеÑти до того, що вікно ksnip з'ÑвитьÑÑ Ð½Ð° знімку. ImgurHistoryDialog Imgur History ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½ÑŒ Close Закрити Time Stamp Позначка чаÑу Link ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Delete Link Видалити поÑÐ¸Ð»Ð°Ð½Ð½Ñ ImgurUploader Upload to imgur.com finished! Ð’Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° imgur.com завершено! Received new token, trying upload again… Отримано новий жетон, Ñпробуємо вивантажити ще раз… Imgur token has expired, requesting new token… Термін дії жетона Imgur вичерпано, надÑилаємо запит щодо нового жетона… ImgurUploaderSettings Force anonymous upload ПримуÑове анонімне Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Always copy Imgur link to clipboard Завжди копіювати поÑÐ¸Ð»Ð°Ð½Ð½Ñ Imgur до буфера обміну даними Client ID Ід. клієнта Client Secret Закритий ключ клієнта PIN PIN Enter imgur Pin which will be exchanged for a token. Вкажіть PIN-код imgur, Ñкий буде обмінÑно на жетон. Get PIN Отримати PIN-код Get Token Отримати жетон Imgur History Журнал Imgur Imgur Uploader Вивантажувач на Imgur Username КориÑтувач Waiting for imgur.com… ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° imgur.com… Imgur.com token successfully updated. Жетор Imgur.com уÑпішно оновлено. Imgur.com token update error. Помилка під Ñ‡Ð°Ñ Ñпроби оновити жетон Imgur.com. After uploading open Imgur link in default browser ПіÑÐ»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° Imgur у браузері за замовчуваннÑм Link directly to image ПрÑме поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð´Ð¾ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Base Url: Базова адреÑа: Base url that will be used for communication with Imgur. Changing requires restart. Базова адреÑа, Ñку буде викориÑтано Ð´Ð»Ñ Ð¾Ð±Ð¼Ñ–Ð½Ñƒ даними з Imgur. Ð”Ð»Ñ Ð½Ð°Ð±ÑƒÑ‚Ñ‚Ñ Ð·Ð¼Ñ–Ð½Ð°Ð¼Ð¸ чинноÑті Ñлід перезапуÑтити програму. Clear Token Вилучити жетон Upload title: Заголовок вивантаженого: Upload description: ÐžÐ¿Ð¸Ñ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð¾Ð³Ð¾: LoadImageFromFileOperation Unable to open image Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Unable to open image from path %1 Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ñ– шлÑхом %1 MainToolBar New Створити Delay in seconds between triggering and capturing screenshot. Затримка у Ñекундах перед тим, Ñк буде зроблено знімок. s The small letter s stands for seconds. Ñ Save Зберегти Save Screen Capture to file system Зберегти знімок у файловій ÑиÑтемі Copy Копіювати Copy Screen Capture to clipboard Копіювати знімок до буфера обміну Tools ІнÑтрументи Undo СкаÑувати Redo Повторити Crop Обрізати Crop Screen Capture Обрізати захоплене з екрана MainWindow Unsaved Ðе збережений Upload Завантажити Print Роздрукувати Opens printer dialog and provide option to print image Відкрити діалогове вікно з можливіÑтю роздрукувати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Print Preview ПереглÑд друку Opens Print Preview dialog where the image orientation can be changed Відкрити попередній переглÑд роздруківки, в Ñкому можна змінити орієнтацію Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Scale Розмір Quit Вийти Settings Параметри &About &Про програму Open Відкрити &Edit &Правка &Options &ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ &Help &Довідка Add Watermark Додати водÑний знак Add Watermark to captured image. Multiple watermarks can be added. Додати водÑний знак до знімка. Можна додати декілька знаків. &File &Файл Unable to show image Ðе вдаєтьÑÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Save As... Зберегти Ñк… Paste Ð’Ñтавити Paste Embedded Ð’Ñтавити вбудованим Pin Пришпилити Pin screenshot to foreground in frameless window Пришпилити знімок вікна до переднього плану у вікні без рамки No image provided but one was expected. Ðе надано зображеннÑ, хоча програма його очікувала. Copy Path Копіювати шлÑÑ… Open Directory Відкрити каталог &View П&ереглÑд Delete Вилучити Rename Перейменувати Open Images Відкрити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Show Docks Показати бічні панелі Hide Docks Приховати бічні панелі Copy as data URI Копіювати Ñк адреÑу даних Open &Recent Відкрити &нещодавні Modify Canvas Змінити полотно Upload triggerCapture to external source Вивантажити triggerCapture на зовнішнє джерело Copy triggerCapture to system clipboard Скопіювати triggerCapture до буфера обміну даними ÑиÑтеми Scale Image МаÑштабувати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Rotate Обертати Rotate Image Обертати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Actions Дії Image Files файли зображень Save All Зберегти уÑе Close Window Закрити вікно Cut Вирізати OCR Розпізнати текÑÑ‚ MultiCaptureHandler Save Зберегти Save As Зберегти Ñк Open Directory Відкрити каталог Copy Копіювати Copy Path Копіювати шлÑÑ… Delete Вилучити Rename Перейменувати Save All Зберегти уÑе NewCaptureNameProvider Capture Захопити OcrWindowCreator OCR Window %1 Вікно Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑту %1 PinWindow Close Закрити Close Other Закрити інші Close All Закрити вÑÑ– PinWindowCreator OCR Window %1 Вікно Ñ€Ð¾Ð·Ð¿Ñ–Ð·Ð½Ð°Ð²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑту %1 PluginsSettings Search Path ШлÑÑ… Ð´Ð»Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ Default Типове The directory where the plugins are located. Каталог, у Ñкому зберігаютьÑÑ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¸. Browse Вибрати Name Ðазва Version ВерÑÑ–Ñ Detect ВиÑвити Plugin Settings Параметри додатків Plugin location Ð Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÑ–Ð² ProcessIndicator Processing Обробка RenameOperation Image Renamed Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¾ Image Rename Failed Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Rename image Перейменувати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ New filename: Ðова назва файла: Successfully renamed image to %1 Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ ÑƒÑпішно перейменовано на %1 Failed to rename image to %1 Ðе вдалоÑÑ Ð¿ÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° %1 SaveOperation Save As Зберегти Ñк All Files уÑÑ– файли Image Saved Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¾ Saving Image Failed Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Image Files файли зображень Saved to %1 Збережено до %1 Failed to save image to %1 Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾ %1 SaverSettings Automatically save new captures to default location Ðвтоматично зберігати нові знімки до типової теки Prompt to save before discarding unsaved changes Питати, чи бажаєте зберегти зміни до зображеннÑ, перш ніж Ñ—Ñ… відкидати Remember last Save Directory Запам'Ñтовувати оÑтанній каталог Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. Якщо позначено, програма перезапиÑуватиме каталог Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² у параметрах оÑтаннім каталогом Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÐ°. Capture save location and filename МіÑце автоматичного Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‚Ð° формат назви знімків Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. Підтримуваними форматами Ñ” JPG, PNG Ñ– BMP. Якщо формат не вказано, типово буде викориÑтано PNG. Шаблон може включати такі Ñ€Ñдки-замінники: - $Y (рік), $M (міÑÑць), $D (день) Ð´Ð»Ñ Ð´Ð°Ñ‚Ð¸, $h (години), $m (хвилини), $s (Ñекунди) Ð´Ð»Ñ Ñ‡Ð°Ñу або $T Ð´Ð»Ñ Ñ‡Ð°Ñу у форматі ггххÑÑ. - Декілька поÑлідовних # Ð´Ð»Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°. #### даÑть нумерацію 0001, далі 0002 тощо. Browse Вибрати Saver Settings Параметри заÑобу Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Capture save location МіÑце Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² Default Типові Factor Коефіцієнт Save Quality ЯкіÑть Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. Вкажіть 0 Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð¼Ð°Ð»Ð¸Ñ… ÑтиÑнених файлів або 100 Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ… файлів без ÑтиÑканнÑ. Повний діапазон коефіцієнтів ÑтиÑÐºÐ°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´Ð±Ð°Ñ‡ÐµÐ½Ð¾ не уÑіма форматами, але його підтримку передбачено у JPEG. Overwrite file with same name ПерезапиÑати файл із тією Ñамою назвою ScriptUploaderSettings Copy script output to clipboard Копіювати Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñкрипту до буфера обміну Script: Скрипт: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. ШлÑÑ… до Ñкрипту, Ñкий буде викликано Ð´Ð»Ñ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…. Під Ñ‡Ð°Ñ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñкрипт буде викликано із параметром шлÑху до тимчаÑового файла png Ñк єдиним аргументом. Browse Вибрати Script Uploader Вивантажувач Ñкриптів Select Upload Script Виберіть Ñкрипт Ð´Ð»Ñ Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Stop when upload script writes to StdErr ЗупинÑти обробку, Ñкщо Ñкрипт Ð²Ð¸Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñує щоÑÑŒ до StdErr Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. Позначати Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñк невдале, Ñкщо Ñкрипт запиÑує щоÑÑŒ до StdErr. Якщо пункт не позначено, програма не братиме до уваги Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ помилки, Ñкі виведено Ñкриптом. Filter: Фільтр: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. Формальний вираз. Копіювати до буфера обміну даними лише те, що відповідає формальному виразу. Якщо не вказано, буде Ñкопійовано уÑÑ– дані. SettingsDialog Settings ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ OK Зберегти Cancel СкаÑувати Image Grabber Ð—Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ñ–Ð¼ÐºÑ–Ð² Imgur Uploader Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° Imgur Application ОÑновне Annotator Параметри анотатору HotKeys ГарÑчі клавіші Uploader Вивантажувач Script Uploader Вивантажувач Ñкриптів Saver Зберігач Stickers Стікери Snipping Area ÐžÐ±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ð°Ñті Tray Icon Піктограма у лотку Watermark ВодÑний знак Actions Дії FTP Uploader Вивантажувач FTP Plugins Додатки Search Settings... Параметри пошуку… SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. Змініть розміри позначеного прÑмокутника за допомогою елементів ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ переÑуньте його перетÑгуваннÑм ділÑнки. Use arrow keys to move the selection. СкориÑтайтеÑÑ ÐºÐ»Ð°Ð²Ñ–ÑˆÐ°Ð¼Ð¸ зі Ñтрілками Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾. Use arrow keys while pressing CTRL to move top left handle. СкориÑтайтеÑÑ ÐºÐ»Ð°Ð²Ñ–ÑˆÐ°Ð¼Ð¸ зі Ñтрілками разом із Ctrl Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑуванÑн верхнього лівого кута. Use arrow keys while pressing ALT to move bottom right handle. СкориÑтайтеÑÑ ÐºÐ»Ð°Ð²Ñ–ÑˆÐ°Ð¼Ð¸ зі Ñтрілками разом із Alt Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð¸Ð¶Ð½ÑŒÐ¾Ð³Ð¾ правого кута. This message can be disabled via settings. Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ð½Ð° вимкнути у параметрах програми. Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Підтвердьте вибір натиÑканнÑм клавіші Enter або подвійним клацаннÑм кнопкою миші у довільному міÑці екрана. Abort by pressing ESC. Перервати дію можна натиÑканнÑм Esc. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. ÐатиÑніть кнопку миші Ñ– перетÑгніть, щоб позначити прÑмокутну ділÑнку, або натиÑніть Esc, щоб вийти. Hold CTRL pressed to resize selection after selecting. Утримуйте натиÑнутою клавішу Ctrl, щоб змінити розміри ділÑнки піÑÐ»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ. Hold CTRL pressed to prevent resizing after selecting. Утримйте натиÑнутою клавішу Ctrl, щоб запобігти зміні розмірів піÑÐ»Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ. Operation will be canceled after 60 sec when no selection made. Дію буде ÑкаÑовано, Ñкщо протÑгом 60 Ñекунд нічного не буде позначено. This message can be disabled via settings. Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ð½Ð° вимкнути у параметрах програми. SnippingAreaSettings Freeze Image while snipping Заморозити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° Ñ‡Ð°Ñ Ð¾Ð±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. Якщо увімкнено, програма заморозить тло при позначенні прÑмокутної ділÑнки. Параметр також змінює поведінку при Ñтворенні відкладених знімків — Ñкщо увімкнено цей параметр, програма робитиме паузу перед тим, Ñк показувати вирізану облаÑть, а Ñкщо параметр вимкнено — піÑÐ»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ вирізаної облаÑті. Цю можливіÑть завжди вимкнено у Wayland Ñ– завжди увімкнено у MacOs. Show magnifying glass on snipping area Показувати лупу під Ñ‡Ð°Ñ Ð²Ð¸Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð´Ñ–Ð»Ñнки Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. Показувати збільшувальне Ñкло, Ñке дає змогу наблизити фонове зображеннÑ. Цей пункт працюватиме, лише Ñкщо ввімкнено Ð·Ð°Ð¼Ð¾Ñ€Ð¾Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ. Show Snipping Area rulers Показувати лінійки облаÑті Ð²Ð¸Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Horizontal and vertical lines going from desktop edges to cursor on snipping area. Показувати горизонтальну та вертикальну лінії, Ñкі відходÑть від краю екрана до вказівника миші під Ñ‡Ð°Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ð°Ñті знімка. Show Snipping Area position and size info Показувати інформацію щодо позиції Ñ– розміру вирізаної облаÑті When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. Якщо ліву кнопку миші не натиÑнуто, буде показано позицію. Якщо ліву кнопку миші натиÑнуто, ліворуч вгорі захопленої облаÑті буде показано Ñ—Ñ— розміри. Allow resizing rect area selection by default Типово дозволити зміну розмірів прÑмокутної позначеної ділÑнки When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. Якщо позначено, піÑÐ»Ñ Ð²Ð¸Ð±Ð¾Ñ€Ñƒ прÑмокутної ділÑнки буде уможливлено зміну Ñ—Ñ— розмірів. Зміну розмірів може бути підтверджено натиÑканнÑм клавіші Enter. Show Snipping Area info text Показати інформаційний текÑÑ‚ облаÑті Ð²Ð¸Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Snipping Area cursor color Колір вказівника під Ñ‡Ð°Ñ Ð²Ð¸Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ð°Ñті Sets the color of the snipping area cursor. Ð’Ñтановлює колір вказівника при вирізанні ділÑнки. Snipping Area cursor thickness Товщина вказівника при вирізанні ділÑнки Sets the thickness of the snipping area cursor. Ð’Ñтановлює товщину вказівника облаÑті обрізаннÑ. Snipping Area ÐžÐ±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ð°Ñті Snipping Area adorner color Орнаментальний колір облаÑті Ð¾Ð±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Sets the color of all adorner elements on the snipping area. Ð’Ñтановлює колір уÑÑ–Ñ… елементів орнаменту облаÑті обрізаннÑ. Snipping Area Transparency ПрозоріÑть облаÑті Ð¾Ð±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Alpha for not selected region on snipping area. Smaller number is more transparent. Рівень прозороÑті Ð´Ð»Ñ Ð½ÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ñ— ділÑнки облаÑті обрізаннÑ. Менше Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ â€” прозоріша ділÑнка. Enable Snipping Area offset Увімкнути відÑтуп облаÑті Ð²Ð¸Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. Якщо позначено, буде заÑтоÑовано налаштований відÑтуп облаÑті вирізаннÑ, Ñкий потрібен, Ñкщо Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ð»Ð°Ñті обчиÑлено неправильно. Такий відÑтуп іноді потрібен, Ñкщо увімкнено маÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ ÐµÐºÑ€Ð°Ð½Ð°. X X Y Y StickerSettings Up ↑ Down ↓ Use Default Stickers ВикориÑтовувати типові Ñтікери Sticker Settings Параметри Ñтікерів Vector Image Files (*.svg) файли векторних зображень (*.svg) Add Додати Remove Вилучити Add Stickers Додати наліпки TrayIcon Show Editor Показати редактор TrayIconSettings Use Tray Icon Показувати піктограму у лотку When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. Якщо позначено, програма додаÑть піктограму лотка на панель задач, Ñкщо у заÑобі ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–ÐºÐ½Ð°Ð¼Ð¸ операційної ÑиÑтеми передбачено Ñ—Ñ— підтримку. Зміна потребує перезапуÑку програми. Minimize to Tray Згорнути до лотка Start Minimized to Tray ЗапуÑкати згорнутою до лотка Close to Tray Закривати до лотка Show Editor Показати редактор Capture Захопити Default Tray Icon action Типова Ð´Ñ–Ñ Ð´Ð»Ñ Ð¿Ñ–ÐºÑ‚Ð¾Ð³Ñ€Ð°Ð¼Ð¸ лотка Default Action that is triggered by left clicking the tray icon. Типова діÑ, Ñку буде виконано у відповідь на ÐºÐ»Ð°Ñ†Ð°Ð½Ð½Ñ Ð»Ñ–Ð²Ð¾ÑŽ кнопкою миші на піктограмі у лотку. Tray Icon Settings Параметри піктограми лотка Use platform specific notification service СкориÑтатиÑÑ Ñпецифічною Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸ Ñлужбою Ñповіщень When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. Якщо увімкнено, програма Ñпробує ÑкориÑтатиÑÑ Ñпецифічною Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸ Ñлужбою Ñповіщень, Ñкщо така Ñ–Ñнує. Ð”Ð»Ñ Ð½Ð°Ð±ÑƒÑ‚Ñ‚Ñ Ñ‡Ð¸Ð½Ð½Ð¾Ñті змінами програму Ñлід буде перезапуÑтити. Display Tray Icon notifications Ð¡Ð¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð· піктограми у лотку UpdateWatermarkOperation Select Image Вибрати Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Image Files файли зображень UploadOperation Upload Script Required Потрібен Ñкрипт Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Please add an upload script via Options > Settings > Upload Script Будь лаÑка, додайте Ñкрипт Ð²Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð° допомогою пункту меню «ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ > Параметри > Скрипт вивантаженнÑ» Capture Upload Ð’Ð¸Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ñ…Ð¾Ð¿Ð»ÐµÐ½Ð¾Ð³Ð¾ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ You are about to upload the image to an external destination, do you want to proceed? Ви наказали програмі вивантажити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° віддалений Ñервер. Хочете зробити Ñаме це? UploaderSettings Ask for confirmation before uploading Питати Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´ вивантаженнÑм Uploader Type: Тип вивантажувача: Imgur Imgur Script Скрипт Uploader Вивантажувач FTP FTP VersionTab Version ВерÑÑ–Ñ Build Збірка Using: ВикориÑтовуємо: WatermarkSettings Watermark Image Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ð¾Ð´Ñного знаку Update Оновити Rotate Watermark Повернути водÑний знак When enabled, Watermark will be added with a rotation of 45° Якщо позначено, водÑний знак буде додано із обертаннÑм на 45° Watermark Settings Параметри водÑного знаку ksnip-master/translations/ksnip_zh_CN.ts000066400000000000000000001761211457262621600210140ustar00rootroot00000000000000 AboutDialog About 关于 About 关于 Version 版本 Author 作者 Close 关闭 Donate æèµ  Contact è”ç³» AboutTab License: 许å¯è¯ï¼š Screenshot and Annotation Tool å±å¹•截图和注释工具 ActionSettingTab Name åç§° Shortcut å¿«æ·é”® Clear 清除 Take Capture æ•获 Include Cursor 包å«å…‰æ ‡ Delay 延迟 s The small letter s stands for seconds. ç§’ Capture Mode æ•èŽ·æ¨¡å¼ Show image in Pin Window 在图钉窗å£ä¸­æ˜¾ç¤ºå›¾åƒ Copy image to Clipboard 图åƒå¤åˆ¶åˆ°å‰ªè´´æ¿ Upload image ä¸Šä¼ å›¾åƒ Open image parent directory 打开图åƒçˆ¶ç›®å½• Save image ä¿å­˜å›¾åƒ Hide Main Window éšè—ä¸»çª—å£ Global 全局 When enabled will make the shortcut available even when ksnip has no focus. å¯ç”¨åŽå°†åˆ›å»ºå¿«æ·æ–¹å¼ å³ä½¿ ksnip 没有焦点也å¯ç”¨ã€‚ ActionsSettings Add 添加 Actions Settings æ“作设置 Action æ“作 AddWatermarkOperation Watermark Image Required éœ€è¦æ°´å°å›¾åƒ Please add a Watermark Image via Options > Settings > Annotator > Update 请通过“选项â€>“设置â€>“注释器â€>â€œæ›´æ–°â€æ·»åŠ æ°´å°å›¾åƒ AnnotationSettings Smooth Painter Paths 平滑绘制的路径 When enabled smooths out pen and marker paths after finished drawing. 如å¯ç”¨ï¼Œç»˜åˆ¶å®ŒæˆåŽ æ¶ˆé™¤ç¬”å’Œæ ‡è®°è·¯å¾„ã€‚ Smooth Factor å¹³æ»‘å› å­ Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. 增加平滑因å­å°†å‡å°‘ 笔和记å·ç¬”的精度,但会 使它们更平滑。 Annotator Settings 注释器设置 Remember annotation tool selection and load on startup è®°ä½æ³¨é‡Šå™¨é€‰æ‹©å¹¶åœ¨å¯åŠ¨æ—¶åŠ è½½ Switch to Select Tool after drawing Item 绘制åŽåˆ‡æ¢åˆ°é€‰æ‹©å·¥å…· Number Tool Seed change updates all Number Items 数字工具ç§å­æ›´æ”¹å°†æ›´æ–°æ‰€æœ‰æ•°å­—项目 Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. ç¦ç”¨æ­¤é€‰é¡¹å°†å¯¼è‡´æ•°å­—工具的更改 ç§å­ä»…影哿–°é¡¹ç›®ï¼Œè€Œä¸å½±å“现有项目。 ç¦ç”¨æ­¤é€‰é¡¹å°†å…许é‡å¤çš„æ•°å­—。 Canvas Color 画布颜色 Default Canvas background color for annotation area. Changing color affects only new annotation areas. 注释区域画布的默认背景颜色 改å˜é¢œè‰²åªä¼šå½±å“新的注释区域。 Select Item after drawing 绘图åŽé€‰æ‹©é¡¹ç›® With this option enabled the item gets selected after being created, allowing changing settings. å¯ç”¨æ­¤é€‰é¡¹åŽï¼Œå°†åœ¨åˆ›å»ºé¡¹ç›®åŽå¯¹å…¶è¿›è¡Œé€‰æ‹©ï¼Œ 从而å¯ä»¥æ›´æ”¹è®¾ç½®ã€‚ Show Controls Widget 显示控件å°éƒ¨ä»¶ The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. 控件å°éƒ¨ä»¶åŒ…嫿’¤æ¶ˆ/é‡åšï¼Œ è£å‰ªã€ç¼©æ”¾ã€æ—‹è½¬å’Œä¿®æ”¹ç”»å¸ƒæŒ‰é’®ã€‚ ApplicationSettings Capture screenshot at startup with default mode 使用默认模å¼åœ¨å¯åŠ¨æ—¶æ•获å±å¹•截图 Application Style åº”ç”¨ç¨‹åºæ ·å¼ Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. 设置定义 GUI å¤–è§‚çš„åº”ç”¨ç¨‹åºæ ·å¼ã€‚ æ›´æ”¹è¦æ±‚ ksnip 釿–°å¯åЍæ‰èƒ½ç”Ÿæ•ˆã€‚ Application Settings 应用程åºè®¾ç½® Automatically copy new captures to clipboard 自动将新的æ•获å¤åˆ¶åˆ°å‰ªè´´æ¿ Use Tabs 使用标签 Change requires restart. 修改需è¦é‡å¯åŽç”Ÿæ•ˆã€‚ Run ksnip as single instance 以å•实例模å¼è¿è¡Œ ksnip Hide Tabbar when only one Tab is used. å½“åªæœ‰ä¸€ä¸ªæ ‡ç­¾æ—¶éšè—标签æ ã€‚ Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. å¯ç”¨è¿™ä¸ªé€‰é¡¹å°†ä¼šåªå…许一个ksnip实例è¿è¡Œï¼Œ 所有其它实例å¯åŠ¨æ—¶ä¼šå°†å‚æ•°ä¼ ç»™ç¬¬ä¸€ä¸ªå®žä¾‹ ç„¶åŽé€€å‡ºã€‚改å˜è¿™ä¸ªé€‰é¡¹éœ€è¦åœ¨å…³é—­æ‰€æœ‰å®žä¾‹ åŽå¯åŠ¨æ–°çš„å®žä¾‹ã€‚ Remember Main Window position on move and load on startup 在移动时记ä½ä¸»çª—å£çš„ä½ç½®å¹¶åœ¨å¯åŠ¨æ—¶åŠ è½½ Auto hide Tabs 自动éšè—标签 Auto hide Docks 自动éšè—åœé  On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. 在å¯åŠ¨æ—¶éšè—工具æ å’Œæ³¨é‡Šå™¨ï¼Œ å¯ä»¥æŒ‰ä¸‹ Tab 键显示åœé ã€‚ Auto resize to content è‡ªåŠ¨è°ƒæ•´å†…å®¹å¤§å° Automatically resize Main Window to fit content image. 自动调整主窗å£çš„大å°ä»¥é€‚åˆå†…容图åƒã€‚ Enable Debugging å¯ç”¨è°ƒè¯• Enables debug output written to the console. Change requires ksnip restart to take effect. å¯ç”¨å†™å…¥æŽ§åˆ¶å°çš„调试输出。 æ›´æ”¹éœ€è¦ ksnip 釿–°å¯åЍæ‰èƒ½ç”Ÿæ•ˆã€‚ Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. æ ¹æ®å†…容大尿˜¯å…许窗å£ç®¡ç†å™¨æŽ¥æ”¶æ–°å†…容的延迟。 如果未正确调整主窗å£ä»¥é€‚应新内容, 增加延迟å¯èƒ½ä¼šæ”¹å–„行为。 Resize delay 调整延迟 Temp Directory 临时目录 Temp directory used for storing temporary images that are going to be deleted after ksnip closes. 用于存储临时图åƒçš„ Temp 目录 ksnip 关闭åŽå°†è¢«åˆ é™¤ã€‚ Browse æµè§ˆ AuthorTab Contributors: 贡献者: Spanish Translation 西ç­ç‰™è¯­ç¿»è¯‘ Dutch Translation è·å…°è¯­ç¿»è¯‘ Russian Translation 俄语翻译 Norwegian BokmÃ¥l Translation 挪å¨è¯­çš„翻译 French Translation 法语翻译 Polish Translation 波兰语翻译 Snap & Flatpak Support Snap å’Œ Flatpak æ”¯æŒ The Authors: 作者: CanDiscardOperation Warning - 警告 - The capture %1%2%3 has been modified. Do you want to save it? æ•获 %1%2%3 å·²ç»è¢«ä¿®æ”¹ã€‚ 是å¦éœ€è¦ä¿å­˜ï¼Ÿ CaptureModePicker New 新建 Draw a rectangular area with your mouse 用鼠标绘制一个矩形区域 Capture full screen including all monitors æ•获全å±ï¼ŒåŒ…括所有监视器 Capture screen where the mouse is located æ•获鼠标所在的å±å¹• Capture window that currently has focus æ•获目å‰ç„¦ç‚¹æ‰€åœ¨çš„çª—å£ Capture that is currently under the mouse cursor æ•获当å‰åœ¨é¼ æ ‡å…‰æ ‡ä¸‹çš„内容 Capture a screenshot of the last selected rectangular area æ•获上一次选择的矩形区域的å±å¹•截图 Uses the screenshot Portal for taking screenshot 使用 the screenshot Portal 截图 ContactTab Community 社区 Bug Reports 错误报告 If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. å¦‚æžœæ‚¨æœ‰å¸¸è§„é—®é¢˜ã€æƒ³æ³•æˆ–åªæƒ³è°ˆè°ˆ ksnip,<br/>请加入我们的 %1 或我们的 %2 æœåŠ¡å™¨ã€‚ Please use %1 to report bugs. 请使用 %1 报告故障。 CopyAsDataUriOperation Failed to copy to clipboard å¤åˆ¶åˆ°å‰ªåˆ‡æ¿å¤±è´¥ Failed to copy to clipboard as base64 encoded image. 以 base64 图片编ç å½¢å¼å¤åˆ¶åˆ°å‰ªåˆ‡æ¿å¤±è´¥ã€‚ Copied to clipboard å·²å¤åˆ¶åˆ°å‰ªåˆ‡æ¿ Copied to clipboard as base64 encoded image. 已将图åƒçš„ base64 ç¼–ç å¤åˆ¶åˆ°å‰ªåˆ‡æ¿ã€‚ DeleteImageOperation Delete Image åˆ é™¤å›¾åƒ The item '%1' will be deleted. Do you want to continue? 项目 '%1' 将被删除。 你想继续å—? DonateTab Donations are always welcome æ¬¢è¿Žææ¬¾ Donation æèµ  ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip 是一个éžç›ˆåˆ©çš„ Copyleft 自由软件项目,并且<br/>仿œ‰ä¸€äº›è´¹ç”¨éœ€è¦æ”¯ä»˜ï¼Œ<br/>å¦‚åŸŸåæˆæœ¬æˆ–è·¨å¹³å°æ”¯æŒçš„ç¡¬ä»¶æˆæœ¬ã€‚ If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. <br/>如果你想通过请开å‘者å–啤酒或咖啡æä¾›å¸®åŠ©æˆ–åªæ˜¯æƒ³èµžèµæ‰€åšçš„工作,欢迎看看%1这里%2。 Become a GitHub Sponsor? æˆä¸º GitHub 赞助者? Also possible, %1here%2. 也å¯ä»¥åœ¨ %1此处%2 ææ¬¾ã€‚ EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. é€šè¿‡ç‚¹å‡»â€œæ·»åŠ â€æ ‡ç­¾æŒ‰é’®æ¥æ·»åŠ æ–°çš„æ“作。 EnumTranslator Rectangular Area 矩形区域 Last Rectangular Area 上一个矩形区域 Full Screen (All Monitors) å…¨å±ï¼ˆæ‰€æœ‰ç›‘视器) Current Screen 当å‰å±å¹• Active Window æ´»åŠ¨çª—å£ Window Under Cursor å…‰æ ‡æ‰€åœ¨çª—å£ Screenshot Portal 截图门户 FtpUploaderSettings Force anonymous upload. 强制匿å上传。 Url Url Username 用户å Password å¯†ç  FTP Uploader FTP 上传器 HandleUploadResultOperation Upload Successful 上传æˆåŠŸ Unable to save temporary image for upload. 无法为上传ä¿å­˜ä¸´æ—¶å›¾åƒã€‚ Unable to start process, check path and permissions. 无法å¯åŠ¨è¿›ç¨‹ï¼Œè¯·æ£€æŸ¥è·¯å¾„å’Œæƒé™æ˜¯å¦æ­£ç¡®ã€‚ Process crashed 进程已崩溃 Process timed out. 进程超时。 Process read error. 进程读错误。 Process write error. 进程写错误。 Web error, check console output. 网络错误,请检查控制å°è¾“出。 Upload Failed 上传失败 Script wrote to StdErr. 脚本在标准错误上有输出。 FTP Upload finished successfully. FTP 上传æˆåŠŸå®Œæˆã€‚ Unknown error. 未知错误。 Connection Error. 连接错误。 Permission Error. æƒé™é”™è¯¯ã€‚ Upload script %1 finished successfully. 脚本 %1 上传æˆåŠŸã€‚ Uploaded to %1 已上传至 %1 HotKeySettings Enable Global HotKeys å¯ç”¨å…¨å±€çƒ­é”® Capture Rect Area æ•获矩形区域 Capture Full Screen æ•èŽ·å…¨å± Capture current Screen æ•获当å‰å±å¹• Capture active Window æ•æ‰æ´»åŠ¨çš„çª—å£ Capture Window under Cursor æ•èŽ·å…‰æ ‡ä¸‹çš„çª—å£ Global HotKeys 全局热键 Capture Last Rect Area æ•æ‰ä¸Šä¸€æ¬¡çš„矩形区域 Clear 清除 Capture using Portal 使用 Portal æ•获 HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. 当å‰ä»… Windows å’Œ X11 支æŒçƒ­é”®ã€‚ ç¦ç”¨æ­¤é€‰é¡¹ä¹Ÿä¼šä½¿ä»… ksnip æ“ä½œå¿«æ·æ–¹å¼ã€‚ ImageGrabberSettings Capture mouse cursor on screenshot 截图时包å«é¼ æ ‡å…‰æ ‡ Should mouse cursor be visible on screenshots. å±å¹•截图时鼠标 光标是å¦å¯è§ã€‚ Image Grabber 图åƒé‡‡é›†å™¨ Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. 使用 XDG-DESKTOP-PORTAL 的通用 Wayland 实现 以ä¸åŒçš„æ–¹å¼å¤„ç†å±å¹•缩放。 å¯ç”¨æ­¤é€‰é¡¹å°†ç¡®å®šå½“å‰å±å¹•缩放 并将其 应用于 ksnip 中的å±å¹•截图 。 GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME å’Œ KDE Plasma 支æŒå„自的Wayland, 也有通用的 XDG-DESKTOP-PORTAL å±å¹•截图。 å¯ç”¨è¯¥é€‰é¡¹å°†å¼ºåˆ¶ KDE Plasma å’Œ GNOME 使用 XDG-DESKTOP-PORTAL 截图方å¼ã€‚ 改å˜è¿™ä¸ªé€‰é¡¹éœ€è¦é‡æ–°å¯åЍ ksnip。 Show Main Window after capturing screenshot æ•æ‰å±å¹•æˆªå›¾åŽæ˜¾ç¤ºä¸»çª—å£ Hide Main Window during screenshot 截图时éšè—ä¸»çª—å£ Hide Main Window when capturing a new screenshot. æ•获一个新截图时éšè—主窗å£ã€‚ Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. éšè—或最å°åŒ–ä¸»çª—å£æ—¶åœ¨æ•获新的 å±å¹•å¿«ç…§åŽæ˜¾ç¤ºä¸»çª—å£ã€‚ Force Generic Wayland (xdg-desktop-portal) Screenshot 强制 Generic Wayland (xdg-desktop-portal) 截图 Scale Generic Wayland (xdg-desktop-portal) Screenshots 缩放 Generic Wayland (xdg-desktop-portal) 截图 Implicit capture delay éšå¼æ•获延迟 This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. 当在 UI 中没有选择延迟时使用此延迟,它å…许 ksnip 在截å±ä¹‹å‰éšè—。 当 ksnip å·²ç»æœ€å°åŒ–时,ä¸åº”用此值。 å‡å°è¿™ä¸ªå€¼å¯ä»¥ä½¿ ksnip 的主窗å£åœ¨å±å¹•截图上å¯è§ã€‚ ImgurHistoryDialog Imgur History Imgur 历å²è®°å½• Close 关闭 Time Stamp 时间戳 Link 链接 Delete Link 删除链接 ImgurUploader Upload to imgur.com finished! 上传到 imgur.com 完æˆï¼ Received new token, trying upload again… 收到新令牌,正在å°è¯•冿¬¡ä¸Šä¼ â€¦ Imgur token has expired, requesting new token… Imgur 令牌已过期,正在请求新令牌… ImgurUploaderSettings Force anonymous upload 强制匿å上传 Always copy Imgur link to clipboard 总是将 Imgur 链接å¤åˆ¶åˆ°å‰ªè´´æ¿ Client ID 客户端 ID Client Secret 客户端 Secret PIN PIN Enter imgur Pin which will be exchanged for a token. 输入Imgur Pin,它将会被替æ¢ä¸ºä»¤ç‰Œã€‚ Get PIN 获得 PIN Get Token 获得令牌 Imgur History Imgur 历å²è®°å½• Imgur Uploader Imgurä¸Šè½½ç¨‹åº Username 用户å Waiting for imgur.com… 等待 imgur.com 的回应… Imgur.com token successfully updated. Imgur.com 令牌已æˆåŠŸæ›´æ–°ã€‚ Imgur.com token update error. Imgur.com 令牌更新错误。 After uploading open Imgur link in default browser 上传到ImguråŽåœ¨é»˜è®¤æµè§ˆå™¨ä¸­æ‰“å¼€ Link directly to image 直接链接到图片 Base Url: åŸºå€ URL: Base url that will be used for communication with Imgur. Changing requires restart. 基地 URL 用æ¥ä¸Ž Imgur 通信。 更改需è¦é‡å¯åº”用。 Clear Token 清空 Token Upload title: 上传标题: Upload description: 上传æè¿°: LoadImageFromFileOperation Unable to open image 无法打开图片 Unable to open image from path %1 无法从路径 %1 中打开图片 MainToolBar New 新建 Delay in seconds between triggering and capturing screenshot. 触å‘å¹¶æ•获å±å¹•截图 的延迟秒数。 s The small letter s stands for seconds. ç§’ Save ä¿å­˜ Save Screen Capture to file system å°†å±å¹•截图ä¿å­˜åˆ°æ–‡ä»¶ Copy å¤åˆ¶ Copy Screen Capture to clipboard å¤åˆ¶å±å¹•æˆªå›¾åˆ°å‰ªè´´æ¿ Tools 工具 Undo 撤消 Redo é‡åš Crop å‰ªè£ Crop Screen Capture 剪è£å±å¹•截图 MainWindow Unsaved 未ä¿å­˜ Upload 上传 Print æ‰“å° Opens printer dialog and provide option to print image æ‰“å¼€æ‰“å°æœºè®¾ç½®å¯¹è¯æ¡† Print Preview 打å°é¢„览 Opens Print Preview dialog where the image orientation can be changed 打开“打å°é¢„览â€å¯¹è¯æ¡†ï¼Œå¯ä»¥åœ¨å…¶ä¸­æ›´æ”¹å›¾åƒæ–¹å‘ Scale 缩放 Quit 退出 Settings 设置 &About 关于(&A) Open 打开 &Edit 编辑(&E) &Options 选项(&O) &Help 帮助(&H) Add Watermark æ·»åŠ æ°´å° Add Watermark to captured image. Multiple watermarks can be added. 为æ•èŽ·çš„å›¾åƒæ·»åŠ æ°´å°ã€‚å¯ä»¥æ·»åŠ å¤šä¸ªæ°´å°ã€‚ &File 文件(&F) Unable to show image æ— æ³•æ˜¾ç¤ºå›¾åƒ Save As... å¦å­˜ä¸º... Paste 粘贴 Paste Embedded 嵌入粘贴 Pin 图钉 Pin screenshot to foreground in frameless window 将截图固定在无边框的å‰å°çª—å£ä¸Š No image provided but one was expected. éœ€è¦æä¾›ä¸€ä¸ªå›¾åƒã€‚ Copy Path å¤åˆ¶è·¯å¾„ Open Directory 打开目录 &View 查看(&V) Delete 删除 Rename é‡å‘½å Open Images æ‰“å¼€å›¾åƒ Show Docks 显示 Docks Hide Docks éšè—åœé  Copy as data URI å¤åˆ¶ä¸ºæ•°æ® URI Open &Recent 打开最近文档( &R) Modify Canvas 修改画布 Upload triggerCapture to external source 上传 triggerCapture åˆ°å¤–éƒ¨æº Copy triggerCapture to system clipboard å¤åˆ¶ triggerCapture åˆ°ç³»ç»Ÿå‰ªè´´æ¿ Scale Image ç¼©æ”¾å›¾åƒ Rotate 旋转 Rotate Image æ—‹è½¬å›¾åƒ Actions æ“作 Image Files å›¾åƒæ–‡ä»¶ Save All ä¿å­˜å…¨éƒ¨ Close Window å…³é—­çª—å£ Cut 剪切 OCR OCR MultiCaptureHandler Save ä¿å­˜ Save As å¦å­˜ä¸º Open Directory 打开目录 Copy å¤åˆ¶ Copy Path å¤åˆ¶è·¯å¾„ Delete 删除 Rename é‡å‘½å Save All ä¿å­˜å…¨éƒ¨ NewCaptureNameProvider Capture æ•获 OcrWindowCreator OCR Window %1 OCR çª—å£ %1 PinWindow Close 关闭 Close Other 关闭其它 Close All 关闭所有 PinWindowCreator OCR Window %1 OCR çª—å£ %1 PluginsSettings Search Path æœç´¢è·¯å¾„ Default 默认 The directory where the plugins are located. æ’件所在的目录。 Browse æµè§ˆ Name åç§° Version 版本 Detect 检测 Plugin Settings æ’件设置 Plugin location æ’ä»¶ä½ç½® ProcessIndicator Processing 处ç†ä¸­ RenameOperation Image Renamed 图åƒå·²é‡å‘½å Image Rename Failed 图åƒé‡å‘½å失败 Rename image é‡å‘½åå›¾åƒ New filename: 新文件å: Successfully renamed image to %1 æˆåŠŸå°†å›¾ç‰‡é‡å‘½å为 %1 Failed to rename image to %1 未能将图片é‡å‘½å为 %1 SaveOperation Save As å¦å­˜ä¸º All Files 所有文件 Image Saved 图片已ä¿å­˜ Saving Image Failed ä¿å­˜å›¾åƒå¤±è´¥ Image Files å›¾åƒæ–‡ä»¶ Saved to %1 å·²ä¿å­˜è‡³ %1 Failed to save image to %1 未能将图片ä¿å­˜è‡³ %1 SaverSettings Automatically save new captures to default location 自动将新的æ•获ä¿å­˜åˆ°é»˜è®¤ä½ç½® Prompt to save before discarding unsaved changes 在放弃未ä¿å­˜çš„æ›´æ”¹ä¹‹å‰æç¤ºä¿å­˜ Remember last Save Directory è®°ä½ä¸Šæ¬¡ä¿å­˜çš„目录 When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. å¯ç”¨åŽæ¯æ¬¡ä¿å­˜éƒ½ä¼šå°†è®¾ç½®ä¸­çš„ä¿å­˜ç›®å½• 覆盖为上次的ä¿å­˜ç›®å½•。 Capture save location and filename æ•获ä¿å­˜ä½ç½®å’Œæ–‡ä»¶å Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. æ”¯æŒ JPGã€PNG å’Œ BMP æ ¼å¼ã€‚如果没有æä¾›æ ¼å¼ï¼Œå°†ä½¿ç”¨PNG作为默认格å¼ã€‚ 文件åå¯ä»¥åŒ…å«ä»¥ä¸‹é€šé…符。 - $Y, $M, $D 代表日期,$h, $m, $s 代表时间,或 $T 代表 hhmmss æ ¼å¼çš„æ—¶é—´ã€‚ - 多个连续的 # 代表计数器。若 #### 代表 0001,下一次æ•获则会是0002。 Browse æµè§ˆ Saver Settings ä¿å­˜è®¾ç½® Capture save location æ•获ä¿å­˜ä½ç½® Default 默认 Factor å› å­ Save Quality ä¿å­˜è´¨é‡ Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. 指定 0 å¯ä»¥èŽ·å¾—å°çš„压缩文件,100 会获得大的未压缩文件。 å¹¶éžæ‰€æœ‰å›¾åƒæ ¼å¼éƒ½åƒ JPEG 一样支æŒå…¨éƒ¨èŒƒå›´ã€‚ Overwrite file with same name 覆盖åŒå文件 ScriptUploaderSettings Copy script output to clipboard 将脚本输出å¤åˆ¶åˆ°å‰ªåˆ‡æ¿ Script: 脚本: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. 上传时调用的脚本的路径。在上传过程中,脚本将被以 临时 png 文件的路径作为å•䏀傿•°è°ƒç”¨ã€‚ Browse æµè§ˆ Script Uploader 上传脚本 Select Upload Script 选择上传脚本 Stop when upload script writes to StdErr åœ¨ä¸Šä¼ è„šæœ¬è¾“å‡ºè‡³æ ‡å‡†é”™è¯¯æ—¶åœæ­¢ Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. 当脚本输出至标准错误时,将上传标记为失败。 没有此设置,脚本中的错误将ä¸ä¼šè¢«æ³¨æ„到。 Filter: 过滤器: RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. 正则表达å¼ã€‚仅在匹é…ä¸Šæ­£åˆ™è¡¨è¾¾å¼æ—¶å¤åˆ¶åˆ°å‰ªè´´æ¿ã€‚ è‹¥çœç•¥æ­¤é¡¹ï¼Œå°†å¤åˆ¶æ‰€æœ‰å†…容。 SettingsDialog Settings 设置 OK 确定 Cancel å–æ¶ˆ Image Grabber 图åƒé‡‡é›†å™¨ Imgur Uploader Imgur ä¸Šä¼ ç¨‹åº Application åº”ç”¨ç¨‹åº Annotator 注释器 HotKeys å¿«æ·é”® Uploader ä¸Šä¼ ç¨‹åº Script Uploader 上传脚本 Saver ä¿å­˜ Stickers 贴纸 Snipping Area 截图区域 Tray Icon 托盘图标 Watermark æ°´å° Actions æ“作 FTP Uploader FTP 上传器 Plugins æ’ä»¶ Search Settings... æœç´¢è®¾ç½®... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. 使用控制柄调整所选矩形的大å°ï¼Œæˆ–通过拖动选区æ¥ç§»åŠ¨å®ƒã€‚ Use arrow keys to move the selection. 使用方å‘键移动选中区域。 Use arrow keys while pressing CTRL to move top left handle. 按 CTRL é”®çš„åŒæ—¶ä½¿ç”¨æ–¹å‘键移动左上角的控制柄。 Use arrow keys while pressing ALT to move bottom right handle. 按 ALT é”®çš„åŒæ—¶ä½¿ç”¨æ–¹å‘键移动å³ä¸‹è§’的控制柄。 This message can be disabled via settings. å¯ä»¥é€šè¿‡è®¾ç½®ç¦ç”¨æ­¤æ¶ˆæ¯ã€‚ Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. 通过按 ENTER/RETURN 或鼠标åŒå‡»ä»»æ„ä½ç½®æ¥ç¡®è®¤é€‰æ‹©ã€‚ Abort by pressing ESC. 按 ESC 键中止。 SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. 点击并拖动选择一个矩形区域或按 ESC 键退出。 Hold CTRL pressed to resize selection after selecting. é€‰æ‹©åŽæŒ‰ä½ CTRL 键调整选区大å°ã€‚ Hold CTRL pressed to prevent resizing after selecting. 选择åŽï¼ŒæŒ‰ä½ CTRL 键防止调整大å°ã€‚ Operation will be canceled after 60 sec when no selection made. 如果未进行选择,则60ç§’åŽå°†å–消æ“作。 This message can be disabled via settings. å¯ä»¥é€šè¿‡è®¾ç½®ç¦ç”¨æ­¤æ¶ˆæ¯ã€‚ SnippingAreaSettings Freeze Image while snipping æˆªå›¾æ—¶å†»ç»“å›¾åƒ When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. å¯ç”¨åŽå°†åœ¨é€‰æ‹©çŸ©å½¢åŒºåŸŸæ—¶å†»ç»“背景。 它还会更改延迟å±å¹•截图的行为, 从而更改了延迟å±å¹•截图的行为, å¯ç”¨æ­¤é€‰é¡¹å°†å»¶è¿Ÿå‘生在显示剪è£åŒºåŸŸä¹‹å‰ï¼Œ 而ç¦ç”¨æ­¤é€‰é¡¹ 将延迟å‘生在显示剪è£åŒºåŸŸä¹‹åŽã€‚ Wayland 始终ç¦ç”¨æ­¤åŠŸèƒ½ï¼Œ MacOs 始终å¯ç”¨æ­¤åŠŸèƒ½ã€‚ Show magnifying glass on snipping area 在截å±åŒºåŸŸæ˜¾ç¤ºæ”¾å¤§é•œ Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. 显示放大背景图的 放大镜。此设置仅在 å¯ç”¨äº†'在截图时冻结图åƒ'时生效。 Show Snipping Area rulers 在截图区域显示标尺 Horizontal and vertical lines going from desktop edges to cursor on snipping area. 在截å±åŒºåŸŸï¼Œæ˜¾ç¤ºä»Žå±å¹•边缘到鼠标 的水平线和垂直线。 Show Snipping Area position and size info 显示截图区域的ä½ç½®å’Œå°ºå¯¸ä¿¡æ¯ When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. 当未按下鼠标左键时, 显示ä½ç½®ï¼Œ 当按下鼠标按钮时, æ‰€é€‰åŒºåŸŸçš„å¤§å°æ˜¾ç¤ºåœ¨æ•获区域的左上方。 Allow resizing rect area selection by default 默认情况下å…è®¸è°ƒæ•´çŸ©å½¢åŒºåŸŸçš„å¤§å° When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. å¯ç”¨åŽï¼Œ 将在选择矩形区域åŽå…许调整选择的大å°ã€‚ 完æˆè°ƒæ•´å¤§å°åŽï¼Œ å¯ä»¥æŒ‰å›žè½¦é”®ç¡®è®¤é€‰æ‹©ã€‚ Show Snipping Area info text æ˜¾ç¤ºæˆªå›¾åŒºåŸŸä¿¡æ¯æ–‡æœ¬ Snipping Area cursor color 截图区域的光标颜色 Sets the color of the snipping area cursor. 设置剪切区域光标的颜色。 Snipping Area cursor thickness 截图区域的光标粗细 Sets the thickness of the snipping area cursor. 设置剪切区域光标的粗细。 Snipping Area 截å±åŒºåŸŸ Snipping Area adorner color 截图区域装饰色 Sets the color of all adorner elements on the snipping area. 设置剪切区域上 所有装饰元素的颜色。 Snipping Area Transparency æˆªå›¾åŒºåŸŸé€æ˜Žåº¦ Alpha for not selected region on snipping area. Smaller number is more transparent. 剪è£åŒºåŸŸä¸­æœªé€‰æ‹©åŒºåŸŸçš„ Alpha。 æ•°å­—è¶Šå°è¶Šé€æ˜Žã€‚ Enable Snipping Area offset å¯ç”¨æˆªå›¾åŒºåŸŸåç§» When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. å¯ç”¨åŽä¼šå°†é…置的åç§»é‡åº”用于未正确计算ä½ç½®æ—¶æ‰€éœ€çš„æˆªå›¾åŒºåŸŸä½ç½®ã€‚ 有时需è¦å¯ç”¨å±å¹•缩放。 X X Y Y StickerSettings Up å‘上 Down å‘下 Use Default Stickers 使用默认贴纸 Sticker Settings 贴纸设置 Vector Image Files (*.svg) 矢é‡å›¾åƒæ–‡ä»¶ (*.svg) Add 添加 Remove 移除 Add Stickers 添加贴纸 TrayIcon Show Editor 显示编辑器 TrayIconSettings Use Tray Icon 使用托盘图标 When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. å¯ç”¨åŽï¼Œå¦‚系统窗å£ç®¡ç†å™¨æ”¯æŒï¼Œä¼šå‘ä»»åŠ¡æ æ·»åŠ æ‰˜ç›˜å›¾æ ‡ã€‚ 更改需è¦é‡æ–°å¯åЍæ‰èƒ½ç”Ÿæ•ˆã€‚ Minimize to Tray 最å°åŒ–到托盘 Start Minimized to Tray å¯åŠ¨æ—¶æœ€å°åŒ–到托盘 Close to Tray 关闭到托盘 Show Editor 显示编辑器 Capture æ•获 Default Tray Icon action 默认托盘图标行为 Default Action that is triggered by left clicking the tray icon. 左键å•击托盘图标时的默认触å‘行为。 Tray Icon Settings 托盘图标设置 Use platform specific notification service 使用平å°ç‰¹å®šçš„通知æœåŠ¡ When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. å¯ç”¨åŽå°†ä½¿ç”¨å°è¯•使用特定于平å°çš„通知存在时æä¾›æœåŠ¡ã€‚ 更改需è¦é‡æ–°å¯åЍæ‰èƒ½ç”Ÿæ•ˆã€‚ Display Tray Icon notifications 显示托盘图标通知 UpdateWatermarkOperation Select Image é€‰æ‹©å›¾åƒ Image Files 图片文件 UploadOperation Upload Script Required 需è¦ä¸Šä¼ è„šæœ¬ Please add an upload script via Options > Settings > Upload Script 请通过选项>设置>上传脚本添加一个上传脚本 Capture Upload æ•获上传 You are about to upload the image to an external destination, do you want to proceed? 您å³å°†æŠŠå›¾åƒä¸Šä¼ è‡³å¤–éƒ¨ç«™ç‚¹ã€‚æ‚¨æ˜¯å¦æƒ³è¦ç»§ç»­ï¼Ÿ UploaderSettings Ask for confirmation before uploading 上传å‰è¯·æ±‚确认 Uploader Type: 上传类型: Imgur Imgur Script 脚本 Uploader ä¸Šä¼ ç¨‹åº FTP FTP VersionTab Version 版本 Build 构建版本 Using: 使用: WatermarkSettings Watermark Image æ°´å°å›¾åƒ Update æ›´æ–° Rotate Watermark æ—‹è½¬æ°´å° When enabled, Watermark will be added with a rotation of 45° å¯ç”¨åŽï¼Œå°†æ·»åŠ æ—‹è½¬ 45° çš„æ°´å° Watermark Settings æ°´å°è®¾ç½® ksnip-master/translations/ksnip_zh_Hant.ts000066400000000000000000001755411457262621600214130ustar00rootroot00000000000000 AboutDialog About 關於 About 關於 Version 版本 Author 作者 Close 關閉 Donate æè´ˆ Contact è¯ç¹« AboutTab License: 許å¯è­‰ï¼š Screenshot and Annotation Tool 螢幕截圖和註釋工具 ActionSettingTab Name å稱 Shortcut å¿«æ·éµ Clear 清除 Take Capture æ“·å– Include Cursor åŒ…å«æ¸¸æ¨™ Delay å»¶é² s The small letter s stands for seconds. s Capture Mode æ“·å–æ¨¡å¼ Show image in Pin Window 在釘é¸è¦–窗中顯示圖片 Copy image to Clipboard 圖片複製到剪貼簿 Upload image 上傳圖片 Open image parent directory 打開圖片父目錄 Save image 儲存圖片 Hide Main Window éš±è—主視窗 Global When enabled will make the shortcut available even when ksnip has no focus. ActionsSettings Add 新增 Actions Settings æ“作設置 Action æ“作 AddWatermarkOperation Watermark Image Required éœ€è¦æµ®æ°´å°åœ–片 Please add a Watermark Image via Options > Settings > Annotator > Update 請通éŽã€Œé¸é …ã€>「設置ã€>「註釋器ã€>ã€Œæ›´æ–°ã€æ–°å¢žæµ®æ°´å°åœ–片 AnnotationSettings Smooth Painter Paths 平滑繪製的路徑 When enabled smooths out pen and marker paths after finished drawing. 如啟用,繪製完æˆå¾Œ 消除筆和標記路徑。 Smooth Factor å¹³æ»‘å› å­ Increasing the smooth factor will decrease precision for pen and marker but will make them more smooth. 增加平滑因å­å°‡æ¸›å°‘ 筆和記號筆的精度,但會 使它們更平滑。 Annotator Settings 註釋器設置 Remember annotation tool selection and load on startup 記ä½è¨»é‡‹å™¨é¸æ“‡ä¸¦åœ¨å•Ÿå‹•時載入 Switch to Select Tool after drawing Item 繪製後切æ›åˆ°é¸æ“‡å·¥å…· Number Tool Seed change updates all Number Items æ•¸å­—å·¥å…·ç¨®å­æ›´æ”¹å°‡æ›´æ–°æ‰€æœ‰æ•¸å­—é …ç›® Disabling this option causes changes of the number tool seed to affect only new items but not existing items. Disabling this option allows having duplicate numbers. ç¦ç”¨æ­¤é¸é …將導致數字工具的更改 種å­åƒ…影響新項目,而ä¸å½±éŸ¿ç¾æœ‰é …目。 ç¦ç”¨æ­¤é¸é …å°‡å…許é‡è¤‡çš„æ•¸å­—。 Canvas Color 畫布é¡è‰² Default Canvas background color for annotation area. Changing color affects only new annotation areas. 註釋å€åŸŸç•«å¸ƒçš„é è¨­èƒŒæ™¯é¡è‰² 改變é¡è‰²åªæœƒå½±éŸ¿æ–°çš„註釋å€åŸŸã€‚ Select Item after drawing ç¹ªåœ–å¾Œé¸æ“‡é …ç›® With this option enabled the item gets selected after being created, allowing changing settings. 啟用此é¸é …後,將在創建項目後å°å…¶é€²è¡Œé¸æ“‡ï¼Œ 從而å¯ä»¥æ›´æ”¹è¨­ç½®ã€‚ Show Controls Widget The Controls Widget contains the Undo/Redo, Crop, Scale, Rotate and Modify Canvas buttons. ApplicationSettings Capture screenshot at startup with default mode 使用é è¨­æ¨¡å¼åœ¨å•Ÿå‹•時擷å–螢幕截圖 Application Style æ‡‰ç”¨ç¨‹å¼æ¨£å¼ Sets the application style which defines the look and feel of the GUI. Change requires ksnip restart to take effect. 設置定義GUIå¤–è§€çš„æ‡‰ç”¨ç¨‹å¼æ¨£å¼ã€‚ æ›´æ”¹è¦æ±‚ksnip釿–°å•Ÿå‹•æ‰èƒ½ç”Ÿæ•ˆã€‚ Application Settings 應用程å¼è¨­ç½® Automatically copy new captures to clipboard 自動將新的擷å–複製到剪貼簿 Use Tabs 使用標籤 Change requires restart. 修改需è¦é‡å•Ÿå¾Œç”Ÿæ•ˆã€‚ Run ksnip as single instance ä»¥å–®ç¨‹åºæ¨¡å¼é‹è¡Œ ksnip Hide Tabbar when only one Tab is used. ç•¶åªæœ‰ä¸€å€‹æ¨™ç±¤æ™‚éš±è—æ¨™ç±¤æ¬„。 Enabling this option will allow only one ksnip instance to run, all other instances started after the first will pass its arguments to the first and close. Changing this option requires a new start of all instances. 啟用這個é¸é …將會åªå…許一個ksnip程åºé‹è¡Œï¼Œ 所有其它程åºå•Ÿå‹•æ™‚æœƒå°‡åƒæ•¸å‚³çµ¦ç¬¬ä¸€å€‹ç¨‹åº 然後退出。改變這個é¸é …需è¦åœ¨é—œé–‰æ‰€æœ‰ç¨‹åº 後啟動新的程åºã€‚ Remember Main Window position on move and load on startup 在移動時記ä½ä¸»è¦–窗的ä½ç½®ä¸¦åœ¨å•Ÿå‹•時載入 Auto hide Tabs è‡ªå‹•éš±è—æ¨™ç±¤ Auto hide Docks è‡ªå‹•éš±è— Docks On startup hide Toolbar and Annotation Settings. Docks visibility can be toggled with the Tab Key. 在啟動時隱è—工具欄和註釋器, å¯ä»¥æŒ‰ä¸‹ Tab éµé¡¯ç¤º Dock。 Auto resize to content è‡ªå‹•èª¿æ•´å…§å®¹å¤§å° Automatically resize Main Window to fit content image. 自動調整主視窗的大å°ä»¥é©åˆå…§å®¹åœ–片。 Enable Debugging 啟用除錯 Enables debug output written to the console. Change requires ksnip restart to take effect. 啟用寫入控製å°çš„除錯輸出。 æ›´æ”¹éœ€è¦ ksnip 釿–°å•Ÿå‹•æ‰èƒ½ç”Ÿæ•ˆã€‚ Resizing to content is delay to allow the Window Manager to receive the new content. In case that the Main Windows is not adjusted correctly to the new content, increasing this delay might improve the behavior. æ ¹æ“šå…§å®¹å¤§å°æ˜¯å…許視窗管ç†å™¨æŽ¥æ”¶æ–°å…§å®¹çš„å»¶é²ã€‚ å¦‚æžœæœªæ­£ç¢ºèª¿æ•´ä¸»è¦–çª—ä»¥é©æ‡‰æ–°å…§å®¹ï¼Œ 增加延é²å¯èƒ½æœƒæ”¹å–„行為。 Resize delay Temp Directory Temp directory used for storing temporary images that are going to be deleted after ksnip closes. Browse ç€è¦½ AuthorTab Contributors: è²¢ç»è€…: Spanish Translation 西ç­ç‰™èªžç¿»è­¯ Dutch Translation è·è˜­èªžç¿»è­¯ Russian Translation 俄語翻譯 Norwegian BokmÃ¥l Translation 挪å¨èªžçš„翻譯 French Translation 法語翻譯 Polish Translation 波蘭語翻譯 Snap & Flatpak Support Snap å’Œ Flatpak æ”¯æŒ The Authors: 作者: CanDiscardOperation Warning - 警告 - The capture %1%2%3 has been modified. Do you want to save it? æ“·å– %1%2%3 已經被修改。 是å¦éœ€è¦å„²å­˜ï¼Ÿ CaptureModePicker New 新建 Draw a rectangular area with your mouse 用游標繪製一個矩形å€åŸŸ Capture full screen including all monitors æ“·å–全螢幕,包括所有螢幕 Capture screen where the mouse is located æ“·å–æ¸¸æ¨™æ‰€åœ¨çš„螢幕 Capture window that currently has focus æ“·å–ç›®å‰ç„¦é»žæ‰€åœ¨çš„視窗 Capture that is currently under the mouse cursor æ“·å–ç•¶å‰åœ¨æ»‘鼠游標下的內容 Capture a screenshot of the last selected rectangular area æ“·å–ä¸Šä¸€æ¬¡é¸æ“‡çš„矩形å€åŸŸçš„螢幕截圖 Uses the screenshot Portal for taking screenshot 使用 the screenshot Portal 截圖 ContactTab Community ç¤¾å€ Bug Reports 錯誤報告 If you have general questions, ideas or just want to talk about ksnip,<br/>please join our %1 or our %2 server. 如果您有一般å•é¡Œã€æƒ³æ³•æˆ–åªæƒ³è«‡è«‡ ksnip,<br/>請加入我們的 %1 或我們的 %2 伺æœå™¨ã€‚ Please use %1 to report bugs. 請使用 %1 報告故障。 CopyAsDataUriOperation Failed to copy to clipboard 複製到剪貼簿失敗 Failed to copy to clipboard as base64 encoded image. 以 base64 圖片編碼形å¼è¤‡è£½åˆ°å‰ªè²¼ç°¿å¤±æ•—。 Copied to clipboard 已複製到剪貼簿 Copied to clipboard as base64 encoded image. 已將圖片的 base64 編碼複製到剪貼簿。 DeleteImageOperation Delete Image 刪除圖片 The item '%1' will be deleted. Do you want to continue? é …ç›® '%1' 將被刪除。 你想繼續嗎? DonateTab Donations are always welcome æ­¡è¿Žææ¬¾ Donation æè´ˆ ksnip is a non-profitable copyleft libre software project, and<br/>still has some costs that need to be covered,<br/>like domain costs or hardware costs for cross-platform support. ksnip 是一個éžç›ˆåˆ©çš„ Copyleft 自由軟體項目,並且<br/>仿œ‰ä¸€äº›è²»ç”¨éœ€è¦æ”¯ä»˜ï¼Œ<br/>å¦‚åŸŸåæˆæœ¬æˆ–è·¨å¹³å°æ”¯æŒçš„ç¡¬é«”æˆæœ¬ã€‚ If you want to help or just want to appreciate the work being done<br/>by treating developers to a beer or coffee, you can do that %1here%2. <br/>如果你想通éŽè«‹é–‹ç™¼è€…å–啤酒或咖啡æä¾›å¹«åŠ©æˆ–åªæ˜¯æƒ³è®šè³žæ‰€åšçš„工作,歡迎看看%1這裡%2。 Become a GitHub Sponsor? æˆç‚º GitHub 贊助者? Also possible, %1here%2. 也å¯ä»¥åœ¨ %1此處%2 ææ¬¾ã€‚ EmptyActionSettingTab Add new actions by pressing the 'Add' tab button. 通éŽé»žæ“Šã€Œæ–°å¢žã€æ¨™ç±¤æŒ‰éˆ•來新增新的æ“作。 EnumTranslator Rectangular Area 矩形å€åŸŸ Last Rectangular Area 上一個矩形å€åŸŸ Full Screen (All Monitors) 全螢幕(所有螢幕) Current Screen ç•¶å‰èž¢å¹• Active Window 活動的視窗 Window Under Cursor 游標下的視窗 Screenshot Portal æˆªåœ–å…¥å£ FtpUploaderSettings Force anonymous upload. 強制匿å上傳。 Url Url Username 用戶å Password 密碼 FTP Uploader FTP 上傳器 HandleUploadResultOperation Upload Successful 上傳æˆåŠŸ Unable to save temporary image for upload. 無法為上傳儲存臨時圖片。 Unable to start process, check path and permissions. 無法啟動程åºï¼Œè«‹æª¢æŸ¥è·¯å¾‘å’Œæ¬Šé™æ˜¯å¦æ­£ç¢ºã€‚ Process crashed 程åºå·²å´©æ½° Process timed out. 程åºè¶…時。 Process read error. 程åºè®€éŒ¯èª¤ã€‚ Process write error. 程åºå¯«éŒ¯èª¤ã€‚ Web error, check console output. 網路錯誤,請檢查控製å°è¼¸å‡ºã€‚ Upload Failed 上傳失敗 Script wrote to StdErr. 腳本在標準錯誤上有輸出。 FTP Upload finished successfully. FTP 上傳æˆåŠŸå®Œæˆã€‚ Unknown error. 未知錯誤。 Connection Error. 連接錯誤。 Permission Error. 權é™éŒ¯èª¤ã€‚ Upload script %1 finished successfully. 腳本 %1 上傳æˆåŠŸã€‚ Uploaded to %1 已上傳至 %1 HotKeySettings Enable Global HotKeys å•Ÿç”¨å…¨åŸŸç†±éµ Capture Rect Area æ“·å–矩形å€åŸŸ Capture Full Screen æ“·å–全螢幕 Capture current Screen æ“·å–ç•¶å‰èž¢å¹• Capture active Window æ“·å–æ´»å‹•的視窗 Capture Window under Cursor æ“·å–æ¸¸æ¨™ä¸‹çš„視窗 Global HotKeys å…¨åŸŸç†±éµ Capture Last Rect Area æ“·å–上一次的矩形å€åŸŸ Clear 清除 Capture using Portal 使用 Portal æ“·å– HotKeys are currently supported only for Windows and X11. Disabling this option makes also the action shortcuts ksnip only. ç•¶å‰åƒ… Windows å’Œ X11 支æŒç†±éµã€‚ ç¦ç”¨æ­¤é¸é …也會使僅 ksnip æ“ä½œå¿«æ·æ–¹å¼ã€‚ ImageGrabberSettings Capture mouse cursor on screenshot æˆªåœ–æ™‚åŒ…å«æ»‘鼠游標 Should mouse cursor be visible on screenshots. 螢幕截圖時游標 游標是å¦å¯è¦‹ã€‚ Image Grabber 圖片採集器 Generic Wayland implementations that use XDG-DESKTOP-PORTAL handle screen scaling differently. Enabling this option will determine the current screen scaling and apply that to the screenshot in ksnip. 使用 XDG-DESKTOP-PORTAL 的通用 Wayland å¯¦ç¾ ä»¥ä¸åŒçš„æ–¹å¼è™•ç†èž¢å¹•縮放。 啟用此é¸é …將確定當å‰èž¢å¹•縮放 並將其 應用於 ksnip 中的螢幕截圖 。 GNOME and KDE Plasma support their own Wayland and the Generic XDG-DESKTOP-PORTAL screenshots. Enabling this option will force KDE Plasma and GNOME to use the XDG-DESKTOP-PORTAL screenshots. Change in this option require a ksnip restart. GNOME å’Œ KDE Plasma 支æŒå„自的Wayland, 也有通用的 XDG-DESKTOP-PORTAL 螢幕截圖。 啟用該é¸é …將強制 KDE Plasma å’Œ GNOME 使用 XDG-DESKTOP-PORTAL 截圖方å¼ã€‚ 改變這個é¸é …需è¦é‡æ–°å•Ÿå‹• ksnip。 Show Main Window after capturing screenshot æ“·å–螢幕截圖後顯示主視窗 Hide Main Window during screenshot 截圖時隱è—主視窗 Hide Main Window when capturing a new screenshot. æ“·å–一個新截圖時隱è—主視窗。 Show Main Window after capturing a new screenshot when the Main Window was hidden or minimize. éš±è—æˆ–最å°åŒ–ä¸»è¦–çª—æ™‚åœ¨æ“·å–æ–°çš„ 螢幕快照後顯示主視窗。 Force Generic Wayland (xdg-desktop-portal) Screenshot 強制 Generic Wayland (xdg-desktop-portal) 截圖 Scale Generic Wayland (xdg-desktop-portal) Screenshots 縮放 Generic Wayland (xdg-desktop-portal) 截圖 Implicit capture delay This delay is used when no delay was selected in the UI, it allows ksnip to hide before taking a screenshot. This value is not applied when ksnip was already minimized. Reducing this value can have the effect that ksnip's main window is visible on the screenshot. ImgurHistoryDialog Imgur History Imgur æ­·å²è¨˜éŒ„ Close 關閉 Time Stamp 時間戳 Link é€£çµ Delete Link åˆªé™¤é€£çµ ImgurUploader Upload to imgur.com finished! 上傳到 imgur.com 完æˆï¼ Received new token, trying upload again… æ”¶åˆ°æ–°è¨˜è™Ÿï¼Œæ­£åœ¨å˜—è©¦å†æ¬¡ä¸Šå‚³â€¦ Imgur token has expired, requesting new token… Imgur è¨˜è™Ÿå·²éŽæœŸï¼Œæ­£åœ¨è«‹æ±‚新記號… ImgurUploaderSettings Force anonymous upload 強制匿å上傳 Always copy Imgur link to clipboard 總是將 Imgur 連çµè¤‡è£½åˆ°å‰ªè²¼ç°¿ Client ID Client ID Client Secret 客戶端密碼 PIN PIN Enter imgur Pin which will be exchanged for a token. 輸入Imgur Pin,它將會被替æ›ç‚ºè¨˜è™Ÿã€‚ Get PIN ç²å¾— PIN Get Token ç²å¾—記號 Imgur History Imgur æ­·å²è¨˜éŒ„ Imgur Uploader Imgurä¸Šå‚³ç¨‹å¼ Username 用戶å Waiting for imgur.com… 等待 imgur.com 的回應… Imgur.com token successfully updated. Imgur.com 記號已æˆåŠŸæ›´æ–°ã€‚ Imgur.com token update error. Imgur.com 記號更新錯誤。 After uploading open Imgur link in default browser 上傳到Imgur後在é è¨­ç€è¦½å™¨ä¸­æ‰“é–‹ Link directly to image 直接連çµåˆ°åœ–片 Base Url: åŸºå€ URL: Base url that will be used for communication with Imgur. Changing requires restart. 基本 URL 用來與 Imgur 通信。 更改需è¦é‡å•Ÿæ‡‰ç”¨ã€‚ Clear Token 清空記號 Upload title: Upload description: LoadImageFromFileOperation Unable to open image 無法打開圖片 Unable to open image from path %1 無法從路徑 %1 中打開圖片 MainToolBar New 新建 Delay in seconds between triggering and capturing screenshot. 觸發並擷å–螢幕截圖 的延é²ç§’數。 s The small letter s stands for seconds. ç§’ Save 儲存 Save Screen Capture to file system 將螢幕截圖儲存到檔案 Copy 複製 Copy Screen Capture to clipboard 複製螢幕截圖到剪貼簿 Tools 工具 Undo å–æ¶ˆ Redo é‡åš Crop å‰ªè£ Crop Screen Capture 剪è£èž¢å¹•截圖 MainWindow Unsaved 未儲存 Upload 上傳 Print åˆ—å° Opens printer dialog and provide option to print image 打開å°è¡¨æ©Ÿè¨­ç½®å°è©±æ¡† Print Preview 列å°é è¦½ Opens Print Preview dialog where the image orientation can be changed 打開「列å°é è¦½ã€å°è©±æ¡†ï¼Œå¯ä»¥åœ¨å…¶ä¸­æ›´æ”¹åœ–ç‰‡æ–¹å‘ Scale 縮放 Quit 退出 Settings 設置 &About 關於(&A) Open 打開 &Edit 編輯(&E) &Options é¸é …(&O) &Help 幫助(&H) Add Watermark æ–°å¢žæµ®æ°´å° Add Watermark to captured image. Multiple watermarks can be added. 為擷å–的圖片新增浮水å°ã€‚å¯ä»¥æ–°å¢žå¤šå€‹æµ®æ°´å°ã€‚ &File 檔案(&F) Unable to show image 無法顯示圖片 Save As... å¦å­˜ç‚º... Paste 貼上 Paste Embedded 嵌入貼上 Pin é‡˜é¸ Pin screenshot to foreground in frameless window 將截圖固定在無邊框的å‰å°è¦–窗上 No image provided but one was expected. éœ€è¦æä¾›ä¸€å€‹åœ–ç‰‡ã€‚ Copy Path 複製路徑 Open Directory 打開目錄 &View 查看(&V) Delete 刪除 Rename é‡å‘½å Open Images 打開圖片 Show Docks 顯示 Docks Hide Docks éš±è— Docks Copy as data URI 複製為數據 URI Open &Recent 打開 & 最近 Modify Canvas 修改畫布 Upload triggerCapture to external source 上傳 triggerCapture åˆ°å¤–éƒ¨ä¾†æº Copy triggerCapture to system clipboard 複製 triggerCapture 到系統剪貼簿 Scale Image 縮放圖片 Rotate 旋轉 Rotate Image 旋轉圖片 Actions æ“作 Image Files 圖片檔案 Save All Close Window Cut OCR MultiCaptureHandler Save 儲存 Save As å¦å­˜ç‚º Open Directory 打開目錄 Copy 複製 Copy Path 複製路徑 Delete 刪除 Rename é‡å‘½å Save All NewCaptureNameProvider Capture æ“·å– OcrWindowCreator OCR Window %1 PinWindow Close 關閉 Close Other 關閉其它 Close All 關閉所有 PinWindowCreator OCR Window %1 PluginsSettings Search Path Default é è¨­ The directory where the plugins are located. Browse ç€è¦½ Name å稱 Version 版本 Detect Plugin Settings Plugin location ProcessIndicator Processing RenameOperation Image Renamed 圖片已é‡å‘½å Image Rename Failed 圖片é‡å‘½å失敗 Rename image é‡å‘½å圖片 New filename: 新檔案å: Successfully renamed image to %1 æˆåŠŸå°‡åœ–ç‰‡é‡å‘½å為 %1 Failed to rename image to %1 未能將圖片é‡å‘½å為 %1 SaveOperation Save As å¦å­˜ç‚º All Files 所有檔案 Image Saved 圖片已儲存 Saving Image Failed 儲存圖片失敗 Image Files 圖片檔案 Saved to %1 已儲存至 %1 Failed to save image to %1 未能將圖片儲存至 %1 SaverSettings Automatically save new captures to default location 自動將新的擷å–儲存到é è¨­ä½ç½® Prompt to save before discarding unsaved changes åœ¨æ”¾æ£„æœªå„²å­˜çš„æ›´æ”¹ä¹‹å‰æç¤ºå„²å­˜ Remember last Save Directory 記ä½ä¸Šæ¬¡å„²å­˜çš„目錄 When enabled will overwrite the save directory stored in settings with the latest save directory, for every save. å•Ÿç”¨å¾Œæ¯æ¬¡å„²å­˜éƒ½æœƒå°‡è¨­ç½®ä¸­çš„儲存目錄 覆蓋為上次的儲存目錄。 Capture save location and filename æ“·å–儲存ä½ç½®å’Œæª”案å Supported Formats are JPG, PNG and BMP. If no format provided, PNG will be used as default. Filename can contain following wildcards: - $Y, $M, $D for date, $h, $m, $s for time, or $T for time in hhmmss format. - Multiple consecutive # for counter. #### will result in 0001, next capture would be 0002. æ”¯æŒ JPGã€PNG å’Œ BMP æ ¼å¼ã€‚如果沒有æä¾›æ ¼å¼ï¼Œå°‡ä½¿ç”¨PNG作為é è¨­æ ¼å¼ã€‚ 檔案åå¯ä»¥åŒ…å«ä»¥ä¸‹é€šé…符。 - $Y, $M, $D 代表日期,$h, $m, $s 代表時間,或 $T 代表 hhmmss æ ¼å¼çš„æ™‚間。 - 多個連續的 # 代表計數器。若 #### 代表 0001,下一次擷å–則會是0002。 Browse ç€è¦½ Saver Settings 儲存設置 Capture save location æ“·å–儲存ä½ç½® Default é è¨­ Factor å› å­ Save Quality 儲存å“質 Specify 0 to obtain small compressed files, 100 for large uncompressed files. Not all image formats support the full range, JPEG does. 指定 0 å¯ä»¥ç²å¾—å°çš„壓縮檔案,100 會ç²å¾—大的未壓縮檔案。 ä¸¦éžæ‰€æœ‰åœ–片格å¼éƒ½åƒ JPEG 一樣支æŒå…¨éƒ¨ç¯„åœã€‚ Overwrite file with same name ScriptUploaderSettings Copy script output to clipboard 將腳本輸出複製到剪貼簿 Script: 腳本: Path to script that will be called for uploading. During upload the script will be called with the path to a temporary png file as a single argument. 上傳時調用的腳本的路徑。在上傳éŽç¨‹ä¸­ï¼Œè…³æœ¬å°‡è¢«ä»¥ 臨時 png æª”æ¡ˆçš„è·¯å¾‘ä½œç‚ºå–®ä¸€åƒæ•¸èª¿ç”¨ã€‚ Browse ç€è¦½ Script Uploader 上傳腳本 Select Upload Script 鏿“‡ä¸Šå‚³è…³æœ¬ Stop when upload script writes to StdErr åœ¨ä¸Šå‚³è…³æœ¬è¼¸å‡ºè‡³æ¨™æº–éŒ¯èª¤æ™‚åœæ­¢ Marks the upload as failed when script writes to StdErr. Without this setting errors in the script will be unnoticed. 當腳本輸出至標準錯誤時,將上傳標記為失敗。 æ²’æœ‰æ­¤è¨­ç½®ï¼Œè…³æœ¬ä¸­çš„éŒ¯èª¤å°‡ä¸æœƒè¢«è¨»æ„到。 Filter: éŽæ¿¾å™¨ï¼š RegEx Expression. Only copy to clipboard what matches the RegEx Expression. When omitted, everything is copied. æ­£è¦è¡¨ç¤ºæ³•。僅在匹é…上正è¦è¡¨ç¤ºæ³•時複製到剪貼簿。 è‹¥çœç•¥æ­¤é …,將複製所有內容。 SettingsDialog Settings 設置 OK 確定 Cancel å–æ¶ˆ Image Grabber 圖片採集器 Imgur Uploader Imgur ä¸Šå‚³ç¨‹å¼ Application æ‡‰ç”¨ç¨‹å¼ Annotator 註釋器 HotKeys å¿«æ·éµ Uploader ä¸Šå‚³ç¨‹å¼ Script Uploader 上傳腳本 Saver 儲存 Stickers 貼紙 Snipping Area 截圖å€åŸŸ Tray Icon 托盤圖示 Watermark æµ®æ°´å° Actions æ“作 FTP Uploader FTP 上傳器 Plugins Search Settings... SnippingAreaResizerInfoText Resize selected rect using the handles or move it by dragging the selection. 使用控製柄調整所é¸çŸ©å½¢çš„大å°ï¼Œæˆ–é€šéŽæ‹–å‹•é¸å€ä¾†ç§»å‹•它。 Use arrow keys to move the selection. 使用方å‘éµç§»å‹•é¸ä¸­å€åŸŸã€‚ Use arrow keys while pressing CTRL to move top left handle. 按 CTRL éµçš„åŒæ™‚使用方å‘éµç§»å‹•左上角的控製柄。 Use arrow keys while pressing ALT to move bottom right handle. 按 ALT éµçš„åŒæ™‚使用方å‘éµç§»å‹•å³ä¸‹è§’的控製柄。 This message can be disabled via settings. å¯ä»¥é€šéŽè¨­ç½®ç¦ç”¨æ­¤æ¶ˆæ¯ã€‚ Confirm selection by pressing ENTER/RETURN or mouse double-click anywhere. Abort by pressing ESC. SnippingAreaSelectorInfoText Click and Drag to select a rectangular area or press ESC to quit. é»žæ“Šä¸¦æ‹–å‹•é¸æ“‡ä¸€å€‹çŸ©å½¢å€åŸŸæˆ–按 ESC éµé€€å‡ºã€‚ Hold CTRL pressed to resize selection after selecting. 鏿“‡å¾ŒæŒ‰ä½ CTRL éµèª¿æ•´é¸å€å¤§å°ã€‚ Hold CTRL pressed to prevent resizing after selecting. 鏿“‡å¾Œï¼ŒæŒ‰ä½ CTRL éµé˜²æ­¢èª¿æ•´å¤§å°ã€‚ Operation will be canceled after 60 sec when no selection made. å¦‚æžœæœªé€²è¡Œé¸æ“‡ï¼Œå‰‡60ç§’å¾Œå°‡å–æ¶ˆæ“作。 This message can be disabled via settings. å¯ä»¥é€šéŽè¨­ç½®ç¦ç”¨æ­¤æ¶ˆæ¯ã€‚ SnippingAreaSettings Freeze Image while snipping 截圖時å‡çµåœ–片 When enabled will freeze the background while selecting a rectangular region. It also changes the behavior of delayed screenshots, with this option enabled the delay happens before the snipping area is shown and with the option disabled the delay happens after the snipping area is shown. This feature is always disabled for Wayland and always enabled for MacOs. å•Ÿç”¨å¾Œå°‡åœ¨é¸æ“‡çŸ©å½¢å€åŸŸæ™‚å‡çµèƒŒæ™¯ã€‚ 它還會更改延é²èž¢å¹•截圖的行為, 從而更改了延é²èž¢å¹•截圖的行為, 啟用此é¸é …將延é²ç™¼ç”Ÿåœ¨é¡¯ç¤ºå‰ªè£å€åŸŸä¹‹å‰ï¼Œ 而ç¦ç”¨æ­¤é¸é … 將延é²ç™¼ç”Ÿåœ¨é¡¯ç¤ºå‰ªè£å€åŸŸä¹‹å¾Œã€‚ Wayland 始終ç¦ç”¨æ­¤åŠŸèƒ½ï¼Œ MacOs 始終啟用此功能。 Show magnifying glass on snipping area 在截圖å€åŸŸé¡¯ç¤ºæ”¾å¤§é¡ Show a magnifying glass which zooms into the background image. This option only works with 'Freeze Image while snipping' enabled. 顯示放大背景圖的 放大é¡ã€‚此設置僅在 啟用了'在截圖時å‡çµåœ–片'時生效。 Show Snipping Area rulers 在截圖å€åŸŸé¡¯ç¤ºæ¨™å°º Horizontal and vertical lines going from desktop edges to cursor on snipping area. 在截圖å€åŸŸï¼Œé¡¯ç¤ºå¾žèž¢å¹•邊緣到游標 的水平線和垂直線。 Show Snipping Area position and size info 顯示截圖å€åŸŸçš„ä½ç½®å’Œå°ºå¯¸è¨Šæ¯ When left mouse button is not pressed the position is shown, when the mouse button is pressed, the size of the select area is shown left and above from the captured area. ç•¶æœªæŒ‰ä¸‹æ¸¸æ¨™å·¦éµæ™‚, 顯示ä½ç½®ï¼Œ 當按下游標按鈕時, 所é¸å€åŸŸçš„大å°é¡¯ç¤ºåœ¨æ“·å–å€åŸŸçš„左上方。 Allow resizing rect area selection by default é è¨­æƒ…æ³ä¸‹å…許調整矩形å€åŸŸçš„å¤§å° When enabled will, after selecting a rect area, allow resizing the selection. When done resizing the selection can be confirmed by pressing return. 啟用後, å°‡åœ¨é¸æ“‡çŸ©å½¢å€åŸŸå¾Œå…è¨±èª¿æ•´é¸æ“‡çš„大å°ã€‚ 完æˆèª¿æ•´å¤§å°å¾Œï¼Œ å¯ä»¥æŒ‰Enteréµç¢ºèªé¸æ“‡ã€‚ Show Snipping Area info text 顯示截圖å€åŸŸè¨Šæ¯æ–‡å­— Snipping Area cursor color 截圖å€åŸŸçš„æ¸¸æ¨™é¡è‰² Sets the color of the snipping area cursor. 設置剪切å€åŸŸæ¸¸æ¨™çš„é¡è‰²ã€‚ Snipping Area cursor thickness 截圖å€åŸŸçš„æ¸¸æ¨™ç²—ç´° Sets the thickness of the snipping area cursor. 設置剪切å€åŸŸæ¸¸æ¨™çš„粗細。 Snipping Area 截圖å€åŸŸ Snipping Area adorner color 截圖å€åŸŸè£é£¾è‰² Sets the color of all adorner elements on the snipping area. 設置剪切å€åŸŸä¸Š 所有è£é£¾å…ƒç´ çš„é¡è‰²ã€‚ Snipping Area Transparency 截圖å€åŸŸé€æ˜Žåº¦ Alpha for not selected region on snipping area. Smaller number is more transparent. 剪è£å€åŸŸä¸­æœªé¸æ“‡å€åŸŸçš„ Alpha。 數字越å°è¶Šé€æ˜Žã€‚ Enable Snipping Area offset When enabled will apply the configured offset to the Snipping Area position which is required when the position is not correctly calculated. This is sometimes required with screen scaling enabled. X Y StickerSettings Up å‘上 Down å‘下 Use Default Stickers 使用é è¨­è²¼ç´™ Sticker Settings 貼紙設置 Vector Image Files (*.svg) å‘é‡åœ–片檔案 (*.svg) Add 新增 Remove 移除 Add Stickers 新增貼紙 TrayIcon Show Editor 顯示編輯器 TrayIconSettings Use Tray Icon 使用托盤圖示 When enabled will add a Tray Icon to the TaskBar if the OS Window Manager supports it. Change requires restart. 啟用後,如系統視窗管ç†å™¨æ”¯æŒï¼Œæœƒå‘任務欄新增托盤圖示。 更改需è¦é‡æ–°å•Ÿå‹•æ‰èƒ½ç”Ÿæ•ˆã€‚ Minimize to Tray 最å°åŒ–到托盤 Start Minimized to Tray 啟動時最å°åŒ–到托盤 Close to Tray 關閉到托盤 Show Editor 顯示編輯器 Capture æ“·å– Default Tray Icon action é è¨­æ‰˜ç›¤åœ–示行為 Default Action that is triggered by left clicking the tray icon. å·¦éµå–®æ“Šæ‰˜ç›¤åœ–示時的é è¨­è§¸ç™¼è¡Œç‚ºã€‚ Tray Icon Settings 托盤圖示設置 Use platform specific notification service 使用平å°ç‰¹å®šçš„通知æœå‹™ When enabled will use try to use platform specific notification service when such exists. Change requires restart to take effect. 啟用後將使用嘗試使用特定於平å°çš„通知存在時æä¾›æœå‹™ã€‚ 更改需è¦é‡æ–°å•Ÿå‹•æ‰èƒ½ç”Ÿæ•ˆã€‚ Display Tray Icon notifications 顯示托盤圖示通知 UpdateWatermarkOperation Select Image 鏿“‡åœ–片 Image Files 圖片檔案 UploadOperation Upload Script Required 需è¦ä¸Šå‚³è…³æœ¬ Please add an upload script via Options > Settings > Upload Script 請通éŽé¸é …>設置>上傳腳本新增一個上傳腳本 Capture Upload æ“·å–上傳 You are about to upload the image to an external destination, do you want to proceed? 您å³å°‡æŠŠåœ–ç‰‡ä¸Šå‚³è‡³å¤–éƒ¨ç«™é»žã€‚æ‚¨æ˜¯å¦æƒ³è¦ç¹¼çºŒï¼Ÿ UploaderSettings Ask for confirmation before uploading 上傳å‰è«‹æ±‚ç¢ºèª Uploader Type: 上傳類型: Imgur Imgur Script 腳本 Uploader ä¸Šå‚³ç¨‹å¼ FTP FTP VersionTab Version 版本 Build 構建版本 Using: 使用: WatermarkSettings Watermark Image 浮水å°åœ–片 Update æ›´æ–° Rotate Watermark æ—‹è½‰æµ®æ°´å° When enabled, Watermark will be added with a rotation of 45° 啟用後,將新增旋轉 45° çš„æµ®æ°´å° Watermark Settings 浮水å°è¨­ç½®