diff --git a/.github/workflows/MacOS-pack.yml b/.github/workflows/MacOS-pack.yml new file mode 100644 index 00000000..e63f6bd5 --- /dev/null +++ b/.github/workflows/MacOS-pack.yml @@ -0,0 +1,66 @@ +name: Packaging(MacOS) + +on: + push: + branches: + - master + - feature/RND-680-macos-.dmg-package-build + paths-ignore: + - 'README.md' + - 'LICENSE' + + pull_request: + paths-ignore: + - 'README.md' + - 'LICENSE' + +env: + PRODUCT: flameshot + +jobs: + catalina: + name: macOS Catalina 10.15 + runs-on: macos-10.15 + + steps: + - name: Checkout Source code + uses: actions/checkout@v1 + + - name: Install Qt + run: brew install qt cmake + + - name: Configure + run: | + mkdir build + cd build + rm -rf ./src/flameshot.dmg ./src/flameshot.app/ + cmake .. -DQt5_DIR=$(brew --prefix qt5)/lib/cmake/Qt5 + + - name: Compile + run: | + cd build + make + + - name: Build dmg package + run: | + cd build/src + /usr/local/opt/qt5/bin/macdeployqt flameshot.app -dmg + + - name: Update dmg package links + run: | + cd build/src + ../../packaging/macos/update_package.sh + + - name: Upload dmg package + shell: bash + run: | + python3 -m pip install -U -q requests + echo "================MacOS dmg image download link================" + echo $(python3 $GITHUB_WORKSPACE/scripts/upload_services/transferwee.py upload $GITHUB_WORKSPACE/build/src/flameshot.dmg) + echo "=====no operation for you can see link in the log console=====" + + - name: Artifact Upload + uses: actions/upload-artifact@v2 + with: + name: MacOS-artifact + path: ${{ github.workspace }}/build/src/flameshot.dmg diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index e1b13f5d..155b2b82 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -7,6 +7,7 @@ on: - 'README.md' - 'LICENSE' pull_request: + branches: [ master ] paths-ignore: - 'README.md' - 'LICENSE' diff --git a/.gitignore b/.gitignore index ee583724..6039cfcb 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,10 @@ data/flatpak/.flatpak-builder # Jetbrains .idea/ +.run + +# MacOS +.DS_Store # End of https://www.gitignore.io/api/snapcraft diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a4c082a..0d15a8a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,23 +1,61 @@ cmake_minimum_required(VERSION 3.13) # cmake_policy(SET CMP0076 OLD) -# This can be read from ${PROJECT_NAME} after project() is called +set(FLAMESHOT_VERSION 0.8.5.6) + +# Flameshot-org +#set(GIT_API_URL "https://api.github.com/repos/flameshot-org/flameshot/releases/latest") +# Namecheap +set(GIT_API_URL "https://api.github.com/repos/namecheap/flameshot/releases/latest") + +# TODO - fix it for all linux distros +# find_package (Git) +#if (GIT_FOUND) +# message("git found: ${GIT_EXECUTABLE} in version ${GIT_VERSION_STRING}") +# +# # set flameshot updates url +# execute_process(COMMAND ${GIT_EXECUTABLE} ls-remote --get-url OUTPUT_VARIABLE GIT_ORIGIN_REMOTE) +# message("GIT_ORIGIN_REMOTE: ${GIT_ORIGIN_REMOTE}") +# string(REGEX REPLACE ".git\r*\n*$" "/releases/latest" GIT_API_URL ${GIT_ORIGIN_REMOTE}) +# string(REGEX REPLACE "^.*:" "https://api.github.com/repos/" GIT_API_URL ${GIT_API_URL}) +# message("GIT_API_URL: '${GIT_API_URL}'") +# +# # get application version +# execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 --match v[0-9]* OUTPUT_VARIABLE FLAMESHOT_VERSION) +# string(REGEX REPLACE "\r" "" FLAMESHOT_VERSION ${FLAMESHOT_VERSION}) +# string(REGEX REPLACE "\n" "" FLAMESHOT_VERSION ${FLAMESHOT_VERSION}) +# string(REGEX REPLACE "^v" "" FLAMESHOT_VERSION ${FLAMESHOT_VERSION}) +# message("FLAMESHOT_VERSION: '${FLAMESHOT_VERSION}'") +#else() +# message("git command is not found") +#endif () + project( flameshot - VERSION 0.8.5 + VERSION ${FLAMESHOT_VERSION} LANGUAGES CXX) set(PROJECT_NAME_CAPITALIZED "Flameshot") +# This can be read from ${PROJECT_NAME} after project() is called +if(APPLE) + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version") +endif() + + # Configuration options set(DEFAULT_RUN_IN_PLACE FALSE) if(WIN32) - set(DEFAULT_RUN_IN_PLACE TRUE) - # For Windows RC file. - add_definitions(-DFLAMESHOT_VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}) - add_definitions(-DFLAMESHOT_VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}) - add_definitions(-DFLAMESHOT_VERSION_BUGFIX=${CMAKE_PROJECT_VERSION_PATCH}) - add_definitions(-DFLAMESHOT_VERSION_BUILD=1) - add_definitions(-DFLAMESHOT_VERSION_STRING="${PROJECT_VERSION}") + set(DEFAULT_RUN_IN_PLACE TRUE) + # For Windows RC file. + add_definitions(-DFLAMESHOT_VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}) + add_definitions(-DFLAMESHOT_VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}) + add_definitions(-DFLAMESHOT_VERSION_BUGFIX=${CMAKE_PROJECT_VERSION_PATCH}) + add_definitions(-DFLAMESHOT_VERSION_BUILD=1) + add_definitions(-DFLAMESHOT_VERSION_STRING="${PROJECT_VERSION}") +elseif(APPLE) + set(Qt5_DIR "$(brew --prefix qt5)/lib/cmake/Qt5/" CACHE PATH "directory where Qt5Config.cmake exists.") + set(CMAKE_MACOSX_BUNDLE ON) + set(CMAKE_MACOSX_RPATH ON) endif() set(RUN_IN_PLACE ${DEFAULT_RUN_IN_PLACE} diff --git a/cmake/modules/MacOSXBundleInfo.plist.in b/cmake/modules/MacOSXBundleInfo.plist.in new file mode 100644 index 00000000..535d1fe1 --- /dev/null +++ b/cmake/modules/MacOSXBundleInfo.plist.in @@ -0,0 +1,46 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + flameshot + CFBundleGetInfoString + + CFBundleIconFile + flameshot + CFBundleIdentifier + https://flameshot.org/ + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + + CFBundleName + + CFBundlePackageType + APPL + CFBundleShortVersionString + + CFBundleSignature + ???? + CFBundleVersion + 0.8.5 + CSResourcesFileMapped + + NSHumanReadableCopyright + + LSMinimumSystemVersion + 10.15 + NSPrincipalClass + NSApplication + NSHighResolutionCapable + True + LSUIElement + 1 + NSPhotoLibraryAddUsageDescription + Application requires access to save screenshots to your gallery + NSSupportsAutomaticGraphicsSwitching + + + diff --git a/data/img/app/org.flameshot.Flameshot-1024.png b/data/img/app/org.flameshot.Flameshot-1024.png new file mode 100644 index 00000000..e6f5d3c7 Binary files /dev/null and b/data/img/app/org.flameshot.Flameshot-1024.png differ diff --git a/data/translations/Internationalization_ca.ts b/data/translations/Internationalization_ca.ts index ff56d241..b24d6573 100644 --- a/data/translations/Internationalization_ca.ts +++ b/data/translations/Internationalization_ca.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,13 +123,13 @@ CaptureWidget - + Unable to capture screen Impossible capturar la pantalla Imposible capturar la pantalla - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -138,7 +138,7 @@ Press Space to open the side panel. - + Tool Settings @@ -205,22 +205,37 @@ Press Space to open the side panel. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Open Launcher - + &Configuration &Configuració - + &About - + + Check for updates + + + + &Latest Uploads @@ -229,12 +244,12 @@ Press Space to open the side panel. &Informació - + &Quit &Ix - + &Take Screenshot @@ -324,170 +339,170 @@ Press Space to open the side panel. GeneneralConf - + Show help message Mostra el missatge d'ajuda - + Show the help message at the beginning in the capture mode. Mostra el missatge d'ajuda en iniciar el mode de captura. - - + + Show desktop notifications Mostra les notificacions d'escriptori - + Show tray icon Mostra la icona en la barra de tasques - + Show the systemtray icon Mostra la icona en la barra de tasques - - + + Import Importar - - - - + + + + Error Error - + Unable to read file. Impossible llegir el fitxer. - - + + Unable to write file. Impossible escriure al fitxer. - + Save File Guardar Arxiu - + Confirm Reset Confirmar Reset - + Are you sure you want to reset the configuration? Esteu segur que voleu reiniciar la configuració? - + Show the side panel button - + Show the side panel toggle button in the capture mode. - + Configuration File Fitxer de Configuració - + Export Exportar - + Reset Reset - + Launch at startup Llançament a l'inici - - + + Launch Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -495,27 +510,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copia l'URL - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. - + Open in browser @@ -523,60 +538,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 - Uploading Image - S'està pujant la imatge + S'està pujant la imatge - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Error + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -594,15 +628,8 @@ Press Space to open the side panel. - - Uploading Image - S'està pujant la imatge - - - - Upload image - + S'està pujant la imatge @@ -620,10 +647,16 @@ Press Space to open the side panel. La captura s'ha copiat al porta-retalls. + Deleting image... + + + Uploading Image... + + Copy URL @@ -635,6 +668,7 @@ Press Space to open the side panel. Obri l'URL + Delete image @@ -656,7 +690,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur Puja a Imgur @@ -677,7 +711,7 @@ Press Space to open the side panel. Imatge al porta-retalls. - + Unable to open the URL. No es pot obrir l'URL. @@ -845,12 +879,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1045,7 +1079,7 @@ You may need to escape the '#' sign as in '\#FFF' - + URL copied to clipboard. L'URL s'ha copiat al porta-retalls. @@ -1086,57 +1120,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Ix de la captura @@ -1151,12 +1185,12 @@ You can find me in the system tray. - + Show color picker Mostra el selector de color - + Change the tool's thickness Canvia el gruix de l'eina @@ -1190,12 +1224,12 @@ You can find me in the system tray. SaveTool - + Save Guarda - + Save the capture Guarda la captura @@ -1203,7 +1237,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Imposible capturar la pantalla @@ -1242,22 +1276,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Dreceres disponibles en el mode de captura de pantalla. - + Description Descripció - + Key Tecla @@ -1316,92 +1350,92 @@ You can find me in the system tray. Any (2000) - + Month Name (jan) Nom del mes (jul) - + Month Name (january) Nom del mes (juliol) - + Month (01-12) Mes (01-12) - + Week Day (1-7) Dia de la setmana (1-7) - + Week (01-53) Setmana (01-53) - + Day Name (mon) Nom del dia (dg) - + Day Name (monday) Nom del dia (diumenge) - + Day (01-31) Dia (01-31) - + Day of Month (1-31) Dia del mes (1-31) - + Day (001-366) Dia (001-366) - + Hour (00-23) Hora (00-23) - + Hour (01-12) Hora (01-12) - + Minute (00-59) Minut (00-59) - + Second (00-59) Segon (00-59) - + Full Date (%m/%d/%y) Data (%m/%d/%y) - + Full Date (%Y-%m-%d) Data (%Y-%m-%d) - + Time (%H-%M-%S) - + Time (%H-%M) @@ -1501,6 +1535,29 @@ You can find me in the system tray. Desfés l'última modificació + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1522,15 +1579,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_cs.ts b/data/translations/Internationalization_cs.ts index 2a6fb76a..71093008 100644 --- a/data/translations/Internationalization_cs.ts +++ b/data/translations/Internationalization_cs.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Režim zachytávání</b> - + Rectangular Region Pravouhlá oblast - + Full Screen (All Monitors) Celá obrazovka (všechny monitory) - + No Delay Bez zpoždění - + second sekunda - + seconds sekund - + Take new screenshot Zachytit nový snímek - + Area: Oblast: - + Delay: Zpoždění: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Nelze zachytit obrazovku - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Použijte kolečko myši pro změnu tloušťky nástroje. Stiskněte mezerník pro otevření postranního panelu. - + Tool Settings Nastavení nástrojů @@ -208,27 +208,42 @@ Stiskněte mezerník pro otevření postranního panelu. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Zachytit obrazovku - + &Open Launcher &Otevřít spouštěč - + &Configuration &Nastavení - + &About O &programu - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Stiskněte mezerník pro otevření postranního panelu. &Informace - + &Quit &Ukončit @@ -327,114 +342,114 @@ Stiskněte mezerník pro otevření postranního panelu. GeneneralConf - - + + Import Zavést - - - - + + + + Error Chyba - + Unable to read file. Nelze přečíst soubor. - - + + Unable to write file. Nelze zapsat soubor. - + Save File Uložit soubor - + Confirm Reset Potvrdit vrácení na výchozí - + Are you sure you want to reset the configuration? Opravdu chcete nastavení vrátit do výchozího stavu? - + Show help message Ukázat zprávu s nápovědou - + Show the help message at the beginning in the capture mode. Ukázat zprávu s nápovědou na začátku v režimu zachytávání. - + Show the side panel button Ukázat tlačítko na postranním panelu - + Show the side panel toggle button in the capture mode. V režimu zachytávání ukazovat tlačítko na postranním panelu. - - + + Show desktop notifications Ukázat oznámení - + Show tray icon Ukázat ikonu v oznamovací oblasti panelu - + Show the systemtray icon Ukázat ikonu v oznamovací oblasti panelu - + Configuration File Soubor s nastavením - + Export Vyvést - + Reset Nastavit znovu - + Launch at startup Spustit při spuštění - - + + Launch Flameshot Spustit Flameshot - + Show welcome message on launch - + Close application after capture @@ -443,58 +458,58 @@ Stiskněte mezerník pro otevření postranního panelu. Zavřít po vytvoření snímku - + Close after taking a screenshot Zavřít po vytvoření snímku obrazovky - + Copy URL after upload Kopírovat adresu (URL) po nahrání - + Copy URL and close window after upload Po nahrání zkopírovat URL a zavřít okno - + Save image after copy Uložit obrázek po kopírování - + Save image file after copying it Uložit obrázek se souborem po jeho zkopírování - + Save Path Cesta pro ukládání - + Change... Změnit... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder Vyberte složku - + Unable to write to directory. Nelze zapsat do adresáře. @@ -502,27 +517,27 @@ Stiskněte mezerník pro otevření postranního panelu. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Kopírovat adresu (URL) - + URL copied to clipboard. Adresa (URL) zkopírována do schránky. - + Open in browser @@ -530,60 +545,79 @@ Stiskněte mezerník pro otevření postranního panelu. ImgS3Uploader - + Upload image to S3 - Uploading Image - Nahrává se obrázek + Nahrává se obrázek - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. Adresa (URL) zkopírována do schránky. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Chyba + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -601,15 +635,8 @@ Stiskněte mezerník pro otevření postranního panelu. - - Uploading Image - Nahrává se obrázek - - - - Upload image - + Nahrává se obrázek @@ -627,10 +654,16 @@ Stiskněte mezerník pro otevření postranního panelu. Snímek obrazovky zkopírován do schránky. + Deleting image... + + + Uploading Image... + + Copy URL @@ -642,6 +675,7 @@ Stiskněte mezerník pro otevření postranního panelu. Otevřít adresu (URL) + Delete image Smazat obrázek @@ -663,7 +697,7 @@ Stiskněte mezerník pro otevření postranního panelu. ImgurUploader - + Upload to Imgur Nahrát do Imgur @@ -688,7 +722,7 @@ Stiskněte mezerník pro otevření postranního panelu. Obrázek do schránky. - + Unable to open the URL. Nelze otevřít adresu (URL). @@ -864,12 +898,12 @@ Stiskněte mezerník pro otevření postranního panelu. PixelateTool - + Pixelate Rozčtverečkování - + Set Pixelate as the paint tool Nastaviť rozčtverečkování jako nástroj pro úpravy @@ -1104,7 +1138,7 @@ Možná budete muset napsat před '#' opačné (obrácené) lomítko, Obvykle se Flameshot spouští na pozadí a přidává do oznamovací oblasti panelu ikonu, kterou je ho možné ovládat. - + URL copied to clipboard. Adresa (URL) zkopírována do schránky. @@ -1115,57 +1149,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Ukončit zachytávání obrazovky @@ -1180,12 +1214,12 @@ You can find me in the system tray. - + Show color picker Ukázat volič barev - + Change the tool's thickness Změnit tloušťku nástroje @@ -1219,12 +1253,12 @@ You can find me in the system tray. SaveTool - + Save Uložit - + Save the capture Uložit zachycenou obrazovku @@ -1232,7 +1266,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Nelze zachytit obrazovku @@ -1271,22 +1305,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Dostupné zkratky v režimu zachytávání obrazovky. - + Description Popis - + Key Klávesa @@ -1345,92 +1379,92 @@ You can find me in the system tray. Rok (2000) - + Month Name (jan) Název měsíce (led) - + Month Name (january) Název měsíce (leden) - + Month (01-12) Měsíc (01-12) - + Week Day (1-7) Den v týdnu (1-7) - + Week (01-53) Týden (01-53) - + Day Name (mon) Název dne (pon) - + Day Name (monday) Název dne (pondělí) - + Day (01-31) Den (01-31) - + Day of Month (1-31) Den v měsíci (1-31) - + Day (001-366) Den v roce (001-366) - + Time (%H-%M-%S) Čas (%H-%M-%S) - + Time (%H-%M) Čas (%H-%M) - + Hour (00-23) Hodina (00-23) - + Hour (01-12) Hodina (01-12) - + Minute (00-59) Minuta (00-59) - + Second (00-59) Sekunda (00-59) - + Full Date (%m/%d/%y) Celé datum (%m/%d/%y) - + Full Date (%Y-%m-%d) Celé datum (%Y-%m-%d) @@ -1530,6 +1564,29 @@ You can find me in the system tray. Zrušit poslední změnu + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1551,15 +1608,10 @@ You can find me in the system tray. UtilityPanel - + Close Zavřít - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_de_DE.ts b/data/translations/Internationalization_de_DE.ts index b7260abe..0eeef2f8 100644 --- a/data/translations/Internationalization_de_DE.ts +++ b/data/translations/Internationalization_de_DE.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Bereich kann nicht erfasst werden - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Benutze das Mausrad um die Dicke des Werkzeugs auszuwählen. Drücke die Leertaste um das Seitenmenü zu öffnen. - + Tool Settings @@ -208,27 +208,42 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Bildschirmaufnahme anfertigen - + &Open Launcher - + &Configuration &Einstellungen - + &About - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. &Informationen - + &Quit &Beenden @@ -327,170 +342,170 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. GeneneralConf - - + + Import Importieren - - - - + + + + Error Fehler - + Unable to read file. Datei kann nicht gelesen werden. - - + + Unable to write file. Datei kann nicht geschrieben werden. - + Save File Datei speichern - + Confirm Reset Zurücksetzen bestätigen - + Are you sure you want to reset the configuration? Sind Sie sicher, dass sie die Konfiguration zurücksetzen wollen? - + Show help message Hilfetext anzeigen - + Show the help message at the beginning in the capture mode. Hilfetext am Start der Auswahl anzeigen. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications Zeige Desktopbenachrichtigungen - + Show tray icon Zeige Taskleistensymbol - + Show the systemtray icon Zeigt das Taskleistensymbol - + Configuration File Konfigurationsdatei - + Export Exportieren - + Reset Zurücksetzen - + Launch at startup Automatisch starten - - + + Launch Flameshot Starte Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -498,27 +513,27 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL kopieren - + URL copied to clipboard. URL kopiert. - + Open in browser @@ -526,60 +541,79 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. ImgS3Uploader - + Upload image to S3 - Uploading Image - Bild hochladen + Bild hochladen - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL kopiert. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Fehler + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,15 +631,8 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. - - Uploading Image - Bild hochladen - - - - Upload image - + Bild hochladen @@ -623,10 +650,16 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. Bildschirmaufnahme in Zwischenablage kopiert. + Deleting image... + + + Uploading Image... + + Copy URL @@ -638,6 +671,7 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. URL öffnen + Delete image Bild löschen @@ -659,7 +693,7 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. ImgurUploader - + Upload to Imgur Zu Imgur hochladen @@ -684,7 +718,7 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. Bild in Zwischenablage. - + Unable to open the URL. Kann URL nicht öffnen. @@ -860,12 +894,12 @@ Drücke die Leertaste um das Seitenmenü zu öffnen. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1090,7 +1124,7 @@ You may need to escape the '#' sign as in '\#FFF' - + URL copied to clipboard. URL kopiert. @@ -1101,57 +1135,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Auswahl verlassen @@ -1166,12 +1200,12 @@ You can find me in the system tray. - + Show color picker Zeige Farbauswahl - + Change the tool's thickness Ändere die Dicke des Werkzeugs @@ -1205,12 +1239,12 @@ You can find me in the system tray. SaveTool - + Save Speichern - + Save the capture Speichere die Aufnahme @@ -1218,7 +1252,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Kann Bereich nicht aufnehmen @@ -1257,22 +1291,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Verfügbare Tastenkürzel im Aufnahmemodus. - + Description Beschreibung - + Key Taste @@ -1331,92 +1365,92 @@ You can find me in the system tray. Jahr (2000) - + Month Name (jan) Monatsname (Jan) - + Month Name (january) Monatsname (Januar) - + Month (01-12) Monat (01-12) - + Week Day (1-7) Wochentag (1-7) - + Week (01-53) Woche (01-53) - + Day Name (mon) Wochentag (Mon) - + Day Name (monday) Wochentag (Montag) - + Day (01-31) Tag (01-31) - + Day of Month (1-31) Tag des Monats (1-31) - + Day (001-366) Tag (001-366) - + Time (%H-%M-%S) Zeit (%H-%M-%S) - + Time (%H-%M) Zeit (%H-%M) - + Hour (00-23) Stunde (00-23) - + Hour (01-12) Stunde (01-12) - + Minute (00-59) Minute (00-59) - + Second (00-59) Sekunde (00-59) - + Full Date (%m/%d/%y) Komplettes Datum (%m/%d/%y) - + Full Date (%Y-%m-%d) Komplettes Datum (%Y-%m-%d) @@ -1516,6 +1550,29 @@ You can find me in the system tray. Letzte Änderung verwerfen + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1537,15 +1594,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_es.ts b/data/translations/Internationalization_es.ts index 0ac6ef0a..4dbc3b27 100644 --- a/data/translations/Internationalization_es.ts +++ b/data/translations/Internationalization_es.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Imposible capturar la pantalla - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Usa la rueda del ratón para cambiar el grosor de la herramienta. Presiona Espacio para abrir el panel lateral. - + Tool Settings @@ -208,27 +208,42 @@ Presiona Espacio para abrir el panel lateral. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Tomar captura de pantalla - + &Open Launcher - + &Configuration &Configuración - + &About - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Presiona Espacio para abrir el panel lateral. &Información - + &Quit &Salir @@ -327,170 +342,170 @@ Presiona Espacio para abrir el panel lateral. GeneneralConf - - + + Import Importar - - - - + + + + Error Error - + Unable to read file. Imposible leer el archivo. - - + + Unable to write file. Imposible escribir el archivo. - + Save File Guardar Archivo - + Confirm Reset Confirmar Reset - + Are you sure you want to reset the configuration? ¿Estás seguro de que quieres reiniciar la configuración? - + Show help message Mostrar mensaje de ayuda - + Show the help message at the beginning in the capture mode. Muestra el mensaje de ayuda al iniciar el modo de captura. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications Mostrar notificaciones del escritorio - + Show tray icon Mostrar icono en la barra de tareas - + Show the systemtray icon Mostrar el icono en la barra de tareas - + Configuration File Archivo de Configuración - + Export Exportar - + Reset Reset - + Launch at startup Lanzar en el arranque - - + + Launch Flameshot Lanzar Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -498,27 +513,27 @@ Presiona Espacio para abrir el panel lateral. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copiar URL - + URL copied to clipboard. URL copiada al portapapeles. - + Open in browser @@ -526,60 +541,79 @@ Presiona Espacio para abrir el panel lateral. ImgS3Uploader - + Upload image to S3 - Uploading Image - Subiendo Imagen + Subiendo Imagen - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL copiada al portapapeles. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Error + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,15 +631,8 @@ Presiona Espacio para abrir el panel lateral. - - Uploading Image - Subiendo Imagen - - - - Upload image - + Subiendo Imagen @@ -623,10 +650,16 @@ Presiona Espacio para abrir el panel lateral. Captura copiada al portapapeles. + Deleting image... + + + Uploading Image... + + Copy URL @@ -638,6 +671,7 @@ Presiona Espacio para abrir el panel lateral. Abrir URL + Delete image Borrar imagen @@ -659,7 +693,7 @@ Presiona Espacio para abrir el panel lateral. ImgurUploader - + Upload to Imgur Subir a Imgur @@ -684,7 +718,7 @@ Presiona Espacio para abrir el panel lateral. Imagen al Portapapeles. - + Unable to open the URL. No puede abrir la URL. @@ -856,12 +890,12 @@ Presiona Espacio para abrir el panel lateral. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1056,7 +1090,7 @@ You may need to escape the '#' sign as in '\#FFF' Imposible escribir en - + URL copied to clipboard. URL copiada al portapapeles. @@ -1097,57 +1131,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Salir de la captura @@ -1162,12 +1196,12 @@ You can find me in the system tray. - + Show color picker Mostrar el selector de color - + Change the tool's thickness Cambiar el grosor de la herramienta @@ -1201,12 +1235,12 @@ You can find me in the system tray. SaveTool - + Save Guardar - + Save the capture Guardar la captura @@ -1214,7 +1248,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Imposible capturar la pantalla @@ -1253,22 +1287,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Atajos disponibles en el modo captura de pantalla. - + Description Descripción - + Key Tecla @@ -1327,92 +1361,92 @@ You can find me in the system tray. Año (2000) - + Month Name (jan) Nombre del Mes (jul) - + Month Name (january) Nombre del Mes (julio) - + Month (01-12) Mes (01-12) - + Week Day (1-7) Día de la Semana (1-7) - + Week (01-53) Semana (01-53) - + Day Name (mon) Nombre del Día (dom) - + Day Name (monday) Nombre del Día (domingo) - + Day (01-31) Día (01-31) - + Day of Month (1-31) Día del Mes (1-31) - + Day (001-366) Día (001-366) - + Time (%H-%M-%S) Tiempo (%H-%M-%S) - + Time (%H-%M) Tiempo (%H-%M) - + Hour (00-23) Hora (00-23) - + Hour (01-12) Hora (01-12) - + Minute (00-59) Minuto (00-59) - + Second (00-59) Segundo (00-59) - + Full Date (%m/%d/%y) Fecha (%m/%d/%y) - + Full Date (%Y-%m-%d) Fecha (%Y-%m-%d) @@ -1512,6 +1546,29 @@ You can find me in the system tray. Borra la última modificación + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1533,15 +1590,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_eu.ts b/data/translations/Internationalization_eu.ts index 9c1359fd..f0ffb96f 100644 --- a/data/translations/Internationalization_eu.ts +++ b/data/translations/Internationalization_eu.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Argazki-modua</b> - + Rectangular Region Eremu laukizuzena - + Full Screen (All Monitors) Pantaila osoa (pantaila guztiak) - + No Delay Atzerapenik ez - + second segundo - + seconds segundo - + Take new screenshot Egin pantaila-argazki berria - + Area: Eremua: - + Delay: Atzerapena: @@ -691,12 +691,12 @@ Sakatu Zuriunea alboko panela irekitzeko. PixelateTool - + Pixelate Pixelatu - + Set Pixelate as the paint tool Ezarri Pixelatu margotzeko tresna gisa @@ -951,12 +951,12 @@ Baliteke '#' karakterea ihes egin behar izatea, '\#FFF'n bez SaveTool - + Save Gorde - + Save the capture Gorde argazkia @@ -964,7 +964,7 @@ Baliteke '#' karakterea ihes egin behar izatea, '\#FFF'n bez ScreenGrabber - + Unable to capture screen Ezin da pantailaren argazkia egin @@ -1036,92 +1036,92 @@ Baliteke '#' karakterea ihes egin behar izatea, '\#FFF'n bez Urtea (2000) - + Month Name (jan) Hilabetearen izena (ira) - + Month Name (january) Hilabetearen izena (iraila) - + Month (01-12) Hilabetea (01-12) - + Week Day (1-7) Asteko eguna (1-7) - + Week (01-53) Astea (01-53) - + Day Name (mon) Egunaren izena (ar.) - + Day Name (monday) Egunaren izena (asteartea) - + Day (01-31) Eguna (01-31) - + Day of Month (1-31) Hilabeteko eguna (1-31) - + Day (001-366) Urteko eguna (001-366) - + Time (%H-%M-%S) Ordua (%H-%M-%S) - + Time (%H-%M) Ordua (%H-%M) - + Hour (00-23) Eguneko ordua (00-23) - + Hour (01-12) Eguneko ordua (01-12) - + Minute (00-59) Minutua (00-59) - + Second (00-59) Segundoa (00-59) - + Full Date (%m/%d/%y) Data (%h/%e/%u) - + Full Date (%Y-%m-%d) Data (%U-%h-%e) diff --git a/data/translations/Internationalization_fr.ts b/data/translations/Internationalization_fr.ts index 9a91935d..dc4fd957 100644 --- a/data/translations/Internationalization_fr.ts +++ b/data/translations/Internationalization_fr.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Impossible de capturer l'écran - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Utiliser la molette de la souris pour changer l'épaisseur de l'outil. Appuyer sur Espace pour ouvrir le panneau latéral. - + Tool Settings @@ -208,27 +208,42 @@ Appuyer sur Espace pour ouvrir le panneau latéral. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Capturer l'écran - + &Open Launcher - + &Configuration &Configuration - + &About - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Appuyer sur Espace pour ouvrir le panneau latéral. &Informations - + &Quit &Quitter @@ -327,114 +342,114 @@ Appuyer sur Espace pour ouvrir le panneau latéral. GeneneralConf - - + + Import Importer - - - - + + + + Error Erreur - + Unable to read file. Impossible de lire le fichier. - - + + Unable to write file. Impossible d'écrire le fichier. - + Save File Sauvegarder le fichier - + Confirm Reset Confirmer la Réinitialisation - + Are you sure you want to reset the configuration? Êtes-vous sûr de vouloir réinitialiser la configuration ? - + Show help message Montrer le message d'aide - + Show the help message at the beginning in the capture mode. Afficher ce message au lancement du mode capture. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications Afficher les notifications du bureau - + Show tray icon Afficher les icones de la barre d'état - + Show the systemtray icon Afficher l'icône dans la barre de tâches - + Configuration File Fichier de Configuration - + Export Exporter - + Reset Réinitialiser - + Launch at startup Lancer au démarrage - - + + Launch Flameshot Démarrer Flameshot - + Show welcome message on launch - + Close application after capture @@ -443,58 +458,58 @@ Appuyer sur Espace pour ouvrir le panneau latéral. Fermer après une capture - + Close after taking a screenshot Fermer l'application après une capture d'écran - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -502,27 +517,27 @@ Appuyer sur Espace pour ouvrir le panneau latéral. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copier l'URL - + URL copied to clipboard. URL copiée dans le Presse-papier. - + Open in browser @@ -530,60 +545,79 @@ Appuyer sur Espace pour ouvrir le panneau latéral. ImgS3Uploader - + Upload image to S3 - Uploading Image - Mise en ligne de l'image + Mise en ligne de l'image - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL copiée dans le Presse-papier. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Erreur + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -601,15 +635,8 @@ Appuyer sur Espace pour ouvrir le panneau latéral. - - Uploading Image - Mise en ligne de l'image - - - - Upload image - + Mise en ligne de l'image @@ -627,10 +654,16 @@ Appuyer sur Espace pour ouvrir le panneau latéral. Capture d'écran copiée dans le Presse-papier. + Deleting image... + + + Uploading Image... + + Copy URL @@ -642,6 +675,7 @@ Appuyer sur Espace pour ouvrir le panneau latéral. Ouvrir l'URL + Delete image @@ -663,7 +697,7 @@ Appuyer sur Espace pour ouvrir le panneau latéral. ImgurUploader - + Upload to Imgur Mettre en ligne vers Imgur @@ -684,7 +718,7 @@ Appuyer sur Espace pour ouvrir le panneau latéral. Image dans le Presse-papier. - + Unable to open the URL. Impossible d'ouvrir l'URL. @@ -852,12 +886,12 @@ Appuyer sur Espace pour ouvrir le panneau latéral. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1052,7 +1086,7 @@ You may need to escape the '#' sign as in '\#FFF' Impossible d'écrire par dessus - + URL copied to clipboard. URL copiée dans le Presse-papier. @@ -1093,57 +1127,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Quitter la capture d'écran @@ -1158,12 +1192,12 @@ You can find me in the system tray. - + Show color picker Afficher la palette de couleurs - + Change the tool's thickness Changer l'épaisseur des outils @@ -1197,12 +1231,12 @@ You can find me in the system tray. SaveTool - + Save Sauvegarder - + Save the capture Sauvegarder la capture d'écran @@ -1210,7 +1244,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Impossible de capturer l'écran @@ -1249,22 +1283,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Raccourcis disponibles en mode capture d'écran. - + Description Description - + Key Clé @@ -1323,92 +1357,92 @@ You can find me in the system tray. Année (2000) - + Month Name (jan) Nom des Mois (jan) - + Month Name (january) nom des Mois (janvier) - + Month (01-12) Mois (01-12) - + Week Day (1-7) Jour de la Semaine (1-7) - + Week (01-53) Semaine (01-53) - + Day Name (mon) Nom du Jour (lun) - + Day Name (monday) Nom du Jour (lundi) - + Day (01-31) Jour (01-31) - + Day of Month (1-31) Jour du Mois (1-31) - + Day (001-366) Jour de l'année (001-366) - + Time (%H-%M-%S) Heure (%H-%M-%S) - + Time (%H-%M) Heure (%H-%M) - + Hour (00-23) Heure (00-23) - + Hour (01-12) Heure (01-12) - + Minute (00-59) Minute (00-59) - + Second (00-59) Seconde (00-59) - + Full Date (%m/%d/%y) Date (%m/%d/%y) - + Full Date (%Y-%m-%d) Date Complête (%Y-%m-%d) @@ -1508,6 +1542,29 @@ You can find me in the system tray. Annuler la dernière modification + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1529,15 +1586,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_hu.ts b/data/translations/Internationalization_hu.ts index 2d08036b..bfb6fb28 100644 --- a/data/translations/Internationalization_hu.ts +++ b/data/translations/Internationalization_hu.ts @@ -208,6 +208,18 @@ Press Space to open the side panel. &Latest Uploads + + New version %1 is available + + + + You have the latest version + + + + Check for updates + + CopyTool @@ -457,7 +469,7 @@ Press Space to open the side panel. Uploading Image - Kép felötlése + Kép felötlése Delete image from S3 @@ -495,6 +507,22 @@ Press Space to open the side panel. S3 Creds URL is not found in your configuration file + + Uploading Image... + + + + Retrieving configuration file with s3 creds... + + + + Error + Hiba + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -511,11 +539,7 @@ Press Space to open the side panel. Uploading Image - Kép felötlése - - - Upload image - + Kép felötlése Unable to open the URL. @@ -549,6 +573,10 @@ Press Space to open the side panel. Image to Clipboard. Kép a vágolapra. + + Uploading Image... + + ImgUploaderTool @@ -1272,6 +1300,25 @@ You can find me in the system tray. Visszavonja az utolsó módosítást + + UpdateNotificationWidget + + New Flameshot version %1 is available + + + + Ignore + + + + Later + + + + Update + + + UploadStorageConfig @@ -1293,10 +1340,6 @@ You can find me in the system tray. Close - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_it_IT.ts b/data/translations/Internationalization_it_IT.ts index 31409aa7..6c98838f 100644 --- a/data/translations/Internationalization_it_IT.ts +++ b/data/translations/Internationalization_it_IT.ts @@ -64,47 +64,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -112,12 +112,12 @@ CaptureWidget - + Unable to capture screen - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -126,7 +126,7 @@ Press Space to open the side panel. - + Tool Settings @@ -193,32 +193,47 @@ Press Space to open the side panel. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot - + &Open Launcher - + &Configuration - + &About - + + Check for updates + + + + &Quit - + &Latest Uploads @@ -308,170 +323,170 @@ Press Space to open the side panel. GeneneralConf - - + + Import - - - - + + + + Error - + Unable to read file. - - + + Unable to write file. - + Save File - + Confirm Reset - + Are you sure you want to reset the configuration? - + Show help message - + Show the help message at the beginning in the capture mode. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications - + Show tray icon - + Show the systemtray icon - + Configuration File - + Export - + Reset - + Launch at startup - - + + Launch Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -479,27 +494,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL - + URL copied to clipboard. - + Open in browser @@ -507,60 +522,75 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 - - Uploading Image + + Uploading Image... - + Delete image from S3 - + Deleting image... - + URL copied to clipboard. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -577,17 +607,6 @@ Press Space to open the side panel. Upload image to S3 - - - - Uploading Image - - - - - Upload image - - Unable to open the URL. @@ -604,10 +623,16 @@ Press Space to open the side panel. + Deleting image... + + + Uploading Image... + + Copy URL @@ -619,6 +644,7 @@ Press Space to open the side panel. + Delete image @@ -640,12 +666,12 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur - + Unable to open the URL. @@ -749,12 +775,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -932,7 +958,7 @@ You may need to escape the '#' sign as in '\#FFF' - + URL copied to clipboard. @@ -990,57 +1016,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture @@ -1055,12 +1081,12 @@ You can find me in the system tray. - + Show color picker - + Change the tool's thickness @@ -1094,12 +1120,12 @@ You can find me in the system tray. SaveTool - + Save - + Save the capture @@ -1107,7 +1133,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen @@ -1146,22 +1172,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. - + Description - + Key @@ -1220,92 +1246,92 @@ You can find me in the system tray. - + Month Name (jan) - + Month Name (january) - + Month (01-12) - + Week Day (1-7) - + Week (01-53) - + Day Name (mon) - + Day Name (monday) - + Day (01-31) - + Day of Month (1-31) - + Day (001-366) - + Time (%H-%M-%S) - + Time (%H-%M) - + Hour (00-23) - + Hour (01-12) - + Minute (00-59) - + Second (00-59) - + Full Date (%m/%d/%y) - + Full Date (%Y-%m-%d) @@ -1405,6 +1431,29 @@ You can find me in the system tray. + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1426,15 +1475,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_ja.ts b/data/translations/Internationalization_ja.ts index 373c1fb0..b2396e0e 100644 --- a/data/translations/Internationalization_ja.ts +++ b/data/translations/Internationalization_ja.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen 画面をキャプチャーできません - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Enter を押すと画面をキャプチャー。 スペースを押すとサイドパネルを開く。 - + Tool Settings @@ -208,27 +208,42 @@ Enter を押すと画面をキャプチャー。 Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot スクリーンショットを撮る(&T) - + &Open Launcher - + &Configuration 設定(&C) - + &About - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Enter を押すと画面をキャプチャー。 情報(&I) - + &Quit 終了(&Q) @@ -327,170 +342,170 @@ Enter を押すと画面をキャプチャー。 GeneneralConf - + Show help message ヘルプメッセージを表示する - + Show the help message at the beginning in the capture mode. キャプチャーモード開始時にヘルプメッセージを表示する。 - - + + Show desktop notifications デスクトップの通知を表示する - + Show tray icon トレイアイコンを表示する - + Show the systemtray icon システムトレイアイコンを表示する - - + + Import インポート - - - - + + + + Error エラー - + Unable to read file. ファイルを読み込めません。 - - + + Unable to write file. ファイルに書き込めません。 - + Save File ファイルを保存 - + Confirm Reset リセットの確認 - + Are you sure you want to reset the configuration? 設定をリセットしてもよろしいですか? - + Show the side panel button - + Show the side panel toggle button in the capture mode. - + Configuration File 設定ファイル - + Export エクスポート - + Reset リセット - + Launch at startup スタートアップ時に起動する - - + + Launch Flameshot Flameshot を起動する - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -498,27 +513,27 @@ Enter を押すと画面をキャプチャー。 HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL をコピー - + URL copied to clipboard. URL をクリップボードにコピーしました。 - + Open in browser @@ -526,60 +541,79 @@ Enter を押すと画面をキャプチャー。 ImgS3Uploader - + Upload image to S3 - Uploading Image - 画像をアップロード中 + 画像をアップロード中 - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL をクリップボードにコピーしました。 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + エラー + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,15 +631,8 @@ Enter を押すと画面をキャプチャー。 - - Uploading Image - 画像をアップロード中 - - - - Upload image - + 画像をアップロード中 @@ -623,10 +650,16 @@ Enter を押すと画面をキャプチャー。 スクリーンショットをクリップボードにコピーしました。 + Deleting image... + + + Uploading Image... + + Copy URL @@ -638,6 +671,7 @@ Enter を押すと画面をキャプチャー。 URL を開く + Delete image 画像を削除 @@ -659,7 +693,7 @@ Enter を押すと画面をキャプチャー。 ImgurUploader - + Upload to Imgur Imgur にアップロード @@ -684,7 +718,7 @@ Enter を押すと画面をキャプチャー。 画像をクリップボードへ。 - + Unable to open the URL. URL を開けません。 @@ -852,12 +886,12 @@ Enter を押すと画面をキャプチャー。 PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1052,7 +1086,7 @@ You may need to escape the '#' sign as in '\#FFF' 書き込めません: - + URL copied to clipboard. URL をクリップボードにコピーしました。 @@ -1093,57 +1127,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture キャプチャーを終了する @@ -1158,12 +1192,12 @@ You can find me in the system tray. - + Show color picker カラーピッカーを表示する - + Change the tool's thickness ツールの値 (太さや濃さ) を変更する @@ -1197,12 +1231,12 @@ You can find me in the system tray. SaveTool - + Save 保存 - + Save the capture キャプチャーを保存する @@ -1210,7 +1244,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen 画面をキャプチャーできません @@ -1249,22 +1283,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. スクリーンキャプチャーモードで利用可能なショートカット。 - + Description 説明 - + Key キー @@ -1323,92 +1357,92 @@ You can find me in the system tray. 年 (2000) - + Month Name (jan) 月 (jan) - + Month Name (january) 月 (january) - + Month (01-12) 月 (01-12) - + Week Day (1-7) 週日 (1-7) - + Week (01-53) 週 (01-53) - + Day Name (mon) 曜日 (月) - + Day Name (monday) 曜日 (月曜日) - + Day (01-31) 日 (01-31) - + Day of Month (1-31) 日 (1-31) - + Day (001-366) 日 (001-366) - + Time (%H-%M-%S) 時刻 (%H-%M-%S) - + Time (%H-%M) 時刻 (%H-%M) - + Hour (00-23) 時 (00-23) - + Hour (01-12) 時 (01-12) - + Minute (00-59) 分 (00-59) - + Second (00-59) 秒 (00-59) - + Full Date (%m/%d/%y) 年月日 (%m/%d/%y) - + Full Date (%Y-%m-%d) 年月日 (%Y-%m-%d) @@ -1508,6 +1542,29 @@ You can find me in the system tray. 最後の変更を元に戻す + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1529,15 +1586,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_ka.ts b/data/translations/Internationalization_ka.ts index e3931166..75c54ced 100644 --- a/data/translations/Internationalization_ka.ts +++ b/data/translations/Internationalization_ka.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen ეკრანის გადაღება ვერ მოხერხდა - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -137,7 +137,7 @@ Press Space to open the side panel. - + Tool Settings @@ -204,27 +204,42 @@ Press Space to open the side panel. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot - + &Open Launcher - + &Configuration &პარამეტრები - + &About - + + Check for updates + + + + &Latest Uploads @@ -233,7 +248,7 @@ Press Space to open the side panel. &ინფორმაცია - + &Quit &გამოსვლა @@ -323,170 +338,170 @@ Press Space to open the side panel. GeneneralConf - - + + Import იმპორტირება - - - - + + + + Error შეცდომა - + Unable to read file. ფაილის წაკითხვა ვერ მოხერხდა. - - + + Unable to write file. ფაილის ჩაწერა ვერ მოხერხდა. - + Save File ფაილის შენახვა - + Confirm Reset განულების დადასტურება - + Are you sure you want to reset the configuration? დარწმუნებული ხართ, რომ გსურთ პარამეტრების განულება? - + Show help message დახმარების შეტყობინების ნახვა - + Show the help message at the beginning in the capture mode. დახმარების შეტყობინების ნახვა გადაღების რეჟიმის დაწყებისას. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications ცნობების ჩვენება სამუშაო მაგიდაზე - + Show tray icon ხატულის ჩვენება სისტემურ პანელზე - + Show the systemtray icon ხატულის ჩვენება სისტემურ პანელზე - + Configuration File პარამეტრების ფაილი - + Export ექსპორტირება - + Reset განულება - + Launch at startup გაშვება სისტემის ჩატვირთვისას - - + + Launch Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -494,27 +509,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL-ის კოპირება - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. - + Open in browser @@ -522,60 +537,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 - Uploading Image - სურათის ატვირთვა + სურათის ატვირთვა - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + შეცდომა + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -593,15 +627,8 @@ Press Space to open the side panel. - - Uploading Image - სურათის ატვირთვა - - - - Upload image - + სურათის ატვირთვა @@ -619,10 +646,16 @@ Press Space to open the side panel. სურათი დაკოპირდა გაცვლის ბუფერში. + Deleting image... + + + Uploading Image... + + Copy URL @@ -634,6 +667,7 @@ Press Space to open the side panel. URL-ის გახსნა + Delete image @@ -655,7 +689,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur Imgur-ზე ატვირთვა @@ -676,7 +710,7 @@ Press Space to open the side panel. სურათის გაცვლის ბუფერში გაგზავნა - + Unable to open the URL. URL-ის გახსნა ვერ მოხერხდა. @@ -844,12 +878,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1044,7 +1078,7 @@ You may need to escape the '#' sign as in '\#FFF' შემდეგ მისამართზე ჩაწერა ვერ მოხერხდა: - + URL copied to clipboard. URL დაკოპირდა გაცვლის ბუფერში. @@ -1085,57 +1119,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture გადაღებიდან გამოსვლა @@ -1150,12 +1184,12 @@ You can find me in the system tray. - + Show color picker ფერის შესარჩევის ჩვენება - + Change the tool's thickness ხელსაწყოს სისქის შეცვლა @@ -1189,12 +1223,12 @@ You can find me in the system tray. SaveTool - + Save შენახვა - + Save the capture სურათის შენახვა @@ -1202,7 +1236,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen ეკრანის გადაღება ვერ მოხერხდა @@ -1241,22 +1275,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. გადაღების რეჟიმში ხელმისაწვდომი მალსახმობები. - + Description აღწერა - + Key კლავიში @@ -1315,92 +1349,92 @@ You can find me in the system tray. წელი (2000) - + Month Name (jan) თვის სახელი (იან) - + Month Name (january) თვის სახელი (იანვარი) - + Month (01-12) თვე (01-12) - + Week Day (1-7) კვირის დღე (1-7) - + Week (01-53) კვირა (01-53) - + Day Name (mon) დღის სახელი (ორშ) - + Day Name (monday) დღის სახელი (ორშაბათი) - + Day (01-31) დღე (01-31) - + Day of Month (1-31) თვის დღე (1-31) - + Day (001-366) დღე (001-366) - + Time (%H-%M-%S) - + Time (%H-%M) - + Hour (00-23) საათი (00-23) - + Hour (01-12) საათი (01-12) - + Minute (00-59) წუთი (00-59) - + Second (00-59) წამი (00-59) - + Full Date (%m/%d/%y) სრული თარიღი (%m/%d/%y) - + Full Date (%Y-%m-%d) სრული თარიღი (%Y-%m-%d) @@ -1500,6 +1534,29 @@ You can find me in the system tray. ბოლო ცვლილების გაუქმება + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1521,15 +1578,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_nl.ts b/data/translations/Internationalization_nl.ts index 657bb924..deeb3549 100644 --- a/data/translations/Internationalization_nl.ts +++ b/data/translations/Internationalization_nl.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Vastlegmodus</b> - + Rectangular Region Rechthoekig gebied - + Full Screen (All Monitors) Volledig scherm (alle beeldschermen) - + No Delay Geen vertraging - + second seconde - + seconds seconden - + Take new screenshot Schermfoto maken - + Area: Gebied: - + Delay: Vertraging: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Kan scherm niet vastleggen - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Gebruik het muiswiel om de gereedschapsdikte aan te passen. Druk op spatie om het zijpaneel te openen. - + Tool Settings Gereedschapsinstellingen @@ -208,27 +208,42 @@ Druk op spatie om het zijpaneel te openen. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot Schermfo&to maken - + &Open Launcher Programmastarter t&onen - + &Configuration &Configuratie - + &About &Over - + + Check for updates + + + + &Latest Uploads Recentste up&loads @@ -237,7 +252,7 @@ Druk op spatie om het zijpaneel te openen. &Informatie - + &Quit &Afsluiten @@ -327,170 +342,170 @@ Druk op spatie om het zijpaneel te openen. GeneneralConf - - + + Import Importeren - - - - + + + + Error Fout - + Unable to read file. Kan bestand niet uitlezen. - - + + Unable to write file. Kan bestand niet wegschrijven. - + Save File Bestand opslaan - + Confirm Reset Herstellen bevestigen - + Are you sure you want to reset the configuration? Weet je zeker dat je de standwaardwaarden van de configuratie wilt herstellen? - + Show help message Uitleg tonen - + Show the help message at the beginning in the capture mode. Toont een bericht met uitleg bij het openen van de vastlegmodus. - + Show the side panel button Zijpaneelknop tonen - + Show the side panel toggle button in the capture mode. Toont een knop om het zijpaneel te tonen/verbergen in de vastlegmodus. - - + + Show desktop notifications Meldingen tonen - + Show tray icon Systeemvakpictogram tonen - + Show the systemtray icon Toont het systeemvakpictogram - + Configuration File Configuratiebestand - + Export Exporteren - + Reset Standaardwaarden - + Launch at startup Automatisch opstarten - - + + Launch Flameshot Flameshot openen - + Show welcome message on launch Welkomstbericht tonen na opstarten - + Close application after capture Programma sluiten na vastleggen - + Close after taking a screenshot Sluiten na maken van schermfoto - + Copy URL after upload URL kopiëren na uploaden - + Copy URL and close window after upload URL kopiëren en venster sluiten na uploaden - + Save image after copy Afbeelding opslaan na kopiëren - + Save image file after copying it Afbeeldingsbestand opslaan na kopiëren - + Save Path Opslagpad - + Change... Wijzigen... - - + + Copy file path after save Bestandspad kopiëren na opslaan - + Use fixed path for screenshots to save Schermfoto's opslaan in vaste map - + Choose a Folder Kies een map - + Unable to write to directory. Kan niet wegschrijven naar map. @@ -498,27 +513,27 @@ Druk op spatie om het zijpaneel te openen. HistoryWidget - + Latest Uploads Recentste uploads - + Screenshots history is empty Je hebt nog geen schermfoto's gemaakt - + Copy URL URL kopiëren - + URL copied to clipboard. De url is gekopieerd naar het klembord. - + Open in browser Openen in webbrowser @@ -526,60 +541,79 @@ Druk op spatie om het zijpaneel te openen. ImgS3Uploader - + Upload image to S3 Afbeelding uploaden naar S3 - Uploading Image Bezig met uploaden... - + + Uploading Image... + + + + Delete image from S3 Afbeelding verwijderen van S3 - + Deleting image... Bezig met verwijderen... - + URL copied to clipboard. De url is gekopieerd naar het klembord. - + Unable to remove screenshot from the remote storage. De schermfoto kan niet worden verwijderd van externe opslag. - + Network error Netwerkfout - + Possibly it doesn't exist anymore Mogelijk bestaat het bestand niet meer - + Do you want to remove screenshot from local history anyway? Wil je de schermfoto tóch verwijderen uit de lokale geschiedenis? - + Remove screenshot from history? Schermfoto verwijderen uit geschiedenis? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file De S3-inlogurl is niet aangetroffen in je configuratiebestand + + + Error + Fout + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,8 +631,6 @@ Druk op spatie om het zijpaneel te openen. Afbeelding uploaden naar S3 - - Uploading Image Bezig met uploaden... @@ -623,10 +655,16 @@ Druk op spatie om het zijpaneel te openen. De schermfoto is gekopieerd naar het klembord. + Deleting image... Bezig met verwijderen... + + + Uploading Image... + + Copy URL @@ -638,6 +676,7 @@ Druk op spatie om het zijpaneel te openen. URL openen + Delete image Afbeelding verwijderen @@ -659,7 +698,7 @@ Druk op spatie om het zijpaneel te openen. ImgurUploader - + Upload to Imgur Uploaden naar Imgur @@ -684,7 +723,7 @@ Druk op spatie om het zijpaneel te openen. Afbeelding naar klembord. - + Unable to open the URL. De url kan niet worden geopend. @@ -856,12 +895,12 @@ Druk op spatie om het zijpaneel te openen. PixelateTool - + Pixelate Pixelvorming - + Set Pixelate as the paint tool Stel pixelvorming in als verfgereedschap @@ -1062,7 +1101,7 @@ Mogelijk moet je het '#'-teken insluiten. Voorbeeld: '\#FFF' Kan niet wegschrijven naar - + URL copied to clipboard. De url is gekopieerd naar het klembord. @@ -1104,57 +1143,57 @@ You can find me in the system tray. Zoek me op in het systeemvak. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. Hallo, hier ben ik! Klik op het systeemvakpictogram om een schermfoto te maken of rechtsklik om meer opties te bekijken. - + Toggle side panel Zijpaneel tonen/verbergen - + Resize selection left 1px Afmetingen van selectie 1px naar links aanpassen - + Resize selection right 1px Afmetingen van selectie 1px naar rechts aanpassen - + Resize selection up 1px Afmetingen van selectie 1px omhoog aanpassen - + Resize selection down 1px Afmetingen van selectie 1px omlaag aanpassen - + Move selection left 1px Selectie 1px naar links verplaatsen - + Move selection right 1px Selectie 1px naar rechts verplaatsen - + Move selection up 1px Selectie 1px omhoog verplaatsen - + Move selection down 1px Selectie 1px omlaag verplaatsen - + Quit capture Vastlegmodus afsluiten @@ -1169,12 +1208,12 @@ Zoek me op in het systeemvak. Scherm vastleggen - + Show color picker Kleurkiezer tonen - + Change the tool's thickness Wijzig de gereedschapsdikte @@ -1208,12 +1247,12 @@ Zoek me op in het systeemvak. SaveTool - + Save Opslaan - + Save the capture Sla de schermfoto op @@ -1221,7 +1260,7 @@ Zoek me op in het systeemvak. ScreenGrabber - + Unable to capture screen Kan scherm niet vastleggen @@ -1260,22 +1299,22 @@ Zoek me op in het systeemvak. ShortcutsWidget - + Hot Keys Sneltoetsen - + Available shortcuts in the screen capture mode. Beschikbare sneltoetsen in de vastlegmodus. - + Description Omschrijving - + Key Toets @@ -1334,92 +1373,92 @@ Zoek me op in het systeemvak. Jaar (2000) - + Month Name (jan) Naam van de maand (јаn) - + Month Name (january) Naam van de maand (јаnuari) - + Month (01-12) Maand (01-12) - + Week Day (1-7) Weekdag (1-7) - + Week (01-53) Week (01-53) - + Day Name (mon) Naam van de dag (ma) - + Day Name (monday) Naam van de dag (maandag) - + Day (01-31) Dag (01-31) - + Day of Month (1-31) Dag van de maand (1-31) - + Day (001-366) Dag (001-366) - + Time (%H-%M-%S) Tijd (%H-%M-%S) - + Time (%H-%M) Tijd (%H-%M) - + Hour (00-23) Uur (00-23) - + Hour (01-12) Uur (01-12) - + Minute (00-59) Minuten (00-59) - + Second (00-59) Seconden (00-59) - + Full Date (%m/%d/%y) Volledige datum (%m/%d/%y) - + Full Date (%Y-%m-%d) Volledige datum (%Y-%m-%d) @@ -1519,6 +1558,29 @@ Zoek me op in het systeemvak. Maak de vorige aanpassing ongedaan + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1540,7 +1602,7 @@ Zoek me op in het systeemvak. UtilityPanel - + Close Sluiten diff --git a/data/translations/Internationalization_nl_NL.ts b/data/translations/Internationalization_nl_NL.ts index 657bb924..b28a6b3c 100644 --- a/data/translations/Internationalization_nl_NL.ts +++ b/data/translations/Internationalization_nl_NL.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Vastlegmodus</b> - + Rectangular Region Rechthoekig gebied - + Full Screen (All Monitors) Volledig scherm (alle beeldschermen) - + No Delay Geen vertraging - + second seconde - + seconds seconden - + Take new screenshot Schermfoto maken - + Area: Gebied: - + Delay: Vertraging: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Kan scherm niet vastleggen - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Gebruik het muiswiel om de gereedschapsdikte aan te passen. Druk op spatie om het zijpaneel te openen. - + Tool Settings Gereedschapsinstellingen @@ -208,27 +208,42 @@ Druk op spatie om het zijpaneel te openen. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot Schermfo&to maken - + &Open Launcher Programmastarter t&onen - + &Configuration &Configuratie - + &About &Over - + + Check for updates + + + + &Latest Uploads Recentste up&loads @@ -237,7 +252,7 @@ Druk op spatie om het zijpaneel te openen. &Informatie - + &Quit &Afsluiten @@ -327,170 +342,170 @@ Druk op spatie om het zijpaneel te openen. GeneneralConf - - + + Import Importeren - - - - + + + + Error Fout - + Unable to read file. Kan bestand niet uitlezen. - - + + Unable to write file. Kan bestand niet wegschrijven. - + Save File Bestand opslaan - + Confirm Reset Herstellen bevestigen - + Are you sure you want to reset the configuration? Weet je zeker dat je de standwaardwaarden van de configuratie wilt herstellen? - + Show help message Uitleg tonen - + Show the help message at the beginning in the capture mode. Toont een bericht met uitleg bij het openen van de vastlegmodus. - + Show the side panel button Zijpaneelknop tonen - + Show the side panel toggle button in the capture mode. Toont een knop om het zijpaneel te tonen/verbergen in de vastlegmodus. - - + + Show desktop notifications Meldingen tonen - + Show tray icon Systeemvakpictogram tonen - + Show the systemtray icon Toont het systeemvakpictogram - + Configuration File Configuratiebestand - + Export Exporteren - + Reset Standaardwaarden - + Launch at startup Automatisch opstarten - - + + Launch Flameshot Flameshot openen - + Show welcome message on launch Welkomstbericht tonen na opstarten - + Close application after capture Programma sluiten na vastleggen - + Close after taking a screenshot Sluiten na maken van schermfoto - + Copy URL after upload URL kopiëren na uploaden - + Copy URL and close window after upload URL kopiëren en venster sluiten na uploaden - + Save image after copy Afbeelding opslaan na kopiëren - + Save image file after copying it Afbeeldingsbestand opslaan na kopiëren - + Save Path Opslagpad - + Change... Wijzigen... - - + + Copy file path after save Bestandspad kopiëren na opslaan - + Use fixed path for screenshots to save Schermfoto's opslaan in vaste map - + Choose a Folder Kies een map - + Unable to write to directory. Kan niet wegschrijven naar map. @@ -498,27 +513,27 @@ Druk op spatie om het zijpaneel te openen. HistoryWidget - + Latest Uploads Recentste uploads - + Screenshots history is empty Je hebt nog geen schermfoto's gemaakt - + Copy URL URL kopiëren - + URL copied to clipboard. De url is gekopieerd naar het klembord. - + Open in browser Openen in webbrowser @@ -526,60 +541,74 @@ Druk op spatie om het zijpaneel te openen. ImgS3Uploader - + Upload image to S3 Afbeelding uploaden naar S3 - Uploading Image Bezig met uploaden... - + Delete image from S3 Afbeelding verwijderen van S3 - + Deleting image... Bezig met verwijderen... - + URL copied to clipboard. De url is gekopieerd naar het klembord. - + Unable to remove screenshot from the remote storage. De schermfoto kan niet worden verwijderd van externe opslag. - + Network error Netwerkfout - + Possibly it doesn't exist anymore Mogelijk bestaat het bestand niet meer - + Do you want to remove screenshot from local history anyway? Wil je de schermfoto tóch verwijderen uit de lokale geschiedenis? - + Remove screenshot from history? Schermfoto verwijderen uit geschiedenis? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file De S3-inlogurl is niet aangetroffen in je configuratiebestand + + + Error + Fout + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,8 +626,6 @@ Druk op spatie om het zijpaneel te openen. Afbeelding uploaden naar S3 - - Uploading Image Bezig met uploaden... @@ -623,10 +650,16 @@ Druk op spatie om het zijpaneel te openen. De schermfoto is gekopieerd naar het klembord. + Deleting image... Bezig met verwijderen... + + + Uploading Image... + + Copy URL @@ -638,6 +671,7 @@ Druk op spatie om het zijpaneel te openen. URL openen + Delete image Afbeelding verwijderen @@ -659,7 +693,7 @@ Druk op spatie om het zijpaneel te openen. ImgurUploader - + Upload to Imgur Uploaden naar Imgur @@ -684,7 +718,7 @@ Druk op spatie om het zijpaneel te openen. Afbeelding naar klembord. - + Unable to open the URL. De url kan niet worden geopend. @@ -856,12 +890,12 @@ Druk op spatie om het zijpaneel te openen. PixelateTool - + Pixelate Pixelvorming - + Set Pixelate as the paint tool Stel pixelvorming in als verfgereedschap @@ -1062,7 +1096,7 @@ Mogelijk moet je het '#'-teken insluiten. Voorbeeld: '\#FFF' Kan niet wegschrijven naar - + URL copied to clipboard. De url is gekopieerd naar het klembord. @@ -1104,57 +1138,57 @@ You can find me in the system tray. Zoek me op in het systeemvak. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. Hallo, hier ben ik! Klik op het systeemvakpictogram om een schermfoto te maken of rechtsklik om meer opties te bekijken. - + Toggle side panel Zijpaneel tonen/verbergen - + Resize selection left 1px Afmetingen van selectie 1px naar links aanpassen - + Resize selection right 1px Afmetingen van selectie 1px naar rechts aanpassen - + Resize selection up 1px Afmetingen van selectie 1px omhoog aanpassen - + Resize selection down 1px Afmetingen van selectie 1px omlaag aanpassen - + Move selection left 1px Selectie 1px naar links verplaatsen - + Move selection right 1px Selectie 1px naar rechts verplaatsen - + Move selection up 1px Selectie 1px omhoog verplaatsen - + Move selection down 1px Selectie 1px omlaag verplaatsen - + Quit capture Vastlegmodus afsluiten @@ -1169,12 +1203,12 @@ Zoek me op in het systeemvak. Scherm vastleggen - + Show color picker Kleurkiezer tonen - + Change the tool's thickness Wijzig de gereedschapsdikte @@ -1208,12 +1242,12 @@ Zoek me op in het systeemvak. SaveTool - + Save Opslaan - + Save the capture Sla de schermfoto op @@ -1221,7 +1255,7 @@ Zoek me op in het systeemvak. ScreenGrabber - + Unable to capture screen Kan scherm niet vastleggen @@ -1260,22 +1294,22 @@ Zoek me op in het systeemvak. ShortcutsWidget - + Hot Keys Sneltoetsen - + Available shortcuts in the screen capture mode. Beschikbare sneltoetsen in de vastlegmodus. - + Description Omschrijving - + Key Toets @@ -1334,92 +1368,92 @@ Zoek me op in het systeemvak. Jaar (2000) - + Month Name (jan) Naam van de maand (јаn) - + Month Name (january) Naam van de maand (јаnuari) - + Month (01-12) Maand (01-12) - + Week Day (1-7) Weekdag (1-7) - + Week (01-53) Week (01-53) - + Day Name (mon) Naam van de dag (ma) - + Day Name (monday) Naam van de dag (maandag) - + Day (01-31) Dag (01-31) - + Day of Month (1-31) Dag van de maand (1-31) - + Day (001-366) Dag (001-366) - + Time (%H-%M-%S) Tijd (%H-%M-%S) - + Time (%H-%M) Tijd (%H-%M) - + Hour (00-23) Uur (00-23) - + Hour (01-12) Uur (01-12) - + Minute (00-59) Minuten (00-59) - + Second (00-59) Seconden (00-59) - + Full Date (%m/%d/%y) Volledige datum (%m/%d/%y) - + Full Date (%Y-%m-%d) Volledige datum (%Y-%m-%d) @@ -1519,6 +1553,29 @@ Zoek me op in het systeemvak. Maak de vorige aanpassing ongedaan + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1540,7 +1597,7 @@ Zoek me op in het systeemvak. UtilityPanel - + Close Sluiten diff --git a/data/translations/Internationalization_pl.ts b/data/translations/Internationalization_pl.ts index 3751eb9b..50d68676 100644 --- a/data/translations/Internationalization_pl.ts +++ b/data/translations/Internationalization_pl.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Tryb przechwytywania</b> - + Rectangular Region Zaznaczony obszar - + Full Screen (All Monitors) Pełny ekran (Wszystkie monitory) - + No Delay Bez opóźnienia - + second sekunda - + seconds sekundy - + Take new screenshot Wykonaj nowy zrzut ekranu - + Area: Obszar: - + Delay: Opóźnienie: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Nie można przechwycić ekranu - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -140,7 +140,7 @@ Prawy klik, aby pokazać próbnik kolorów. Spacja, aby pokazać panel boczny. - + Tool Settings @@ -207,27 +207,42 @@ Spacja, aby pokazać panel boczny. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Zrzut ekranu - + &Open Launcher Pokaż &okno - + &Configuration &Konfiguracja - + &About O progr&amie - + + Check for updates + + + + &Latest Uploads @@ -236,7 +251,7 @@ Spacja, aby pokazać panel boczny. &Informacje - + &Quit &Wyjdź @@ -326,114 +341,114 @@ Spacja, aby pokazać panel boczny. GeneneralConf - - + + Import Import - - - - + + + + Error Błąd - + Unable to read file. Nie można odczytać pliku. - - + + Unable to write file. Nie można zapisać pliku. - + Save File Zapisz plik - + Confirm Reset Potwierdź Reset - + Are you sure you want to reset the configuration? Czy na pewno chcesz zresetować konfigurację? - + Show help message Pokaż podpowiedzi - + Show the help message at the beginning in the capture mode. Pokaż podpowiedzi na początku trybu przechwytywania. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications Pokaż powiadomienia ekranowe - + Show tray icon Pokaż ikonę w trayu - + Show the systemtray icon Pokaż ikonę w zasobniku systemowym - + Configuration File Plik konfiguracyjny - + Export Export - + Reset Reset - + Launch at startup Uruchom podczas startu - - + + Launch Flameshot Uruchom Flameshot - + Show welcome message on launch - + Close application after capture @@ -442,58 +457,58 @@ Spacja, aby pokazać panel boczny. Zamknij po wykonaniu zrzutu - + Close after taking a screenshot Zamknij po wykonaniu zrzutu ekranu - + Copy URL after upload Kopiuj adres URL po wysłaniu - + Copy URL and close window after upload Kopiuj adres URL po wysłaniu i zamknij okno - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -501,27 +516,27 @@ Spacja, aby pokazać panel boczny. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Kopiuj URL - + URL copied to clipboard. URL skopiowany do schowka. - + Open in browser @@ -529,60 +544,79 @@ Spacja, aby pokazać panel boczny. ImgS3Uploader - + Upload image to S3 - Uploading Image - Wysyłanie obrazka + Wysyłanie obrazka - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL skopiowany do schowka. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Błąd + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -600,15 +634,8 @@ Spacja, aby pokazać panel boczny. - - Uploading Image - Wysyłanie obrazka - - - - Upload image - + Wysyłanie obrazka @@ -626,10 +653,16 @@ Spacja, aby pokazać panel boczny. Zrzut ekranu skopiowany do schowka. + Deleting image... + + + Uploading Image... + + Copy URL @@ -641,6 +674,7 @@ Spacja, aby pokazać panel boczny. Otwórz URL + Delete image Usuń obrazek @@ -662,7 +696,7 @@ Spacja, aby pokazać panel boczny. ImgurUploader - + Upload to Imgur Wyślij do Imgur @@ -687,7 +721,7 @@ Spacja, aby pokazać panel boczny. Obrazek do schowka. - + Unable to open the URL. Nie można otworzyć adresu URL. @@ -863,12 +897,12 @@ Spacja, aby pokazać panel boczny. PixelateTool - + Pixelate Zamazywanie - + Set Pixelate as the paint tool Ustaw Zamazywanie jako narzędzie malowania @@ -1063,7 +1097,7 @@ You may need to escape the '#' sign as in '\#FFF' Nie można zapisać w - + URL copied to clipboard. URL skopiowany do schowka. @@ -1108,57 +1142,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Zakończ przechwytywanie @@ -1173,12 +1207,12 @@ You can find me in the system tray. - + Show color picker Pokaż próbnik kolorów - + Change the tool's thickness Zmień grubość narzędzia @@ -1212,12 +1246,12 @@ You can find me in the system tray. SaveTool - + Save Zapisz - + Save the capture Zapisz zaznaczenie @@ -1225,7 +1259,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Nie można przechwycić ekranu @@ -1264,22 +1298,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Dostępne skróty w trybie przechwytywania obrazu. - + Description Działanie - + Key Klawisz @@ -1338,92 +1372,92 @@ You can find me in the system tray. Rok (2000) - + Month Name (jan) Nazwa miesiąca (cze) - + Month Name (january) Nazwa miesiąca (czerwiec) - + Month (01-12) Miesiąc (01-12) - + Week Day (1-7) Dzień tygodnia (1-7) - + Week (01-53) Tydzień (01-53) - + Day Name (mon) Nazwa dniaa (pią) - + Day Name (monday) Nazwa dnia (piątek) - + Day (01-31) Dzień (01-31) - + Day of Month (1-31) Dzień miesiąca (1-31) - + Day (001-366) Dzień (001-366) - + Time (%H-%M-%S) Czas (%H-%M-%S) - + Time (%H-%M) Czas (%H-%M) - + Hour (00-23) Godzina (00-23) - + Hour (01-12) Godzina (01-12) - + Minute (00-59) Minuta (00-59) - + Second (00-59) Sekunda (00-59) - + Full Date (%m/%d/%y) Data (%m/%d/%y) - + Full Date (%Y-%m-%d) Data (%Y-%m-%d) @@ -1523,6 +1557,29 @@ You can find me in the system tray. Cofnij ostatnią zmianę + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1544,15 +1601,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_pt_BR.ts b/data/translations/Internationalization_pt_BR.ts index 6120968e..f9c876d0 100644 --- a/data/translations/Internationalization_pt_BR.ts +++ b/data/translations/Internationalization_pt_BR.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Modo Captura</b> - + Rectangular Region Região Retangular - + Full Screen (All Monitors) Tela Inteira (Todos os Monitores) - + No Delay Sem atraso - + second segundo - + seconds segundos - + Take new screenshot Tirar uma nova screenshot - + Area: Area: - + Delay: Atraso: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Não foi possível capturar a tela - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Use a roda do mouse para aumentar a grossura do pincel. Pressione espaço abrir o painel lateral. - + Tool Settings Configurações da ferramenta @@ -208,27 +208,42 @@ Pressione espaço abrir o painel lateral. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Tirar Screenshot - + &Open Launcher &Abrir carregador - + &Configuration &Configuração - + &About &Sobre - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Pressione espaço abrir o painel lateral. &Informações - + &Quit &Sair @@ -327,114 +342,114 @@ Pressione espaço abrir o painel lateral. GeneneralConf - - + + Import Importar - - - - + + + + Error Erro - + Unable to read file. Não foi possível ler o arquivo. - - + + Unable to write file. Não foi possível escrever no arquivo. - + Save File Salvar Arquivo - + Confirm Reset Confirmar Reset - + Are you sure you want to reset the configuration? Tem certeza que deseja resetar a configuração? - + Show help message Mostrar mensagem de ajuda - + Show the help message at the beginning in the capture mode. Mostrar mensagem de ajuda no início do modo de captura. - + Show the side panel button Mostrar botão no painel lateral - + Show the side panel toggle button in the capture mode. Mostrar altenador do painel lateral. - - + + Show desktop notifications Mostrar notificações de Desktop - + Show tray icon Mostrar ícone de tray - + Show the systemtray icon Mosrar ícone na barra de aplicações - + Configuration File Arquivo de Configurações - + Export Exportar - + Reset Reset - + Launch at startup Iniciar junto com o sistema - - + + Launch Flameshot Iniciar Flameshot - + Show welcome message on launch - + Close application after capture @@ -443,58 +458,58 @@ Pressione espaço abrir o painel lateral. Fechar após captura - + Close after taking a screenshot Fechar após tirar uma screenshot - + Copy URL after upload Copiar URL após upload - + Copy URL and close window after upload Copiar URL e fechar janela após upload - + Save image after copy Salvar imagem após copiar - + Save image file after copying it Salvar imagem após copiar - + Save Path Salvar Caminho - + Change... Alterar... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder Selecione uma pasta - + Unable to write to directory. Não foi possível escrever no diretório. @@ -502,27 +517,27 @@ Pressione espaço abrir o painel lateral. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Copiar URL - + URL copied to clipboard. URL copiada para a área de transferência. - + Open in browser @@ -530,60 +545,79 @@ Pressione espaço abrir o painel lateral. ImgS3Uploader - + Upload image to S3 - Uploading Image - Upando Imagem + Upando Imagem - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL copiada para a área de transferência. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Erro + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -601,15 +635,8 @@ Pressione espaço abrir o painel lateral. - - Uploading Image - Upando Imagem - - - - Upload image - + Upando Imagem @@ -627,10 +654,16 @@ Pressione espaço abrir o painel lateral. Screenshot copiada para a área de transferência. + Deleting image... + + + Uploading Image... + + Copy URL @@ -642,6 +675,7 @@ Pressione espaço abrir o painel lateral. Abrir URL + Delete image Deletar imagem @@ -663,7 +697,7 @@ Pressione espaço abrir o painel lateral. ImgurUploader - + Upload to Imgur Upload no Imgur @@ -688,7 +722,7 @@ Pressione espaço abrir o painel lateral. Imagem na área de transferência. - + Unable to open the URL. Não foi possível abrir a URL. @@ -864,12 +898,12 @@ Pressione espaço abrir o painel lateral. PixelateTool - + Pixelate Pixelar - + Set Pixelate as the paint tool Usar Pixelar na ferramenta de pintura @@ -1104,7 +1138,7 @@ Você pode ter que invalidar o sinal '#', por exemplo '\#FFF&apos Por padrão roda Flameshot no background e adiciona um ícone na bandeija para configuração. - + URL copied to clipboard. URL copiada para a área de transferência. @@ -1115,57 +1149,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Sair da captura @@ -1180,12 +1214,12 @@ You can find me in the system tray. - + Show color picker Mostrar seletor de cores - + Change the tool's thickness Mudar a grossura do pincel @@ -1219,12 +1253,12 @@ You can find me in the system tray. SaveTool - + Save Salvar - + Save the capture Salvar a captura @@ -1232,7 +1266,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Não foi possível capturar a tela @@ -1271,22 +1305,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Atalhos disponívels na tela de captura. - + Description Descrição - + Key Tecla @@ -1345,92 +1379,92 @@ You can find me in the system tray. Ano (2000) - + Month Name (jan) Nome do mês (jan) - + Month Name (january) Nome do mês (janeiro) - + Month (01-12) Mês (01-12) - + Week Day (1-7) Dia da semana (1-7) - + Week (01-53) Semana (01-53) - + Day Name (mon) Nome do dia (seg) - + Day Name (monday) Nome do dia (segunda) - + Day (01-31) Dia (01-31) - + Day of Month (1-31) Dia do Mês (1-31) - + Day (001-366) Dia (001-366) - + Time (%H-%M-%S) Tempo (%H-%M-%S) - + Time (%H-%M) Tempo (%H-%M) - + Hour (00-23) Hora (00-23) - + Hour (01-12) Hora (01-12) - + Minute (00-59) Minuto (00-59) - + Second (00-59) Segundo (00-59) - + Full Date (%m/%d/%y) Data Completa (%m/%d/%y) - + Full Date (%Y-%m-%d) Data Completa (%Y-%m-%d) @@ -1530,6 +1564,29 @@ You can find me in the system tray. Desfazer a última modificação + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1551,15 +1608,10 @@ You can find me in the system tray. UtilityPanel - + Close Fechar - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_ru.ts b/data/translations/Internationalization_ru.ts index 77b0a5c0..bad227b7 100644 --- a/data/translations/Internationalization_ru.ts +++ b/data/translations/Internationalization_ru.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Режим захвата</b> - + Rectangular Region Прямоугольная область - + Full Screen (All Monitors) Весь экран (все мониторы) - + No Delay Без задержки - + second сек - + seconds сек - + Take new screenshot Сделать новый снимок - + Area: Область: - + Delay: Задержка: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Не удалось захватить экран - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Press Space to open the side panel. Нажмите Пробел, чтобы открыть боковую панель. - + Tool Settings Настройки инструмента @@ -208,27 +208,42 @@ Press Space to open the side panel. Controller - + + New version %1 is available + Доступна новая версия %1 + + + + You have the latest version + У Вас самая последня версия + + + &Take Screenshot &Сделать снимок - + &Open Launcher &Открыть лаунчер - + &Configuration &Настройка - + &About &Информация - + + Check for updates + Проверить обновления + + + &Latest Uploads Последние загрузки @@ -237,7 +252,7 @@ Press Space to open the side panel. &Информация - + &Quit &Выход @@ -327,114 +342,114 @@ Press Space to open the side panel. GeneneralConf - - + + Import Импорт - - - - + + + + Error Ошибка - + Unable to read file. Не удалось прочитать файл. - - + + Unable to write file. Не удалось записать файл. - + Save File Сохранить файл - + Confirm Reset Подтвердить сброс - + Are you sure you want to reset the configuration? Вы действительно хотите сбросить настройки? - + Show help message Показывать справочное сообщение - + Show the help message at the beginning in the capture mode. Показывать справочное сообщение перед началом захвата экрана. - + Show the side panel button Показывать кнопку боковой панели - + Show the side panel toggle button in the capture mode. Показывать кнопку открытия боковой панели в режиме захвата. - - + + Show desktop notifications Показывать уведомления - + Show tray icon Показывать значок в трее - + Show the systemtray icon Показать значок в системном трее - + Configuration File Файл конфигурации - + Export Экспорт - + Reset Сброс - + Launch at startup Запускать при старте системы - - + + Launch Flameshot Запустить Flameshot - + Show welcome message on launch Показывать приветствие при запуске - + Close application after capture Закрывать приложение после захвата экрана @@ -443,43 +458,43 @@ Press Space to open the side panel. Закрыть после снимка - + Close after taking a screenshot Закрыть после снимка - + Copy URL after upload Копировать URL после загрузки - + Copy URL and close window after upload Копировать URL и закрыть окно после загрузки - + Save image after copy Сохранять изображение после копирования - + Save image file after copying it Сохранять файл изображения после копирования - + Save Path Путь сохранения - + Change... Сменить... - - + + Copy file path after save Скопировать путь к файлу после сохранения @@ -488,17 +503,17 @@ Press Space to open the side panel. Выберите путь по умолчанию для снимков экрана - + Use fixed path for screenshots to save Использовать фиксированный путь для сохранения снимков экрана - + Choose a Folder Выберите папку - + Unable to write to directory. Не удалось записать в папку. @@ -506,27 +521,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads Последние загрузки - + Screenshots history is empty История скриншотов пуста - + Copy URL Скопировать URL - + URL copied to clipboard. URL скопирован в буфер обмена. - + Open in browser Открыть в браузере @@ -534,60 +549,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 Загрузка изображения на S3 - Uploading Image - Загрузка изображения + Загрузка изображения - + + Uploading Image... + Выгрузка изображения... + + + Delete image from S3 Удалить изображение из S3 - + Deleting image... Удаление изображения... - + URL copied to clipboard. URL скопирован в буфер обмена. - + Unable to remove screenshot from the remote storage. Невозможно удалить снимок экрана из удаленного хранилища. - + Network error Ошибка сети - + Possibly it doesn't exist anymore Возможно, его больше не существует - + Do you want to remove screenshot from local history anyway? Вы все равно хотите удалить скриншот из локальной истории? - + Remove screenshot from history? Удалить скриншот из истории? - + + Retrieving configuration file with s3 creds... + Получение конфигурационного файла с параметрами доступа к s3... + + + S3 Creds URL is not found in your configuration file S3 Creds URL не найден в вашем файле конфигурации + + + Error + Ошибка + + + + Unable to get s3 credentials, please check your VPN connection and try again + Не удалось получить конфигурацию для s3, проверьте свое VPN-соединение и повторите попытку + ImgS3UploaderTool @@ -605,15 +639,12 @@ Press Space to open the side panel. Загрузить изображение в S3 - - Uploading Image - Загрузка изображения + Загрузка изображения - Upload image - Загрузить изображение + Загрузить изображение @@ -631,10 +662,16 @@ Press Space to open the side panel. Снимок скопирован в буфер обмена. + Deleting image... Удаление изображения... + + + Uploading Image... + Выгрузка изображения... + Copy URL @@ -646,6 +683,7 @@ Press Space to open the side panel. Открыть URL + Delete image Удалить изображение @@ -671,7 +709,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur Загрузить в Imgur @@ -696,7 +734,7 @@ Press Space to open the side panel. Изображение в буфер обмена. - + Unable to open the URL. Не удалось открыть URL. @@ -872,12 +910,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate Размытие - + Set Pixelate as the paint tool Выбрать Pixelate инструментом для рисования @@ -1078,7 +1116,7 @@ You may need to escape the '#' sign as in '\#FFF' Не удалось сохранить - + URL copied to clipboard. URL скопирован в буфер обмена. @@ -1120,57 +1158,57 @@ You can find me in the system tray. Вы можете найти меня в системном трее. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. Привет я тут! Щелкните значок на панели задач, чтобы сделать снимок экрана, или щелкните правой кнопкой, чтобы увидеть дополнительные параметры. - + Toggle side panel Вызвать/спрятать боковую панель - + Resize selection left 1px Изменить размер выделения влево на 1 пиксель - + Resize selection right 1px Изменить размер выделения вправо на 1 пиксель - + Resize selection up 1px Изменить размер выделения вверх на 1 пиксель - + Resize selection down 1px Изменить размер выделения вниз на 1 пиксель - + Move selection left 1px Переместить выделение влево на 1 пиксель - + Move selection right 1px Переместить выделение вправо на 1 пиксель - + Move selection up 1px Переместить выделение вверх на 1 пиксель - + Move selection down 1px Переместить выделение вниз на 1 пиксель - + Quit capture Выйти из захвата экрана @@ -1185,12 +1223,12 @@ You can find me in the system tray. Захватить экран - + Show color picker Показать выбор цвета - + Change the tool's thickness Изменить толщину инструмента @@ -1224,12 +1262,12 @@ You can find me in the system tray. SaveTool - + Save Сохранить - + Save the capture Сохранить снимок @@ -1237,7 +1275,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Не удалось захватить экран @@ -1276,22 +1314,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys Горячие клавиши - + Available shortcuts in the screen capture mode. Доступные горячие клавиши в режиме захвата экрана. - + Description Описание - + Key Клавиша @@ -1350,92 +1388,92 @@ You can find me in the system tray. Год (2000) - + Month Name (jan) Название месяца (янв) - + Month Name (january) Название месяца (январь) - + Month (01-12) Месяц (01-12) - + Week Day (1-7) День недели (1-7) - + Week (01-53) Неделя (01-53) - + Day Name (mon) День недели (пн) - + Day Name (monday) День недели (понедельник) - + Day (01-31) День (01-31) - + Day of Month (1-31) День месяца (1-31) - + Day (001-366) День (001-366) - + Time (%H-%M-%S) Время (%H-%M-%S) - + Time (%H-%M) Время (%H-%M) - + Hour (00-23) Час (00-23) - + Hour (01-12) Час (01-12) - + Minute (00-59) Минута (00-59) - + Second (00-59) Секунда (00-59) - + Full Date (%m/%d/%y) Полная дата (%m/%d/%y) - + Full Date (%Y-%m-%d) Полная дата (%Y-%m-%d) @@ -1535,6 +1573,29 @@ You can find me in the system tray. Отменить последнее изменение + + UpdateNotificationWidget + + + New Flameshot version %1 is available + Доступна новая версия Flameshot %1 + + + + Ignore + Игнорировать + + + + Later + Позже + + + + Update + Обновить + + UploadStorageConfig @@ -1556,14 +1617,13 @@ You can find me in the system tray. UtilityPanel - + Close Закрыть - Hide - Спрятать + Спрятать diff --git a/data/translations/Internationalization_sk.ts b/data/translations/Internationalization_sk.ts index c5917398..5ad97823 100644 --- a/data/translations/Internationalization_sk.ts +++ b/data/translations/Internationalization_sk.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Režim zachytávania</b> - + Rectangular Region Pravouhlá oblasť - + Full Screen (All Monitors) Celá obrazovka (všetky monitory) - + No Delay Bez oneskorenia - + second sekunda - + seconds sekundy - + Take new screenshot Zachytiť novú snímku - + Area: Oblasť: - + Delay: Oneskorenie: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Nepodarilo sa zachytiť obrazovku - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Použite kolečko myši pre zmenu hrúbky vybraného nástroja. Stlačte medzerník pre otvorenie postranného panelu. - + Tool Settings Nastavenia nástrojov @@ -208,27 +208,42 @@ Stlačte medzerník pre otvorenie postranného panelu. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Vytvoriť snímku - + &Open Launcher - + &Configuration &Konfigurácia - + &About O &programe - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Stlačte medzerník pre otvorenie postranného panelu. &Informácie - + &Quit &Ukončiť @@ -327,114 +342,114 @@ Stlačte medzerník pre otvorenie postranného panelu. GeneneralConf - - + + Import Importovať - - - - + + + + Error Chyba - + Unable to read file. Zlyhalo čítanie súboru. - - + + Unable to write file. Zlyhal zápis do súboru. - + Save File Uložiť súbor - + Confirm Reset Potvrdiť Reset - + Are you sure you want to reset the configuration? Naozaj si želáte resetovať aktuálnu konfiguráciu? - + Show help message Zobraziť nápovedu - + Show the help message at the beginning in the capture mode. Zobraziť nápovedu na začiatku počas režimu zachytávania obrazovky. - + Show the side panel button Zobraziť tlačidlo na postrannom paneli - + Show the side panel toggle button in the capture mode. V režime zachytávania zobrazovať tlačidlo na postrannom paneli. - - + + Show desktop notifications Zobraziť systémové upozornenia - + Show tray icon Zobraziť stavovú ikonu - + Show the systemtray icon Zobraziť ikonu v stavovej oblasti - + Configuration File Súbor s konfiguráciou - + Export Exportovať - + Reset Resetovať - + Launch at startup Spúšťať pri štarte - - + + Launch Flameshot Spustiť Flameshot - + Show welcome message on launch - + Close application after capture @@ -443,58 +458,58 @@ Stlačte medzerník pre otvorenie postranného panelu. Zavrieť po vytvorení snímky - + Close after taking a screenshot Zatvoriť po vytvorení snímky obrazovky - + Copy URL after upload Kopírovať URL po uploade - + Copy URL and close window after upload Po nahratí skopírovať URL a zavrieť okno - + Save image after copy Uložiť obrázok po kopírovaní - + Save image file after copying it Uložiť obrázok so súborom po jeho skopírovaní - + Save Path Cesta pre ukladanie - + Change... Zmeniť... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder Vyberte priečinok - + Unable to write to directory. Zápis do adresára nie je možný. @@ -502,27 +517,27 @@ Stlačte medzerník pre otvorenie postranného panelu. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Kopírovať URL - + URL copied to clipboard. URL skopírovaná do schránky. - + Open in browser @@ -530,60 +545,79 @@ Stlačte medzerník pre otvorenie postranného panelu. ImgS3Uploader - + Upload image to S3 - Uploading Image - Nahrávam obrázok + Nahrávam obrázok - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL skopírovaná do schránky. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Chyba + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -601,15 +635,8 @@ Stlačte medzerník pre otvorenie postranného panelu. - - Uploading Image - Nahrávam obrázok - - - - Upload image - + Nahrávam obrázok @@ -627,10 +654,16 @@ Stlačte medzerník pre otvorenie postranného panelu. Snímka obrazovky bola skopírovaná do schránky. + Deleting image... + + + Uploading Image... + + Copy URL @@ -642,6 +675,7 @@ Stlačte medzerník pre otvorenie postranného panelu. Otvoriť URL + Delete image Vymazať obrázok @@ -663,7 +697,7 @@ Stlačte medzerník pre otvorenie postranného panelu. ImgurUploader - + Upload to Imgur Nahrať na Imgur @@ -688,7 +722,7 @@ Stlačte medzerník pre otvorenie postranného panelu. Obrázok do schránky. - + Unable to open the URL. Nepodarilo sa otvoriť URL. @@ -864,12 +898,12 @@ Stlačte medzerník pre otvorenie postranného panelu. PixelateTool - + Pixelate Rozštvorčekovanie - + Set Pixelate as the paint tool Nastaviť Rozštvorčekovanie ako nástroj pre úpravy @@ -1070,7 +1104,7 @@ Možno budete musieť napísať pred '#' opačnú lomku, teda '\# Chyba pri ukladaní - + URL copied to clipboard. URL skopírovaná do schránky. @@ -1115,57 +1149,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Ukončiť zachytávanie obrazovky @@ -1180,12 +1214,12 @@ You can find me in the system tray. - + Show color picker Zobraziť dialóg na výber farby - + Change the tool's thickness Zmena hrúbky nástroja @@ -1219,12 +1253,12 @@ You can find me in the system tray. SaveTool - + Save Uložiť - + Save the capture Uložiť snímku obrazovky @@ -1232,7 +1266,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Nepodarilo sa zachytiť obrazovku @@ -1271,22 +1305,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Dostupné klávesové skratky v režime zachytávania obrazovky. - + Description Popis - + Key Kláves @@ -1345,92 +1379,92 @@ You can find me in the system tray. Rok (2000) - + Month Name (jan) Meno mesiaca (jan) - + Month Name (january) Meno mesiaca (január) - + Month (01-12) Mesiac (01-12) - + Week Day (1-7) Deň v týždni (1-7) - + Week (01-53) Týždeň (01-53) - + Day Name (mon) Meno dňa (pon) - + Day Name (monday) Meno dňa (pondelok) - + Day (01-31) Deň (01-31) - + Day of Month (1-31) Deň v mesiaci (1-31) - + Day (001-366) Deň (001-366) - + Time (%H-%M-%S) Čas (%H-%M-%S) - + Time (%H-%M) Čas (%H-%M) - + Hour (00-23) Hodina (00-23) - + Hour (01-12) Hodina (01-12) - + Minute (00-59) Minúta (00-59) - + Second (00-59) Sekunda (00-59) - + Full Date (%m/%d/%y) Celý dátum (%m/%d/%y) - + Full Date (%Y-%m-%d) Celý dátum (%Y-%m-%d) @@ -1530,6 +1564,29 @@ You can find me in the system tray. Vrátiť poslednú úpravu + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1551,15 +1608,10 @@ You can find me in the system tray. UtilityPanel - + Close Zavrieť - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_sr_SP.ts b/data/translations/Internationalization_sr_SP.ts index 707a544e..c06a914e 100644 --- a/data/translations/Internationalization_sr_SP.ts +++ b/data/translations/Internationalization_sr_SP.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Нисам успео да снимим екран - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Press Space to open the side panel. Притисните размак на тастатури за приказ помоћног панела. - + Tool Settings @@ -208,27 +208,42 @@ Press Space to open the side panel. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Направи снимак екрана - + &Open Launcher - + &Configuration &Подешавања - + &About - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Press Space to open the side panel. Ин&формације - + &Quit &Излаз @@ -327,170 +342,170 @@ Press Space to open the side panel. GeneneralConf - - + + Import Увоз - - - - + + + + Error Грешка - + Unable to read file. Нисам успео да прочитам датотеку. - - + + Unable to write file. Нисам успео да сачувам датотеку. - + Save File Сачувај датотеку - + Confirm Reset Потврда поништавања - + Are you sure you want to reset the configuration? Да ли сте сигурни да желите да поништите сва прилагођена подешавања? - + Show help message Приказуј поруку са упутством - + Show the help message at the beginning in the capture mode. Приказуј поруку са кратким упутством на почетку снимања екрана. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications Користи системска обавештења - + Show tray icon Иконица на системској полици - + Show the systemtray icon Приказуј иконицу на системској полици - + Configuration File Датотека са подешавањима - + Export Извоз - + Reset Поништи - + Launch at startup Покрени на почетку - - + + Launch Flameshot Покрени Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -498,27 +513,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL Запамти интернет адресу - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. - + Open in browser @@ -526,60 +541,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 - Uploading Image - Објављујем слику + Објављујем слику - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Грешка + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,15 +631,8 @@ Press Space to open the side panel. - - Uploading Image - Објављујем слику - - - - Upload image - + Објављујем слику @@ -623,10 +650,16 @@ Press Space to open the side panel. Слика је сачувана у привременој меморији. + Deleting image... + + + Uploading Image... + + Copy URL @@ -638,6 +671,7 @@ Press Space to open the side panel. Посети интернет адресу + Delete image Избриши слику @@ -659,7 +693,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur Објави на Imgur @@ -684,7 +718,7 @@ Press Space to open the side panel. Сачувај у привремену меморију. - + Unable to open the URL. Нисам успео да посетим интернет адресу. @@ -852,12 +886,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1052,7 +1086,7 @@ You may need to escape the '#' sign as in '\#FFF' Нисам успео са сачувам - + URL copied to clipboard. Интернет адреса је сачувана у привременој меморији. @@ -1093,57 +1127,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Излаз из снимача екрана @@ -1158,12 +1192,12 @@ You can find me in the system tray. - + Show color picker Прикажи избор боје - + Change the tool's thickness Измени дебљину линије алата @@ -1197,13 +1231,13 @@ You can find me in the system tray. SaveTool - + Save Сачувај Сохранить - + Save the capture Сачувај снимак @@ -1211,7 +1245,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Нисам успео да снимим екран @@ -1250,22 +1284,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Доступне пречице у моду снимка екрана. - + Description Опис - + Key Тастер @@ -1324,92 +1358,92 @@ You can find me in the system tray. Година (2000) - + Month Name (jan) Име месеца (јан) - + Month Name (january) Име месеца (јануар) - + Month (01-12) Месец (01-12) - + Week Day (1-7) Дани у недељи (1-7) - + Week (01-53) Недеља (01-53) - + Day Name (mon) Дан у недељи (пон) - + Day Name (monday) Дан у недељи (понедељак) - + Day (01-31) Дан (01-31) - + Day of Month (1-31) Дан месеца (1-31) - + Day (001-366) Дан (001-366) - + Time (%H-%M-%S) Време (%H-%M-%S) - + Time (%H-%M) Време (%H-%M) - + Hour (00-23) Сат (00-23) - + Hour (01-12) Сат (01-12) - + Minute (00-59) Минута (00-59) - + Second (00-59) Секунда (00-59) - + Full Date (%m/%d/%y) Комплетан датум (%m/%d/%y) - + Full Date (%Y-%m-%d) Комплетан датум (%Y-%m-%d) @@ -1509,6 +1543,29 @@ You can find me in the system tray. Поништи последњу измену + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1530,15 +1587,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_sv_SE.ts b/data/translations/Internationalization_sv_SE.ts index 962b31fc..e348a395 100644 --- a/data/translations/Internationalization_sv_SE.ts +++ b/data/translations/Internationalization_sv_SE.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Klippläge</b> - + Rectangular Region Rektangulärt område - + Full Screen (All Monitors) Helskärm (Alla skärmar) - + No Delay Ingen fördröjning - + second sekund - + seconds sekunder - + Take new screenshot Ta nytt skärmklipp - + Area: Område: - + Delay: Fördröjning: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Kunde inte avbilda skärmen - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Använd skrollhjulet för att ändra tjockleken på ditt verktyg. Tryck Blanksteg för att öppna sidopanelen. - + Tool Settings Verktygsinställningar @@ -208,27 +208,42 @@ Tryck Blanksteg för att öppna sidopanelen. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Ta skärmklipp - + &Open Launcher &Öppna startfönster - + &Configuration &Konfiguration - + &About &Om - + + Check for updates + + + + &Latest Uploads &Senaste uppladdningarna @@ -237,7 +252,7 @@ Tryck Blanksteg för att öppna sidopanelen. &Information - + &Quit &Avsluta @@ -327,109 +342,109 @@ Tryck Blanksteg för att öppna sidopanelen. GeneneralConf - - + + Import Importera - - - - + + + + Error Fel - + Unable to read file. Kunde inte läsa filen. - - + + Unable to write file. Kunde inte skriva till filen. - + Save File Spara fil - + Confirm Reset Bekräfta återställning - + Are you sure you want to reset the configuration? Vill du verkligen återställa konfigurationen? - + Show help message Visa hjälpmeddelande - + Show the help message at the beginning in the capture mode. Visa hjälpmeddelande vid början av skärmklippsläget. - + Show the side panel button Visa sidpanelknappen - + Show the side panel toggle button in the capture mode. Visa sidpanelknappen i klippläget. - - + + Show desktop notifications Visa skrivbordsaviseringar - + Show tray icon Visa systemfältsikon - + Show the systemtray icon Visa ikon i systemfältet - + Configuration File Konfigurationsfil - + Export Exportera - + Reset Återställ - + Launch at startup Starta vid systemstart - - + + Launch Flameshot Starta Flameshot - + Show welcome message on launch Visa välkomstmeddelande vid start @@ -439,58 +454,58 @@ Tryck Blanksteg för att öppna sidopanelen. Stäng efter skärmklipp - + Close after taking a screenshot Stäng efter att skärmklipp tagits - + Copy URL after upload Kopiera URL efter uppladdning - + Copy URL and close window after upload Kopiera URL och stäng fönstret efter uppladdning - + Save image after copy Spara bild efter kopiering - + Save image file after copying it Spara bildfilen efter att den kopierats - + Save Path Lagringsplats - + Change... Ändra... - - + + Copy file path after save Kopiera filsökväg efter spara - + Use fixed path for screenshots to save Använd fast lagringsplats för att spara skärmklipp - + Choose a Folder Välj en mapp - + Unable to write to directory. Kan inte skriva till mappen. @@ -498,27 +513,27 @@ Tryck Blanksteg för att öppna sidopanelen. HistoryWidget - + Latest Uploads Senaste uppladdningar - + Screenshots history is empty Skärmklippshistoriken är tom - + Copy URL Kopiera URL - + URL copied to clipboard. URL kopierad till urklipp. - + Open in browser Öppna i webbläsaren @@ -526,60 +541,79 @@ Tryck Blanksteg för att öppna sidopanelen. ImgS3Uploader - + Upload image to S3 Ladda upp bild till S3 - Uploading Image Laddar upp bild - + + Uploading Image... + + + + Delete image from S3 Ta bort bild från S3 - + Deleting image... Tar bort bild... - + URL copied to clipboard. URL kopierad till urklipp. - + Unable to remove screenshot from the remote storage. Kan inte ta bort skärmklippet från fjärrlagringsplatsen. - + Network error Nätverksfel - + Possibly it doesn't exist anymore Den kanske inte finns längre - + Do you want to remove screenshot from local history anyway? Vill du ta bort skärmklippet från lokal historik i alla fall? - + Remove screenshot from history? Vill du ta bort skärmklippet från historiken? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file S3 uppgifts-URL kan inte hittas i din konfigurationsfil + + + Error + Fel + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,8 +631,6 @@ Tryck Blanksteg för att öppna sidopanelen. Ladda upp bild till S3 - - Uploading Image Laddar upp bild @@ -623,10 +655,16 @@ Tryck Blanksteg för att öppna sidopanelen. Skärmklipp kopierat till urklipp. + Deleting image... Tar bort bild... + + + Uploading Image... + + Copy URL @@ -638,6 +676,7 @@ Tryck Blanksteg för att öppna sidopanelen. Öppna URL + Delete image Ta bort bilden @@ -659,7 +698,7 @@ Tryck Blanksteg för att öppna sidopanelen. ImgurUploader - + Upload to Imgur Ladda upp till Imgur @@ -684,7 +723,7 @@ Tryck Blanksteg för att öppna sidopanelen. Bild till klippbord. - + Unable to open the URL. Kan inte öppna URL:en. @@ -856,12 +895,12 @@ Tryck Blanksteg för att öppna sidopanelen. PixelateTool - + Pixelate Pixelisera - + Set Pixelate as the paint tool Använd pixelisering som ritverktyg @@ -1092,7 +1131,7 @@ Du kan behöva kommentera ut tecknet "#" som i "\#FFF"Som standard körs Flameshot i bakgrunden och lägger till en systemfältsikon för konfiguration. - + URL copied to clipboard. URL kopierad till urklipp. @@ -1104,57 +1143,57 @@ You can find me in the system tray. Du hittar mig i systemfältet. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. Hej, jag är här! Klicka på ikonen i systemfältet för att ta ett skärmklipp, eller högerklicka för att se fler alternativ. - + Toggle side panel Sidopanel av/på - + Resize selection left 1px Storleksändra markeringen en pixel åt vänster - + Resize selection right 1px Storleksändra markeringen en pixel åt höger - + Resize selection up 1px Storleksändra markeringen en pixel uppåt - + Resize selection down 1px Storleksändra markeringen en pixel neråt - + Move selection left 1px Flytta markeringen en pixel åt vänster - + Move selection right 1px Flytta markeringen en pixel åt höger - + Move selection up 1px Flytta markeringen en pixel uppåt - + Move selection down 1px Flytta markeringen en pixel neråt - + Quit capture Avsluta skärmklippet @@ -1169,12 +1208,12 @@ Du hittar mig i systemfältet. Ta skärmklipp - + Show color picker Visa färgväljare - + Change the tool's thickness Ändra verktygets tjocklek @@ -1208,12 +1247,12 @@ Du hittar mig i systemfältet. SaveTool - + Save Spara - + Save the capture Spara skärmklippet @@ -1221,7 +1260,7 @@ Du hittar mig i systemfältet. ScreenGrabber - + Unable to capture screen Kunde inte ta skärmklipp @@ -1260,22 +1299,22 @@ Du hittar mig i systemfältet. ShortcutsWidget - + Hot Keys Kortkommandon - + Available shortcuts in the screen capture mode. Tillgängliga kortkommandon i skärmklippsläge. - + Description Beskrivning - + Key Tangent @@ -1334,92 +1373,92 @@ Du hittar mig i systemfältet. År (2000) - + Month Name (jan) Månad namn (jan) - + Month Name (january) Månad namn (januari) - + Month (01-12) Månad (01-12) - + Week Day (1-7) Veckodag (1-7) - + Week (01-53) Vecka (1-53) - + Day Name (mon) Dag namn (mån) - + Day Name (monday) Dag namn (måndag) - + Day (01-31) Dag (01-31) - + Day of Month (1-31) Dag i månad (1-31) - + Day (001-366) Dag (001-366) - + Time (%H-%M-%S) Tid (%H-%M-%S) - + Time (%H-%M) Tid (%H-%M) - + Hour (00-23) Timme (00-23) - + Hour (01-12) Timme (01-12) - + Minute (00-59) Minut (00-59) - + Second (00-59) Sekund (00-59) - + Full Date (%m/%d/%y) Fullständigt datum (%m/%d/%y) - + Full Date (%Y-%m-%d) Fullständigt datum (%Y-%m-%d) @@ -1519,6 +1558,29 @@ Du hittar mig i systemfältet. Ångra senaste ändringen + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1540,7 +1602,7 @@ Du hittar mig i systemfältet. UtilityPanel - + Close Stäng diff --git a/data/translations/Internationalization_tr.ts b/data/translations/Internationalization_tr.ts index 3ca1ca6c..1e07140e 100644 --- a/data/translations/Internationalization_tr.ts +++ b/data/translations/Internationalization_tr.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen Ekran resmi alınamadı - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Aracınızın kalınlığını değiştirmek için Fare Tekerleğini kullanın. Yan paneli açmak için Boşluk tuşuna basın. - + Tool Settings @@ -208,27 +208,42 @@ Yan paneli açmak için Boşluk tuşuna basın. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &Ekran Resmi Al - + &Open Launcher - + &Configuration &Ayarlar - + &About - + + Check for updates + + + + &Latest Uploads @@ -237,7 +252,7 @@ Yan paneli açmak için Boşluk tuşuna basın. &Bilgi - + &Quit &Çıkış @@ -327,170 +342,170 @@ Yan paneli açmak için Boşluk tuşuna basın. GeneneralConf - - + + Import Dışa aktar - - - - + + + + Error Hata - + Unable to read file. Dosya okunamıyor. - - + + Unable to write file. Dosya yazılamıyor. - + Save File Dosyayı Kaydet - + Confirm Reset Sıfırlamayı Onayla - + Are you sure you want to reset the configuration? Ayarları sıfırlamak istediğinizden emin misiniz? - + Show help message Yardım mesajını göster - + Show the help message at the beginning in the capture mode. Yakalama modunda başında yardım mesajını gösterin. - + Show the side panel button - + Show the side panel toggle button in the capture mode. - - + + Show desktop notifications Masaüstü bildirimlerini göster - + Show tray icon Tepsi simgesini göster - + Show the systemtray icon Sistem tepsisi simgesini göster - + Configuration File Yapılandırma Dosyası - + Export Dışa aktar - + Reset Sıfırla - + Launch at startup Başlangıçta başlatın - - + + Launch Flameshot Flameshot'ı başlat - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -498,27 +513,27 @@ Yan paneli açmak için Boşluk tuşuna basın. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL URL Kopyala - + URL copied to clipboard. URL panoya kopyalandı. - + Open in browser @@ -526,60 +541,79 @@ Yan paneli açmak için Boşluk tuşuna basın. ImgS3Uploader - + Upload image to S3 - Uploading Image - Resim Yükleniyor + Resim Yükleniyor - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. URL panoya kopyalandı. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + Hata + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -597,15 +631,8 @@ Yan paneli açmak için Boşluk tuşuna basın. - - Uploading Image - Resim Yükleniyor - - - - Upload image - + Resim Yükleniyor @@ -623,10 +650,16 @@ Yan paneli açmak için Boşluk tuşuna basın. Ekran görüntüsü panoya kopyalandı. + Deleting image... + + + Uploading Image... + + Copy URL @@ -638,6 +671,7 @@ Yan paneli açmak için Boşluk tuşuna basın. URL Aç + Delete image Resmi sil @@ -659,7 +693,7 @@ Yan paneli açmak için Boşluk tuşuna basın. ImgurUploader - + Upload to Imgur Imgur'a yükle @@ -684,7 +718,7 @@ Yan paneli açmak için Boşluk tuşuna basın. Resim Pano'ya. - + Unable to open the URL. URL açılamıyor. @@ -852,12 +886,12 @@ Yan paneli açmak için Boşluk tuşuna basın. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1052,7 +1086,7 @@ You may need to escape the '#' sign as in '\#FFF' Yazma mümkün değil - + URL copied to clipboard. URL panoya kopyalandı. @@ -1093,57 +1127,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture Çıkış @@ -1158,12 +1192,12 @@ You can find me in the system tray. - + Show color picker Renk seçici göster - + Change the tool's thickness Araç kalınlığını değiştirin @@ -1197,12 +1231,12 @@ You can find me in the system tray. SaveTool - + Save Kaydet - + Save the capture Yakalamayı kaydet @@ -1210,7 +1244,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Ekran resmi alınamadı @@ -1249,22 +1283,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. Ekran yakalama modunda kullanılabilir kısayollar. - + Description Tanım - + Key Anahtar @@ -1323,92 +1357,92 @@ You can find me in the system tray. Yıl (2000) - + Month Name (jan) Ay Adı (Oca) - + Month Name (january) Ay Adı (Ocak) - + Month (01-12) Ay (01-12) - + Week Day (1-7) Haftanın Günü (1-7) - + Week (01-53) Hafta (01-53) - + Day Name (mon) Gün Adı (pzt) - + Day Name (monday) Gün Adı (pazartesi) - + Day (01-31) Gün (01-31) - + Day of Month (1-31) Ayın Günü (1-31) - + Day (001-366) Gün (001-366) - + Time (%H-%M-%S) - + Time (%H-%M) - + Hour (00-23) Saat (00-23) - + Hour (01-12) Saat (01-12) - + Minute (00-59) Dakika (00-59) - + Second (00-59) Saniye (00-59) - + Full Date (%m/%d/%y) Tam Tarih (%d/%m/%y) - + Full Date (%Y-%m-%d) Tam Tarih (%d-%m-%Y) @@ -1508,6 +1542,29 @@ You can find me in the system tray. Son değişikliği geri al + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1529,15 +1586,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_uk.ts b/data/translations/Internationalization_uk.ts index 992235ca..1268e716 100644 --- a/data/translations/Internationalization_uk.ts +++ b/data/translations/Internationalization_uk.ts @@ -75,60 +75,60 @@ CaptureLauncher - + <b>Capture Mode</b> <b>Режим захвату</b> - + Rectangular Region Прямокутна область - + Full Screen (All Monitors) Весь екран (всі монітори) - + No Delay Без затримки - + second сек - + seconds сек - + Take new screenshot Зробити новий знімок - + Area: Область: - + Delay: - Затримка: + Затримка: CaptureWidget - + Unable to capture screen Не вдалось захопити екран - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Press Space to open the side panel. Натисніть Пробіл, щоб відкрити бічну панель. - + Tool Settings Налаштування інструменту @@ -208,27 +208,42 @@ Press Space to open the side panel. Controller - + + New version %1 is available + Доступна нова версія %1 + + + + You have the latest version + Ви маєте найпізнішу версію + + + &Take Screenshot &Зробити знімок - + &Open Launcher & Відкрити лаунчер - + &Configuration &Налаштування - + &About Про - + + Check for updates + Перевірити оновлення + + + &Latest Uploads Останні завантаження @@ -237,7 +252,7 @@ Press Space to open the side panel. &Інформація - + &Quit Ви&йти @@ -327,114 +342,114 @@ Press Space to open the side panel. GeneneralConf - - + + Import Імпорт - - - - + + + + Error Помилка - + Unable to read file. Не вдалось прочитати файл. - - + + Unable to write file. Не вдалось записати файл. - + Save File Зберегти файл - + Confirm Reset Підтвердити скидання - + Are you sure you want to reset the configuration? Ви дійсно хочете скинути налаштування? - + Show help message Показувати повідомлення довідки - + Show the help message at the beginning in the capture mode. Показувати повідомлення довідки на початку режиму захоплення. - + Show the side panel button Показувати кнопку бічній панелі - + Show the side panel toggle button in the capture mode. Показувати кнопку відкриття бічної панелі в режимі захоплення. - - + + Show desktop notifications Показувати повідомлення - + Show tray icon Показувати значок на панелі - + Show the systemtray icon Показувати значок на панелі повідомленнь - + Configuration File Файл налаштувань - + Export Експорт - + Reset Скинути - + Launch at startup Запускати при старті системи - - + + Launch Flameshot Запускати Flameshot - + Show welcome message on launch Показувати вітання під час запуску - + Close application after capture Закривати програму після захоплення екрану @@ -443,43 +458,43 @@ Press Space to open the side panel. Закрити після знімка - + Close after taking a screenshot Закрити після знімка - + Copy URL after upload Копіювати URL після завантаження - + Copy URL and close window after upload Копіювати URL і закрити вікно після завантаження - + Save image after copy Зберігати зображення після копіювання - + Save image file after copying it Зберігати файл зображення після копіювання - + Save Path Шлях збереження - + Change... Змінити... - - + + Copy file path after save Скопіювати шлях до файлу після збереження @@ -488,17 +503,17 @@ Press Space to open the side panel. Виберіть шлях за замовчуванням для скріншотів - + Use fixed path for screenshots to save Використовувати фіксований шлях для знімків екрана для збереження - + Choose a Folder Обрати папку - + Unable to write to directory. Не вдалося записати в папку. @@ -506,27 +521,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads Останні завантаження - + Screenshots history is empty Історія знімків екрана порожня - + Copy URL Скопіювати URL - + URL copied to clipboard. URL скопійовано до буферу обміну. - + Open in browser Відкрити в браузері @@ -534,60 +549,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 Вивантаження зображення на S3 - Uploading Image - Вивантаження зображення + Вивантаження зображення - + + Uploading Image... + Вивантаження зображення... + + + Delete image from S3 Видаліть зображення з S3 - + Deleting image... Видалення зображення... - + URL copied to clipboard. URL скопійовано до буферу обміну. - + Unable to remove screenshot from the remote storage. Не вдалося видалити знімок екрана з віддаленого сховища. - + Network error Помилка мережі - + Possibly it doesn't exist anymore Можливо, його вже не існує - + Do you want to remove screenshot from local history anyway? Ви все одно хочете видалити знімок екрана з місцевої історії? - + Remove screenshot from history? Видалити знімок екрана з історії? - + + Retrieving configuration file with s3 creds... + Отримання конфігураційного файлу з параметрами доступу до s3 ... + + + S3 Creds URL is not found in your configuration file S3 Creds URL не знайдено у вашому файлі конфігурації + + + Error + Помилка + + + + Unable to get s3 credentials, please check your VPN connection and try again + Не вдалося отримати конфігурацію для s3, перевірити своє з'єднання VPN і повторити спробу + ImgS3UploaderTool @@ -605,15 +639,12 @@ Press Space to open the side panel. Вивантажити зображення на S3 - - Uploading Image - Вивантаження зображення + Вивантаження зображення - Upload image - Вивантажити зображення + Вивантажити зображення @@ -631,10 +662,16 @@ Press Space to open the side panel. Знімок скопійовано до буферу обміну. + Deleting image... Видалення зображення... + + + Uploading Image... + Вивантаження зображення... + Copy URL @@ -646,6 +683,7 @@ Press Space to open the side panel. Відкрити URL + Delete image Видалити зображення @@ -671,7 +709,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur Вивантажити до Imgur @@ -696,7 +734,7 @@ Press Space to open the side panel. Зображення до буферу обміну. - + Unable to open the URL. Не вдалось відкрити URL. @@ -872,12 +910,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate Розмиття - + Set Pixelate as the paint tool Обрати Pixelate інструментом для малювання @@ -1078,7 +1116,7 @@ You may need to escape the '#' sign as in '\#FFF' Не вдалось зберегти - + URL copied to clipboard. URL скопійовано до буферу обміну. @@ -1120,57 +1158,57 @@ You can find me in the system tray. Ви можете знайти мене в системному треї. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. Привіт, я тут! Клацніть піктограму в треї, щоб зробити знімок екрана, або клацніть правою кнопкою, щоб побачити більше опцій. - + Toggle side panel Визвати/сховати бічну панель - + Resize selection left 1px Змінити розмір виділення ліворуч на 1 пікс - + Resize selection right 1px Змінити розмір виділення праворуч на 1 пікс - + Resize selection up 1px Змінити розмір виділення вгору на 1 пікс - + Resize selection down 1px Змінити розмір виділення вниз на 1 пікс - + Move selection left 1px Перемістити виділення вліво на 1 пікс - + Move selection right 1px Перемістити виділення вправо на 1 пікс - + Move selection up 1px Перемістити виділення вгору на 1 пікс - + Move selection down 1px Перемістити виділення вниз на 1 пікс - + Quit capture Вийти із захоплення екрану @@ -1185,12 +1223,12 @@ You can find me in the system tray. Захоплення екрану - + Show color picker Показати вибір кольору - + Change the tool's thickness Змінити товщину інструменту @@ -1224,12 +1262,12 @@ You can find me in the system tray. SaveTool - + Save Зберегти - + Save the capture Зберегти знімок @@ -1237,7 +1275,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen Не вдалось захопити екран @@ -1276,22 +1314,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys Гарячі клавиші - + Available shortcuts in the screen capture mode. Доступні комбінації клавіш у режимі захоплення екрану. - + Description Опис - + Key Клавіша @@ -1350,92 +1388,92 @@ You can find me in the system tray. Рік (2000) - + Month Name (jan) Назва місяця (січ) - + Month Name (january) Назва місяця (січень) - + Month (01-12) Місяць (01-12) - + Week Day (1-7) День тижня (1-7) - + Week (01-53) Тиждень (01-53) - + Day Name (mon) Назва дня тижня (пн) - + Day Name (monday) Назва дня тижня (понеділок) - + Day (01-31) День (01-31) - + Day of Month (1-31) День місяця (1-31) - + Day (001-366) День (001-366) - + Time (%H-%M-%S) Час (%H-%M-%S) - + Time (%H-%M) Час (%H-%M) - + Hour (00-23) Година (00-23) - + Hour (01-12) Година (01-12) - + Minute (00-59) Хвилина (00-59) - + Second (00-59) Секунда (00-59) - + Full Date (%m/%d/%y) Повна дата (%m/%d/%y) - + Full Date (%Y-%m-%d) Повна дата (%Y-%m-%d) @@ -1535,6 +1573,29 @@ You can find me in the system tray. Скасувати останню зміну + + UpdateNotificationWidget + + + New Flameshot version %1 is available + Доступна нова версія Flameshot %1 + + + + Ignore + Ігнорувати + + + + Later + Пізніше + + + + Update + Оновити + + UploadStorageConfig @@ -1556,14 +1617,13 @@ You can find me in the system tray. UtilityPanel - + Close Затворити - Hide - Сховати + Сховати diff --git a/data/translations/Internationalization_zh_CN.ts b/data/translations/Internationalization_zh_CN.ts index c67a276f..8afc09ae 100644 --- a/data/translations/Internationalization_zh_CN.ts +++ b/data/translations/Internationalization_zh_CN.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> <b>捕获模式</b> - + Rectangular Region 方形区域 - + Full Screen (All Monitors) 全屏(所有显示器) - + No Delay 无延迟 - + second - + seconds - + Take new screenshot 获取新屏幕截图 - + Area: 区域: - + Delay: 延迟: @@ -123,13 +123,13 @@ CaptureWidget - + Unable to capture screen 无法捕获屏幕 无法捕获屏幕 - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -142,7 +142,7 @@ Press Space to open the side panel. 按下空格键以打开侧边面板。 - + Tool Settings 工具设置 @@ -209,27 +209,42 @@ Press Space to open the side panel. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot 进行截图(&T) - + &Open Launcher 打开启动器(&O) - + &Configuration 配置(&C) - + &About 关于(&A) - + + Check for updates + + + + &Latest Uploads @@ -238,7 +253,7 @@ Press Space to open the side panel. 信息(&I) - + &Quit 退出(&Q) @@ -328,114 +343,114 @@ Press Space to open the side panel. GeneneralConf - + Show help message 显示帮助文档 - + Show the help message at the beginning in the capture mode. 在捕获之前显示帮助信息。 - - + + Show desktop notifications 显示桌面通知 - + Show tray icon 显示托盘图标 - + Show the systemtray icon 显示任务栏图标 - - + + Import 导入 - - - - + + + + Error 错误 - + Unable to read file. 无法读取文件。 - - + + Unable to write file. 无法写入文件。 - + Save File 保存到文件 - + Confirm Reset 确定重置 - + Are you sure you want to reset the configuration? 你确定你想要重置配置? - + Show the side panel button 显示侧边栏按钮 - + Show the side panel toggle button in the capture mode. 在捕获模式下显示侧边栏切换按钮。 - + Configuration File 配置文件 - + Export 导出 - + Reset 重置 - + Launch at startup 开机时启动 - - + + Launch Flameshot 启动 Flameshot - + Show welcome message on launch - + Close application after capture @@ -444,58 +459,58 @@ Press Space to open the side panel. 捕获后关闭 - + Close after taking a screenshot 获取屏幕截图后关闭 - + Copy URL after upload 上传后复制 URL - + Copy URL and close window after upload 上传后复制 URL 并关闭窗口 - + Save image after copy 复制后保存图像 - + Save image file after copying it 复制到剪贴板后保存图像文件 - + Save Path 保存路径 - + Change... 变更… - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder 选择文件夹 - + Unable to write to directory. 无法写入目录。 @@ -503,27 +518,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL 复制链接 - + URL copied to clipboard. - + Open in browser @@ -531,60 +546,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 - Uploading Image - 正在上传 + 正在上传 - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + 错误 + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -602,15 +636,8 @@ Press Space to open the side panel. - - Uploading Image - 正在上传 - - - - Upload image - + 正在上传 @@ -628,10 +655,16 @@ Press Space to open the side panel. 截图复制到剪贴板。 + Deleting image... + + + Uploading Image... + + Copy URL @@ -643,6 +676,7 @@ Press Space to open the side panel. 打开链接 + Delete image 删除图像 @@ -664,7 +698,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur 上传到Imgur @@ -689,7 +723,7 @@ Press Space to open the side panel. 保存文件到剪贴板。 - + Unable to open the URL. 无法打开此链接。 @@ -865,12 +899,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate 像素化 - + Set Pixelate as the paint tool 将像素化设置为绘画工具 @@ -1071,7 +1105,7 @@ You may need to escape the '#' sign as in '\#FFF' 无法写入 - + URL copied to clipboard. URL 已复制到剪贴板。 @@ -1116,57 +1150,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture 退出捕获 @@ -1181,12 +1215,12 @@ You can find me in the system tray. - + Show color picker 显示颜色选择器 - + Change the tool's thickness 改变工具的厚度 @@ -1220,12 +1254,12 @@ You can find me in the system tray. SaveTool - + Save 保存 - + Save the capture 保存捕获 @@ -1233,7 +1267,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen 无法捕获屏幕 @@ -1272,22 +1306,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. 屏幕捕捉模式中的可用快捷键。 - + Description 描述 - + Key @@ -1346,92 +1380,92 @@ You can find me in the system tray. 年(2000) - + Month Name (jan) 月(1月 - 12月) - + Month Name (january) 月(一月 - 十二月) - + Month (01-12) 月 (01-12) - + Week Day (1-7) 周内的日(1-7) - + Week (01-53) 周(01-53) - + Day Name (mon) 星期(一 - 七) - + Day Name (monday) 星期(星期一 - 星期日) - + Day (01-31) 天(01-31) - + Day of Month (1-31) 一月中的某天(1-31) - + Day (001-366) 天(001-366) - + Time (%H-%M-%S) 时间(%H-%M-%S) - + Time (%H-%M) 时间(%H-%M) - + Hour (00-23) 小时(00-23) - + Hour (01-12) 小时(01-12) - + Minute (00-59) 分钟(00-59) - + Second (00-59) 秒(00-59) - + Full Date (%m/%d/%y) 完整日期(%m/%d/%y) - + Full Date (%Y-%m-%d) 完整日期(%Y-%m-%d) @@ -1531,6 +1565,29 @@ You can find me in the system tray. 撤消上次修改 + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1552,15 +1609,10 @@ You can find me in the system tray. UtilityPanel - + Close 关闭 - - - Hide - - VisualsEditor diff --git a/data/translations/Internationalization_zh_HK.ts b/data/translations/Internationalization_zh_HK.ts index a1d38922..aee7801b 100644 --- a/data/translations/Internationalization_zh_HK.ts +++ b/data/translations/Internationalization_zh_HK.ts @@ -4,12 +4,12 @@ AppLauncher - + App Launcher 應用程式啟動器 - + Choose an app to open the capture 選擇一個程式打開此截圖 @@ -32,18 +32,18 @@ 選擇後保持開啟 - - + + Error 錯誤 - + Unable to launch in terminal. 無法從終端啟動。 - + Unable to write in 無法寫入 @@ -51,12 +51,12 @@ ArrowTool - + Arrow 指針 - + Set the Arrow as the paint tool 選取指針作為繪製工具 @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region 矩形區域 - + Full Screen (All Monitors) 满屏(所有顯示器) - + No Delay 無時延 - + second - + seconds - + Take new screenshot 捕獲新截圖 - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen 無法捕獲屏幕 - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -141,7 +141,7 @@ Press Space to open the side panel. 按Space以打開側方面板。 - + Tool Settings 工具選項 @@ -149,12 +149,12 @@ Press Space to open the side panel. CircleCountTool - + Circle Counter 環狀計數器 - + Add an autoincrementing counter bubble 添加自增計數器 @@ -162,12 +162,12 @@ Press Space to open the side panel. CircleTool - + Circle 環形 - + Set the Circle as the paint tool 選取環形作為繪畫工具 @@ -180,49 +180,79 @@ Press Space to open the side panel. 設定 - + Interface 接口 - + Filename Editor 文檔名稱編輯器 - + General 一般 + + + Shortcuts + + + + + Storage + + Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot &捕獲截圖 - + &Open Launcher &開啓啓動器 - + &Configuration &設定 - + &About &關於 + + + Check for updates + + + + + &Latest Uploads + + &Information &資訊 - + &Quit &結束 @@ -230,12 +260,12 @@ Press Space to open the side panel. CopyTool - + Copy 複製 - + Copy the selection into the clipboard 複製選項到剪貼板 @@ -243,7 +273,7 @@ Press Space to open the side panel. DBusUtils - + Unable to connect via DBus 無法通過 DBus 連接 @@ -251,12 +281,12 @@ Press Space to open the side panel. ExitTool - + Exit 離開 - + Leave the capture screen 離開螢幕擷取 @@ -264,47 +294,47 @@ Press Space to open the side panel. FileNameEditor - + Edit the name of your captures: 編輯您的截圖名稱: - + Edit: 編輯器: - + Preview: 預覽: - + Save 存檔 - + Saves the pattern 儲存樣式 - + Reset 重設 - + Restores the saved pattern 恢復儲存的樣式 - + Clear 清除 - + Deletes the name 刪除這個名稱 @@ -312,215 +342,400 @@ Press Space to open the side panel. GeneneralConf - + Show help message 顯示説明資訊 - + Show the help message at the beginning in the capture mode. 在擷取之前顯示説明資訊。 - - + + Show desktop notifications 顯示桌面通知 - + Show tray icon 顯示託盤圖標 - + Show the systemtray icon 顯示工作列圖標 - - + + Import 導入 - - - - + + + + Error 錯誤 - + Unable to read file. 無法讀取檔案。 - - + + Unable to write file. 無法寫入檔案。 - + Save File 存檔 - + Confirm Reset 確認重設 - + Are you sure you want to reset the configuration? 你確定想要重設? - + Show the side panel button 顯示側邊欄按鈕 - + Show the side panel toggle button in the capture mode. 在截圖模式下顯示側邊欄切換按鈕。 - + Configuration File 設定文檔 - + Export 導出 - + Reset 重設 - + Launch at startup 自動啟動 - + + Launch Flameshot 啓動Flameshot - - Close after capture - 捕獲截圖后關閉 + + Show welcome message on launch + - + + Close application after capture + + + + Close after capture + 捕獲截圖后關閉 + + + Close after taking a screenshot 進行截屏后關閉 - + Copy URL after upload 上載后複製URL - + Copy URL and close window after upload 上載后複製URL並關閉窗口 - + Save image after copy 複製後保存圖像 - + Save image file after copying it 複製圖像檔案后保存 - + Save Path 保存路徑 - + Change... 變更... - + + Use fixed path for screenshots to save + + + + + + Copy file path after save + + + + Choose a Folder 選取檔案集 - + Unable to write to directory. 無法寫入目錄。 + + HistoryWidget + + + Latest Uploads + + + + + Screenshots history is empty + + + + + Copy URL + 複製連結 + + + + URL copied to clipboard. + + + + + Open in browser + + + + + ImgS3Uploader + + + Upload image to S3 + + + + + Uploading Image... + + + + + Delete image from S3 + + + + + Deleting image... + + + + + URL copied to clipboard. + + + + + Unable to remove screenshot from the remote storage. + + + + + Network error + + + + + Possibly it doesn't exist anymore + + + + + Do you want to remove screenshot from local history anyway? + + + + + Remove screenshot from history? + + + + + Retrieving configuration file with s3 creds... + + + + + S3 Creds URL is not found in your configuration file + + + + + Error + 錯誤 + + + + Unable to get s3 credentials, please check your VPN connection and try again + + + + + ImgS3UploaderTool + + + Upload the selection to S3 bucket + + + + + ImgUploader + + + Upload image to S3 + + + + + Uploading Image... + + + + + + Delete image + 刪除圖像 + + + + + Deleting image... + + + + + Unable to open the URL. + 無法打開該URL。 + + + + URL copied to clipboard. + + + + + Screenshot copied to clipboard. + 截圖已複製到剪貼板。 + + + + Copy URL + 複製連結 + + + + Open URL + 打開連結 + + + + Image to Clipboard. + 將檔案複製到剪貼簿。 + + + + ImgUploaderTool + + + Image uploader tool + + + ImgurUploader - + Upload to Imgur 上傳到 Imgur - Uploading Image - 正在上傳 + 正在上傳 - Copy URL - 複製連結 + 複製連結 - Open URL - 打開連結 + 打開連結 - Delete image - 刪除圖像 + 刪除圖像 - Image to Clipboard. - 將檔案複製到剪貼簿。 + 將檔案複製到剪貼簿。 - - + Unable to open the URL. 無法打開該URL。 - URL copied to clipboard. - URL已複製到剪貼板。 + URL已複製到剪貼板。 - Screenshot copied to clipboard. - 截圖已複製到剪貼板。 + 截圖已複製到剪貼板。 ImgurUploaderTool - + Image Uploader 上傳圖片 - + Upload the selection to Imgur 上載到 Imgur @@ -528,110 +743,90 @@ Press Space to open the side panel. InfoWindow - + About 關於 - - SPACEBAR - - - - Right Click - 右鍵 + 右鍵 - Mouse Wheel - 滑鼠滑輪 + 滑鼠滑輪 - Move selection 1px - 移動 1px + 移動 1px - Resize selection 1px - 調整大小 1px + 調整大小 1px - Quit capture - 結束擷取 + 結束擷取 - Copy to clipboard - 複製到剪貼簿 + 複製到剪貼簿 - Save selection as a file - 將選擇範圍另存新檔 + 將選擇範圍另存新檔 - Undo the last modification - 復原上次修改 + 復原上次修改 - Toggle visibility of sidebar with options of the selected tool - 使用所選工具選項切換側邊欄可見性 + 使用所選工具選項切換側邊欄可見性 - Show color picker - 顯示顏色選擇器 + 顯示顏色選擇器 - Change the tool's thickness - 改變工具的寬度 + 改變工具的寬度 - Key - + - Description - 描述 + 描述 - + <u><b>License</b></u> <u><b>授權條款</b></u> - + <u><b>Version</b></u> <u><b>版本</b></u> - <u><b>Shortcuts</b></u> - <u><b>快速鍵</b></u> + <u><b>快速鍵</b></u> - Available shortcuts in the screen capture mode. - 螢幕捕獲模式中的可用快捷鍵。 + 螢幕捕獲模式中的可用快捷鍵。 LineTool - + Line 直綫 - + Set the Line as the paint tool 將直綫設定為繪畫工具 @@ -639,12 +834,12 @@ Press Space to open the side panel. MarkerTool - + Marker 標記 - + Set the Marker as the paint tool 將標記設定為繪畫工具 @@ -652,12 +847,12 @@ Press Space to open the side panel. MoveTool - + Move 移動 - + Move the selection area 移動選擇區域 @@ -665,12 +860,12 @@ Press Space to open the side panel. PencilTool - + Pencil 鉛筆 - + Set the Pencil as the paint tool 將鉛筆設定為繪畫工具 @@ -678,12 +873,12 @@ Press Space to open the side panel. PinTool - + Pin Tool 固定工具 - + Pin image on the desktop 將圖像固定到桌面 @@ -691,12 +886,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate 馬賽克工具 - + Set Pixelate as the paint tool 將馬賽克工具設定為繪畫工具 @@ -704,18 +899,18 @@ Press Space to open the side panel. QObject - + Save Error 存檔錯誤 - + Capture saved as 截圖已另存為 - + Capture saved to clipboard. 熒幕捕獲已存儲到剪貼板。 @@ -725,122 +920,132 @@ Press Space to open the side panel. 螢幕捕獲已存儲到剪貼板 - - + + Error trying to save as 嘗試另存新檔時發生錯誤 - - - - - + + Save screenshot + + + + + Capture is saved and copied to the clipboard as + + + + + + + + Unable to connect via DBus 無法透過 DBus 進行連接 - + Powerful yet simple to use screenshot software. - + See - + Capture the entire desktop. 捕獲整個桌面。 - + Open the capture launcher. 開啓捕獲啓動器。 - + Start a manual capture in GUI mode. 在GUi模式下開啓手動捕獲。 - + Configure Configure - + Capture a single screen. 捕獲單一熒幕。 - + Path where the capture will be saved - + Save the capture to the clipboard - + Delay time in milliseconds - + Set the filename pattern - + Enable or disable the trayicon - + Enable or disable run at startup - + Show the help message in the capture mode - + Define the main UI color - + Define the contrast UI color - + Print raw PNG capture - + Define the screen to capture - + default: screen containing the cursor - + Screen number - + Invalid color, this flag supports the following formats: - #RGB (each of R, G, and B is a single hex digit) - #RRGGBB @@ -851,37 +1056,37 @@ You may need to escape the '#' sign as in '\#FFF' - + Invalid delay, it must be higher than 0 - + Invalid screen number, it must be non negative - + Invalid path, it must be a real path in the system - + Invalid value, it must be defined as 'true' or 'false' - + Error 錯誤 - + Unable to write in 無法寫入 - + URL copied to clipboard. 連結已複製到剪貼板。 @@ -891,40 +1096,121 @@ You may need to escape the '#' sign as in '\#FFF' 選項 - + Arguments - + arguments - + Usage 使用 - + options 選項 - - Per default runs Flameshot in the background and adds a tray icon for configuration. + + Per default runs Flameshot in the background and adds a tray icon for configuration. + + + Hi, I'm already running! +You can find me in the system tray. + + + + + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. + + + + + Toggle side panel + + + + + Resize selection left 1px + + + + + Resize selection right 1px + + + + + Resize selection up 1px + + + + + Resize selection down 1px + + + + + Move selection left 1px + + + + + Move selection right 1px + + + + + Move selection up 1px + + + + + Move selection down 1px + + + + + Quit capture + 結束擷取 + + + + Screenshot history + + + + + Capture screen + + + + + Show color picker + 顯示顏色選擇器 + + + + Change the tool's thickness + 改變工具的寬度 + RectangleTool - + Rectangle 矩形 - + Set the Rectangle as the paint tool 將矩形設定為繪畫工具 @@ -932,12 +1218,12 @@ You may need to escape the '#' sign as in '\#FFF' RedoTool - + Redo 重做 - + Redo the next modification 重做下一次修改 @@ -945,12 +1231,12 @@ You may need to escape the '#' sign as in '\#FFF' SaveTool - + Save 儲存 - + Save the capture 儲存螢幕捕獲 @@ -958,7 +1244,7 @@ You may need to escape the '#' sign as in '\#FFF' ScreenGrabber - + Unable to capture screen 無法捕獲螢幕 @@ -966,35 +1252,76 @@ You may need to escape the '#' sign as in '\#FFF' SelectionTool - + Rectangular Selection 矩形選擇 - + Set Selection as the paint tool 將矩形選擇設定為繪畫工具 + + SetShortcutDialog + + + Set Shortcut + + + + + Enter new shortcut to change + + + + + Press Esc to cancel or Backspace to disable the keyboard shortcut. + + + + + ShortcutsWidget + + + Hot Keys + + + + + Available shortcuts in the screen capture mode. + 螢幕捕獲模式中的可用快捷鍵。 + + + + Description + 描述 + + + + Key + + + SidePanelWidget - + Active thickness: 動態寬度: - + Active color: 動態顔色: - + Press ESC to cancel 按ESC以取消 - + Grab Color 選取顔色 @@ -1002,12 +1329,12 @@ You may need to escape the '#' sign as in '\#FFF' SizeIndicatorTool - + Selection Size Indicator 選擇尺寸指示 - + Show the dimensions of the selection (X Y) 顯示選擇的尺寸 (X Y) @@ -1015,107 +1342,107 @@ You may need to escape the '#' sign as in '\#FFF' StrftimeChooserWidget - + Century (00-99) 世紀(00-99) - + Year (00-99) 年(00-99) - + Year (2000) 年(2000) - + Month Name (jan) 月(jan) - + Month Name (january) 月(january) - + Month (01-12) 月(01-12) - + Week Day (1-7) 工作日(1-7) - + Week (01-53) 周(01-53) - + Day Name (mon) 星期(mon) - + Day Name (monday) 星期(diumenge) - + Day (01-31) 日(01-31) - + Day of Month (1-31) 一月中的某日(1-31) - + Day (001-366) 日(001-366) - + Time (%H-%M-%S) 時間(%H-%M-%S) - + Time (%H-%M) 時間(%H-%M) - + Hour (00-23) 小時(00-23) - + Hour (01-12) 小時(01-12) - + Minute (00-59) 分(00-59) - + Second (00-59) 秒(00-59) - + Full Date (%m/%d/%y) 日期(%m/%d/%y) - + Full Date (%Y-%m-%d) 日期(%Y-%m-%d) @@ -1154,12 +1481,12 @@ You may need to escape the '#' sign as in '\#FFF' TextTool - + Text 文本工具 - + Add text to your capture 往您捕獲的截圖中添加文本 @@ -1172,32 +1499,32 @@ You may need to escape the '#' sign as in '\#FFF' UI 顏色編輯器 - + Change the color moving the selectors and see the changes in the preview buttons. 移動顏色選擇並在預覽按鈕檢視。 - + Select a Button to modify it 選擇一個按鈕以修改 - + Main Color 主色 - + Click on this button to set the edition mode of the main color. 點選按鈕設定主色。 - + Contrast Color 對比色 - + Click on this button to set the edition mode of the contrast color. 點選按鈕設定對比色。 @@ -1205,20 +1532,61 @@ You may need to escape the '#' sign as in '\#FFF' UndoTool - + Undo 撤銷 - + Undo the last modification 撤銷上次修改 + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + + + UploadStorageConfig + + + Upload storage + + + + + Imgur storage + + + + + S3 storage (require config.ini file with s3 credentials) + + + UtilityPanel - + Close 關閉 @@ -1226,17 +1594,17 @@ You may need to escape the '#' sign as in '\#FFF' VisualsEditor - + Opacity of area outside selection: 選取區域以外的不透明度: - + Button Selection 按鈕選取 - + Select All 全選 diff --git a/data/translations/Internationalization_zh_TW.ts b/data/translations/Internationalization_zh_TW.ts index dcdca448..d925475f 100644 --- a/data/translations/Internationalization_zh_TW.ts +++ b/data/translations/Internationalization_zh_TW.ts @@ -75,47 +75,47 @@ CaptureLauncher - + <b>Capture Mode</b> - + Rectangular Region - + Full Screen (All Monitors) - + No Delay - + second - + seconds - + Take new screenshot - + Area: - + Delay: @@ -123,12 +123,12 @@ CaptureWidget - + Unable to capture screen 無法擷取螢幕 - + Select an area with the mouse, or press Esc to exit. Press Enter to capture the screen. Press Right Click to show the color picker. @@ -137,7 +137,7 @@ Press Space to open the side panel. - + Tool Settings @@ -204,27 +204,42 @@ Press Space to open the side panel. Controller - + + New version %1 is available + + + + + You have the latest version + + + + &Take Screenshot - + &Open Launcher - + &Configuration &設定 - + &About - + + Check for updates + + + + &Latest Uploads @@ -233,7 +248,7 @@ Press Space to open the side panel. &資訊 - + &Quit &結束 @@ -323,170 +338,170 @@ Press Space to open the side panel. GeneneralConf - + Show help message 顯示説明資訊 - + Show the help message at the beginning in the capture mode. 在擷取之前顯示説明資訊 - - + + Show desktop notifications 顯示桌面通知 - + Show tray icon 顯示託盤圖示 - + Show the systemtray icon 顯示工作列圖示 - - + + Import 匯入 - - - - + + + + Error 錯誤 - + Unable to read file. 無法讀取檔案 - - + + Unable to write file. 無法寫入檔案 - + Save File 存檔 - + Confirm Reset 確認重設 - + Are you sure you want to reset the configuration? 你確定你想要重設? - + Show the side panel button - + Show the side panel toggle button in the capture mode. - + Configuration File 設定檔 - + Export 匯出 - + Reset 重設 - + Launch at startup 自動啟動 - - + + Launch Flameshot - + Show welcome message on launch - + Close application after capture - + Close after taking a screenshot - + Copy URL after upload - + Copy URL and close window after upload - + Save image after copy - + Save image file after copying it - + Save Path - + Change... - - + + Copy file path after save - + Use fixed path for screenshots to save - + Choose a Folder - + Unable to write to directory. @@ -494,27 +509,27 @@ Press Space to open the side panel. HistoryWidget - + Latest Uploads - + Screenshots history is empty - + Copy URL 複製連結 - + URL copied to clipboard. 連結已複製到剪貼簿 - + Open in browser @@ -522,60 +537,79 @@ Press Space to open the side panel. ImgS3Uploader - + Upload image to S3 - Uploading Image - 正在上傳 + 正在上傳 - + + Uploading Image... + + + + Delete image from S3 - + Deleting image... - + URL copied to clipboard. 連結已複製到剪貼簿 - + Unable to remove screenshot from the remote storage. - + Network error - + Possibly it doesn't exist anymore - + Do you want to remove screenshot from local history anyway? - + Remove screenshot from history? - + + Retrieving configuration file with s3 creds... + + + + S3 Creds URL is not found in your configuration file + + + Error + 錯誤 + + + + Unable to get s3 credentials, please check your VPN connection and try again + + ImgS3UploaderTool @@ -593,15 +627,8 @@ Press Space to open the side panel. - - Uploading Image - 正在上傳 - - - - Upload image - + 正在上傳 @@ -619,10 +646,16 @@ Press Space to open the side panel. 截圖已複製到剪貼簿 + Deleting image... + + + Uploading Image... + + Copy URL @@ -634,6 +667,7 @@ Press Space to open the side panel. 打開連結 + Delete image @@ -655,7 +689,7 @@ Press Space to open the side panel. ImgurUploader - + Upload to Imgur 上傳到 Imgur @@ -676,7 +710,7 @@ Press Space to open the side panel. 將檔案複製到剪貼簿 - + Unable to open the URL. 無法打開此連結 @@ -844,12 +878,12 @@ Press Space to open the side panel. PixelateTool - + Pixelate - + Set Pixelate as the paint tool @@ -1044,7 +1078,7 @@ You may need to escape the '#' sign as in '\#FFF' 無法寫入 - + URL copied to clipboard. 連結已複製到剪貼簿 @@ -1085,57 +1119,57 @@ You can find me in the system tray. - + Hello, I'm here! Click icon in the tray to take a screenshot or click with a right button to see more options. - + Toggle side panel - + Resize selection left 1px - + Resize selection right 1px - + Resize selection up 1px - + Resize selection down 1px - + Move selection left 1px - + Move selection right 1px - + Move selection up 1px - + Move selection down 1px - + Quit capture 結束擷取 @@ -1150,12 +1184,12 @@ You can find me in the system tray. - + Show color picker 顯示顏色選擇器 - + Change the tool's thickness 改變工具的寬度 @@ -1189,12 +1223,12 @@ You can find me in the system tray. SaveTool - + Save 儲存 - + Save the capture 儲存擷取 @@ -1202,7 +1236,7 @@ You can find me in the system tray. ScreenGrabber - + Unable to capture screen 無法擷取螢幕 @@ -1241,22 +1275,22 @@ You can find me in the system tray. ShortcutsWidget - + Hot Keys - + Available shortcuts in the screen capture mode. 螢幕擷取模式中的可用快速鍵 - + Description 描述 - + Key @@ -1315,92 +1349,92 @@ You can find me in the system tray. 年 (2000) - + Month Name (jan) 月 (jul) - + Month Name (january) 月 (juliol) - + Month (01-12) 月 (01-12) - + Week Day (1-7) 平常日 (1-7) - + Week (01-53) 周 (01-53) - + Day Name (mon) 星期 (dg) - + Day Name (monday) 星期 (diumenge) - + Day (01-31) 天 (01-31) - + Day of Month (1-31) 一月中的某天 (1-31) - + Day (001-366) 天 (001-366) - + Time (%H-%M-%S) - + Time (%H-%M) - + Hour (00-23) 小時 (00-23) - + Hour (01-12) 小時 (01-12) - + Minute (00-59) 分鐘 (00-59) - + Second (00-59) 秒 (00-59) - + Full Date (%m/%d/%y) 日期 (%m/%d/%y) - + Full Date (%Y-%m-%d) 日期 (%Y-%m-%d) @@ -1500,6 +1534,29 @@ You can find me in the system tray. 復原上次修改 + + UpdateNotificationWidget + + + New Flameshot version %1 is available + + + + + Ignore + + + + + Later + + + + + Update + + + UploadStorageConfig @@ -1521,15 +1578,10 @@ You can find me in the system tray. UtilityPanel - + Close - - - Hide - - VisualsEditor diff --git a/packaging/macos/update_package.sh b/packaging/macos/update_package.sh new file mode 100755 index 00000000..f68103a9 --- /dev/null +++ b/packaging/macos/update_package.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +echo "Change the permision of .dmg file" +hdiutil convert "flameshot.dmg" -format UDRW -o "flameshot_rw.dmg" + +echo "Mount it and save the device" +DEVICE=$(hdiutil attach -readwrite -noverify "flameshot_rw.dmg" | egrep '^/dev/' | sed 1q | awk '{print $1}') +sleep 5 + +echo "Create the sysmbolic link to application folder" +PATH_AT_VOLUME="/Volumes/flameshot/" +CURRENT_PATH="$(pwd)" +cd "${PATH_AT_VOLUME}" +ln -s /Applications +cd "${CURRENT_PATH}" + +# TODO - add background and icon location. +# https://forum.qt.io/topic/94987/how-can-i-add-symbolic-link-application-and-background-image-in-dmg-package/3 +#echo "copy the background image in to package" +#mkdir -p "${PATH_AT_VOLUME}".background/ +#cp backgroundImage.png "${PATH_AT_VOLUME}".background/ +#echo "done" +# +## tell the Finder to resize the window, set the background, +## change the icon size, place the icons in the right position, etc. +#echo ' +# tell application "Finder" +# tell disk "/Volumes/src:flameshot" +# open +# set current view of container window to icon view +# set toolbar visible of container window to false +# set statusbar visible of container window to false +# set the bounds of container window to {400, 100, 1110, 645} +# set viewOptions to the icon view options of container window +# set arrangement of viewOptions to not arranged +# set icon size of viewOptions to 72 +# set background picture of viewOptions to file ".background:backgroundImage.png" +# set position of item "flameshot.app" of container window to {160, 325} +# set position of item "Applications" of container window to {560, 320} +# close +# open +# update without registering applications +# delay 2 +# end tell +# end tell +#' | osascript +# +#sync + +# unmount it +hdiutil detach "${DEVICE}" +rm -f "flameshot.dmg" + +hdiutil convert "flameshot_rw.dmg" -format UDZO -o "flameshot.dmg" +rm -f "flameshot_rw.dmg" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 75f7b508..ffb3b24f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,44 @@ find_package( set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) -add_executable(flameshot) + +# set application icon +if (APPLE) + # generate iconset + execute_process( + COMMAND bash "-c" "mkdir -p flameshot.iconset" + ) + execute_process( + COMMAND bash "-c" "sips -z 16 16 ../data/img/app/flameshot.png --out flameshot.iconset/icon_16x16.png" + COMMAND bash "-c" "sips -z 32 32 ../data/img/app/flameshot.png --out flameshot.iconset/icon_16x16@2x.png" + COMMAND bash "-c" "sips -z 32 32 ../data/img/app/flameshot.png --out flameshot.iconset/icon_32x32.png" + COMMAND bash "-c" "sips -z 64 64 ../data/img/app/flameshot.png --out flameshot.iconset/icon_32x32@2x.png" + COMMAND bash "-c" "sips -z 64 64 ../data/img/app/flameshot.png --out flameshot.iconset/icon_64x64x.png" + COMMAND bash "-c" "sips -z 128 128 ../data/img/app/flameshot.png --out flameshot.iconset/icon_64x64@2.png" + COMMAND bash "-c" "sips -z 128 128 ../data/img/app/flameshot.png --out flameshot.iconset/icon_128x128.png" + COMMAND bash "-c" "sips -z 256 256 ../data/img/app/org.flameshot.Flameshot-1024.png --out flameshot.iconset/icon_128x128@2x.png" + COMMAND bash "-c" "sips -z 256 256 ../data/img/app/org.flameshot.Flameshot-1024.png --out flameshot.iconset/icon_256x256.png" + COMMAND bash "-c" "sips -z 512 512 ../data/img/app/org.flameshot.Flameshot-1024.png --out flameshot.iconset/icon_256x256@2x.png" + COMMAND bash "-c" "sips -z 512 512 ../data/img/app/org.flameshot.Flameshot-1024.png --out flameshot.iconset/icon_512x512.png" + COMMAND bash "-c" "sips -z 1024 1024 ../data/img/app/org.flameshot.Flameshot-1024.png --out flameshot.iconset/icon_512x512@2x.png" + COMMAND bash "-c" "iconutil -c icns flameshot.iconset" + ) + + execute_process( + COMMAND bash "-c" "rm -R flameshot.iconset" + ) + + # Set application icon + set(MACOSX_BUNDLE_ICON_FILE flameshot.icns) + + # And this part tells CMake where to find and install the file itself + set(APP_ICON_MACOSX ${CMAKE_BINARY_DIR}/flameshot.icns) + set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") + + add_executable(flameshot MACOSX_BUNDLE main.cpp ${APP_ICON_MACOSX}) +else() + add_executable(flameshot) +endif() add_executable(Flameshot::flameshot ALIAS flameshot) @@ -24,6 +61,7 @@ if(WIN32) endif() endif() + add_subdirectory(cli) add_subdirectory(config) add_subdirectory(core) @@ -111,16 +149,31 @@ target_include_directories( $ $) -target_link_libraries( - flameshot - project_warnings - project_options - Qt5::Svg - Qt5::DBus - Qt5::Network - Qt5::Widgets - SingleApplication::SingleApplication - spdlog::spdlog) +if (APPLE) + target_link_libraries( + flameshot + project_warnings + project_options + qhotkey + Qt5::Svg + Qt5::DBus + Qt5::Network + Qt5::Widgets + SingleApplication::SingleApplication + spdlog::spdlog) +else () + target_link_libraries( + flameshot + project_warnings + project_options + Qt5::Svg + Qt5::DBus + Qt5::Network + Qt5::Widgets + SingleApplication::SingleApplication + spdlog::spdlog + ) +endif () set(USE_OPENSSL FALSE) if(ENABLE_OPENSSL) @@ -134,12 +187,14 @@ else() endif() if(NOT USE_OPENSSL) - message(WARNING "OpenSSL is required to upload screenshot to imgur") + message(WARNING "OpenSSL is required to upload screenshots") endif() target_compile_definitions(flameshot PRIVATE APP_PREFIX="${CMAKE_INSTALL_PREFIX}") target_compile_definitions(flameshot PRIVATE APP_VERSION="v${PROJECT_VERSION}") target_compile_definitions(flameshot PRIVATE IMGUR_CLIENT_ID="313baf0c7b4d3ff") +target_compile_definitions(flameshot PRIVATE QAPPLICATION_CLASS=QApplication) +target_compile_definitions(flameshot PRIVATE FLAMESHOT_APP_VERSION_URL="${GIT_API_URL}") foreach(FILE ${QM_FILES}) get_filename_component(F_NAME ${FILE} NAME) @@ -157,10 +212,10 @@ include(GNUInstallDirs) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Flameshot) # Install binary -install( - TARGETS flameshot - EXPORT flameshot-targets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS flameshot + EXPORT flameshot-targets + BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # Install desktop files, completion and dbus files configure_file(${CMAKE_SOURCE_DIR}/data/desktopEntry/package/org.flameshot.Flameshot.desktop @@ -246,3 +301,21 @@ if(WIN32) message("Unable to find executable QTDIR/bin/windeployqt.") endif() endif() + +# macdeployqt +if (APPLE) + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + execute_process(COMMAND brew --prefix qt5 OUTPUT_VARIABLE QTDIR) + string(REGEX REPLACE "\n$" "" QTDIR "${QTDIR}") + set(MAC_DEPLOY_QT ${QTDIR}/bin/macdeployqt) + if (EXISTS ${MAC_DEPLOY_QT}) + set_source_files_properties(resources/icon.icns PROPERTIES + MACOSX_PACKAGE_LOCATION Resources) + + set_target_properties(${target} PROPERTIES + MACOSX_BUNDLE TRUE + ) + else () + message("Unable to find executable ${MAC_DEPLOY_QT}.") + endif () +endif () diff --git a/src/config/configwindow.cpp b/src/config/configwindow.cpp index c3d1cc45..c77f57d6 100644 --- a/src/config/configwindow.cpp +++ b/src/config/configwindow.cpp @@ -36,8 +36,8 @@ ConfigWindow::ConfigWindow(QWidget* parent) : QTabWidget(parent) { setAttribute(Qt::WA_DeleteOnClose); - const int size = GlobalValues::buttonBaseSize() * 12; - setMinimumSize(size, size); + setMinimumSize(GlobalValues::buttonBaseSize() * 15, + GlobalValues::buttonBaseSize() * 12); setWindowIcon(QIcon(":img/app/flameshot.svg")); setWindowTitle(tr("Configuration")); diff --git a/src/config/geneneralconf.cpp b/src/config/geneneralconf.cpp index 7d64729b..c511605f 100644 --- a/src/config/geneneralconf.cpp +++ b/src/config/geneneralconf.cpp @@ -315,7 +315,7 @@ void GeneneralConf::changeSavePath() QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)); if (!path.isEmpty()) { m_savePath->setText(path); - ConfigHandler().setSaveAfterCopyPath(path); + ConfigHandler().setSavePath(path); } } diff --git a/src/config/shortcutswidget.cpp b/src/config/shortcutswidget.cpp index 963207cb..4345d742 100644 --- a/src/config/shortcutswidget.cpp +++ b/src/config/shortcutswidget.cpp @@ -48,7 +48,7 @@ ShortcutsWidget::ShortcutsWidget(QWidget* parent) #endif m_layout = new QVBoxLayout(this); - m_layout->setAlignment(Qt::AlignHCenter); + m_layout->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); m_shortcuts = m_config.shortcuts(); initInfoTable(); @@ -90,10 +90,13 @@ void ShortcutsWidget::initInfoTable() const auto default_key_sequence = current_shortcut.at(2); m_table->setItem(i, 0, new QTableWidgetItem(description)); - const auto key_sequence = identifier.isEmpty() - ? default_key_sequence - : m_config.shortcut(identifier); - QTableWidgetItem* item = new QTableWidgetItem(key_sequence); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QTableWidgetItem* item = + new QTableWidgetItem(nativeOSHotKeyText(m_shortcuts.at(i).at(2))); +#else + QTableWidgetItem* item = new QTableWidgetItem(m_shortcuts.at(i).at(2)); +#endif item->setTextAlignment(Qt::AlignCenter); m_table->setItem(i, 1, item); @@ -117,10 +120,8 @@ void ShortcutsWidget::initInfoTable() // adjust size m_table->resizeColumnsToContents(); m_table->resizeRowsToContents(); - m_table->setMinimumWidth(400); - m_table->setMaximumWidth(600); - - m_table->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); + m_table->horizontalHeader()->setMinimumSectionSize(200); + m_table->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); m_table->horizontalHeader()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); } @@ -145,8 +146,14 @@ void ShortcutsWidget::slotShortcutCellClicked(int row, int col) } if (m_config.setShortcut(shortcutName, shortcutValue.toString())) { +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QTableWidgetItem* item = new QTableWidgetItem( + nativeOSHotKeyText(shortcutValue.toString())); +#else QTableWidgetItem* item = new QTableWidgetItem(shortcutValue.toString()); +#endif item->setTextAlignment(Qt::AlignCenter); item->setFlags(item->flags() ^ Qt::ItemIsEditable); m_table->setItem(row, col, item); @@ -155,3 +162,16 @@ void ShortcutsWidget::slotShortcutCellClicked(int row, int col) delete setShortcutDialog; } } + +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) +const QString& ShortcutsWidget::nativeOSHotKeyText(const QString& text) +{ + m_res = text; + m_res.replace("Ctrl+", "⌘"); + m_res.replace("Alt+", "⌥"); + m_res.replace("Meta+", "⌃"); + m_res.replace("Shift+", "⇧"); + return m_res; +} +#endif \ No newline at end of file diff --git a/src/config/shortcutswidget.h b/src/config/shortcutswidget.h index 20fc3909..3d01657a 100644 --- a/src/config/shortcutswidget.h +++ b/src/config/shortcutswidget.h @@ -36,11 +36,19 @@ public: private: void initInfoTable(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + const QString& nativeOSHotKeyText(const QString& text); +#endif private slots: void slotShortcutCellClicked(int, int); private: +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QString m_res; +#endif ConfigHandler m_config; QTableWidget* m_table; QVBoxLayout* m_layout; diff --git a/src/config/strftimechooserwidget.cpp b/src/config/strftimechooserwidget.cpp index e415a077..57de3856 100644 --- a/src/config/strftimechooserwidget.cpp +++ b/src/config/strftimechooserwidget.cpp @@ -51,22 +51,34 @@ QMap StrftimeChooserWidget::m_buttonData{ { QT_TR_NOOP("Century (00-99)"), "%C" }, { QT_TR_NOOP("Year (00-99)"), "%y" }, { QT_TR_NOOP("Year (2000)"), "%Y" }, +#ifndef Q_OS_WIN + // TODO - fix localized names on windows (ex. Cyrillic) { QT_TR_NOOP("Month Name (jan)"), "%b" }, { QT_TR_NOOP("Month Name (january)"), "%B" }, +#endif { QT_TR_NOOP("Month (01-12)"), "%m" }, { QT_TR_NOOP("Week Day (1-7)"), "%u" }, { QT_TR_NOOP("Week (01-53)"), "%V" }, +#ifndef Q_OS_WIN + // TODO - fix localized names on windows (ex. Cyrillic) { QT_TR_NOOP("Day Name (mon)"), "%a" }, { QT_TR_NOOP("Day Name (monday)"), "%A" }, +#endif { QT_TR_NOOP("Day (01-31)"), "%d" }, { QT_TR_NOOP("Day of Month (1-31)"), "%e" }, { QT_TR_NOOP("Day (001-366)"), "%j" }, +#ifndef Q_OS_WIN + // TODO - fix localized names on windows (ex. Cyrillic) { QT_TR_NOOP("Time (%H-%M-%S)"), "%T" }, { QT_TR_NOOP("Time (%H-%M)"), "%R" }, +#endif { QT_TR_NOOP("Hour (00-23)"), "%H" }, { QT_TR_NOOP("Hour (01-12)"), "%I" }, { QT_TR_NOOP("Minute (00-59)"), "%M" }, { QT_TR_NOOP("Second (00-59)"), "%S" }, +#ifndef Q_OS_WIN + // TODO - fix localized names on windows (ex. Cyrillic) { QT_TR_NOOP("Full Date (%m/%d/%y)"), "%D" }, +#endif { QT_TR_NOOP("Full Date (%Y-%m-%d)"), "%F" }, }; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2cea0765..e93645c8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,9 +1,12 @@ - # Required to generate MOC +IF (APPLE) + add_subdirectory(QHotkey) +ENDIF () + target_sources(flameshot PRIVATE controller.h flameshotdbusadapter.h) target_sources(flameshot PRIVATE capturerequest.cpp controller.cpp flameshotdbusadapter.cpp) -IF(WIN32) +IF (WIN32) target_sources(flameshot PRIVATE globalshortcutfilter.h globalshortcutfilter.cpp) -ENDIF() +ENDIF () diff --git a/src/core/QHotkey/CMakeLists.txt b/src/core/QHotkey/CMakeLists.txt new file mode 100644 index 00000000..05487262 --- /dev/null +++ b/src/core/QHotkey/CMakeLists.txt @@ -0,0 +1,43 @@ +find_package(Qt5 COMPONENTS Core Widgets REQUIRED) + +qt5_wrap_cpp(MOC_HEADERS + qhotkey.h + qhotkey_p.h) + +set(LIBS + Qt5::Core + Qt5::Widgets) + +set(SRC_FILES + qhotkey.cpp) + +if(APPLE) + set(CMAKE_C_ARCHIVE_CREATE " Scr ") + set(CMAKE_CXX_ARCHIVE_CREATE " Scr ") + set(CMAKE_C_ARCHIVE_FINISH " -no_warning_for_no_symbols -c ") + set(CMAKE_CXX_ARCHIVE_FINISH " -no_warning_for_no_symbols -c ") + + find_library(CARBON_LIBRARY Carbon) + mark_as_advanced(CARBON_LIBRARY) + + set(SRC_FILES ${SRC_FILES} qhotkey_mac.cpp) + set(LIBS ${LIBS} ${CARBON_LIBRARY}) +elseif(WIN32) + set(SRC_FILES ${SRC_FILES} qhotkey_win.cpp) +else() + find_package(X11 REQUIRED) + find_package(Qt5X11Extras REQUIRED) + + include_directories(${X11_INCLUDE_DIR}) + set(LIBS ${LIBS} ${X11_LIBRARIES} Qt5::X11Extras) + set(SRC_FILES ${SRC_FILES} qhotkey_x11.cpp) +endif() + +add_library(qhotkey ${SRC_FILES} ${MOC_HEADERS}) +add_library(QHotkey::QHotkey ALIAS qhotkey) +target_link_libraries(qhotkey ${LIBS}) + +target_include_directories(qhotkey + PUBLIC + $ + $) diff --git a/src/core/QHotkey/LICENSE b/src/core/QHotkey/LICENSE new file mode 100644 index 00000000..55e0b00a --- /dev/null +++ b/src/core/QHotkey/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2016, Felix Barz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of QHotkey nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/core/QHotkey/QHotkey b/src/core/QHotkey/QHotkey new file mode 100644 index 00000000..21d5e577 --- /dev/null +++ b/src/core/QHotkey/QHotkey @@ -0,0 +1 @@ +#include "qhotkey.h" diff --git a/src/core/QHotkey/README.md b/src/core/QHotkey/README.md new file mode 100644 index 00000000..e4f3f787 --- /dev/null +++ b/src/core/QHotkey/README.md @@ -0,0 +1,104 @@ +# QHotkey +A global shortcut/hotkey for Desktop Qt-Applications. + +The QHotkey is a class that can be used to create hotkeys/global shortcuts, aka shortcuts that work everywhere, independent of the application state. This means your application can be active, inactive, minimized or not visible at all and still receive the shortcuts. + +## Features +- Works on Windows, Mac and X11 +- Easy to use, can use `QKeySequence` for easy shortcut input +- Supports almost all common keys (Depends on OS & Keyboard-Layout) +- Allows direct input of Key/Modifier-Combinations +- Supports multiple QHotkey-instances for the same shortcut (with optimisations) +- Thread-Safe - Can be used on all threads (See section Thread safety) +- Allows usage of native keycodes and modifiers, if needed + +**Note:** For now Wayland is not supported, as it is simply not possible to register a global shortcut with wayland. For more details, or possible Ideas on how to get Hotkeys working on wayland, see [Issue #14](https://github.com/Skycoder42/QHotkey/issues/14). + +## Installation +The package is providet as qpm package, [`de.skycoder42.qhotkey`](https://www.qpm.io/packages/de.skycoder42.qhotkey/index.html). You can install it either via qpmx (preferred) or directly via qpm. + +### Via qpmx +[qpmx](https://github.com/Skycoder42/qpmx) is a frontend for qpm (and other tools) with additional features, and is the preferred way to install packages. To use it: + +1. Install qpmx (See [GitHub - Installation](https://github.com/Skycoder42/qpmx#installation)) +2. Install qpm (See [GitHub - Installing](https://github.com/Cutehacks/qpm/blob/master/README.md#installing), for **windows** see below) +3. In your projects root directory, run `qpmx install de.skycoder42.qhotkey` + +### Via qpm + +1. Install qpm (See [GitHub - Installing](https://github.com/Cutehacks/qpm/blob/master/README.md#installing), for **windows** see below) +2. In your projects root directory, run `qpm install de.skycoder42.qhotkey` +3. Include qpm to your project by adding `include(vendor/vendor.pri)` to your `.pro` file + +Check their [GitHub - Usage for App Developers](https://github.com/Cutehacks/qpm/blob/master/README.md#usage-for-app-developers) to learn more about qpm. + +**Important for Windows users:** QPM Version *0.10.0* (the one you can download on the website) is currently broken on windows! It's already fixed in master, but not released yet. Until a newer versions gets released, you can download the latest dev build from here: +- https://storage.googleapis.com/www.qpm.io/download/latest/windows_amd64/qpm.exe +- https://storage.googleapis.com/www.qpm.io/download/latest/windows_386/qpm.exe + +## Usage +The general usage is to create QHotkey instances for specific hotkeys, register them and then simply connect to the signal emitted once the hotkey is pressed. + +### Example +The following example shows a simple application that will run without a window in the background until you press the key-combination Ctrl+Alt+Q (++Q on Mac). This will quit the application. The debug output will tell if the hotkey was successfully registered and that it was pressed. +```cpp +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + auto hotkey = new QHotkey(QKeySequence("ctrl+alt+Q"), true, &a);//The hotkey will be automatically registered + qDebug() << "Is Registered: " << hotkey->isRegistered(); + + QObject::connect(hotkey, &QHotkey::activated, qApp, [&](){ + qDebug() << "Hotkey Activated - the application will quit now"; + qApp->quit(); + }); + + return a.exec(); +} +``` + +**Note:** You need the .pri include for this to work. + +### Testing +By running the example in `./HotkeyTest` you can test out the QHotkey class. There are 4 sections: +- **Playground:** You can enter some sequences here and try it out with different key combinations. +- **Testings:** A list of selected hotkeys. Activate it and try out which ones work for you (*Hint:* Depending on OS and keyboard layout, it's very possible that a few don't work). +- **Threading:** Activate the checkbox to move 2 Hotkeys of the playground to seperate threads. It should work without a difference. +- **Native Shortcut**: Allows you to try out the direct usage of native shortcuts + +### Logging +By default, QHotkey prints some warning messages if something goes wrong (For example, a key that cannot be translated). All messages of QHotkey are grouped into the [QLoggingCategory](https://doc.qt.io/qt-5/qloggingcategory.html) `"QHotkey"`. If you want to simply disable the logging, call the folling function somewhere in your code: +```cpp +QLoggingCategory::setFilterRules(QStringLiteral("QHotkey.warning=false")); +``` +This will turn all warnings of QHotkey of (It only uses warnings for now, thats why this is enough). For more information about all the things you can do with the logging categories, check the Qt-Documentation + +## Thread saftey +The QHotkey class itself is reentrant - wich means you can create as many instances as required on any thread. This allows you to use the QHotkey on all threads. **But** you should never use the QHotkey instance on a thread that is different from the one the instance belongs to! Internally the system uses a singleton instance that handles the hotkey events and distributes them to the QHotkey instances. This internal class is completley threadsafe. + +However, this singleton instance only runs on the main thread. (One reason is that some of the OS-Functions are not thread safe). To make threaded hotkeys possible, the critical functions (registering/unregistering hotkeys and keytranslation) are all run on the mainthread too. The QHotkey instances on other threads use `QMetaObject::invokeMethod` with a `Qt::BlockingQueuedConnection`. + +For you this means: QHotkey instances on other threads than the main thread may take a little longer to register/unregister/translate hotkeys, because they have to wait for the main thread to do this for them. **Important:** there is however, one additional limitation that comes with that feature: QHotkey instances on other threads but the main thread *must* be unregistered or destroyed *before* the main eventloop ends. Otherwise, your application will hangup on destruction of the hotkey. This limitation does not apply for instances on the main thread. Furthermore, the same happens if you change the shortcut or register/unregister before the loop started, until it actually starts. + +## Documentation +The documentation is available as release and on [github pages](https://skycoder42.github.io/QHotkey/). + +The documentation was created using [doxygen](http://www.doxygen.org). It includes an HTML-documentation and Qt-Help files that can be included into QtCreator (QtAssistant) to show F1-Help (See [Adding External Documentation](https://doc.qt.io/qtcreator/creator-help.html#adding-external-documentation) for more details). + +## Technical +### Requirements + - Explicit support is only given down to the latest Qt LTS, but may work with earlier versions, too + - At least the QtGui-Module (a QGuiApplication). Hotkeys on console based applications are not supported (By the operating systems). You can however create a gui application without any visible window. + - C++11 + +### Known Limitations + - Only single key/modifier combinations are possible. If using QKeySequence, only the first key+modifier of the sequence will be used. + - Qt::Key makes no difference between normal numbers and the Numpad numbers. Most keyboards however require this. Thus, you can't register shortcuts for the numpad, unless you use a native shortcut. + - Supports not all keys, but most of the common ones. There are differences between platforms and it depends on the Keyboard-Layout. "Delete", for example, works on windows and mac, but not on X11 (At least on my test machines). I tried to use OS-Functions where possible, but since the Qt::Key values need to be converted into native keys, there are some limitations. I can use need such a key, try using the native shortcut. + - The registered keys will be "taken" by QHotkey. This means after a hotkey was cosumend by your application, it will not be sent to the active application. This is done this way by the operating systems and cannot be changed. +- If you get a `QHotkey: Failed to register hotkey. Error: BadAccess (attempt to access private resource denied)` error on X11, this means you are trying to register a hotkey that is private to X11. Those keys simply cannot be registered using the normal API diff --git a/src/core/QHotkey/qhotkey.cpp b/src/core/QHotkey/qhotkey.cpp new file mode 100644 index 00000000..0869810c --- /dev/null +++ b/src/core/QHotkey/qhotkey.cpp @@ -0,0 +1,391 @@ +#include "qhotkey.h" +#include "qhotkey_p.h" +#include +#include +#include +#include +#include + +Q_LOGGING_CATEGORY(logQHotkey, "QHotkey") + +void QHotkey::addGlobalMapping(const QKeySequence& shortcut, + QHotkey::NativeShortcut nativeShortcut) +{ + QMetaObject::invokeMethod( + QHotkeyPrivate::instance(), + "addMappingInvoked", + Qt::QueuedConnection, + Q_ARG(Qt::Key, Qt::Key(shortcut[0] & ~Qt::KeyboardModifierMask)), + Q_ARG(Qt::KeyboardModifiers, + Qt::KeyboardModifiers(shortcut[0] & Qt::KeyboardModifierMask)), + Q_ARG(QHotkey::NativeShortcut, nativeShortcut)); +} + +bool QHotkey::isPlatformSupported() +{ + return QHotkeyPrivate::isPlatformSupported(); +} + +QHotkey::QHotkey(QObject* parent) + : QObject(parent) + , _keyCode(Qt::Key_unknown) + , _modifiers(Qt::NoModifier) + , _registered(false) +{} + +QHotkey::QHotkey(const QKeySequence& shortcut, + bool autoRegister, + QObject* parent) + : QHotkey(parent) +{ + setShortcut(shortcut, autoRegister); +} + +QHotkey::QHotkey(Qt::Key keyCode, + Qt::KeyboardModifiers modifiers, + bool autoRegister, + QObject* parent) + : QHotkey(parent) +{ + setShortcut(keyCode, modifiers, autoRegister); +} + +QHotkey::QHotkey(QHotkey::NativeShortcut shortcut, + bool autoRegister, + QObject* parent) + : QHotkey(parent) +{ + setNativeShortcut(shortcut, autoRegister); +} + +QHotkey::~QHotkey() +{ + if (_registered) + QHotkeyPrivate::instance()->removeShortcut(this); +} + +QKeySequence QHotkey::shortcut() const +{ + if (_keyCode == Qt::Key_unknown) + return QKeySequence(); + return QKeySequence(static_cast(_keyCode | _modifiers)); +} + +Qt::Key QHotkey::keyCode() const +{ + return _keyCode; +} + +Qt::KeyboardModifiers QHotkey::modifiers() const +{ + return _modifiers; +} + +QHotkey::NativeShortcut QHotkey::currentNativeShortcut() const +{ + return _nativeShortcut; +} + +bool QHotkey::isRegistered() const +{ + return _registered; +} + +bool QHotkey::setShortcut(const QKeySequence& shortcut, bool autoRegister) +{ + if (shortcut.isEmpty()) + return resetShortcut(); + if (shortcut.count() > 1) { + qCWarning(logQHotkey, + "Keysequences with multiple shortcuts are not allowed! " + "Only the first shortcut will be used!"); + } + + return setShortcut( + Qt::Key(shortcut[0] & ~Qt::KeyboardModifierMask), + Qt::KeyboardModifiers(shortcut[0] & Qt::KeyboardModifierMask), + autoRegister); +} + +bool QHotkey::setShortcut(Qt::Key keyCode, + Qt::KeyboardModifiers modifiers, + bool autoRegister) +{ + if (_registered) { + if (autoRegister) { + if (!QHotkeyPrivate::instance()->removeShortcut(this)) + return false; + } else + return false; + } + + if (keyCode == Qt::Key_unknown) { + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = NativeShortcut(); + return true; + } + + _keyCode = keyCode; + _modifiers = modifiers; + _nativeShortcut = + QHotkeyPrivate::instance()->nativeShortcut(keyCode, modifiers); + if (_nativeShortcut.isValid()) { + if (autoRegister) + return QHotkeyPrivate::instance()->addShortcut(this); + return true; + } + + qCWarning(logQHotkey) << "Unable to map shortcut to native keys. Key:" + << keyCode << "Modifiers:" << modifiers; + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = NativeShortcut(); + return false; +} + +bool QHotkey::resetShortcut() +{ + if (_registered && !QHotkeyPrivate::instance()->removeShortcut(this)) { + return false; + } + + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = NativeShortcut(); + return true; +} + +bool QHotkey::setNativeShortcut(QHotkey::NativeShortcut nativeShortcut, + bool autoRegister) +{ + if (_registered) { + if (autoRegister) { + if (!QHotkeyPrivate::instance()->removeShortcut(this)) + return false; + } else + return false; + } + + if (nativeShortcut.isValid()) { + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = nativeShortcut; + if (autoRegister) + return QHotkeyPrivate::instance()->addShortcut(this); + return true; + } + + _keyCode = Qt::Key_unknown; + _modifiers = Qt::NoModifier; + _nativeShortcut = NativeShortcut(); + return true; +} + +bool QHotkey::setRegistered(bool registered) +{ + if (_registered && !registered) + return QHotkeyPrivate::instance()->removeShortcut(this); + if (!_registered && registered) { + if (!_nativeShortcut.isValid()) + return false; + return QHotkeyPrivate::instance()->addShortcut(this); + } + return true; +} + +// ---------- QHotkeyPrivate implementation ---------- + +QHotkeyPrivate::QHotkeyPrivate() +{ + Q_ASSERT_X(qApp, + Q_FUNC_INFO, + "QHotkey requires QCoreApplication to be instantiated"); + qApp->eventDispatcher()->installNativeEventFilter(this); +} + +QHotkeyPrivate::~QHotkeyPrivate() +{ + if (!shortcuts.isEmpty()) + qCWarning(logQHotkey) + << "QHotkeyPrivate destroyed with registered shortcuts!"; + if (qApp && qApp->eventDispatcher()) + qApp->eventDispatcher()->removeNativeEventFilter(this); +} + +QHotkey::NativeShortcut QHotkeyPrivate::nativeShortcut( + Qt::Key keycode, + Qt::KeyboardModifiers modifiers) +{ + Qt::ConnectionType conType = + (QThread::currentThread() == thread() ? Qt::DirectConnection + : Qt::BlockingQueuedConnection); + QHotkey::NativeShortcut res; + if (!QMetaObject::invokeMethod(this, + "nativeShortcutInvoked", + conType, + Q_RETURN_ARG(QHotkey::NativeShortcut, res), + Q_ARG(Qt::Key, keycode), + Q_ARG(Qt::KeyboardModifiers, modifiers))) { + return QHotkey::NativeShortcut(); + } + return res; +} + +bool QHotkeyPrivate::addShortcut(QHotkey* hotkey) +{ + if (hotkey->_registered) + return false; + + Qt::ConnectionType conType = + (QThread::currentThread() == thread() ? Qt::DirectConnection + : Qt::BlockingQueuedConnection); + bool res = false; + if (!QMetaObject::invokeMethod(this, + "addShortcutInvoked", + conType, + Q_RETURN_ARG(bool, res), + Q_ARG(QHotkey*, hotkey))) { + return false; + } + + if (res) + emit hotkey->registeredChanged(true); + return res; +} + +bool QHotkeyPrivate::removeShortcut(QHotkey* hotkey) +{ + if (!hotkey->_registered) + return false; + + Qt::ConnectionType conType = + (QThread::currentThread() == thread() ? Qt::DirectConnection + : Qt::BlockingQueuedConnection); + bool res = false; + if (!QMetaObject::invokeMethod(this, + "removeShortcutInvoked", + conType, + Q_RETURN_ARG(bool, res), + Q_ARG(QHotkey*, hotkey))) { + return false; + } + + if (res) + emit hotkey->registeredChanged(false); + return res; +} + +void QHotkeyPrivate::activateShortcut(QHotkey::NativeShortcut shortcut) +{ + QMetaMethod signal = QMetaMethod::fromSignal(&QHotkey::activated); + for (QHotkey* hkey : shortcuts.values(shortcut)) + signal.invoke(hkey, Qt::QueuedConnection); +} + +void QHotkeyPrivate::releaseShortcut(QHotkey::NativeShortcut shortcut) +{ + QMetaMethod signal = QMetaMethod::fromSignal(&QHotkey::released); + for (QHotkey* hkey : shortcuts.values(shortcut)) + signal.invoke(hkey, Qt::QueuedConnection); +} + +void QHotkeyPrivate::addMappingInvoked(Qt::Key keycode, + Qt::KeyboardModifiers modifiers, + QHotkey::NativeShortcut nativeShortcut) +{ + mapping.insert({ keycode, modifiers }, nativeShortcut); +} + +bool QHotkeyPrivate::addShortcutInvoked(QHotkey* hotkey) +{ + QHotkey::NativeShortcut shortcut = hotkey->_nativeShortcut; + + if (!shortcuts.contains(shortcut)) { + if (!registerShortcut(shortcut)) { + qCWarning(logQHotkey) + << QHotkey::tr("Failed to register %1. Error: %2") + .arg(hotkey->shortcut().toString(), error); + return false; + } + } + + shortcuts.insert(shortcut, hotkey); + hotkey->_registered = true; + return true; +} + +bool QHotkeyPrivate::removeShortcutInvoked(QHotkey* hotkey) +{ + QHotkey::NativeShortcut shortcut = hotkey->_nativeShortcut; + + if (shortcuts.remove(shortcut, hotkey) == 0) + return false; + hotkey->_registered = false; + emit hotkey->registeredChanged(true); + if (shortcuts.count(shortcut) == 0) { + if (!unregisterShortcut(shortcut)) { + qCWarning(logQHotkey) + << QHotkey::tr("Failed to unregister %1. Error: %2") + .arg(hotkey->shortcut().toString(), error); + return false; + } + return true; + } + return true; +} + +QHotkey::NativeShortcut QHotkeyPrivate::nativeShortcutInvoked( + Qt::Key keycode, + Qt::KeyboardModifiers modifiers) +{ + if (mapping.contains({ keycode, modifiers })) + return mapping.value({ keycode, modifiers }); + + bool ok1 = false; + auto k = nativeKeycode(keycode, ok1); + bool ok2 = false; + auto m = nativeModifiers(modifiers, ok2); + if (ok1 && ok2) + return { k, m }; + return {}; +} + +QHotkey::NativeShortcut::NativeShortcut() + : key() + , modifier() + , valid(false) +{} + +QHotkey::NativeShortcut::NativeShortcut(quint32 key, quint32 modifier) + : key(key) + , modifier(modifier) + , valid(true) +{} + +bool QHotkey::NativeShortcut::isValid() const +{ + return valid; +} + +bool QHotkey::NativeShortcut::operator==(QHotkey::NativeShortcut other) const +{ + return (key == other.key) && (modifier == other.modifier) && + valid == other.valid; +} + +bool QHotkey::NativeShortcut::operator!=(QHotkey::NativeShortcut other) const +{ + return (key != other.key) || (modifier != other.modifier) || + valid != other.valid; +} + +uint qHash(QHotkey::NativeShortcut key) +{ + return qHash(key.key) ^ qHash(key.modifier); +} + +uint qHash(QHotkey::NativeShortcut key, uint seed) +{ + return qHash(key.key, seed) ^ qHash(key.modifier, seed); +} diff --git a/src/core/QHotkey/qhotkey.h b/src/core/QHotkey/qhotkey.h new file mode 100644 index 00000000..8ab96468 --- /dev/null +++ b/src/core/QHotkey/qhotkey.h @@ -0,0 +1,138 @@ +#ifndef QHOTKEY_H +#define QHOTKEY_H + +#include +#include +#include +#include + +#ifdef QHOTKEY_LIB +#ifdef QHOTKEY_LIB_BUILD +#define QHOTKEY_SHARED_EXPORT Q_DECL_EXPORT +#else +#define QHOTKEY_SHARED_EXPORT Q_DECL_IMPORT +#endif +#else +#define QHOTKEY_SHARED_EXPORT +#endif + +//! A class to define global, systemwide Hotkeys +class QHOTKEY_SHARED_EXPORT QHotkey : public QObject +{ + Q_OBJECT + //! @private + friend class QHotkeyPrivate; + + //! Specifies whether this hotkey is currently registered or not + Q_PROPERTY(bool registered READ isRegistered WRITE setRegistered NOTIFY + registeredChanged) + //! Holds the shortcut this hotkey will be triggered on + Q_PROPERTY( + QKeySequence shortcut READ shortcut WRITE setShortcut RESET resetShortcut) + +public: + //! Defines shortcut with native keycodes + class QHOTKEY_SHARED_EXPORT NativeShortcut + { + public: + //! The native keycode + quint32 key; + //! The native modifiers + quint32 modifier; + + //! Creates an invalid native shortcut + NativeShortcut(); + //! Creates a valid native shortcut, with the given key and modifiers + NativeShortcut(quint32 key, quint32 modifier = 0); + + //! Checks, whether this shortcut is valid or not + bool isValid() const; + + //! Equality operator + bool operator==(NativeShortcut other) const; + //! Inequality operator + bool operator!=(NativeShortcut other) const; + + private: + bool valid; + }; + + //! Adds a global mapping of a key sequence to a replacement native shortcut + static void addGlobalMapping(const QKeySequence& shortcut, + NativeShortcut nativeShortcut); + + //! Checks if global shortcuts are supported by the current platform + static bool isPlatformSupported(); + + //! Default Constructor + explicit QHotkey(QObject* parent = nullptr); + //! Constructs a hotkey with a shortcut and optionally registers it + explicit QHotkey(const QKeySequence& shortcut, + bool autoRegister = false, + QObject* parent = nullptr); + //! Constructs a hotkey with a key and modifiers and optionally registers it + explicit QHotkey(Qt::Key keyCode, + Qt::KeyboardModifiers modifiers, + bool autoRegister = false, + QObject* parent = nullptr); + //! Constructs a hotkey from a native shortcut and optionally registers it + explicit QHotkey(NativeShortcut shortcut, + bool autoRegister = false, + QObject* parent = nullptr); + ~QHotkey() override; + + //! @readAcFn{QHotkey::registered} + bool isRegistered() const; + //! @readAcFn{QHotkey::shortcut} + QKeySequence shortcut() const; + //! @readAcFn{QHotkey::shortcut} - the key only + Qt::Key keyCode() const; + //! @readAcFn{QHotkey::shortcut} - the modifiers only + Qt::KeyboardModifiers modifiers() const; + + //! Get the current native shortcut + NativeShortcut currentNativeShortcut() const; + +public slots: + //! @writeAcFn{QHotkey::registered} + bool setRegistered(bool registered); + + //! @writeAcFn{QHotkey::shortcut} + bool setShortcut(const QKeySequence& shortcut, bool autoRegister = false); + //! @writeAcFn{QHotkey::shortcut} + bool setShortcut(Qt::Key keyCode, + Qt::KeyboardModifiers modifiers, + bool autoRegister = false); + //! @resetAcFn{QHotkey::shortcut} + bool resetShortcut(); + + //! Set this hotkey to a native shortcut + bool setNativeShortcut(QHotkey::NativeShortcut nativeShortcut, + bool autoRegister = false); + +signals: + //! Will be emitted if the shortcut is pressed + void activated(QPrivateSignal); + + //! Will be emitted if the shortcut press is released + void released(QPrivateSignal); + + //! @notifyAcFn{QHotkey::registered} + void registeredChanged(bool registered); + +private: + Qt::Key _keyCode; + Qt::KeyboardModifiers _modifiers; + + NativeShortcut _nativeShortcut; + bool _registered; +}; + +uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key); +uint QHOTKEY_SHARED_EXPORT qHash(QHotkey::NativeShortcut key, uint seed); + +QHOTKEY_SHARED_EXPORT Q_DECLARE_LOGGING_CATEGORY(logQHotkey) + + Q_DECLARE_METATYPE(QHotkey::NativeShortcut) + +#endif // QHOTKEY_H diff --git a/src/core/QHotkey/qhotkey_mac.cpp b/src/core/QHotkey/qhotkey_mac.cpp new file mode 100644 index 00000000..29e50df5 --- /dev/null +++ b/src/core/QHotkey/qhotkey_mac.cpp @@ -0,0 +1,328 @@ +#include "qhotkey.h" +#include "qhotkey_p.h" +#include +#include + +class QHotkeyPrivateMac : public QHotkeyPrivate +{ +public: + // QAbstractNativeEventFilter interface + bool nativeEventFilter(const QByteArray& eventType, + void* message, + long* result) Q_DECL_OVERRIDE; + + static OSStatus hotkeyPressEventHandler(EventHandlerCallRef nextHandler, + EventRef event, + void* data); + static OSStatus hotkeyReleaseEventHandler(EventHandlerCallRef nextHandler, + EventRef event, + void* data); + +protected: + // QHotkeyPrivate interface + quint32 nativeKeycode(Qt::Key keycode, bool& ok) Q_DECL_OVERRIDE; + quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) Q_DECL_OVERRIDE; + bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; + bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; + +private: + static bool isHotkeyHandlerRegistered; + static QHash hotkeyRefs; +}; +NATIVE_INSTANCE(QHotkeyPrivateMac) + +bool QHotkeyPrivate::isPlatformSupported() +{ + return true; +} + +bool QHotkeyPrivateMac::isHotkeyHandlerRegistered = false; +QHash QHotkeyPrivateMac::hotkeyRefs; + +bool QHotkeyPrivateMac::nativeEventFilter(const QByteArray& eventType, + void* message, + long* result) +{ + Q_UNUSED(eventType) + Q_UNUSED(message) + Q_UNUSED(result) + return false; +} + +quint32 QHotkeyPrivateMac::nativeKeycode(Qt::Key keycode, bool& ok) +{ + // Constants found in NSEvent.h from AppKit.framework + ok = true; + switch (keycode) { + case Qt::Key_Return: + return kVK_Return; + case Qt::Key_Enter: + return kVK_ANSI_KeypadEnter; + case Qt::Key_Tab: + return kVK_Tab; + case Qt::Key_Space: + return kVK_Space; + case Qt::Key_Backspace: + return kVK_Delete; + case Qt::Key_Escape: + return kVK_Escape; + case Qt::Key_CapsLock: + return kVK_CapsLock; + case Qt::Key_Option: + return kVK_Option; + case Qt::Key_F17: + return kVK_F17; + case Qt::Key_VolumeUp: + return kVK_VolumeUp; + case Qt::Key_VolumeDown: + return kVK_VolumeDown; + case Qt::Key_F18: + return kVK_F18; + case Qt::Key_F19: + return kVK_F19; + case Qt::Key_F20: + return kVK_F20; + case Qt::Key_F5: + return kVK_F5; + case Qt::Key_F6: + return kVK_F6; + case Qt::Key_F7: + return kVK_F7; + case Qt::Key_F3: + return kVK_F3; + case Qt::Key_F8: + return kVK_F8; + case Qt::Key_F9: + return kVK_F9; + case Qt::Key_F11: + return kVK_F11; + case Qt::Key_F13: + return kVK_F13; + case Qt::Key_F16: + return kVK_F16; + case Qt::Key_F14: + return kVK_F14; + case Qt::Key_F10: + return kVK_F10; + case Qt::Key_F12: + return kVK_F12; + case Qt::Key_F15: + return kVK_F15; + case Qt::Key_Help: + return kVK_Help; + case Qt::Key_Home: + return kVK_Home; + case Qt::Key_PageUp: + return kVK_PageUp; + case Qt::Key_Delete: + return kVK_ForwardDelete; + case Qt::Key_F4: + return kVK_F4; + case Qt::Key_End: + return kVK_End; + case Qt::Key_F2: + return kVK_F2; + case Qt::Key_PageDown: + return kVK_PageDown; + case Qt::Key_F1: + return kVK_F1; + case Qt::Key_Left: + return kVK_LeftArrow; + case Qt::Key_Right: + return kVK_RightArrow; + case Qt::Key_Down: + return kVK_DownArrow; + case Qt::Key_Up: + return kVK_UpArrow; + default: + ok = false; + break; + } + + UTF16Char ch = keycode; + + CFDataRef currentLayoutData; + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + + if (currentKeyboard == NULL) + return 0; + + currentLayoutData = (CFDataRef)TISGetInputSourceProperty( + currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + CFRelease(currentKeyboard); + if (currentLayoutData == NULL) + return 0; + + UCKeyboardLayout* header = + (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData); + UCKeyboardTypeHeader* table = header->keyboardTypeList; + + uint8_t* data = (uint8_t*)header; + for (quint32 i = 0; i < header->keyboardTypeCount; i++) { + UCKeyStateRecordsIndex* stateRec = 0; + if (table[i].keyStateRecordsIndexOffset != 0) { + stateRec = reinterpret_cast( + data + table[i].keyStateRecordsIndexOffset); + if (stateRec->keyStateRecordsIndexFormat != + kUCKeyStateRecordsIndexFormat) + stateRec = 0; + } + + UCKeyToCharTableIndex* charTable = + reinterpret_cast( + data + table[i].keyToCharTableIndexOffset); + if (charTable->keyToCharTableIndexFormat != + kUCKeyToCharTableIndexFormat) + continue; + + for (quint32 j = 0; j < charTable->keyToCharTableCount; j++) { + UCKeyOutput* keyToChar = reinterpret_cast( + data + charTable->keyToCharTableOffsets[j]); + for (quint32 k = 0; k < charTable->keyToCharTableSize; k++) { + if (keyToChar[k] & kUCKeyOutputTestForIndexMask) { + long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; + if (stateRec && idx < stateRec->keyStateRecordCount) { + UCKeyStateRecord* rec = + reinterpret_cast( + data + stateRec->keyStateRecordOffsets[idx]); + if (rec->stateZeroCharData == ch) { + ok = true; + return k; + } + } + } else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && + keyToChar[k] < 0xFFFE) { + if (keyToChar[k] == ch) { + ok = true; + return k; + } + } + } + } + } + return 0; +} + +quint32 QHotkeyPrivateMac::nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) +{ + quint32 nMods = 0; + if (modifiers & Qt::ShiftModifier) + nMods |= shiftKey; + if (modifiers & Qt::ControlModifier) + nMods |= cmdKey; + if (modifiers & Qt::AltModifier) + nMods |= optionKey; + if (modifiers & Qt::MetaModifier) + nMods |= controlKey; + if (modifiers & Qt::KeypadModifier) + nMods |= kEventKeyModifierNumLockMask; + ok = true; + return nMods; +} + +bool QHotkeyPrivateMac::registerShortcut(QHotkey::NativeShortcut shortcut) +{ + if (!this->isHotkeyHandlerRegistered) { + EventTypeSpec pressEventSpec; + pressEventSpec.eventClass = kEventClassKeyboard; + pressEventSpec.eventKind = kEventHotKeyPressed; + InstallApplicationEventHandler( + &QHotkeyPrivateMac::hotkeyPressEventHandler, + 1, + &pressEventSpec, + NULL, + NULL); + + EventTypeSpec releaseEventSpec; + releaseEventSpec.eventClass = kEventClassKeyboard; + releaseEventSpec.eventKind = kEventHotKeyReleased; + InstallApplicationEventHandler( + &QHotkeyPrivateMac::hotkeyReleaseEventHandler, + 1, + &releaseEventSpec, + NULL, + NULL); + } + + EventHotKeyID hkeyID; + hkeyID.signature = shortcut.key; + hkeyID.id = shortcut.modifier; + + EventHotKeyRef eventRef = 0; + OSStatus status = RegisterEventHotKey(shortcut.key, + shortcut.modifier, + hkeyID, + GetApplicationEventTarget(), + 0, + &eventRef); + if (status != noErr) { + error = QString::number(status); + return false; + } else { + this->hotkeyRefs.insert(shortcut, eventRef); + return true; + } +} + +bool QHotkeyPrivateMac::unregisterShortcut(QHotkey::NativeShortcut shortcut) +{ + EventHotKeyRef eventRef = QHotkeyPrivateMac::hotkeyRefs.value(shortcut); + OSStatus status = UnregisterEventHotKey(eventRef); + if (status != noErr) { + error = QString::number(status); + return false; + } else { + this->hotkeyRefs.remove(shortcut); + return true; + } +} + +OSStatus QHotkeyPrivateMac::hotkeyPressEventHandler( + EventHandlerCallRef nextHandler, + EventRef event, + void* data) +{ + Q_UNUSED(nextHandler); + Q_UNUSED(data); + + if (GetEventClass(event) == kEventClassKeyboard && + GetEventKind(event) == kEventHotKeyPressed) { + EventHotKeyID hkeyID; + GetEventParameter(event, + kEventParamDirectObject, + typeEventHotKeyID, + NULL, + sizeof(EventHotKeyID), + NULL, + &hkeyID); + hotkeyPrivate->activateShortcut({ hkeyID.signature, hkeyID.id }); + } + + return noErr; +} + +OSStatus QHotkeyPrivateMac::hotkeyReleaseEventHandler( + EventHandlerCallRef nextHandler, + EventRef event, + void* data) +{ + Q_UNUSED(nextHandler); + Q_UNUSED(data); + + if (GetEventClass(event) == kEventClassKeyboard && + GetEventKind(event) == kEventHotKeyReleased) { + EventHotKeyID hkeyID; + GetEventParameter(event, + kEventParamDirectObject, + typeEventHotKeyID, + NULL, + sizeof(EventHotKeyID), + NULL, + &hkeyID); + hotkeyPrivate->releaseShortcut({ hkeyID.signature, hkeyID.id }); + } + + return noErr; +} \ No newline at end of file diff --git a/src/core/QHotkey/qhotkey_p.h b/src/core/QHotkey/qhotkey_p.h new file mode 100644 index 00000000..c82bf4d2 --- /dev/null +++ b/src/core/QHotkey/qhotkey_p.h @@ -0,0 +1,68 @@ +#ifndef QHOTKEY_P_H +#define QHOTKEY_P_H + +#include "qhotkey.h" +#include +#include +#include +#include + +class QHOTKEY_SHARED_EXPORT QHotkeyPrivate + : public QObject + , public QAbstractNativeEventFilter +{ + Q_OBJECT + +public: + QHotkeyPrivate(); // singleton!!! + ~QHotkeyPrivate(); + + static QHotkeyPrivate* instance(); + static bool isPlatformSupported(); + + QHotkey::NativeShortcut nativeShortcut(Qt::Key keycode, + Qt::KeyboardModifiers modifiers); + + bool addShortcut(QHotkey* hotkey); + bool removeShortcut(QHotkey* hotkey); + +protected: + void activateShortcut(QHotkey::NativeShortcut shortcut); + void releaseShortcut(QHotkey::NativeShortcut shortcut); + + virtual quint32 nativeKeycode(Qt::Key keycode, + bool& ok) = 0; // platform implement + virtual quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) = 0; // platform implement + + virtual bool registerShortcut( + QHotkey::NativeShortcut shortcut) = 0; // platform implement + virtual bool unregisterShortcut( + QHotkey::NativeShortcut shortcut) = 0; // platform implement + + QString error; + +private: + QHash, QHotkey::NativeShortcut> + mapping; + QMultiHash shortcuts; + + Q_INVOKABLE void addMappingInvoked(Qt::Key keycode, + Qt::KeyboardModifiers modifiers, + QHotkey::NativeShortcut nativeShortcut); + Q_INVOKABLE bool addShortcutInvoked(QHotkey* hotkey); + Q_INVOKABLE bool removeShortcutInvoked(QHotkey* hotkey); + Q_INVOKABLE QHotkey::NativeShortcut nativeShortcutInvoked( + Qt::Key keycode, + Qt::KeyboardModifiers modifiers); +}; + +#define NATIVE_INSTANCE(ClassName) \ + Q_GLOBAL_STATIC(ClassName, hotkeyPrivate) \ + \ + QHotkeyPrivate* QHotkeyPrivate::instance() { return hotkeyPrivate; } + +Q_DECLARE_METATYPE(Qt::Key) +Q_DECLARE_METATYPE(Qt::KeyboardModifiers) + +#endif // QHOTKEY_P_H diff --git a/src/core/QHotkey/qhotkey_win.cpp b/src/core/QHotkey/qhotkey_win.cpp new file mode 100644 index 00000000..9f1ca215 --- /dev/null +++ b/src/core/QHotkey/qhotkey_win.cpp @@ -0,0 +1,313 @@ +#include "qhotkey.h" +#include "qhotkey_p.h" +#include +#include +#include + +#define HKEY_ID(nativeShortcut) \ + (((nativeShortcut.key ^ (nativeShortcut.modifier << 8)) & 0x0FFF) | 0x7000) + +#if !defined(MOD_NOREPEAT) +#define MOD_NOREPEAT 0x4000 +#endif + +class QHotkeyPrivateWin : public QHotkeyPrivate +{ +public: + QHotkeyPrivateWin(); + // QAbstractNativeEventFilter interface + bool nativeEventFilter(const QByteArray& eventType, + void* message, + long* result) Q_DECL_OVERRIDE; + +protected: + void pollForHotkeyRelease(); + // QHotkeyPrivate interface + quint32 nativeKeycode(Qt::Key keycode, bool& ok) Q_DECL_OVERRIDE; + quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) Q_DECL_OVERRIDE; + bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; + bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; + +private: + static QString formatWinError(DWORD winError); + QTimer pollTimer; + QHotkey::NativeShortcut polledShortcut; +}; +NATIVE_INSTANCE(QHotkeyPrivateWin) + +QHotkeyPrivateWin::QHotkeyPrivateWin() +{ + pollTimer.setInterval(50); + connect(&pollTimer, + &QTimer::timeout, + this, + &QHotkeyPrivateWin::pollForHotkeyRelease); +} + +bool QHotkeyPrivate::isPlatformSupported() +{ + return true; +} + +bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray& eventType, + void* message, + long* result) +{ + Q_UNUSED(eventType) + Q_UNUSED(result) + + MSG* msg = static_cast(message); + if (msg->message == WM_HOTKEY) { + QHotkey::NativeShortcut shortcut = { HIWORD(msg->lParam), + LOWORD(msg->lParam) }; + this->activateShortcut(shortcut); + this->polledShortcut = shortcut; + this->pollTimer.start(); + } + + return false; +} + +void QHotkeyPrivateWin::pollForHotkeyRelease() +{ + bool pressed = + (GetAsyncKeyState(this->polledShortcut.key) & (1 << 15)) != 0; + if (!pressed) { + this->pollTimer.stop(); + this->releaseShortcut(this->polledShortcut); + } +} + +quint32 QHotkeyPrivateWin::nativeKeycode(Qt::Key keycode, bool& ok) +{ + ok = true; + if (keycode <= 0xFFFF) { // Try to obtain the key from it's "character" + const SHORT vKey = VkKeyScanW(static_cast(keycode)); + if (vKey > -1) + return LOBYTE(vKey); + } + + // find key from switch/case --> Only finds a very small subset of keys + switch (keycode) { + case Qt::Key_Escape: + return VK_ESCAPE; + case Qt::Key_Tab: + case Qt::Key_Backtab: + return VK_TAB; + case Qt::Key_Backspace: + return VK_BACK; + case Qt::Key_Return: + case Qt::Key_Enter: + return VK_RETURN; + case Qt::Key_Insert: + return VK_INSERT; + case Qt::Key_Delete: + return VK_DELETE; + case Qt::Key_Pause: + return VK_PAUSE; + case Qt::Key_Print: + return VK_PRINT; + case Qt::Key_Clear: + return VK_CLEAR; + case Qt::Key_Home: + return VK_HOME; + case Qt::Key_End: + return VK_END; + case Qt::Key_Left: + return VK_LEFT; + case Qt::Key_Up: + return VK_UP; + case Qt::Key_Right: + return VK_RIGHT; + case Qt::Key_Down: + return VK_DOWN; + case Qt::Key_PageUp: + return VK_PRIOR; + case Qt::Key_PageDown: + return VK_NEXT; + case Qt::Key_CapsLock: + return VK_CAPITAL; + case Qt::Key_NumLock: + return VK_NUMLOCK; + case Qt::Key_ScrollLock: + return VK_SCROLL; + + case Qt::Key_F1: + return VK_F1; + case Qt::Key_F2: + return VK_F2; + case Qt::Key_F3: + return VK_F3; + case Qt::Key_F4: + return VK_F4; + case Qt::Key_F5: + return VK_F5; + case Qt::Key_F6: + return VK_F6; + case Qt::Key_F7: + return VK_F7; + case Qt::Key_F8: + return VK_F8; + case Qt::Key_F9: + return VK_F9; + case Qt::Key_F10: + return VK_F10; + case Qt::Key_F11: + return VK_F11; + case Qt::Key_F12: + return VK_F12; + case Qt::Key_F13: + return VK_F13; + case Qt::Key_F14: + return VK_F14; + case Qt::Key_F15: + return VK_F15; + case Qt::Key_F16: + return VK_F16; + case Qt::Key_F17: + return VK_F17; + case Qt::Key_F18: + return VK_F18; + case Qt::Key_F19: + return VK_F19; + case Qt::Key_F20: + return VK_F20; + case Qt::Key_F21: + return VK_F21; + case Qt::Key_F22: + return VK_F22; + case Qt::Key_F23: + return VK_F23; + case Qt::Key_F24: + return VK_F24; + + case Qt::Key_Menu: + return VK_APPS; + case Qt::Key_Help: + return VK_HELP; + case Qt::Key_MediaNext: + return VK_MEDIA_NEXT_TRACK; + case Qt::Key_MediaPrevious: + return VK_MEDIA_PREV_TRACK; + case Qt::Key_MediaPlay: + return VK_MEDIA_PLAY_PAUSE; + case Qt::Key_MediaStop: + return VK_MEDIA_STOP; + case Qt::Key_VolumeDown: + return VK_VOLUME_DOWN; + case Qt::Key_VolumeUp: + return VK_VOLUME_UP; + case Qt::Key_VolumeMute: + return VK_VOLUME_MUTE; + case Qt::Key_Mode_switch: + return VK_MODECHANGE; + case Qt::Key_Select: + return VK_SELECT; + case Qt::Key_Printer: + return VK_PRINT; + case Qt::Key_Execute: + return VK_EXECUTE; + case Qt::Key_Sleep: + return VK_SLEEP; + case Qt::Key_Period: + return VK_DECIMAL; + case Qt::Key_Play: + return VK_PLAY; + case Qt::Key_Cancel: + return VK_CANCEL; + + case Qt::Key_Forward: + return VK_BROWSER_FORWARD; + case Qt::Key_Refresh: + return VK_BROWSER_REFRESH; + case Qt::Key_Stop: + return VK_BROWSER_STOP; + case Qt::Key_Search: + return VK_BROWSER_SEARCH; + case Qt::Key_Favorites: + return VK_BROWSER_FAVORITES; + case Qt::Key_HomePage: + return VK_BROWSER_HOME; + + case Qt::Key_LaunchMail: + return VK_LAUNCH_MAIL; + case Qt::Key_LaunchMedia: + return VK_LAUNCH_MEDIA_SELECT; + case Qt::Key_Launch0: + return VK_LAUNCH_APP1; + case Qt::Key_Launch1: + return VK_LAUNCH_APP2; + + case Qt::Key_Massyo: + return VK_OEM_FJ_MASSHOU; + case Qt::Key_Touroku: + return VK_OEM_FJ_TOUROKU; + + default: + if (keycode <= 0xFFFF) + return (byte)keycode; + else { + ok = false; + return 0; + } + } +} + +quint32 QHotkeyPrivateWin::nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) +{ + quint32 nMods = 0; + if (modifiers & Qt::ShiftModifier) + nMods |= MOD_SHIFT; + if (modifiers & Qt::ControlModifier) + nMods |= MOD_CONTROL; + if (modifiers & Qt::AltModifier) + nMods |= MOD_ALT; + if (modifiers & Qt::MetaModifier) + nMods |= MOD_WIN; + ok = true; + return nMods; +} + +bool QHotkeyPrivateWin::registerShortcut(QHotkey::NativeShortcut shortcut) +{ + BOOL ok = RegisterHotKey( + NULL, HKEY_ID(shortcut), shortcut.modifier + MOD_NOREPEAT, shortcut.key); + if (ok) + return true; + else { + error = QHotkeyPrivateWin::formatWinError(::GetLastError()); + return false; + } +} + +bool QHotkeyPrivateWin::unregisterShortcut(QHotkey::NativeShortcut shortcut) +{ + BOOL ok = UnregisterHotKey(NULL, HKEY_ID(shortcut)); + if (ok) + return true; + else { + error = QHotkeyPrivateWin::formatWinError(::GetLastError()); + return false; + } +} + +QString QHotkeyPrivateWin::formatWinError(DWORD winError) +{ + wchar_t* buffer = NULL; + DWORD num = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + winError, + 0, + (LPWSTR)&buffer, + 0, + NULL); + if (buffer) { + QString res = QString::fromWCharArray(buffer, num); + LocalFree(buffer); + return res; + } else + return QString(); +} diff --git a/src/core/QHotkey/qhotkey_x11.cpp b/src/core/QHotkey/qhotkey_x11.cpp new file mode 100644 index 00000000..acc0f26d --- /dev/null +++ b/src/core/QHotkey/qhotkey_x11.cpp @@ -0,0 +1,259 @@ +#include "qhotkey.h" +#include "qhotkey_p.h" +#include +#include +#include +#include +#include +#include + +// compability to pre Qt 5.8 +#ifndef Q_FALLTHROUGH +#define Q_FALLTHROUGH() (void)0 +#endif + +class QHotkeyPrivateX11 : public QHotkeyPrivate +{ +public: + // QAbstractNativeEventFilter interface + bool nativeEventFilter(const QByteArray& eventType, + void* message, + long* result) Q_DECL_OVERRIDE; + +protected: + // QHotkeyPrivate interface + quint32 nativeKeycode(Qt::Key keycode, bool& ok) Q_DECL_OVERRIDE; + quint32 nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) Q_DECL_OVERRIDE; + static QString getX11String(Qt::Key keycode); + bool registerShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; + bool unregisterShortcut(QHotkey::NativeShortcut shortcut) Q_DECL_OVERRIDE; + +private: + static const QVector specialModifiers; + static const quint32 validModsMask; + xcb_key_press_event_t prevHandledEvent; + xcb_key_press_event_t prevEvent; + + static QString formatX11Error(Display* display, int errorCode); + + class HotkeyErrorHandler + { + public: + HotkeyErrorHandler(); + ~HotkeyErrorHandler(); + + static bool hasError; + static QString errorString; + + private: + XErrorHandler prevHandler; + + static int handleError(Display* display, XErrorEvent* error); + }; +}; +NATIVE_INSTANCE(QHotkeyPrivateX11) + +bool QHotkeyPrivate::isPlatformSupported() +{ + return QX11Info::isPlatformX11(); +} + +const QVector QHotkeyPrivateX11::specialModifiers = { 0, + Mod2Mask, + LockMask, + (Mod2Mask | + LockMask) }; +const quint32 QHotkeyPrivateX11::validModsMask = + ShiftMask | ControlMask | Mod1Mask | Mod4Mask; + +bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray& eventType, + void* message, + long* result) +{ + Q_UNUSED(eventType) + Q_UNUSED(result) + + auto* genericEvent = static_cast(message); + if (genericEvent->response_type == XCB_KEY_PRESS) { + xcb_key_press_event_t keyEvent = + *static_cast(message); + this->prevEvent = keyEvent; + if (this->prevHandledEvent.response_type == XCB_KEY_RELEASE) { + if (this->prevHandledEvent.time == keyEvent.time) + return false; + } + this->activateShortcut( + { keyEvent.detail, + keyEvent.state & QHotkeyPrivateX11::validModsMask }); + } else if (genericEvent->response_type == XCB_KEY_RELEASE) { + xcb_key_release_event_t keyEvent = + *static_cast(message); + this->prevEvent = keyEvent; + QTimer::singleShot(50, [this, keyEvent] { + if (this->prevEvent.time == keyEvent.time && + this->prevEvent.response_type == keyEvent.response_type && + this->prevEvent.detail == keyEvent.detail) { + this->releaseShortcut( + { keyEvent.detail, + keyEvent.state & QHotkeyPrivateX11::validModsMask }); + } + }); + this->prevHandledEvent = keyEvent; + } + + return false; +} + +QString QHotkeyPrivateX11::getX11String(Qt::Key keycode) +{ + switch (keycode) { + + case Qt::Key_MediaLast: + case Qt::Key_MediaPrevious: + return QStringLiteral("XF86AudioPrev"); + case Qt::Key_MediaNext: + return QStringLiteral("XF86AudioNext"); + case Qt::Key_MediaPause: + case Qt::Key_MediaPlay: + case Qt::Key_MediaTogglePlayPause: + return QStringLiteral("XF86AudioPlay"); + case Qt::Key_MediaRecord: + return QStringLiteral("XF86AudioRecord"); + case Qt::Key_MediaStop: + return QStringLiteral("XF86AudioStop"); + default: + return QKeySequence(keycode).toString(QKeySequence::NativeText); + } +} + +quint32 QHotkeyPrivateX11::nativeKeycode(Qt::Key keycode, bool& ok) +{ + QString keyString = getX11String(keycode); + + KeySym keysym = XStringToKeysym(keyString.toLatin1().constData()); + if (keysym == NoSymbol) { + // not found -> just use the key + if (keycode <= 0xFFFF) + keysym = keycode; + else + return 0; + } + + if (QX11Info::isPlatformX11()) { + auto res = XKeysymToKeycode(QX11Info::display(), keysym); + if (res != 0) + ok = true; + return res; + } + return 0; +} + +quint32 QHotkeyPrivateX11::nativeModifiers(Qt::KeyboardModifiers modifiers, + bool& ok) +{ + quint32 nMods = 0; + if (modifiers & Qt::ShiftModifier) + nMods |= ShiftMask; + if (modifiers & Qt::ControlModifier) + nMods |= ControlMask; + if (modifiers & Qt::AltModifier) + nMods |= Mod1Mask; + if (modifiers & Qt::MetaModifier) + nMods |= Mod4Mask; + ok = true; + return nMods; +} + +bool QHotkeyPrivateX11::registerShortcut(QHotkey::NativeShortcut shortcut) +{ + Display* display = QX11Info::display(); + if (!display || !QX11Info::isPlatformX11()) + return false; + + HotkeyErrorHandler errorHandler; + for (quint32 specialMod : QHotkeyPrivateX11::specialModifiers) { + XGrabKey(display, + shortcut.key, + shortcut.modifier | specialMod, + DefaultRootWindow(display), + True, + GrabModeAsync, + GrabModeAsync); + } + XSync(display, False); + + if (errorHandler.hasError) { + error = errorHandler.errorString; + this->unregisterShortcut(shortcut); + return false; + } + return true; +} + +bool QHotkeyPrivateX11::unregisterShortcut(QHotkey::NativeShortcut shortcut) +{ + Display* display = QX11Info::display(); + if (!display) + return false; + + HotkeyErrorHandler errorHandler; + for (quint32 specialMod : QHotkeyPrivateX11::specialModifiers) { + XUngrabKey(display, + shortcut.key, + shortcut.modifier | specialMod, + XDefaultRootWindow(display)); + } + XSync(display, False); + + if (HotkeyErrorHandler::hasError) { + error = HotkeyErrorHandler::errorString; + return false; + } + return true; +} + +QString QHotkeyPrivateX11::formatX11Error(Display* display, int errorCode) +{ + char errStr[256]; + XGetErrorText(display, errorCode, errStr, 256); + return QString::fromLatin1(errStr); +} + +// ---------- QHotkeyPrivateX11::HotkeyErrorHandler implementation ---------- + +bool QHotkeyPrivateX11::HotkeyErrorHandler::hasError = false; +QString QHotkeyPrivateX11::HotkeyErrorHandler::errorString; + +QHotkeyPrivateX11::HotkeyErrorHandler::HotkeyErrorHandler() +{ + prevHandler = XSetErrorHandler(&HotkeyErrorHandler::handleError); +} + +QHotkeyPrivateX11::HotkeyErrorHandler::~HotkeyErrorHandler() +{ + XSetErrorHandler(prevHandler); + hasError = false; + errorString.clear(); +} + +int QHotkeyPrivateX11::HotkeyErrorHandler::handleError(Display* display, + XErrorEvent* error) +{ + switch (error->error_code) { + case BadAccess: + case BadValue: + case BadWindow: + if (error->request_code == 33 || // grab key + error->request_code == 34) { // ungrab key + hasError = true; + errorString = + QHotkeyPrivateX11::formatX11Error(display, error->error_code); + return 1; + } + Q_FALLTHROUGH(); + // fall through + default: + return 0; + } +} diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 7003c84c..2e34fe10 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -17,6 +17,7 @@ #include "controller.h" #include "src/config/configwindow.h" +#include "src/core/QHotkey/QHotkey" #include "src/utils/confighandler.h" #include "src/utils/history.h" #include "src/utils/screengrabber.h" @@ -30,22 +31,42 @@ #include #include #include +#include #include +#include +#include #include +#include +#include +#include #include #ifdef Q_OS_WIN #include "src/core/globalshortcutfilter.h" #endif +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) +#include +#include +#endif + // Controller is the core component of Flameshot, creates the trayIcon and // launches the capture widget Controller::Controller() : m_captureWindow(nullptr) + , m_history(nullptr) + , m_trayIconMenu(nullptr) + , m_networkCheckUpdates(nullptr) + , m_showCheckAppUpdateStatus(false) +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + , m_HotkeyScreenshotCapture(nullptr) + , m_HotkeyScreenshotHistory(nullptr) +#endif { - m_history = nullptr; - + m_appLatestVersion = QStringLiteral(APP_VERSION).replace("v", ""); qApp->setQuitOnLastWindowClosed(false); // set default shortcusts if not set yet @@ -68,11 +89,36 @@ Controller::Controller() QString StyleSheet = CaptureButton::globalStyleSheet(); qApp->setStyleSheet(StyleSheet); + +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Try to take a test screenshot, MacOS will request a "Screen Recording" + // permissions on the first run. Otherwise it will be hidden under the + // CaptureWidget + QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + currentScreen->grabWindow(QApplication::desktop()->winId(), 0, 0, 1, 1); + + // set global shortcuts for MacOS + m_HotkeyScreenshotCapture = + new QHotkey(QKeySequence("Ctrl+Alt+Shift+4"), true, this); + QObject::connect(m_HotkeyScreenshotCapture, + &QHotkey::activated, + qApp, + [&]() { this->startVisualCapture(); }); + m_HotkeyScreenshotHistory = + new QHotkey(QKeySequence("Ctrl+Alt+Shift+H"), true, this); + QObject::connect(m_HotkeyScreenshotHistory, + &QHotkey::activated, + qApp, + [&]() { this->showRecentScreenshots(); }); +#endif + getLatestAvailableVersion(); } Controller::~Controller() { delete m_history; + delete m_trayIconMenu; } Controller* Controller::getInstance() @@ -89,6 +135,67 @@ void Controller::enableExports() this, &Controller::captureFailed, this, &Controller::handleCaptureFailed); } +void Controller::getLatestAvailableVersion() +{ + // This features is required for MacOS and Windows user and for Linux users + // who installed Flameshot not from the repository. + m_networkCheckUpdates = new QNetworkAccessManager(this); + QNetworkRequest requestCheckUpdates(QUrl(FLAMESHOT_APP_VERSION_URL)); + connect(m_networkCheckUpdates, + &QNetworkAccessManager::finished, + this, + &Controller::handleReplyCheckUpdates); + m_networkCheckUpdates->get(requestCheckUpdates); + + // check for updates each 24 hours + doLater(1000 * 60 * 60 * 24, this, [this]() { + this->getLatestAvailableVersion(); + }); +} + +void Controller::handleReplyCheckUpdates(QNetworkReply* reply) +{ + if (reply->error() == QNetworkReply::NoError) { + QJsonDocument response = QJsonDocument::fromJson(reply->readAll()); + QJsonObject json = response.object(); + m_appLatestVersion = json["tag_name"].toString().replace("v", ""); + if (QStringLiteral(APP_VERSION) + .replace("v", "") + .compare(m_appLatestVersion) < 0) { + m_appLatestUrl = json["html_url"].toString(); + QString newVersion = + tr("New version %1 is available").arg(m_appLatestVersion); + m_appUpdates->setText(newVersion); + if (m_showCheckAppUpdateStatus) { + sendTrayNotification(newVersion, "Flameshot"); + QDesktopServices::openUrl(QUrl(m_appLatestUrl)); + } + } else if (m_showCheckAppUpdateStatus) { + sendTrayNotification(tr("You have the latest version"), + "Flameshot"); + } + } else { + qWarning() << "Failed to get information about the latest version. " + << reply->errorString(); + if (m_showCheckAppUpdateStatus) { + sendTrayNotification( + tr("Failed to get information about the latest version."), + "Flameshot"); + } + } + m_showCheckAppUpdateStatus = false; +} + +void Controller::appUpdates() +{ + if (m_appLatestUrl.isEmpty()) { + m_showCheckAppUpdateStatus = true; + getLatestAvailableVersion(); + } else { + QDesktopServices::openUrl(QUrl(m_appLatestUrl)); + } +} + void Controller::requestCapture(const CaptureRequest& request) { uint id = request.id(); @@ -150,10 +257,21 @@ void Controller::startVisualCapture(const uint id, #ifdef Q_OS_WIN m_captureWindow->show(); +#elif (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // In "Emulate fullscreen mode" + m_captureWindow->showFullScreen(); + m_captureWindow->activateWindow(); + m_captureWindow->raise(); #else m_captureWindow->showFullScreen(); - // m_captureWindow->show(); // Debug #endif + if (!m_appLatestUrl.isEmpty() && + ConfigHandler().ignoreUpdateToVersion().compare( + m_appLatestVersion) < 0) { + m_captureWindow->showAppUpdateNotification(m_appLatestVersion, + m_appLatestUrl); + } } else { emit captureFailed(id); } @@ -183,6 +301,11 @@ void Controller::openConfigWindow() if (!m_configWindow) { m_configWindow = new ConfigWindow(); m_configWindow->show(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + m_configWindow->activateWindow(); + m_configWindow->raise(); +#endif } } @@ -191,6 +314,11 @@ void Controller::openInfoWindow() { if (!m_infoWindow) { m_infoWindow = new InfoWindow(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + m_infoWindow->activateWindow(); + m_infoWindow->raise(); +#endif } } @@ -200,6 +328,11 @@ void Controller::openLauncherWindow() m_launcherWindow = new CaptureLauncher(); } m_launcherWindow->show(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + m_launcherWindow->activateWindow(); + m_launcherWindow->raise(); +#endif } void Controller::enableTrayIcon() @@ -207,7 +340,7 @@ void Controller::enableTrayIcon() if (m_trayIcon) { return; } - QMenu* trayIconMenu = new QMenu(); + m_trayIconMenu = new QMenu(); ConfigHandler().setDisabledTrayIcon(false); QAction* captureAction = new QAction(tr("&Take Screenshot"), this); @@ -225,6 +358,10 @@ void Controller::enableTrayIcon() configAction, &QAction::triggered, this, &Controller::openConfigWindow); QAction* infoAction = new QAction(tr("&About"), this); connect(infoAction, &QAction::triggered, this, &Controller::openInfoWindow); + + m_appUpdates = new QAction(tr("Check for updates"), this); + connect(m_appUpdates, &QAction::triggered, this, &Controller::appUpdates); + QAction* quitAction = new QAction(tr("&Quit"), this); connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); @@ -234,29 +371,60 @@ void Controller::enableTrayIcon() recentAction, SIGNAL(triggered()), this, SLOT(showRecentScreenshots())); // generate menu - trayIconMenu->addAction(captureAction); - trayIconMenu->addAction(launcherAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(recentAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(configAction); - trayIconMenu->addAction(infoAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(quitAction); + m_trayIconMenu->addAction(captureAction); + m_trayIconMenu->addAction(launcherAction); + m_trayIconMenu->addSeparator(); + m_trayIconMenu->addAction(recentAction); + m_trayIconMenu->addSeparator(); + m_trayIconMenu->addAction(configAction); + m_trayIconMenu->addSeparator(); + m_trayIconMenu->addAction(m_appUpdates); + m_trayIconMenu->addAction(infoAction); + m_trayIconMenu->addSeparator(); + m_trayIconMenu->addAction(quitAction); m_trayIcon = new QSystemTrayIcon(); m_trayIcon->setToolTip(QStringLiteral("Flameshot")); - m_trayIcon->setContextMenu(trayIconMenu); +#if defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) + // Because of the following issues on MacOS "Catalina": + // https://bugreports.qt.io/browse/QTBUG-86393 + // https://developer.apple.com/forums/thread/126072 + auto currentMacOsVersion = QOperatingSystemVersion::current(); + if (currentMacOsVersion >= currentMacOsVersion.MacOSBigSur) { + m_trayIcon->setContextMenu(m_trayIconMenu); + } +#else + m_trayIcon->setContextMenu(m_trayIconMenu); +#endif QIcon trayicon = QIcon::fromTheme("flameshot-tray", QIcon(":img/app/flameshot.png")); m_trayIcon->setIcon(trayicon); +#if defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) + if (currentMacOsVersion < currentMacOsVersion.MacOSBigSur) { + // Because of the following issues on MacOS "Catalina": + // https://bugreports.qt.io/browse/QTBUG-86393 + // https://developer.apple.com/forums/thread/126072 + auto trayIconActivated = [this](QSystemTrayIcon::ActivationReason r) { + if (m_trayIconMenu->isVisible()) { + m_trayIconMenu->hide(); + } else { + m_trayIconMenu->popup(QCursor::pos()); + } + }; + connect( + m_trayIcon, &QSystemTrayIcon::activated, this, trayIconActivated); + } +#else auto trayIconActivated = [this](QSystemTrayIcon::ActivationReason r) { if (r == QSystemTrayIcon::Trigger) { startVisualCapture(); } }; connect(m_trayIcon, &QSystemTrayIcon::activated, this, trayIconActivated); +#endif #ifdef Q_OS_WIN // Ensure proper removal of tray icon when program quits on Windows. @@ -310,6 +478,11 @@ void Controller::showRecentScreenshots() } m_history->loadHistory(); m_history->show(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + m_history->activateWindow(); + m_history->raise(); +#endif } void Controller::startFullscreenCapture(const uint id) diff --git a/src/core/controller.h b/src/core/controller.h index ac5445b1..8c7a4a84 100644 --- a/src/core/controller.h +++ b/src/core/controller.h @@ -19,6 +19,7 @@ #include "src/core/capturerequest.h" #include +#include #include #include #include @@ -31,6 +32,12 @@ class InfoWindow; class QSystemTrayIcon; class CaptureLauncher; class HistoryWidget; +class QNetworkAccessManager; +class QNetworkReply; +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) +class QHotkey; +#endif using lambda = std::function; class Controller : public QObject @@ -56,6 +63,7 @@ public slots: void openConfigWindow(); void openInfoWindow(); + void appUpdates(); void openLauncherWindow(); void enableTrayIcon(); void disableTrayIcon(); @@ -77,13 +85,22 @@ private slots: void handleCaptureTaken(uint id, QPixmap p, QRect selection); void handleCaptureFailed(uint id); + void handleReplyCheckUpdates(QNetworkReply* reply); + private: Controller(); + void getLatestAvailableVersion(); // replace QTimer::singleShot introduced in Qt 5.4 // the actual target Qt version is 5.3 void doLater(int msec, QObject* receiver, lambda func); + // class members + QAction* m_appUpdates; + QString m_appLatestUrl; + QString m_appLatestVersion; + bool m_showCheckAppUpdateStatus; + QMap m_requestMap; QPointer m_captureWindow; QPointer m_infoWindow; @@ -92,4 +109,12 @@ private: QPointer m_trayIcon; HistoryWidget* m_history; + QMenu* m_trayIconMenu; + + QNetworkAccessManager* m_networkCheckUpdates; +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QHotkey* m_HotkeyScreenshotCapture; + QHotkey* m_HotkeyScreenshotHistory; +#endif }; diff --git a/src/main.cpp b/src/main.cpp index d93012d8..21fae96e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -93,7 +93,8 @@ int main(int argc, char* argv[]) app.setOrganizationName(QStringLiteral("flameshot")); auto c = Controller::getInstance(); -#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) || defined(Q_OS_WIN)) new FlameshotDBusAdapter(c); QDBusConnection dbus = QDBusConnection::sessionBus(); if (!dbus.isConnected()) { @@ -109,7 +110,8 @@ int main(int argc, char* argv[]) return app.exec(); } -#ifndef Q_OS_WIN +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) || defined(Q_OS_WIN)) /*--------------| * CLI parsing | * ------------*/ diff --git a/src/tools/abstractactiontool.h b/src/tools/abstractactiontool.h index 0c973c91..1dba903c 100644 --- a/src/tools/abstractactiontool.h +++ b/src/tools/abstractactiontool.h @@ -36,9 +36,6 @@ public: void paintMousePreview(QPainter& painter, const CaptureContext& context) override; -protected: - virtual ToolType nameID() const = 0; - public slots: void drawEnd(const QPoint& p) override; void drawMove(const QPoint& p) override; diff --git a/src/tools/abstractpathtool.cpp b/src/tools/abstractpathtool.cpp index 67a8b6d2..c4a771b9 100644 --- a/src/tools/abstractpathtool.cpp +++ b/src/tools/abstractpathtool.cpp @@ -46,9 +46,16 @@ bool AbstractPathTool::showMousePreview() const void AbstractPathTool::undo(QPixmap& pixmap) { QPainter p(&pixmap); - const int val = m_thickness + m_padding; - QRect area = m_backupArea + QMargins(val, val, val, val); - p.drawPixmap(area.intersected(pixmap.rect()).topLeft(), m_pixmapBackup); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Not sure how will it work on 4k and fullHd on Linux or Windows with a + // capture of different displays with different DPI, so let it be MacOS + // specific only. + const qreal pixelRatio = pixmap.devicePixelRatio(); + p.drawPixmap(backupRect(pixmap).topLeft() / pixelRatio, m_pixmapBackup); +#else + p.drawPixmap(backupRect(pixmap).topLeft(), m_pixmapBackup); +#endif } void AbstractPathTool::drawEnd(const QPoint& p) @@ -73,9 +80,30 @@ void AbstractPathTool::thicknessChanged(const int th) void AbstractPathTool::updateBackup(const QPixmap& pixmap) { + m_pixmapBackup = pixmap.copy(backupRect(pixmap)); +} + +QRect AbstractPathTool::backupRect(const QPixmap& pixmap) const +{ + const QRect& limits = pixmap.rect(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Not sure how will it work on 4k and fullHd on Linux or Windows with a + // capture of different displays with different DPI, so let it be MacOS + // specific only. + const qreal pixelRatio = pixmap.devicePixelRatio(); + const int val = (m_thickness + m_padding) * pixelRatio; + QRect r = m_backupArea.normalized(); + if (1 != pixelRatio) { + r.moveTo(r.topLeft() * pixelRatio); + r.setSize(r.size() * pixelRatio); + } +#else const int val = m_thickness + m_padding; - QRect area = m_backupArea.normalized() + QMargins(val, val, val, val); - m_pixmapBackup = pixmap.copy(area); + QRect r = m_backupArea.normalized(); +#endif + r += QMargins(val, val, val, val); + return r.intersected(limits); } void AbstractPathTool::addPoint(const QPoint& point) diff --git a/src/tools/abstractpathtool.h b/src/tools/abstractpathtool.h index f1f4cfe3..4b80016f 100644 --- a/src/tools/abstractpathtool.h +++ b/src/tools/abstractpathtool.h @@ -41,8 +41,7 @@ public slots: protected: void updateBackup(const QPixmap& pixmap); void addPoint(const QPoint& point); - - virtual ToolType nameID() const = 0; + QRect backupRect(const QPixmap& pixmap) const; QPixmap m_pixmapBackup; QRect m_backupArea; diff --git a/src/tools/abstracttwopointtool.cpp b/src/tools/abstracttwopointtool.cpp index ab54291a..681d8312 100644 --- a/src/tools/abstracttwopointtool.cpp +++ b/src/tools/abstracttwopointtool.cpp @@ -16,6 +16,9 @@ // along with Flameshot. If not, see . #include "abstracttwopointtool.h" +#include +#include +#include #include namespace { @@ -71,7 +74,16 @@ bool AbstractTwoPointTool::showMousePreview() const void AbstractTwoPointTool::undo(QPixmap& pixmap) { QPainter p(&pixmap); - p.drawPixmap(backupRect(pixmap.rect()).topLeft(), m_pixmapBackup); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Not sure how will it work on 4k and fullHd on Linux or Windows with a + // capture of different displays with different DPI, so let it be MacOS + // specific only. + const qreal pixelRatio = pixmap.devicePixelRatio(); + p.drawPixmap(backupRect(pixmap).topLeft() / pixelRatio, m_pixmapBackup); +#else + p.drawPixmap(backupRect(pixmap).topLeft(), m_pixmapBackup); +#endif if (this->nameID() == ToolType::CIRCLECOUNT) { emit requestAction(REQ_DECREMENT_CIRCLE_COUNT); } @@ -104,13 +116,27 @@ void AbstractTwoPointTool::thicknessChanged(const int th) void AbstractTwoPointTool::updateBackup(const QPixmap& pixmap) { - m_pixmapBackup = pixmap.copy(backupRect(pixmap.rect())); + m_pixmapBackup = pixmap.copy(backupRect(pixmap)); } -QRect AbstractTwoPointTool::backupRect(const QRect& limits) const +QRect AbstractTwoPointTool::backupRect(const QPixmap& pixmap) const { + const QRect& limits = pixmap.rect(); QRect r = QRect(m_points.first, m_points.second).normalized(); - const int val = m_thickness + m_padding; +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Not sure how will it work on 4k and fullHd on Linux or Windows with a + // capture of different displays with different DPI, so let it be MacOS + // specific only. + const qreal pixelRatio = pixmap.devicePixelRatio(); + if (1 != pixelRatio) { + r.moveTo(r.topLeft() * pixelRatio); + r.setSize(r.size() * pixelRatio); + } + const int val = (m_thickness + m_padding) * pixelRatio; +#else + const int val = (m_thickness + m_padding); +#endif r += QMargins(val, val, val, val); return r.intersected(limits); } diff --git a/src/tools/abstracttwopointtool.h b/src/tools/abstracttwopointtool.h index 061807a9..2bfe46e8 100644 --- a/src/tools/abstracttwopointtool.h +++ b/src/tools/abstracttwopointtool.h @@ -41,7 +41,7 @@ public slots: protected: void updateBackup(const QPixmap& pixmap); - QRect backupRect(const QRect& limits) const; + QRect backupRect(const QPixmap& pixmap) const; QPixmap m_pixmapBackup; QPair m_points; @@ -53,8 +53,6 @@ protected: bool m_supportsOrthogonalAdj = false; bool m_supportsDiagonalAdj = false; - virtual ToolType nameID() const = 0; - private: QPoint adjustedVector(QPoint v) const; }; diff --git a/src/tools/copy/copytool.h b/src/tools/copy/copytool.h index f8fe081b..20f1f243 100644 --- a/src/tools/copy/copytool.h +++ b/src/tools/copy/copytool.h @@ -25,7 +25,7 @@ class CopyTool : public AbstractActionTool public: explicit CopyTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/exit/exittool.h b/src/tools/exit/exittool.h index 109b3e32..be586995 100644 --- a/src/tools/exit/exittool.h +++ b/src/tools/exit/exittool.h @@ -25,7 +25,7 @@ class ExitTool : public AbstractActionTool public: explicit ExitTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/launcher/applaunchertool.h b/src/tools/launcher/applaunchertool.h index 9a7513a7..9da32d00 100644 --- a/src/tools/launcher/applaunchertool.h +++ b/src/tools/launcher/applaunchertool.h @@ -25,7 +25,7 @@ class AppLauncher : public AbstractActionTool public: explicit AppLauncher(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/move/movetool.h b/src/tools/move/movetool.h index dd36d98d..76e1f7f9 100644 --- a/src/tools/move/movetool.h +++ b/src/tools/move/movetool.h @@ -25,7 +25,7 @@ class MoveTool : public AbstractActionTool public: explicit MoveTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/pin/pintool.h b/src/tools/pin/pintool.h index 0192f53d..ec781be2 100644 --- a/src/tools/pin/pintool.h +++ b/src/tools/pin/pintool.h @@ -25,7 +25,7 @@ class PinTool : public AbstractActionTool public: explicit PinTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/pixelate/pixelatetool.cpp b/src/tools/pixelate/pixelatetool.cpp index e74d1de8..1fa9c67f 100644 --- a/src/tools/pixelate/pixelatetool.cpp +++ b/src/tools/pixelate/pixelatetool.cpp @@ -22,7 +22,6 @@ #include #include #include -#include PixelateTool::PixelateTool(QObject* parent) : AbstractTwoPointTool(parent) @@ -65,13 +64,12 @@ void PixelateTool::process(QPainter& painter, QPoint& p0 = m_points.first; QPoint& p1 = m_points.second; QRect selection = QRect(p0, p1).normalized(); + auto pixelRatio = pixmap.devicePixelRatio(); + QRect selectionScaled = + QRect(p0 * pixelRatio, p1 * pixelRatio).normalized(); // If thickness is less than 1, use old blur process if (m_thickness <= 1) { - auto pixelRatio = pixmap.devicePixelRatio(); - - QRect selectionScaled = - QRect(p0 * pixelRatio, p1 * pixelRatio).normalized(); QGraphicsBlurEffect* blur = new QGraphicsBlurEffect; blur->setBlurRadius(10); @@ -92,7 +90,7 @@ void PixelateTool::process(QPainter& painter, int height = selection.height() * (0.5 / qMax(1, m_thickness)); QSize size = QSize(qMax(width, 1), qMax(height, 1)); - QPixmap t = pixmap.copy(selection); + QPixmap t = pixmap.copy(selectionScaled); t = t.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); t = t.scaled(selection.width(), selection.height()); painter.drawImage(selection, t.toImage()); diff --git a/src/tools/redo/redotool.h b/src/tools/redo/redotool.h index 4c0791a0..b23b4bc9 100644 --- a/src/tools/redo/redotool.h +++ b/src/tools/redo/redotool.h @@ -25,7 +25,7 @@ class RedoTool : public AbstractActionTool public: explicit RedoTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/save/savetool.cpp b/src/tools/save/savetool.cpp index 43c194b0..ac5eae54 100644 --- a/src/tools/save/savetool.cpp +++ b/src/tools/save/savetool.cpp @@ -18,6 +18,12 @@ #include "savetool.h" #include "src/utils/screenshotsaver.h" #include +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) +#include "src/widgets/capture/capturewidget.h" +#include +#include +#endif SaveTool::SaveTool(QObject* parent) : AbstractActionTool(parent) @@ -55,6 +61,17 @@ CaptureTool* SaveTool::copy(QObject* parent) void SaveTool::pressed(const CaptureContext& context) { +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + for (QWidget* widget : qApp->topLevelWidgets()) { + QString className(widget->metaObject()->className()); + if (0 == + className.compare(CaptureWidget::staticMetaObject.className())) { + widget->showNormal(); + break; + } + } +#endif if (context.savePath.isEmpty()) { emit requestAction(REQ_HIDE_GUI); bool ok = ScreenshotSaver().saveToFilesystemGUI( diff --git a/src/tools/save/savetool.h b/src/tools/save/savetool.h index 3c79e442..64f6306b 100644 --- a/src/tools/save/savetool.h +++ b/src/tools/save/savetool.h @@ -25,7 +25,7 @@ class SaveTool : public AbstractActionTool public: explicit SaveTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/selection/selectiontool.h b/src/tools/selection/selectiontool.h index f8448dbd..a7151da3 100644 --- a/src/tools/selection/selectiontool.h +++ b/src/tools/selection/selectiontool.h @@ -25,7 +25,7 @@ class SelectionTool : public AbstractTwoPointTool public: explicit SelectionTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/sizeindicator/sizeindicatortool.h b/src/tools/sizeindicator/sizeindicatortool.h index 26fca63c..57aad37f 100644 --- a/src/tools/sizeindicator/sizeindicatortool.h +++ b/src/tools/sizeindicator/sizeindicatortool.h @@ -25,7 +25,7 @@ class SizeIndicatorTool : public AbstractActionTool public: explicit SizeIndicatorTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/tools/text/texttool.cpp b/src/tools/text/texttool.cpp index c791b20d..7fea1bdf 100644 --- a/src/tools/text/texttool.cpp +++ b/src/tools/text/texttool.cpp @@ -130,7 +130,16 @@ CaptureTool* TextTool::copy(QObject* parent) void TextTool::undo(QPixmap& pixmap) { QPainter p(&pixmap); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Not sure how will it work on 4k and fullHd on Linux or Windows with a + // capture of different displays with different DPI, so let it be MacOS + // specific only. + const qreal pixelRatio = pixmap.devicePixelRatio(); + p.drawPixmap(backupRect(pixmap).topLeft() / pixelRatio, m_pixmapBackup); +#else p.drawPixmap(m_backupArea.topLeft(), m_pixmapBackup); +#endif } void TextTool::process(QPainter& painter, @@ -144,12 +153,32 @@ void TextTool::process(QPainter& painter, QSize size(fm.boundingRect(QRect(), 0, m_text).size()); m_backupArea.setSize(size); if (recordUndo) { - m_pixmapBackup = pixmap.copy(m_backupArea + QMargins(0, 0, 5, 5)); + m_pixmapBackup = pixmap.copy(backupRect(pixmap)); } // draw text painter.setFont(m_font); painter.setPen(m_color); - painter.drawText(m_backupArea + QMargins(-5, -5, 5, 5), m_text); + const int val = 5; + painter.drawText(m_backupArea + QMargins(-val, -val, val, val), m_text); +} + +QRect TextTool::backupRect(const QPixmap& pixmap) const +{ + const QRect& limits = pixmap.rect(); + QRect r = m_backupArea.normalized(); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + const qreal pixelRatio = pixmap.devicePixelRatio(); + const int val = 5 * pixelRatio; + if (1 != pixelRatio) { + r.moveTo(r.topLeft() * pixelRatio); + r.setSize(r.size() * pixelRatio); + } +#else + const int val = 5; +#endif + r += QMargins(0, 0, val, val); + return r.intersected(limits); } void TextTool::paintMousePreview(QPainter& painter, diff --git a/src/tools/text/texttool.h b/src/tools/text/texttool.h index 136bf05e..11ff875a 100644 --- a/src/tools/text/texttool.h +++ b/src/tools/text/texttool.h @@ -51,6 +51,7 @@ public: protected: ToolType nameID() const override; + QRect backupRect(const QPixmap& pixmap) const; public slots: void drawEnd(const QPoint& p) override; diff --git a/src/tools/toolfactory.cpp b/src/tools/toolfactory.cpp index 6ca311e5..8f3e4fb1 100644 --- a/src/tools/toolfactory.cpp +++ b/src/tools/toolfactory.cpp @@ -92,9 +92,12 @@ CaptureTool* ToolFactory::CreateTool(CaptureToolButton::ButtonType t, case CaptureToolButton::TYPE_REDO: tool = new RedoTool(parent); break; +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) case CaptureToolButton::TYPE_OPEN_APP: tool = new AppLauncher(parent); break; +#endif case CaptureToolButton::TYPE_PIXELATE: tool = new PixelateTool(parent); break; @@ -107,7 +110,6 @@ CaptureTool* ToolFactory::CreateTool(CaptureToolButton::ButtonType t, case CaptureToolButton::TYPE_CIRCLECOUNT: tool = new CircleCountTool(parent); break; - default: tool = nullptr; break; diff --git a/src/tools/undo/undotool.h b/src/tools/undo/undotool.h index 140407ea..52292a19 100644 --- a/src/tools/undo/undotool.h +++ b/src/tools/undo/undotool.h @@ -25,7 +25,7 @@ class UndoTool : public AbstractActionTool public: explicit UndoTool(QObject* parent = nullptr); - bool closeOnButtonPressed() const; + bool closeOnButtonPressed() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; diff --git a/src/utils/confighandler.cpp b/src/utils/confighandler.cpp index e37ee35d..faa83f75 100644 --- a/src/utils/confighandler.cpp +++ b/src/utils/confighandler.cpp @@ -60,7 +60,10 @@ QVector ConfigHandler::getButtons() << CaptureToolButton::TYPE_COPY << CaptureToolButton::TYPE_SAVE << CaptureToolButton::TYPE_EXIT << CaptureToolButton::TYPE_IMAGEUPLOADER +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) << CaptureToolButton::TYPE_OPEN_APP +#endif << CaptureToolButton::TYPE_PIN << CaptureToolButton::TYPE_TEXT << CaptureToolButton::TYPE_CIRCLECOUNT; } @@ -230,6 +233,16 @@ void ConfigHandler::setShowSidePanelButton(const bool showSidePanelButton) showSidePanelButton); } +void ConfigHandler::setIgnoreUpdateToVersion(const QString& text) +{ + m_settings.setValue(QStringLiteral("ignoreUpdateToVersion"), text); +} + +QString ConfigHandler::ignoreUpdateToVersion() +{ + return m_settings.value(QStringLiteral("ignoreUpdateToVersion")).toString(); +} + bool ConfigHandler::desktopNotificationValue() { bool res = true; @@ -559,3 +572,28 @@ const QString& ConfigHandler::shortcut(const QString& shortcutName) m_settings.endGroup(); return m_strRes; } + +void ConfigHandler::setValue(const QString& group, + const QString& key, + const QVariant& value) +{ + if (!group.isEmpty()) { + m_settings.beginGroup(group); + } + m_settings.setValue(key, value); + if (!group.isEmpty()) { + m_settings.endGroup(); + } +} + +QVariant& ConfigHandler::value(const QString& group, const QString& key) +{ + if (!group.isEmpty()) { + m_settings.beginGroup(group); + } + m_varRes = m_settings.value(key); + if (!group.isEmpty()) { + m_settings.endGroup(); + } + return m_varRes; +} diff --git a/src/utils/confighandler.h b/src/utils/confighandler.h index 1c03435e..3524c086 100644 --- a/src/utils/confighandler.h +++ b/src/utils/confighandler.h @@ -20,6 +20,7 @@ #include "src/widgets/capture/capturetoolbutton.h" #include #include +#include #include class ConfigHandler @@ -88,6 +89,9 @@ public: void setDefaults(); void setAllTheButtons(); + void setIgnoreUpdateToVersion(const QString& text); + QString ignoreUpdateToVersion(); + QVector shortcuts(); void setShortcutsDefault(); bool setShortcut(const QString&, const QString&); @@ -95,8 +99,14 @@ public: QString configFilePath() const; + void setValue(const QString& group, + const QString& key, + const QVariant& value); + QVariant& value(const QString& group, const QString& key); + private: QString m_strRes; + QVariant m_varRes; QSettings m_settings; QVector m_shortcuts; diff --git a/src/utils/configshortcuts.cpp b/src/utils/configshortcuts.cpp index 61a0095d..d01d6a48 100644 --- a/src/utils/configshortcuts.cpp +++ b/src/utils/configshortcuts.cpp @@ -58,10 +58,18 @@ const QVector& ConfigShortcuts::captureShortcutsDefault( m_shortcuts << (QStringList() << "" << QObject::tr("Quit capture") << QKeySequence(Qt::Key_Escape).toString()); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + m_shortcuts << (QStringList() + << "" << QObject::tr("Screenshot history") << "⇧⌘⌥H"); + m_shortcuts << (QStringList() + << "" << QObject::tr("Capture screen") << "⇧⌘⌥4"); +#else m_shortcuts << (QStringList() << "" << QObject::tr("Screenshot history") << "Shift+Print Screen"); m_shortcuts << (QStringList() << "" << QObject::tr("Capture screen") << "Print Screen"); +#endif m_shortcuts << (QStringList() << "" << QObject::tr("Show color picker") << "Right Click"); m_shortcuts << (QStringList() @@ -116,9 +124,12 @@ const QKeySequence& ConfigShortcuts::captureShortcutDefault( case CaptureToolButton::ButtonType::TYPE_IMAGEUPLOADER: m_ks = QKeySequence(Qt::Key_Return); break; +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) case CaptureToolButton::ButtonType::TYPE_OPEN_APP: m_ks = QKeySequence(Qt::CTRL + Qt::Key_O); break; +#endif case CaptureToolButton::ButtonType::TYPE_PIXELATE: m_ks = QKeySequence(Qt::Key_B); break; diff --git a/src/utils/history.cpp b/src/utils/history.cpp index 35b48567..83844a7f 100644 --- a/src/utils/history.cpp +++ b/src/utils/history.cpp @@ -30,9 +30,20 @@ const QString& History::path() void History::save(const QPixmap& pixmap, const QString& fileName) { + // scale preview only in local disk + QPixmap pixmapScaled = QPixmap(pixmap); + if (pixmap.height() / HISTORYPIXMAP_MAX_PREVIEW_HEIGHT >= + pixmap.width() / HISTORYPIXMAP_MAX_PREVIEW_WIDTH) { + pixmapScaled = pixmap.scaledToHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); + } else { + pixmapScaled = pixmap.scaledToWidth(HISTORYPIXMAP_MAX_PREVIEW_WIDTH); + } + + // save preview QFile file(path() + fileName); file.open(QIODevice::WriteOnly); - pixmap.save(&file, "PNG"); + pixmapScaled.save(&file, "PNG"); + history(); } diff --git a/src/utils/history.h b/src/utils/history.h index a4569175..a0d7266b 100644 --- a/src/utils/history.h +++ b/src/utils/history.h @@ -3,6 +3,9 @@ #define HISTORY_MAX_SIZE 25 +#define HISTORYPIXMAP_MAX_PREVIEW_WIDTH 160 +#define HISTORYPIXMAP_MAX_PREVIEW_HEIGHT 90 + #include #include #include diff --git a/src/utils/screengrabber.cpp b/src/utils/screengrabber.cpp index 03c76657..4e970ba9 100644 --- a/src/utils/screengrabber.cpp +++ b/src/utils/screengrabber.cpp @@ -37,7 +37,18 @@ ScreenGrabber::ScreenGrabber(QObject* parent) QPixmap ScreenGrabber::grabEntireDesktop(bool& ok) { ok = true; -#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QPixmap screenPixmap( + currentScreen->grabWindow(QApplication::desktop()->winId(), + currentScreen->geometry().x(), + currentScreen->geometry().y(), + currentScreen->geometry().width(), + currentScreen->geometry().height())); + screenPixmap.setDevicePixelRatio(currentScreen->devicePixelRatio()); + return screenPixmap; +#elif defined(Q_OS_LINUX) || defined(Q_OS_UNIX) if (m_info.waylandDectected()) { QPixmap res; // handle screenshot based on DE @@ -87,7 +98,7 @@ QPixmap ScreenGrabber::grabEntireDesktop(bool& ok) return res; } #endif - +#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) || defined(Q_OS_WIN) QRect geometry; for (QScreen* const screen : QGuiApplication::screens()) { QRect scrRect = screen->geometry(); @@ -106,6 +117,7 @@ QPixmap ScreenGrabber::grabEntireDesktop(bool& ok) QScreen* screen = QApplication::screens()[screenNumber]; p.setDevicePixelRatio(screen->devicePixelRatio()); return p; +#endif } QPixmap ScreenGrabber::grabScreen(int screenNumber, bool& ok) diff --git a/src/utils/screenshotsaver.cpp b/src/utils/screenshotsaver.cpp index f803987a..a19dbdd2 100644 --- a/src/utils/screenshotsaver.cpp +++ b/src/utils/screenshotsaver.cpp @@ -35,9 +35,9 @@ void ScreenshotSaver::saveToClipboard(const QPixmap& capture) // If we are able to properly save the file, save the file and copy to // clipboard. if ((ConfigHandler().saveAfterCopyValue()) && - (!ConfigHandler().saveAfterCopyPathValue().isEmpty())) { + (!ConfigHandler().savePath().isEmpty())) { saveToFilesystem(capture, - ConfigHandler().saveAfterCopyPathValue(), + ConfigHandler().savePath(), QObject::tr("Capture saved to clipboard.")); QApplication::clipboard()->setPixmap(capture); } diff --git a/src/utils/systemnotification.cpp b/src/utils/systemnotification.cpp index 3df103af..2e3e62c5 100644 --- a/src/utils/systemnotification.cpp +++ b/src/utils/systemnotification.cpp @@ -1,34 +1,30 @@ #include "systemnotification.h" +#include "src/core/controller.h" #include "src/utils/confighandler.h" #include #include -#ifndef Q_OS_WIN +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) || defined(Q_OS_WIN)) #include #include #include -#else #endif -#include "src/core/controller.h" -#if defined(Q_OS_LINUX) || defined(Q_OS_UNIX) SystemNotification::SystemNotification(QObject* parent) : QObject(parent) + , m_interface(nullptr) { +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) || defined(Q_OS_WIN)) m_interface = new QDBusInterface(QStringLiteral("org.freedesktop.Notifications"), QStringLiteral("/org/freedesktop/Notifications"), QStringLiteral("org.freedesktop.Notifications"), QDBusConnection::sessionBus(), this); -} -#else -SystemNotification::SystemNotification(QObject* parent) - : QObject(parent) -{ - m_interface = nullptr; -} #endif +} void SystemNotification::sendMessage(const QString& text, const QString& savePath) @@ -45,7 +41,10 @@ void SystemNotification::sendMessage(const QString& text, return; } -#ifndef Q_OS_WIN +#if defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX) || defined(Q_OS_WIN) + Controller::getInstance()->sendTrayNotification(text, title, timeout); +#else QList args; QVariantMap hintsMap; if (!savePath.isEmpty()) { @@ -64,8 +63,5 @@ void SystemNotification::sendMessage(const QString& text, << timeout; // timeout m_interface->callWithArgumentList( QDBus::AutoDetect, QStringLiteral("Notify"), args); -#else - auto c = Controller::getInstance(); - c->sendTrayNotification(text, title, timeout); #endif } diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 55eee41a..dfb6b6ef 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources( notificationwidget.h orientablepushbutton.h historywidget.h + updatenotificationwidget.h ) target_sources( @@ -24,4 +25,5 @@ target_sources( notificationwidget.cpp orientablepushbutton.cpp historywidget.cpp + updatenotificationwidget.cpp ) diff --git a/src/widgets/capture/capturetoolbutton.cpp b/src/widgets/capture/capturetoolbutton.cpp index 84a1c811..637a969b 100644 --- a/src/widgets/capture/capturetoolbutton.cpp +++ b/src/widgets/capture/capturetoolbutton.cpp @@ -115,27 +115,32 @@ void CaptureToolButton::setColor(const QColor& c) QColor CaptureToolButton::m_mainColor = ConfigHandler().uiMainColorValue(); -static std::map buttonTypeOrder{ +static std::map buttonTypeOrder +{ { CaptureToolButton::TYPE_PENCIL, 0 }, - { CaptureToolButton::TYPE_DRAWER, 1 }, - { CaptureToolButton::TYPE_ARROW, 2 }, - { CaptureToolButton::TYPE_SELECTION, 3 }, - { CaptureToolButton::TYPE_RECTANGLE, 4 }, - { CaptureToolButton::TYPE_CIRCLE, 5 }, - { CaptureToolButton::TYPE_MARKER, 6 }, - { CaptureToolButton::TYPE_TEXT, 7 }, - { CaptureToolButton::TYPE_PIXELATE, 8 }, - { CaptureToolButton::TYPE_CIRCLECOUNT, 9 }, - { CaptureToolButton::TYPE_SELECTIONINDICATOR, 10 }, - { CaptureToolButton::TYPE_MOVESELECTION, 11 }, - { CaptureToolButton::TYPE_UNDO, 12 }, - { CaptureToolButton::TYPE_REDO, 13 }, - { CaptureToolButton::TYPE_COPY, 14 }, - { CaptureToolButton::TYPE_SAVE, 15 }, - { CaptureToolButton::TYPE_EXIT, 16 }, - { CaptureToolButton::TYPE_IMAGEUPLOADER, 17 }, - { CaptureToolButton::TYPE_OPEN_APP, 18 }, - { CaptureToolButton::TYPE_PIN, 19 }, + { CaptureToolButton::TYPE_DRAWER, 1 }, + { CaptureToolButton::TYPE_ARROW, 2 }, + { CaptureToolButton::TYPE_SELECTION, 3 }, + { CaptureToolButton::TYPE_RECTANGLE, 4 }, + { CaptureToolButton::TYPE_CIRCLE, 5 }, + { CaptureToolButton::TYPE_MARKER, 6 }, + { CaptureToolButton::TYPE_TEXT, 7 }, + { CaptureToolButton::TYPE_PIXELATE, 8 }, + { CaptureToolButton::TYPE_CIRCLECOUNT, 9 }, + { CaptureToolButton::TYPE_SELECTIONINDICATOR, 10 }, + { CaptureToolButton::TYPE_MOVESELECTION, 11 }, + { CaptureToolButton::TYPE_UNDO, 12 }, + { CaptureToolButton::TYPE_REDO, 13 }, + { CaptureToolButton::TYPE_COPY, 14 }, + { CaptureToolButton::TYPE_SAVE, 15 }, + { CaptureToolButton::TYPE_IMAGEUPLOADER, 16 }, +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + { CaptureToolButton::TYPE_OPEN_APP, 17 }, + { CaptureToolButton::TYPE_EXIT, 18 }, { CaptureToolButton::TYPE_PIN, 19 }, +#else + { CaptureToolButton::TYPE_EXIT, 17 }, { CaptureToolButton::TYPE_PIN, 18 }, +#endif }; int CaptureToolButton::getPriorityByButton(CaptureToolButton::ButtonType b) @@ -164,7 +169,10 @@ QVector CaptureToolButton::TYPE_SAVE, CaptureToolButton::TYPE_EXIT, CaptureToolButton::TYPE_IMAGEUPLOADER, +#if not(defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) CaptureToolButton::TYPE_OPEN_APP, +#endif CaptureToolButton::TYPE_PIN, CaptureToolButton::TYPE_CIRCLECOUNT, }; diff --git a/src/widgets/capture/capturetoolbutton.h b/src/widgets/capture/capturetoolbutton.h index 2a2908da..319fb9f2 100644 --- a/src/widgets/capture/capturetoolbutton.h +++ b/src/widgets/capture/capturetoolbutton.h @@ -53,8 +53,7 @@ public: TYPE_REDO = 16, TYPE_PIN = 17, TYPE_TEXT = 18, - TYPE_CIRCLECOUNT = 19, - + TYPE_CIRCLECOUNT = 19 }; Q_ENUM(ButtonType) diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 700a0518..5961543f 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -36,7 +36,9 @@ #include "src/widgets/capture/notifierbox.h" #include "src/widgets/orientablepushbutton.h" #include "src/widgets/panel/sidepanelwidget.h" +#include "src/widgets/updatenotificationwidget.h" #include +#include #include #include #include @@ -70,6 +72,8 @@ CaptureWidget::CaptureWidget(const uint id, , m_toolWidget(nullptr) , m_mouseOverHandle(SelectionWidget::NO_SIDE) , m_id(id) + , m_lastMouseWheel(0) + , m_updateNotificationWidget(nullptr) { // Base config of the widget m_eventFilter = new HoverEventFilter(this); @@ -88,7 +92,8 @@ CaptureWidget::CaptureWidget(const uint id, initContext(savePath, fullScreen); initShortcuts(); m_context.circleCount = 1; -#ifdef Q_OS_WIN +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_MAC64) || \ + defined(Q_OS_MACOS) || defined(Q_OS_MACX)) // Top left of the whole set of screens QPoint topLeft(0, 0); #endif @@ -102,7 +107,7 @@ CaptureWidget::CaptureWidget(const uint id, } m_context.origScreenshot = m_context.screenshot; -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Popup); @@ -117,11 +122,24 @@ CaptureWidget::CaptureWidget(const uint id, } } move(topLeft); + resize(pixmap().size()); +#elif (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // Emulate fullscreen mode + // setWindowFlags(Qt::WindowStaysOnTopHint | + // Qt::BypassWindowManagerHint | + // Qt::FramelessWindowHint | + // Qt::NoDropShadowWindowHint | Qt::ToolTip | + // Qt::Popup + // ); + QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + move(currentScreen->geometry().x(), currentScreen->geometry().y()); + resize(currentScreen->size()); #else setWindowFlags(Qt::BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool); -#endif resize(pixmap().size()); +#endif } // Create buttons m_buttonHandler = new ButtonHandler(this); @@ -132,7 +150,7 @@ CaptureWidget::CaptureWidget(const uint id, QRect r = screen->geometry(); r.moveTo(r.x() / screen->devicePixelRatio(), r.y() / screen->devicePixelRatio()); -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) r.moveTo(r.topLeft() - topLeft); #endif areas.append(r); @@ -304,7 +322,19 @@ void CaptureWidget::paintEvent(QPaintEvent*) painter.setClipRect(rect()); if (m_showInitialMsg) { +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QRect helpRect; + QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + if (currentScreen) { + helpRect = currentScreen->geometry(); + } else { + helpRect = QGuiApplication::primaryScreen()->geometry(); + } +#else QRect helpRect = QGuiApplication::primaryScreen()->geometry(); +#endif + helpRect.moveTo(mapFromGlobal(helpRect.topLeft())); QString helpTxt = @@ -606,7 +636,36 @@ void CaptureWidget::keyReleaseEvent(QKeyEvent* e) void CaptureWidget::wheelEvent(QWheelEvent* e) { - m_context.thickness += e->angleDelta().y() / 120; + /* Mouse scroll usually gives value 120, not more or less, just how many + * times. + * Touchpad gives the value 2 or more (usually 2-8), it doesn't give + * too big values like mouse wheel on normal scrolling, so it is almost + * impossible to scroll. It's easier to calculate number of requests and do + * not accept events faster that one in 200ms. + * */ + int thicknessOffset = 0; + if (e->angleDelta().y() >= 60) { + // mouse scroll (wheel) increment + thicknessOffset = 1; + } else if (e->angleDelta().y() <= -60) { + // mouse scroll (wheel) decrement + thicknessOffset = -1; + } else { + // touchpad scroll + qint64 current = QDateTime::currentMSecsSinceEpoch(); + if ((current - m_lastMouseWheel) > 200) { + if (e->angleDelta().y() > 0) { + thicknessOffset = 1; + } else if (e->angleDelta().y() < 0) { + thicknessOffset = -1; + } + m_lastMouseWheel = current; + } else { + return; + } + } + + m_context.thickness += thicknessOffset; m_context.thickness = qBound(0, m_context.thickness, 100); QPoint topLeft = qApp->desktop() @@ -681,10 +740,19 @@ void CaptureWidget::initPanel() } m_panel = new UtilityPanel(this); + m_panel->hide(); makeChild(m_panel); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + panelRect.moveTo(mapFromGlobal(panelRect.topLeft())); + m_panel->setFixedWidth(m_colorPicker->width() * 1.5); + m_panel->setFixedHeight(currentScreen->geometry().height()); +#else panelRect.moveTo(mapFromGlobal(panelRect.topLeft())); panelRect.setWidth(m_colorPicker->width() * 1.5); m_panel->setGeometry(panelRect); +#endif SidePanelWidget* sidePanel = new SidePanelWidget(&m_context.screenshot); connect(sidePanel, @@ -711,6 +779,26 @@ void CaptureWidget::initPanel() m_panel->pushWidget(new QUndoView(&m_undoStack, this)); } +void CaptureWidget::showAppUpdateNotification(const QString& appLatestVersion, + const QString& appLatestUrl) +{ + if (nullptr == m_updateNotificationWidget) { + m_updateNotificationWidget = + new UpdateNotificationWidget(this, appLatestVersion, appLatestUrl); + } +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + int ax = (width() - m_updateNotificationWidget->width()) / 2; +#else + QRect helpRect = QGuiApplication::primaryScreen()->geometry(); + int ax = helpRect.left() + + ((helpRect.width() - m_updateNotificationWidget->width()) / 2); +#endif + m_updateNotificationWidget->move(ax, 0); + makeChild(m_updateNotificationWidget); + m_updateNotificationWidget->show(); +} + void CaptureWidget::initSelection() { m_selection = new SelectionWidget(m_uiColor, this); @@ -1101,6 +1189,10 @@ void CaptureWidget::copyScreenshot() void CaptureWidget::saveScreenshot() { +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + showNormal(); +#endif m_captureDone = true; if (m_activeTool != nullptr) { QPainter painter(&m_context.screenshot); diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index c1d40a65..c0f406b5 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -44,6 +44,7 @@ class QNetworkReply; class ColorPicker; class NotifierBox; class HoverEventFilter; +class UpdateNotificationWidget; class CaptureWidget : public QWidget { @@ -58,6 +59,8 @@ public: void updateButtons(); QPixmap pixmap(); + void showAppUpdateNotification(const QString& appLatestVersion, + const QString& appLatestUrl); public slots: bool commitCurrentTool(); @@ -149,6 +152,8 @@ private: QRect extendedRect(QRect* r) const; private: + UpdateNotificationWidget* m_updateNotificationWidget; + quint64 m_lastMouseWheel; QUndoStack m_undoStack; QPointer m_sizeIndButton; // Last pressed button diff --git a/src/widgets/draggablewidgetmaker.cpp b/src/widgets/draggablewidgetmaker.cpp index c738dc62..70963e90 100644 --- a/src/widgets/draggablewidgetmaker.cpp +++ b/src/widgets/draggablewidgetmaker.cpp @@ -73,6 +73,8 @@ bool DraggableWidgetMaker::eventFilter(QObject* obj, QEvent* event) return true; } } break; + default: + break; } return QObject::eventFilter(obj, event); diff --git a/src/widgets/historywidget.cpp b/src/widgets/historywidget.cpp index 3f04ae72..593cbd0e 100644 --- a/src/widgets/historywidget.cpp +++ b/src/widgets/historywidget.cpp @@ -100,6 +100,8 @@ void HistoryWidget::addLine(const QString& path, const QString& fileName) QPixmap pixmap; pixmap.load(fullFileName, "png"); + // TODO - remove much later, it is still required to keep old previews works + // fine if (pixmap.height() / HISTORYPIXMAP_MAX_PREVIEW_HEIGHT >= pixmap.width() / HISTORYPIXMAP_MAX_PREVIEW_WIDTH) { pixmap = pixmap.scaledToHeight(HISTORYPIXMAP_MAX_PREVIEW_HEIGHT); diff --git a/src/widgets/historywidget.h b/src/widgets/historywidget.h index b713f666..163342bc 100644 --- a/src/widgets/historywidget.h +++ b/src/widgets/historywidget.h @@ -1,9 +1,6 @@ #ifndef HISTORYWIDGET_H #define HISTORYWIDGET_H -#define HISTORYPIXMAP_MAX_PREVIEW_WIDTH 160 -#define HISTORYPIXMAP_MAX_PREVIEW_HEIGHT 90 - #include #include #include diff --git a/src/widgets/panel/utilitypanel.cpp b/src/widgets/panel/utilitypanel.cpp index 12ef5eae..18189b62 100644 --- a/src/widgets/panel/utilitypanel.cpp +++ b/src/widgets/panel/utilitypanel.cpp @@ -43,7 +43,10 @@ UtilityPanel::UtilityPanel(QWidget* parent) m_internalPanel, &QWidget::hide); - hide(); +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_MAC64) || \ + defined(Q_OS_MACOS) || defined(Q_OS_MACX)) + move(0, 0); +#endif } QWidget* UtilityPanel::toolWidget() const @@ -83,6 +86,10 @@ void UtilityPanel::show() m_showAnimation->setEndValue(QRect(0, 0, width(), height())); m_internalPanel->show(); m_showAnimation->start(); +#if (defined(Q_OS_WIN) || defined(Q_OS_MAC) || defined(Q_OS_MAC64) || \ + defined(Q_OS_MACOS) || defined(Q_OS_MACX)) + move(0, 0); +#endif QWidget::show(); } @@ -134,9 +141,5 @@ void UtilityPanel::initInternalPanel() m_hide->setText(tr("Hide")); m_upLayout->addWidget(m_hide); connect(m_hide, SIGNAL(clicked()), this, SLOT(slotHidePanel())); -} - -void UtilityPanel::slotHidePanel() -{ - hide(); + m_internalPanel->hide(); } diff --git a/src/widgets/panel/utilitypanel.h b/src/widgets/panel/utilitypanel.h index 7a340bf9..1aec25ac 100644 --- a/src/widgets/panel/utilitypanel.h +++ b/src/widgets/panel/utilitypanel.h @@ -38,13 +38,8 @@ public: void hide(); void show(); -signals: - void mouseEnter(); - void mouseLeave(); - public slots: void toggle(); - void slotHidePanel(); private: void initInternalPanel(); diff --git a/src/widgets/updatenotificationwidget.cpp b/src/widgets/updatenotificationwidget.cpp new file mode 100644 index 00000000..3a7d8e73 --- /dev/null +++ b/src/widgets/updatenotificationwidget.cpp @@ -0,0 +1,144 @@ +// +// Created by yuriypuchkov on 09.12.2020. +// + +#include "updatenotificationwidget.h" +#include "src/utils/confighandler.h" +#include +#include +#include +#include +#include +#include +#include +#include + +UpdateNotificationWidget::UpdateNotificationWidget( + QWidget* parent, + const QString& appLatestVersion, + const QString& appLatestUrl) + : QWidget(parent) + , m_appLatestVersion(appLatestVersion) + , m_appLatestUrl(appLatestUrl) + , m_layout(nullptr) +{ + setMinimumSize(400, 100); + initInternalPanel(); + setAttribute(Qt::WA_TransparentForMouseEvents); + setCursor(Qt::ArrowCursor); + + m_showAnimation = new QPropertyAnimation(m_internalPanel, "geometry", this); + m_showAnimation->setEasingCurve(QEasingCurve::InOutQuad); + m_showAnimation->setDuration(300); + + m_hideAnimation = new QPropertyAnimation(m_internalPanel, "geometry", this); + m_hideAnimation->setEasingCurve(QEasingCurve::InOutQuad); + m_hideAnimation->setDuration(300); + + connect(m_hideAnimation, + &QPropertyAnimation::finished, + m_internalPanel, + &QWidget::hide); + setAppLatestVersion(appLatestVersion); +} + +void UpdateNotificationWidget::show() +{ + setAttribute(Qt::WA_TransparentForMouseEvents, false); + m_showAnimation->setStartValue(QRect(0, -height(), width(), height())); + m_showAnimation->setEndValue(QRect(0, 0, width(), height())); + m_internalPanel->show(); + m_showAnimation->start(); + QWidget::show(); +} + +void UpdateNotificationWidget::hide() +{ + setAttribute(Qt::WA_TransparentForMouseEvents); + m_hideAnimation->setStartValue(QRect(0, 0, width(), height())); + m_hideAnimation->setEndValue(QRect(0, -height(), 0, height())); + m_hideAnimation->start(); + m_internalPanel->hide(); + QWidget::hide(); +} + +void UpdateNotificationWidget::setAppLatestVersion(const QString& latestVersion) +{ + m_appLatestVersion = latestVersion; + QString newVersion = + tr("New Flameshot version %1 is available").arg(latestVersion); + m_notification->setText(newVersion); +} + +void UpdateNotificationWidget::laterButton() +{ + hide(); +} + +void UpdateNotificationWidget::ignoreButton() +{ + ConfigHandler().setIgnoreUpdateToVersion(m_appLatestVersion); + hide(); +} + +void UpdateNotificationWidget::updateButton() +{ + QDesktopServices::openUrl(m_appLatestUrl); + hide(); + if (parentWidget()) { + parentWidget()->close(); + } +} + +void UpdateNotificationWidget::initInternalPanel() +{ + m_internalPanel = new QScrollArea(this); + m_internalPanel->setAttribute(Qt::WA_NoMousePropagation); + QWidget* widget = new QWidget(); + m_internalPanel->setWidget(widget); + m_internalPanel->setWidgetResizable(true); + + QColor bgColor = palette().window().color(); + bgColor.setAlphaF(0.0); + m_internalPanel->setStyleSheet( + QStringLiteral("QScrollArea {background-color: %1}").arg(bgColor.name())); + m_internalPanel->hide(); + + // + m_layout = new QVBoxLayout(); + widget->setLayout(m_layout); + + // caption + m_notification = new QLabel(m_appLatestVersion, this); + m_layout->addWidget(m_notification); + + // buttons layout + QHBoxLayout* buttonsLayout = new QHBoxLayout(); + QSpacerItem* bottonsSpacer = new QSpacerItem(1, 1, QSizePolicy::Expanding); + buttonsLayout->addSpacerItem(bottonsSpacer); + m_layout->addLayout(buttonsLayout); + + // ignore + QPushButton* ignoreBtn = new QPushButton(tr("Ignore"), this); + buttonsLayout->addWidget(ignoreBtn); + connect(ignoreBtn, + &QPushButton::clicked, + this, + &UpdateNotificationWidget::ignoreButton); + + // later + QPushButton* laterBtn = new QPushButton(tr("Later"), this); + buttonsLayout->addWidget(laterBtn); + connect(laterBtn, + &QPushButton::clicked, + this, + &UpdateNotificationWidget::laterButton); + + // update + QPushButton* updateBtn = new QPushButton(tr("Update"), this); + buttonsLayout->addWidget(updateBtn); + connect(updateBtn, + &QPushButton::clicked, + this, + &UpdateNotificationWidget::updateButton); +} diff --git a/src/widgets/updatenotificationwidget.h b/src/widgets/updatenotificationwidget.h new file mode 100644 index 00000000..b214842c --- /dev/null +++ b/src/widgets/updatenotificationwidget.h @@ -0,0 +1,47 @@ +// +// Created by yuriypuchkov on 09.12.2020. +// + +#ifndef FLAMESHOT_UPDATENOTIFICATIONWIDGET_H +#define FLAMESHOT_UPDATENOTIFICATIONWIDGET_H + +#include +#include + +class QVBoxLayout; +class QPropertyAnimation; +class QScrollArea; +class QPushButton; +class QLabel; + +class UpdateNotificationWidget : public QWidget +{ + Q_OBJECT +public: + explicit UpdateNotificationWidget(QWidget* parent, + const QString& appLatestVersion, + const QString& appLatestUrl); + void setAppLatestVersion(const QString& latestVersion); + + void hide(); + void show(); + +public slots: + void ignoreButton(); + void laterButton(); + void updateButton(); + +private: + void initInternalPanel(); + + // class members + QString m_appLatestVersion; + QString m_appLatestUrl; + QVBoxLayout* m_layout; + QLabel* m_notification; + QScrollArea* m_internalPanel; + QPropertyAnimation* m_showAnimation; + QPropertyAnimation* m_hideAnimation; +}; + +#endif // FLAMESHOT_UPDATENOTIFICATIONWIDGET_H