├── .gitattributes ├── .github └── workflows │ ├── build_and_release.yml │ └── preview_release.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── android ├── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── res │ ├── drawable-hdpi │ │ └── icon.png │ ├── drawable-ldpi │ │ └── icon.png │ ├── drawable-mdpi │ │ └── icon.png │ ├── drawable-xhdpi │ │ └── icon.png │ ├── drawable-xxhdpi │ │ └── icon.png │ ├── drawable-xxxhdpi │ │ └── icon.png │ └── values │ │ └── libs.xml └── src │ └── info │ └── sioyek │ └── sioyek │ ├── SioyekActivity.java │ └── TextToSpeechService.java ├── bak ├── build_mac.yml └── rolling_release.yml ├── begin.png ├── build_and_release.sh ├── build_linux.sh ├── build_mac.sh ├── build_windows.bat ├── data ├── command_docs.json ├── config_docs.json ├── embedding.npy └── linear.npy ├── delete_build.sh ├── deploy.py ├── end.png ├── fzf ├── fzf.c └── fzf.h ├── icons ├── B.svg ├── B_white.svg ├── P.svg ├── P_white.svg ├── adjust.svg ├── arrow-begin.svg ├── arrow-end.svg ├── bookmark - Copy.svg ├── bookmark-add.svg ├── bookmark-g.svg ├── bookmark.svg ├── close.svg ├── copy.svg ├── document-page-number.svg ├── draw.svg ├── erase.svg ├── finger-index.svg ├── fit-horizontal-enabled.svg ├── fit-horizontal.svg ├── fullscreen-enabled.svg ├── fullscreen.svg ├── go-to-file.svg ├── google-scholar.svg ├── google.svg ├── highlight-g.svg ├── highlight.svg ├── home.svg ├── hourglass.svg ├── jump-right.svg ├── left.svg ├── link-enabled.svg ├── link.svg ├── load.svg ├── lock-enabled.svg ├── lock.svg ├── move.svg ├── next.svg ├── page.svg ├── paper-download.svg ├── pause.svg ├── pen.svg ├── play.svg ├── portal-enabled.svg ├── portal.svg ├── previous.svg ├── question.svg ├── right.svg ├── ruler-enabled.svg ├── ruler.svg ├── save.svg ├── screenshot.svg ├── search.svg ├── select_text.svg ├── selection-begin.svg ├── selection-end.svg ├── stop.svg ├── swap.svg ├── table-of-contents.svg ├── text-selection.svg ├── tts-enabled.svg ├── tts.svg └── unlink.svg ├── last_version.txt ├── linuxdeploy_build_and_release.sh ├── pdf_viewer ├── .gitignore ├── OpenWithApplication.cpp ├── OpenWithApplication.h ├── RunGuard.cpp ├── RunGuard.h ├── book.cpp ├── book.h ├── checksum.cpp ├── checksum.h ├── config.cpp ├── config.h ├── coordinates.cpp ├── coordinates.h ├── data │ └── last_document_path.txt ├── database.cpp ├── database.h ├── diff │ ├── keys.config │ └── keys2.config ├── document.cpp ├── document.h ├── document_view.cpp ├── document_view.h ├── fonts │ ├── monaco.ttf │ ├── msuighub.ttf │ └── msuighur.ttf ├── fts_fuzzy_match.h ├── icon1.ico ├── icon2.ico ├── input.cpp ├── input.h ├── keys.config ├── keys_old.config ├── keys_user.config ├── macos_specific.mm ├── main.cpp ├── main_widget.cpp ├── main_widget.h ├── mysortfilterproxymodel.cpp ├── mysortfilterproxymodel.h ├── new_file_checker.cpp ├── new_file_checker.h ├── path.cpp ├── path.h ├── pdf_renderer.cpp ├── pdf_renderer.h ├── pdf_view_opengl_widget.cpp ├── pdf_view_opengl_widget.h ├── prefs.config ├── prefs_user.config ├── qml │ └── MyColorPicker.qml ├── rapidfuzz_amalgamated.hpp ├── shaders │ ├── compiled_drawing.vertex │ ├── compiled_line.fragment │ ├── custom_colors.fragment │ ├── dark_mode.fragment │ ├── debug.fragment │ ├── dot.fragment │ ├── dot.vertex │ ├── highlight.fragment │ ├── line.fragment │ ├── line.vertex │ ├── separator.fragment │ ├── simple.fragment │ ├── simple.vertex │ ├── simple_transparent.fragment │ ├── stencil.fragment │ ├── stencil.vertex │ ├── undendered_page.fragment │ ├── unrendered_page.fragment │ ├── vertical_bar.fragment │ └── vertical_bar_dark.fragment ├── shell.c ├── sqlite3.c ├── sqlite3.h ├── sqlite3ext.h ├── synctex │ ├── synctex_parser.c │ ├── synctex_parser.h │ ├── synctex_parser_advanced.h │ ├── synctex_parser_local.h │ ├── synctex_parser_utils.c │ ├── synctex_parser_utils.h │ └── synctex_version.h ├── touchui │ ├── TouchAudioButtons.cpp │ ├── TouchAudioButtons.h │ ├── TouchAudioButtons.qml │ ├── TouchButtonGroup.qml │ ├── TouchCheckbox.cpp │ ├── TouchCheckbox.h │ ├── TouchCheckbox.qml │ ├── TouchConfigMenu.cpp │ ├── TouchConfigMenu.h │ ├── TouchConfigMenu.qml │ ├── TouchCopyOptions.cpp │ ├── TouchCopyOptions.h │ ├── TouchCopyOptions.qml │ ├── TouchDeleteButton.cpp │ ├── TouchDeleteButton.h │ ├── TouchDeleteButton.qml │ ├── TouchDrawControls.cpp │ ├── TouchDrawControls.h │ ├── TouchDrawControls.qml │ ├── TouchGenericButtons.cpp │ ├── TouchGenericButtons.h │ ├── TouchGenericButtons.qml │ ├── TouchHighlightButtons.cpp │ ├── TouchHighlightButtons.h │ ├── TouchHighlightButtons.qml │ ├── TouchListView.cpp │ ├── TouchListView.h │ ├── TouchListView.qml │ ├── TouchMacroEditor.cpp │ ├── TouchMacroEditor.h │ ├── TouchMacroEditor.qml │ ├── TouchMainMenu.cpp │ ├── TouchMainMenu.h │ ├── TouchMainMenu.qml │ ├── TouchMarkSelector.cpp │ ├── TouchMarkSelector.h │ ├── TouchMarkSelector.qml │ ├── TouchPageSelector.cpp │ ├── TouchPageSelector.h │ ├── TouchPageSelector.qml │ ├── TouchRangeSelectUI.cpp │ ├── TouchRangeSelectUI.h │ ├── TouchRangeSelectUI.qml │ ├── TouchRectangleSelectUI.cpp │ ├── TouchRectangleSelectUI.h │ ├── TouchRectangleSelectUI.qml │ ├── TouchSearchButtons.cpp │ ├── TouchSearchButtons.h │ ├── TouchSearchButtons.qml │ ├── TouchSettings.cpp │ ├── TouchSettings.h │ ├── TouchSettings.qml │ ├── TouchSlider.cpp │ ├── TouchSlider.h │ ├── TouchSlider.qml │ ├── TouchSymbolColorSelector.qml │ ├── TouchTextEdit.cpp │ ├── TouchTextEdit.h │ ├── TouchTextEdit.qml │ └── TouchTreeView.qml ├── ui.cpp ├── ui.h ├── utf8.h ├── utf8 │ ├── checked.h │ ├── core.h │ └── unchecked.h ├── utils.cpp └── utils.h ├── pdf_viewer_build_config.pro ├── resources.qrc ├── resources ├── Info.plist ├── debian │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── rules │ ├── sioyek.dirs │ ├── sioyek.install │ └── source │ │ └── format ├── fonts │ ├── JetBrainsMono.ttf │ └── OFL.txt ├── sioyek-icon-linux.png ├── sioyek.1 └── sioyek.desktop ├── scripts ├── dual_panelify.py ├── embed_annotations_in_file.py ├── embedded_annotations.py ├── paper_downloader.py ├── sioyek-generator.py ├── sioyek.py ├── summary_highlight_server.py ├── tools │ ├── command_names.txt │ ├── config_names.txt │ └── extract_command_docs.py └── tts │ ├── aligner.bat │ ├── aligner.ps1 │ ├── generator.ps1 │ ├── generator2.ps1 │ ├── manager_server.py │ ├── server_follow.py │ ├── server_read.py │ ├── server_stop.py │ └── server_unfollow.py ├── tutorial.pdf ├── tutorial ├── bibs.bib ├── compile.sh ├── mandlebrot_small.jpg └── tut.tex └── windows_runtime ├── libcrypto-1_1-x64.dll ├── libssl-1_1-x64.dll └── vcruntime140_1.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "mupdf"] 2 | path = mupdf 3 | url = https://github.com/ArtifexSoftware/mupdf 4 | ignore = dirty 5 | [submodule "zlib"] 6 | path = zlib 7 | url = https://github.com/madler/zlib 8 | ignore = untracked 9 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # For more details on how to configure your build environment visit 3 | # http://www.gradle.org/docs/current/userguide/build_environment.html 4 | # Specifies the JVM arguments used for the daemon process. 5 | # The setting is particularly useful for tweaking memory settings. 6 | org.gradle.jvmargs=-Xmx2500m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 7 | 8 | # Enable building projects in parallel 9 | org.gradle.parallel=true 10 | 11 | # Gradle caching allows reusing the build artifacts from a previous 12 | # build with the same inputs. However, over time, the cache size will 13 | # grow. Uncomment the following line to enable it. 14 | #org.gradle.caching=true 15 | 16 | android.useAndroidX=true 17 | android.enableJetifier=true 18 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /android/res/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/res/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/res/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/res/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/res/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /android/res/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/android/res/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /android/res/values/libs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /bak/build_mac.yml: -------------------------------------------------------------------------------- 1 | name: Build Mac Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "mac*" 7 | 8 | jobs: 9 | upload-release: 10 | 11 | runs-on: ubuntu-18.04 12 | needs: [build-mac] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: create release 17 | id: create_release 18 | uses: actions/create-release@master 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | with: 22 | tag_name: ${{ github.ref }} 23 | release_name: Release ${{ github.ref }} 24 | draft: false 25 | prerelease: false 26 | - name: download artifacts 27 | uses: actions/download-artifact@v1 28 | with: 29 | name: uploads 30 | - name: upload mac 31 | id: upload-mac 32 | uses: actions/upload-release-asset@v1.0.1 33 | env: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | with: 36 | upload_url: ${{ steps.create_release.outputs.upload_url }} 37 | asset_path: ./uploads/sioyek-release-mac.zip 38 | asset_name: sioyek-release-mac.zip 39 | asset_content_type: application/zip 40 | 41 | build-mac: 42 | 43 | runs-on: macos-latest 44 | 45 | steps: 46 | 47 | - uses: actions/checkout@v2 48 | with: 49 | submodules: 'recursive' 50 | 51 | - name: Install dependencies 52 | run: brew install freeglut mesa harfbuzz 53 | 54 | - name: Install Qt 55 | uses: jurplel/install-qt-action@v2 56 | with: 57 | version: '5.14.2' 58 | 59 | - name: Build 60 | working-directory: ${{env.GITHUB_WORKSPACE}} 61 | run: | 62 | chmod +x build_mac.sh 63 | ./build_mac.sh 64 | 65 | - name: upload mac artifact 66 | uses: actions/upload-artifact@v1 67 | with: 68 | name: uploads 69 | path: sioyek-release-mac.zip 70 | -------------------------------------------------------------------------------- /begin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/begin.png -------------------------------------------------------------------------------- /build_and_release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ -z ${MAKE_PARALLEL+x} ]; then export MAKE_PARALLEL=$(nproc); else echo "MAKE_PARALLEL defined"; fi 5 | echo "MAKE_PARALLEL set to $MAKE_PARALLEL" 6 | 7 | # download linuxdeployqt if not exists 8 | if [[ ! -f linuxdeployqt-continuous-x86_64.AppImage ]]; then 9 | wget -q https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage 10 | chmod +x linuxdeployqt-continuous-x86_64.AppImage 11 | fi 12 | 13 | cd mupdf 14 | make USE_SYSTEM_HARFBUZZ=yes -j$MAKE_PARALLEL 15 | cd .. 16 | 17 | if [ -z ${QMAKE+x} ]; then 18 | QMAKE=qmake 19 | fi 20 | 21 | if [[ $1 == console ]]; then 22 | $QMAKE "CONFIG+=linux_app_image console" pdf_viewer_build_config.pro 23 | else 24 | $QMAKE "CONFIG+=linux_app_image" pdf_viewer_build_config.pro 25 | fi 26 | 27 | rm -rf sioyek-release 2> /dev/null 28 | make install INSTALL_ROOT=sioyek-release -j$MAKE_PARALLEL 29 | 30 | cp pdf_viewer/prefs.config sioyek-release/usr/bin/prefs.config 31 | cp pdf_viewer/prefs_user.config sioyek-release/usr/share/prefs_user.config 32 | cp pdf_viewer/keys.config sioyek-release/usr/bin/keys.config 33 | cp pdf_viewer/keys_user.config sioyek-release/usr/share/keys_user.config 34 | cp -r pdf_viewer/shaders sioyek-release/usr/bin/shaders 35 | cp tutorial.pdf sioyek-release/usr/bin/tutorial.pdf 36 | 37 | ./linuxdeployqt-continuous-x86_64.AppImage ./sioyek-release/usr/share/applications/sioyek.desktop -qmldir=./pdf_viewer/touchui -appimage 38 | # ./linuxdeployqt-continuous-x86_64.AppImage ./sioyek-release/usr/share/applications/sioyek.desktop -appimage 39 | 40 | 41 | mv Sioyek-* Sioyek-x86_64.AppImage 42 | zip sioyek-release-linux.zip Sioyek-x86_64.AppImage 43 | -------------------------------------------------------------------------------- /build_linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | # Compile mupdf 5 | cd mupdf 6 | make USE_SYSTEM_HARFBUZZ=yes -j$(nproc) 7 | cd .. 8 | 9 | # set QMAKE if not already defined 10 | if [ -z "$QMAKE" ]; 11 | then 12 | if [ -f "/usr/bin/qmake-qt6" ]; 13 | then 14 | QMAKE="/usr/bin/qmake-qt6" 15 | elif [ -f "/usr/bin/qmake" ]; 16 | then 17 | QMAKE="/usr/bin/qmake" 18 | else 19 | QMAKE="qmake" 20 | fi 21 | fi 22 | 23 | $QMAKE "CONFIG+=linux_app_image" pdf_viewer_build_config.pro 24 | make -j$(nproc) 25 | 26 | # Copy files in build/ subdirectory 27 | rm -rf build 2> /dev/null 28 | mkdir build 29 | mv sioyek build/sioyek 30 | cp pdf_viewer/prefs.config build/prefs.config 31 | cp pdf_viewer/prefs_user.config build/prefs_user.config 32 | cp pdf_viewer/keys.config build/keys.config 33 | cp pdf_viewer/keys_user.config build/keys_user.config 34 | cp -r pdf_viewer/shaders build/shaders 35 | cp tutorial.pdf build/tutorial.pdf 36 | -------------------------------------------------------------------------------- /build_mac.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | # prerequisite: brew install qt@5 freeglut mesa harfbuzz 4 | 5 | #sys_glut_clfags=`pkg-config --cflags glut gl` 6 | #sys_glut_libs=`pkg-config --libs glut gl` 7 | #sys_harfbuzz_clfags=`pkg-config --cflags harfbuzz` 8 | #sys_harfbuzz_libs=`pkg-config --libs harfbuzz` 9 | 10 | if [ -z ${MAKE_PARALLEL+x} ]; then export MAKE_PARALLEL=1; else echo "MAKE_PARALLEL defined"; fi 11 | echo "MAKE_PARALLEL set to $MAKE_PARALLEL" 12 | 13 | cd mupdf 14 | #make USE_SYSTEM_HARFBUZZ=yes USE_SYSTEM_GLUT=yes SYS_GLUT_CFLAGS="${sys_glut_clfags}" SYS_GLUT_LIBS="${sys_glut_libs}" SYS_HARFBUZZ_CFLAGS="${sys_harfbuzz_clfags}" SYS_HARFBUZZ_LIBS="${sys_harfbuzz_libs}" -j 4 15 | make -j$MAKE_PARALLEL 16 | cd .. 17 | 18 | sed -Ei '' "s/QMAKE_MACOSX_DEPLOYMENT_TARGET.=.[0-9]+/QMAKE_MACOSX_DEPLOYMENT_TARGET = $(sw_vers -productVersion | cut -d. -f1)/" pdf_viewer_build_config.pro 19 | 20 | if [[ $1 == portable ]]; then 21 | qmake pdf_viewer_build_config.pro 22 | else 23 | qmake "CONFIG+=non_portable" pdf_viewer_build_config.pro 24 | fi 25 | 26 | make -j$MAKE_PARALLEL 27 | 28 | rm -rf build 2> /dev/null 29 | mkdir build 30 | mv sioyek.app build/ 31 | cp -r pdf_viewer/shaders build/sioyek.app/Contents/MacOS/shaders 32 | 33 | cp pdf_viewer/prefs.config build/sioyek.app/Contents/MacOS/prefs.config 34 | cp pdf_viewer/prefs_user.config build/sioyek.app/Contents/MacOS/prefs_user.config 35 | cp pdf_viewer/keys.config build/sioyek.app/Contents/MacOS/keys.config 36 | cp pdf_viewer/keys_user.config build/sioyek.app/Contents/MacOS/keys_user.config 37 | cp tutorial.pdf build/sioyek.app/Contents/MacOS/tutorial.pdf 38 | 39 | # Capture the current PATH 40 | CURRENT_PATH=$(echo $PATH) 41 | 42 | # Define the path to the Info.plist file inside the app bundle 43 | INFO_PLIST="build/sioyek.app/Contents/Info.plist" 44 | 45 | # Add LSEnvironment key with PATH to Info.plist 46 | /usr/libexec/PlistBuddy -c "Add :LSEnvironment dict" "$INFO_PLIST" || echo "LSEnvironment already exists" 47 | /usr/libexec/PlistBuddy -c "Add :LSEnvironment:PATH string $CURRENT_PATH" "$INFO_PLIST" || /usr/libexec/PlistBuddy -c "Set :LSEnvironment:PATH $CURRENT_PATH" "$INFO_PLIST" 48 | 49 | # Hack is required to avoid race condition in macos in CI 50 | # See https://github.com/actions/runner-images/issues/7522 51 | if [[ -n "$GITHUB_ACTIONS" ]]; then 52 | echo killing...; sudo pkill -9 XProtect >/dev/null || true; 53 | echo waiting...; while pgrep XProtect; do sleep 3; done; 54 | fi 55 | 56 | sleep 5 57 | 58 | # mac deploys with qml currently don't work due to a qt bug 59 | # macdeployqt build/sioyek.app -qmldir=./pdf_viewer/touchui -dmg 60 | macdeployqt build/sioyek.app -dmg 61 | 62 | zip -r sioyek-release-mac.zip build/sioyek.dmg 63 | -------------------------------------------------------------------------------- /build_windows.bat: -------------------------------------------------------------------------------- 1 | cd mupdf\platform\win32\ 2 | msbuild -maxcpucount mupdf.sln /m /property:Configuration=Debug /property:MultiProcessorCompilation=true 3 | msbuild -maxcpucount mupdf.sln /m /property:Configuration=Release /property:MultiProcessorCompilation=true 4 | cd ..\..\.. 5 | 6 | cd zlib 7 | nmake -f win32/makefile.msc 8 | cd .. 9 | 10 | qmake -tp vc "DEFINES+=NON_PORTABLE" "CONFIG+=release" pdf_viewer_build_config.pro 11 | 12 | msbuild -maxcpucount sioyek.vcxproj /m /property:Configuration=Release 13 | rm -r sioyek-release-windows 2> NUL 14 | mkdir sioyek-release-windows 15 | cp release\sioyek.exe sioyek-release-windows\sioyek.exe 16 | cp pdf_viewer\keys.config sioyek-release-windows\keys.config 17 | cp pdf_viewer\prefs.config sioyek-release-windows\prefs.config 18 | cp -r pdf_viewer\shaders sioyek-release-windows\shaders 19 | cp tutorial.pdf sioyek-release-windows\tutorial.pdf 20 | windeployqt --qmldir ./pdf_viewer/touchui --release sioyek-release-windows\sioyek.exe 21 | REM windeployqt sioyek-release-windows\sioyek.exe 22 | cp windows_runtime\vcruntime140_1.dll sioyek-release-windows\vcruntime140_1.dll 23 | cp windows_runtime\libssl-1_1-x64.dll sioyek-release-windows\libssl-1_1-x64.dll 24 | cp windows_runtime\libcrypto-1_1-x64.dll sioyek-release-windows\libcrypto-1_1-x64.dll 25 | 26 | if %1 == portable ( 27 | cp pdf_viewer\keys_user.config sioyek-release-windows\keys_user.config 28 | cp pdf_viewer\prefs_user.config sioyek-release-windows\prefs_user.config 29 | 7z a sioyek-release-windows-portable.zip sioyek-release-windows 30 | 31 | ) else ( 32 | 7z a sioyek-release-windows.zip sioyek-release-windows 33 | ) 34 | -------------------------------------------------------------------------------- /data/embedding.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/data/embedding.npy -------------------------------------------------------------------------------- /data/linear.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/data/linear.npy -------------------------------------------------------------------------------- /delete_build.sh: -------------------------------------------------------------------------------- 1 | rm -r Sioyek* 2 | rm sioyek 3 | rm *.o 4 | rm -r sioyek-release 5 | -------------------------------------------------------------------------------- /deploy.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | if __name__ == '__main__': 4 | with open('E:\\labs\hexomancer-sioyek\\sioyek\\last_version.txt', 'r') as infile: 5 | last_version = int(infile.read()) 6 | new_version = last_version + 1 7 | with open('E:\\labs\hexomancer-sioyek\\sioyek\\last_version.txt', 'w') as outfile: 8 | outfile.write(str(new_version)) 9 | 10 | os.chdir('E:\\labs\hexomancer-sioyek\\sioyek') 11 | os.system("git pull upstream main") 12 | os.system(f"git tag v0.31.{new_version}") 13 | os.system("git push origin main") 14 | os.system("git push origin --tags") 15 | # os.system(f"git push origin v0.31.{new_version}") 16 | os.system("pause") -------------------------------------------------------------------------------- /end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/end.png -------------------------------------------------------------------------------- /icons/adjust.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 36 | adjust 38 | Created with Sketch. 40 | 46 | 49 | 52 | 55 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /icons/arrow-begin.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 44 | 45 | -------------------------------------------------------------------------------- /icons/arrow-end.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 44 | 45 | -------------------------------------------------------------------------------- /icons/bookmark - Copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 37 | 41 | 42 | -------------------------------------------------------------------------------- /icons/bookmark-add.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 40 | 41 | -------------------------------------------------------------------------------- /icons/bookmark-g.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 40 | 48 | G 60 | 61 | -------------------------------------------------------------------------------- /icons/bookmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 40 | 41 | -------------------------------------------------------------------------------- /icons/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 44 | 52 | 53 | -------------------------------------------------------------------------------- /icons/draw.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/erase.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 43 | 44 | -------------------------------------------------------------------------------- /icons/finger-index.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 31 | 33 | 35 | 36 | finger-index 38 | 41 | 43 | 45 | 50 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /icons/fit-horizontal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 39 | 40 | 41 | 42 | 43 | 90 | 91 | -------------------------------------------------------------------------------- /icons/go-to-file.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 42 | 43 | -------------------------------------------------------------------------------- /icons/google-scholar.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 39 | 40 | -------------------------------------------------------------------------------- /icons/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 37 | 41 | 42 | -------------------------------------------------------------------------------- /icons/highlight-g.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | G 53 | 54 | -------------------------------------------------------------------------------- /icons/highlight.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 32 | 34 | 36 | 37 | 42 | 47 | 48 | -------------------------------------------------------------------------------- /icons/jump-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 44 | 48 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /icons/left.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 43 | 44 | -------------------------------------------------------------------------------- /icons/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 38 | 42 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /icons/load.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 37 | 44 | 51 | 58 | 65 | 72 | 73 | -------------------------------------------------------------------------------- /icons/lock-enabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 21 | 25 | 29 | 30 | 39 | 40 | 59 | 64 | 65 | -------------------------------------------------------------------------------- /icons/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/move.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 40 | 44 | 45 | -------------------------------------------------------------------------------- /icons/next.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 36 | arrow_back_ios 38 | Created with Sketch. 40 | 47 | 51 | 55 | 59 | 62 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /icons/paper-download.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 46 | 54 | 62 | 70 | 71 | -------------------------------------------------------------------------------- /icons/pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 47 | 58 | 59 | -------------------------------------------------------------------------------- /icons/pen.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 32 | 34 | 36 | 37 | 42 | 47 | 52 | 53 | -------------------------------------------------------------------------------- /icons/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 44 | 52 | 60 | 61 | -------------------------------------------------------------------------------- /icons/portal-enabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 22 | 26 | 30 | 31 | 40 | 41 | 60 | 63 | 67 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /icons/portal.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 37 | 41 | 45 | 46 | -------------------------------------------------------------------------------- /icons/previous.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 36 | arrow_forward_ios 38 | Created with Sketch. 40 | 47 | 51 | 55 | 59 | 62 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /icons/question.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 14 | 33 | 37 | 41 | 42 | -------------------------------------------------------------------------------- /icons/right.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/ruler-enabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 18 | 22 | 26 | 27 | 36 | 37 | 56 | 60 | 61 | -------------------------------------------------------------------------------- /icons/ruler.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 14 | 33 | 37 | 38 | -------------------------------------------------------------------------------- /icons/save.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 39 | 40 | -------------------------------------------------------------------------------- /icons/screenshot.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 39 | 40 | -------------------------------------------------------------------------------- /icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/selection-begin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 36 | 38 | 43 | 48 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /icons/selection-end.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 36 | 38 | 43 | 48 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /icons/stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 36 | 41 | 42 | -------------------------------------------------------------------------------- /icons/swap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 39 | 41 | 46 | 47 | 50 | 53 | 58 | 63 | 68 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /icons/table-of-contents.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 31 | 33 | 35 | 36 | table-of-contents 38 | 45 | 52 | 59 | 66 | 73 | 80 | 87 | 94 | 95 | -------------------------------------------------------------------------------- /icons/text-selection.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 31 | 33 | 35 | 36 | text-selection 38 | 42 | 46 | 52 | 53 | -------------------------------------------------------------------------------- /icons/unlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 39 | 40 | -------------------------------------------------------------------------------- /last_version.txt: -------------------------------------------------------------------------------- 1 | 435 -------------------------------------------------------------------------------- /linuxdeploy_build_and_release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | if [ -z ${MAKE_PARALLEL+x} ]; then export MAKE_PARALLEL=$(nproc); else echo "MAKE_PARALLEL defined"; fi 5 | echo "MAKE_PARALLEL set to $MAKE_PARALLEL" 6 | 7 | # download linuxdeployqt if not exists 8 | if [[ ! -f ./linuxdeploy-x86_64.AppImage ]]; then 9 | # the continuous version is not working for some reason 10 | # wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage 11 | # wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage 12 | 13 | wget https://github.com/linuxdeploy/linuxdeploy/releases/download/1-alpha-20240109-1/linuxdeploy-x86_64.AppImage 14 | wget https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/1-alpha-20240109-1/linuxdeploy-plugin-qt-x86_64.AppImage 15 | 16 | chmod +x linuxdeploy-x86_64.AppImage 17 | chmod +x linuxdeploy-plugin-qt-x86_64.AppImage 18 | fi 19 | 20 | cd mupdf 21 | make USE_SYSTEM_HARFBUZZ=yes -j$MAKE_PARALLEL 22 | cd .. 23 | 24 | if [ -z ${QMAKE+x} ]; then 25 | QMAKE=qmake 26 | fi 27 | 28 | if [[ $1 == console ]]; then 29 | $QMAKE "CONFIG+=linux_app_image console" pdf_viewer_build_config.pro 30 | else 31 | $QMAKE "CONFIG+=linux_app_image" pdf_viewer_build_config.pro 32 | fi 33 | 34 | rm -rf sioyek-release 2> /dev/null 35 | make install INSTALL_ROOT=sioyek-release -j$MAKE_PARALLEL 36 | 37 | cp pdf_viewer/prefs.config sioyek-release/usr/bin/prefs.config 38 | cp pdf_viewer/prefs_user.config sioyek-release/usr/share/prefs_user.config 39 | cp pdf_viewer/keys.config sioyek-release/usr/bin/keys.config 40 | cp pdf_viewer/keys_user.config sioyek-release/usr/share/keys_user.config 41 | cp -r pdf_viewer/shaders sioyek-release/usr/bin/shaders 42 | cp tutorial.pdf sioyek-release/usr/bin/tutorial.pdf 43 | 44 | QML_SOURCES_PATHS=./pdf_viewer/touchui ./linuxdeploy-x86_64.AppImage --appdir sioyek-release --plugin qt --output appimage 45 | 46 | # ./linuxdeployqt-continuous-x86_64.AppImage ./sioyek-release/usr/share/applications/sioyek.desktop -qmldir=./pdf_viewer/touchui -appimage 47 | # ./linuxdeployqt-continuous-x86_64.AppImage ./sioyek-release/usr/share/applications/sioyek.desktop -appimage 48 | 49 | 50 | # mv Sioyek-* Sioyek-x86_64.AppImage 51 | zip sioyek-release-linux.zip Sioyek-x86_64.AppImage 52 | -------------------------------------------------------------------------------- /pdf_viewer/.gitignore: -------------------------------------------------------------------------------- 1 | data/* 2 | x64/* 3 | release/* 4 | Debug/* 5 | .vscode/* 6 | Generated 7 | *.pdf 8 | *.pdb 9 | *.db 10 | *.aps 11 | .qmake.stash 12 | last_document_path.txt 13 | imgui.ini 14 | *.jar 15 | last_document_path.txt 16 | *.o 17 | -------------------------------------------------------------------------------- /pdf_viewer/OpenWithApplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool OpenWithApplication::event(QEvent* event) { 4 | if (event->type() == QEvent::FileOpen) { 5 | QFileOpenEvent* openEvent = static_cast(event); 6 | emit file_ready(openEvent->file()); 7 | } 8 | 9 | return QApplication::event(event); 10 | } 11 | -------------------------------------------------------------------------------- /pdf_viewer/OpenWithApplication.h: -------------------------------------------------------------------------------- 1 | #ifndef OPEN_WITH_APP_H 2 | #define OPEN_WITH_APP_H 3 | 4 | #include 5 | #include 6 | 7 | class OpenWithApplication : public QApplication 8 | { 9 | Q_OBJECT 10 | public: 11 | OpenWithApplication(int& argc, char** argv) 12 | : QApplication(argc, argv) 13 | { 14 | } 15 | signals: 16 | void file_ready(const QString& file_name); 17 | 18 | protected: 19 | bool event(QEvent* event) override; 20 | }; 21 | 22 | #endif // OPEN_WITH_APP_H -------------------------------------------------------------------------------- /pdf_viewer/RunGuard.h: -------------------------------------------------------------------------------- 1 | #ifndef SIOYEK_ANDROID 2 | #ifndef SINGLE_INSTANCE_GUARD_H 3 | #define SINGLE_INSTANCE_GUARD_H 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | /** 12 | * This is an control to guarantee that only one application instance exists at 13 | * any time. 14 | * It uses shared memory to check that no more than one instance is running at 15 | * the same time and also it uses Inter Process Communication (IPC) for a 16 | * secondary application instance to send parameters to the primary application 17 | * instance before quitting. 18 | * An Application must be contructed before the control for signals-slot 19 | * communication to work. 20 | * 21 | * Usage example: 22 | * 23 | * int main(int argc, char *argv[]) 24 | * { 25 | * QApplication app{argc, argv}; 26 | * 27 | * ... 28 | * 29 | * RunGuard guard{"Lentigram"}; 30 | * if (guard.isPrimary()) { 31 | * QObject::connect( 32 | * &guard, 33 | * &RunGuard::messageReceived, [this](const QByteArray &message) { 34 | * 35 | * ...process message coming from secondary application... 36 | * 37 | * qDebug() << message; 38 | * } 39 | * ); 40 | * } else { 41 | * guard.sendMessage(app.arguments().join(' ').toUtf8()); 42 | * return 0; 43 | * } 44 | * 45 | * ... 46 | * 47 | * app.exec(); 48 | * } 49 | * 50 | * This code is inspired by the following: 51 | * https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection 52 | * https://github.com/itay-grudev/SingleApplication 53 | */ 54 | class RunGuard : public QObject 55 | { 56 | Q_OBJECT 57 | 58 | public: 59 | std::function on_delete; 60 | explicit RunGuard(const QString& key); 61 | ~RunGuard(); 62 | 63 | bool isPrimary(); 64 | bool isSecondary(); 65 | std::string sendMessage(const QByteArray& message, bool wait=false); 66 | 67 | signals: 68 | void messageReceived(const QByteArray& message, QLocalSocket* socket); 69 | 70 | private slots: 71 | void onNewConnection(); 72 | 73 | private: 74 | 75 | const QString key; 76 | const QString sharedMemLockKey; 77 | const QString memoryKey; 78 | 79 | QSharedMemory* memory; 80 | QLocalServer* server = nullptr; 81 | 82 | void readMessage(QLocalSocket* socket); 83 | }; 84 | 85 | #endif // SINGLE_INSTANCE_GUARD_H 86 | 87 | #endif // SIOYEK_ANDROID 88 | -------------------------------------------------------------------------------- /pdf_viewer/checksum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "checksum.h" 4 | 5 | std::string compute_checksum(const QString& file_name, QCryptographicHash::Algorithm hash_algorithm) 6 | { 7 | QFile infile(file_name); 8 | qint64 file_size = infile.size(); 9 | const qint64 buffer_size = 10240; 10 | 11 | if (infile.open(QIODevice::ReadOnly)) 12 | { 13 | char buffer[buffer_size]; 14 | int bytes_read; 15 | int read_size = qMin(file_size, buffer_size); 16 | 17 | QCryptographicHash hash(hash_algorithm); 18 | while (read_size > 0 && (bytes_read = infile.read(buffer, read_size)) > 0) 19 | { 20 | file_size -= bytes_read; 21 | hash.addData(buffer, bytes_read); 22 | read_size = qMin(file_size, buffer_size); 23 | } 24 | 25 | infile.close(); 26 | return QString(hash.result().toHex()).toStdString(); 27 | } 28 | return ""; 29 | } 30 | 31 | CachedChecksummer::CachedChecksummer(const std::vector>* loaded_checksums) { 32 | if (loaded_checksums) { 33 | for (const auto& [path, checksum_] : *loaded_checksums) { 34 | std::string checksum = QString::fromStdWString(checksum_).toStdString(); 35 | cached_checksums[path] = checksum; 36 | cached_paths[checksum].push_back(path); 37 | } 38 | } 39 | } 40 | 41 | std::optional CachedChecksummer::get_checksum_fast(std::wstring file_path) { 42 | // return the checksum only if it is alreay precomputed in cache 43 | if (cached_checksums.find(file_path) != cached_checksums.end()) { 44 | return cached_checksums[file_path]; 45 | } 46 | return {}; 47 | } 48 | 49 | std::string CachedChecksummer::get_checksum(std::wstring file_path) { 50 | 51 | auto cached_checksum = get_checksum_fast(file_path); 52 | 53 | if (!cached_checksum) { 54 | std::string checksum = compute_checksum(QString::fromStdWString(file_path), QCryptographicHash::Md5); 55 | cached_checksums[file_path] = checksum; 56 | cached_paths[checksum].push_back(file_path); 57 | } 58 | return cached_checksums[file_path]; 59 | 60 | } 61 | 62 | std::optional CachedChecksummer::get_path(std::string checksum) { 63 | const std::vector paths = cached_paths[checksum]; 64 | 65 | for (const auto& path_string : paths) { 66 | if (QFile::exists(QString::fromStdWString(path_string))) { 67 | return path_string; 68 | } 69 | } 70 | return {}; 71 | } 72 | 73 | int CachedChecksummer::num_docs_with_checksum(std::string checksum) { 74 | if (cached_paths.find(checksum) != cached_paths.end()) { 75 | return cached_paths[checksum].size(); 76 | } 77 | return 0; 78 | } -------------------------------------------------------------------------------- /pdf_viewer/checksum.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | std::string compute_checksum(const QString& file_name, QCryptographicHash::Algorithm hash_algorithm); 11 | 12 | class CachedChecksummer { 13 | private: 14 | std::unordered_map cached_checksums; 15 | std::unordered_map> cached_paths; 16 | 17 | public: 18 | CachedChecksummer(const std::vector>* loaded_checksums); 19 | std::string get_checksum(std::wstring file_path); 20 | std::optional get_checksum_fast(std::wstring file_path); 21 | std::optional get_path(std::string checksum); 22 | int num_docs_with_checksum(std::string checksum); 23 | }; -------------------------------------------------------------------------------- /pdf_viewer/data/last_document_path.txt: -------------------------------------------------------------------------------- 1 | C:\Users\Lion\source\repos\pdf_viewer\pdf_viewer\data\test.pdf 2 | -------------------------------------------------------------------------------- /pdf_viewer/fonts/monaco.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/fonts/monaco.ttf -------------------------------------------------------------------------------- /pdf_viewer/fonts/msuighub.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/fonts/msuighub.ttf -------------------------------------------------------------------------------- /pdf_viewer/fonts/msuighur.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/fonts/msuighur.ttf -------------------------------------------------------------------------------- /pdf_viewer/icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/icon1.ico -------------------------------------------------------------------------------- /pdf_viewer/icon2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/icon2.ico -------------------------------------------------------------------------------- /pdf_viewer/keys_user.config: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/keys_user.config -------------------------------------------------------------------------------- /pdf_viewer/mysortfilterproxymodel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | extern "C" { 8 | #include "fzf/fzf.h" 9 | } 10 | 11 | class MySortFilterProxyModel : public QSortFilterProxyModel { 12 | Q_OBJECT 13 | 14 | public: 15 | QString filterString; 16 | mutable std::vector scores; 17 | mutable QString last_update_string; 18 | bool is_fuzzy = false; 19 | fzf_slab_t* slab; 20 | mutable QMap index_map; 21 | bool is_tree = false; 22 | 23 | MySortFilterProxyModel(bool fuzzy, bool is_tree); 24 | ~MySortFilterProxyModel(); 25 | bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const; 26 | bool filter_accepts_row_column(int row, int col, const QModelIndex& source_parent) const; 27 | Q_INVOKABLE void setFilterCustom(const QString& filterString); 28 | 29 | //void setFilterFixedString(const QString &pattern) override; 30 | bool lessThan(const QModelIndex& left, const QModelIndex& right) const; 31 | 32 | int compute_score(QString filter_string, QString item_string) const; 33 | int compute_score(fzf_pattern_t* pattern, QString item_string) const; 34 | int update_scores_for_index(fzf_pattern_t* pattern, const QModelIndex& index, int col) const; 35 | void ensure_scores() const; 36 | void update_scores() const; 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /pdf_viewer/new_file_checker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class MainWidget; 9 | 10 | class NewFileChecker { 11 | private: 12 | std::vector last_files; 13 | QString path; 14 | QFileSystemWatcher paper_folder_watcher; 15 | void get_dir_files_helper(QString parent_path, std::vector& paths); 16 | void register_subdirectories(QString dirpath); 17 | 18 | public: 19 | std::vector get_dir_files(); 20 | void update_files(); 21 | QString get_lastest_new_file_path(); 22 | NewFileChecker(std::wstring dirpath, MainWidget* main_widget); 23 | }; 24 | -------------------------------------------------------------------------------- /pdf_viewer/path.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | 6 | class Path { 7 | private: 8 | std::wstring canon_path; 9 | 10 | public: 11 | Path(); 12 | Path(std::wstring pathname); 13 | 14 | void parts(std::vector& res) const; 15 | Path slash(const std::wstring& suffix) const; 16 | 17 | std::optional filename() const; 18 | std::optional filename_no_ext() const; 19 | Path file_parent() const; 20 | 21 | std::wstring get_path() const; 22 | std::string get_path_utf8() const; 23 | void create_directories(); 24 | bool dir_exists() const; 25 | bool file_exists() const; 26 | //std::wstring add_redundant_dot() const; 27 | 28 | }; 29 | std::wostream& operator<<(std::wostream& stream, const Path& path); 30 | 31 | void copy_file(Path src, Path dst); 32 | -------------------------------------------------------------------------------- /pdf_viewer/prefs_user.config: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/pdf_viewer/prefs_user.config -------------------------------------------------------------------------------- /pdf_viewer/qml/MyColorPicker.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QtQuick.Controls 2.15 3 | //import QtQuick.Dialogs 1.0 4 | //import QtQuick.Dialogs 1.3 5 | import Qt.labs.platform 1.1 6 | 7 | //ColorDialog{ 8 | 9 | //} 10 | 11 | //Slider{ 12 | 13 | //} 14 | //Rectangle{ 15 | // color: "black" 16 | //// anchors.fill: parent 17 | // width: 500 18 | // height: 500 19 | 20 | Item{ 21 | 22 | ColorDialog { 23 | id: colorDialog 24 | title: "Please choose a color" 25 | onAccepted: { 26 | console.log("You chose: " + colorDialog.color) 27 | Qt.quit() 28 | } 29 | onRejected: { 30 | console.log("Canceled") 31 | Qt.quit() 32 | } 33 | Component.onCompleted: visible = true 34 | } 35 | } 36 | 37 | // Slider { 38 | // from: 1 39 | // value: 25 40 | // to: 100 41 | // } 42 | //} 43 | 44 | 45 | //colorDialog { 46 | // id: colorDialog 47 | // title: "Please choose a color" 48 | // onAccepted: { 49 | // console.log("You chose: " + colorDialog.color) 50 | // Qt.quit() 51 | // } 52 | // onRejected: { 53 | // console.log("Canceled") 54 | // Qt.quit() 55 | // } 56 | // Component.onCompleted: visible = true 57 | //} 58 | 59 | //Rectangle { 60 | // width: 1000 61 | // height: 1000 62 | // color: "yellow" 63 | //} 64 | -------------------------------------------------------------------------------- /pdf_viewer/shaders/compiled_drawing.vertex: -------------------------------------------------------------------------------- 1 | layout (location=0) in vec2 vertex_pos; 2 | layout (location=1) in int type_index; 3 | 4 | uniform vec2 offset; 5 | uniform vec2 scale; 6 | uniform vec3 type_colors[26]; 7 | 8 | out vec3 type_color; 9 | 10 | void main(){ 11 | vec2 pos = vertex_pos * scale; 12 | pos.y = -pos.y; 13 | pos = pos + offset; 14 | type_color = type_colors[type_index]; 15 | gl_Position = vec4(pos, 0.0, 1.0); 16 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/compiled_line.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec3 type_color; 5 | 6 | void main(){ 7 | color = vec4(type_color, 1); 8 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/custom_colors.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | uniform mat4 transform_matrix; 8 | 9 | uniform sampler2D pdf_texture; 10 | 11 | 12 | void main(){ 13 | vec4 pdf_color = vec4(texture(pdf_texture, uvs).rgb, 1); 14 | vec3 resulting_unclamped_color = (transform_matrix * pdf_color).rgb; 15 | color = vec4(clamp(resulting_unclamped_color, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0)), 1.0); 16 | } 17 | -------------------------------------------------------------------------------- /pdf_viewer/shaders/dark_mode.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | uniform sampler2D pdf_texture; 7 | 8 | uniform float contrast; 9 | 10 | //http://gamedev.stackexchange.com/questions/59797/glsl-shader-change-hue-saturation-brightness 11 | vec3 rgb2hsv(vec3 c) 12 | { 13 | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 14 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); 15 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); 16 | 17 | float d = q.x - min(q.w, q.y); 18 | float e = 1.0e-10; 19 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 20 | } 21 | 22 | vec3 hsv2rgb(vec3 c) 23 | { 24 | vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 25 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); 26 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); 27 | } 28 | 29 | 30 | void main(){ 31 | vec3 tempcolor = texture(pdf_texture, uvs).rgb; 32 | vec3 inv = (0.5-tempcolor)*contrast+0.5; //Invert colors and shift colors from range 0.0 - 1.0 to -0.5 - 0.5, apply contrast and shift back to 0.0 - 1.0. This way contrast applies on both whites and blacks 33 | vec3 hsvcolor = rgb2hsv(inv); //transform to hsv 34 | float new_hue = mod(hsvcolor.r + 0.5, 1.0); // shift hue 180 degrees to compensate hue shift from inverting colors 35 | vec3 newcolor = hsv2rgb(vec3(new_hue,hsvcolor.gb)); 36 | color = vec4(newcolor, 1.0); 37 | } 38 | -------------------------------------------------------------------------------- /pdf_viewer/shaders/debug.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | void main(){ 8 | color = vec4(1.0, 1.0, 0.0, 0.3); 9 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/dot.fragment: -------------------------------------------------------------------------------- 1 | #extension GL_OES_standard_derivatives : enable 2 | 3 | precision mediump float; 4 | 5 | in vec2 uv; 6 | in vec4 type_color; 7 | out vec4 color; 8 | 9 | void main(){ 10 | float x = (uv.x - 0.5) * 2.0; 11 | float y = (uv.y - 0.5) * 2.0; 12 | float r_squared = x * x + y * y; 13 | float alpha = 1.0; 14 | 15 | #ifdef GL_OES_standard_derivatives 16 | float delta = fwidth(r_squared); 17 | alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r_squared); 18 | color = vec4(type_color.rgb, alpha); 19 | #else 20 | if (r_squared <= 1.0){ 21 | color = type_color; 22 | } 23 | else{ 24 | color = vec4(0.0, 0.0, 0.0, 0.0); 25 | } 26 | #endif 27 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/dot.vertex: -------------------------------------------------------------------------------- 1 | layout (location=0) in vec2 vertex_pos; 2 | layout (location=1) in vec2 vertex_uv; 3 | layout (location=2) in int type_index; 4 | 5 | uniform vec2 offset; 6 | uniform vec2 scale; 7 | uniform vec3 type_colors[26]; 8 | 9 | out vec2 uv; 10 | out vec4 type_color; 11 | 12 | void main(){ 13 | uv = vertex_uv; 14 | 15 | type_color = vec4(type_colors[type_index], 1.0); 16 | vec2 pos = vertex_pos * scale; 17 | pos.y = -pos.y; 18 | pos = pos + offset; 19 | gl_Position = vec4(pos, 0.0, 1.0); 20 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/highlight.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | uniform vec3 highlight_color; 8 | uniform float opacity; 9 | 10 | void main(){ 11 | color = vec4(highlight_color, opacity); 12 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/line.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | uniform vec4 line_color; 5 | 6 | void main(){ 7 | color = line_color; 8 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/line.vertex: -------------------------------------------------------------------------------- 1 | layout (location=0) in vec2 vertex_pos; 2 | 3 | void main(){ 4 | gl_Position = vec4(vertex_pos, 0.0, 1.0); 5 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/separator.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | uniform vec3 background_color; 8 | 9 | void main(){ 10 | color = vec4(background_color, 1.0); 11 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/simple.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | uniform sampler2D pdf_texture; 7 | 8 | void main(){ 9 | color = vec4(texture(pdf_texture, uvs).rgb, 1.0); 10 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/simple.vertex: -------------------------------------------------------------------------------- 1 | out vec2 screen_pos; 2 | out vec2 uvs; 3 | layout (location=0) in vec2 vertex_pos; 4 | layout (location=1) in vec2 vertex_uvs; 5 | 6 | void main(){ 7 | screen_pos = vertex_pos; 8 | uvs = vertex_uvs; 9 | gl_Position = vec4(vertex_pos, 0.0, 1.0); 10 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/simple_transparent.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | uniform sampler2D pdf_texture; 7 | 8 | void main(){ 9 | color = texture(pdf_texture, uvs); 10 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/stencil.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | 6 | void main(){ 7 | color = vec4(0, 0, 0, 0); 8 | } 9 | -------------------------------------------------------------------------------- /pdf_viewer/shaders/stencil.vertex: -------------------------------------------------------------------------------- 1 | out vec2 screen_pos; 2 | layout (location=0) in vec2 vertex_pos; 3 | 4 | void main(){ 5 | screen_pos = vertex_pos; 6 | gl_Position = vec4(vertex_pos, 0.0, 1.0); 7 | } 8 | -------------------------------------------------------------------------------- /pdf_viewer/shaders/undendered_page.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | void main(){ 8 | int x = (int)(uvs.x / 0.1); 9 | int y = (int)(uvs.y / 0.1); 10 | if ((x+y)% 2 == 0){ 11 | color = vec4(1.0, 0.0, 0.0, 1.0); 12 | } 13 | else{ 14 | color = vec4(0.0, 0.0, 1.0, 1.0); 15 | } 16 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/unrendered_page.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | void main(){ 8 | int x = int(uvs.x / 0.1); 9 | int y = int(uvs.y / 0.1); 10 | if ((x+y)% 2 == 0){ 11 | color = vec4(1.0, 1.0, 1.0, 1.0); 12 | } 13 | else{ 14 | color = vec4(0.1, 0.1, 0.1, 1.0); 15 | } 16 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/vertical_bar.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | uniform vec4 line_color; 8 | uniform float time; 9 | 10 | void main(){ 11 | color = line_color; 12 | //color = vec4(0, 0, 0, 0.1); 13 | //int x = int(gl_FragCoord.y / 1); 14 | //int y = int(gl_FragCoord.x / 1); 15 | //if ((x+y) % 2 == 0){ 16 | // color = vec4(0, 0, 0, 0.2); 17 | //} 18 | //else{ 19 | // color = vec4(0, 0, 0, 0.1); 20 | //} 21 | //color = vec4(0, 0, 0, abs(sin(gl_FragCoord.y / 10 + gl_FragCoord.x / 10))); 22 | //if (abs(uvs.x - fract(time * freq)) < 0.05){ 23 | //color = vec4(line_color, 0.1); 24 | //} 25 | //else{ 26 | //color = vec4(0, 0, 0, 0.1); 27 | //} 28 | //color = vec4(line_color * pow(abs(sin(uvs.x - time * freq)), 128), 0.3); 29 | //color = vec4(line_color * abs(sin(time)), 0.3); 30 | //color = vec4(line_color, 0.3); 31 | } -------------------------------------------------------------------------------- /pdf_viewer/shaders/vertical_bar_dark.fragment: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | out vec4 color; 4 | in vec2 screen_pos; 5 | in vec2 uvs; 6 | 7 | uniform vec4 line_color; 8 | uniform float time; 9 | 10 | void main(){ 11 | color = vec4((1-line_color.rgb), line_color.a); 12 | } -------------------------------------------------------------------------------- /pdf_viewer/synctex/synctex_parser_local.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008, 2009, 2010 , 2011 jerome DOT laurens AT u-bourgogne DOT fr 3 | 4 | This file is part of the SyncTeX package. 5 | 6 | Latest Revision: Sun Oct 15 15:09:55 UTC 2017 7 | 8 | Version: 1.21 9 | 10 | See synctex_parser_readme.txt for more details 11 | 12 | License: 13 | -------- 14 | Permission is hereby granted, free of charge, to any person 15 | obtaining a copy of this software and associated documentation 16 | files (the "Software"), to deal in the Software without 17 | restriction, including without limitation the rights to use, 18 | copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | copies of the Software, and to permit persons to whom the 20 | Software is furnished to do so, subject to the following 21 | conditions: 22 | 23 | The above copyright notice and this permission notice shall be 24 | included in all copies or substantial portions of the Software. 25 | 26 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 28 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 30 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 31 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 32 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 33 | OTHER DEALINGS IN THE SOFTWARE 34 | 35 | Except as contained in this notice, the name of the copyright holder 36 | shall not be used in advertising or otherwise to promote the sale, 37 | use or other dealings in this Software without prior written 38 | authorization from the copyright holder. 39 | 40 | */ 41 | 42 | /* This local header file is for TEXLIVE, use your own header to fit your system */ 43 | # include /* for inline && HAVE_xxx */ 44 | /* No inlining for synctex tool in texlive. */ 45 | # define SYNCTEX_INLINE 46 | -------------------------------------------------------------------------------- /pdf_viewer/synctex/synctex_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008-2017 jerome DOT laurens AT u-bourgogne DOT fr 3 | 4 | This file is part of the __SyncTeX__ package. 5 | 6 | [//]: # (Latest Revision: Fri Jul 14 16:20:41 UTC 2017) 7 | [//]: # (Version: 1.21) 8 | 9 | See `synctex_parser_readme.md` for more details 10 | 11 | ## License 12 | 13 | Permission is hereby granted, free of charge, to any person 14 | obtaining a copy of this software and associated documentation 15 | files (the "Software"), to deal in the Software without 16 | restriction, including without limitation the rights to use, 17 | copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | copies of the Software, and to permit persons to whom the 19 | Software is furnished to do so, subject to the following 20 | conditions: 21 | 22 | The above copyright notice and this permission notice shall be 23 | included in all copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 27 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 29 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 30 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 32 | OTHER DEALINGS IN THE SOFTWARE 33 | 34 | Except as contained in this notice, the name of the copyright holder 35 | shall not be used in advertising or otherwise to promote the sale, 36 | use or other dealings in this Software without prior written 37 | authorization from the copyright holder. 38 | 39 | ## Acknowledgments: 40 | 41 | The author received useful remarks from the __pdfTeX__ developers, especially Hahn The Thanh, 42 | and significant help from __XeTeX__ developer Jonathan Kew. 43 | 44 | ## Nota Bene: 45 | 46 | If you include or use a significant part of the __SyncTeX__ package into a software, 47 | I would appreciate to be listed as contributor and see "__SyncTeX__" highlighted. 48 | */ 49 | 50 | #ifndef __SYNCTEX_VERSION__ 51 | # define __SYNCTEX_VERSION__ 52 | 53 | # define SYNCTEX_VERSION_MAJOR 1 54 | 55 | # define SYNCTEX_VERSION_STRING "1.21" 56 | 57 | # define SYNCTEX_CLI_VERSION_STRING "1.5" 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchAudioButtons.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchAudioButtons : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchAudioButtons(QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | void set_rate(float rate); 15 | void set_playing(); 16 | void set_paused(); 17 | 18 | public slots: 19 | void handlePlay(); 20 | void handlePause(); 21 | void handleStop(); 22 | void handleSetRate(qreal rate); 23 | //void handleIncreaseSpeed(); 24 | //void handleDecreaseSpeed(); 25 | //void handleInitial(); 26 | 27 | signals: 28 | void playPressed(); 29 | void pausePressed(); 30 | void stopPressed(); 31 | void rateChanged(qreal rate); 32 | //void speedIncreasePressed(); 33 | //void speedDecreasePressed(); 34 | //void initialPressed(); 35 | 36 | private: 37 | QQuickWidget* quick_widget = nullptr; 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchCheckbox.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchCheckbox.h" 2 | 3 | 4 | TouchCheckbox::TouchCheckbox(QString name, bool initial_value, QWidget* parent) : QWidget(parent) { 5 | 6 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 7 | quick_widget = new QQuickWidget(this); 8 | 9 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 10 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 11 | quick_widget->setClearColor(Qt::transparent); 12 | 13 | quick_widget->rootContext()->setContextProperty("_initialValue", initial_value); 14 | quick_widget->rootContext()->setContextProperty("_name", name); 15 | 16 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchCheckbox.qml")); 17 | 18 | 19 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(valueSelected(bool)), this, SLOT(handleSelect(bool))); 20 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(canceled()), this, SLOT(handleCancel())); 21 | 22 | } 23 | 24 | void TouchCheckbox::handleSelect(bool item) { 25 | emit itemSelected(item); 26 | } 27 | 28 | void TouchCheckbox::handleCancel() { 29 | emit canceled(); 30 | } 31 | 32 | void TouchCheckbox::resizeEvent(QResizeEvent* resize_event) { 33 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 34 | QWidget::resizeEvent(resize_event); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchCheckbox.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchCheckbox : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchCheckbox(QString name, bool initial_value, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleSelect(bool item); 17 | void handleCancel(); 18 | 19 | signals: 20 | void itemSelected(bool); 21 | void canceled(); 22 | 23 | private: 24 | QQuickWidget* quick_widget = nullptr; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchCheckbox.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | 6 | 7 | Rectangle { 8 | color: "#444" 9 | id: root 10 | radius: 10 11 | 12 | signal valueSelected(val: bool) 13 | 14 | Item{ 15 | id: rowid 16 | anchors.centerIn: parent 17 | width: lbl.width + checkbox.width 18 | //width: parent.width / 2 19 | height: parent.height / 2 20 | 21 | Label{ 22 | id: lbl 23 | text: _name 24 | color: "white" 25 | anchors.left: checkbox.right 26 | anchors.verticalCenter: checkbox.verticalCenter 27 | } 28 | 29 | 30 | CheckBox{ 31 | //anchors.centerIn: parent 32 | id: checkbox 33 | checked: _initialValue 34 | } 35 | 36 | anchors { 37 | left: parent.left 38 | right: parent.right 39 | verticalCenter: parent.verticalCenter 40 | } 41 | } 42 | 43 | Button{ 44 | text: "Confirm" 45 | anchors { 46 | horizontalCenter: parent.horizontalCenter 47 | top: rowid.bottom 48 | } 49 | 50 | onClicked: { 51 | root.valueSelected(checkbox.checked); 52 | // console.log("something has happened!"); 53 | } 54 | } 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchConfigMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "mysortfilterproxymodel.h" 11 | #include "config.h" 12 | 13 | 14 | //class MySortFilterProxyModel; 15 | class MainWidget; 16 | 17 | class TouchConfigMenu : public QWidget { 18 | Q_OBJECT 19 | public: 20 | //TouchConfigMenu(std::vector* configs, QWidget* parent = nullptr); 21 | TouchConfigMenu(bool fuzzy, MainWidget* main_widget); 22 | void resizeEvent(QResizeEvent* resize_event) override; 23 | 24 | public slots: 25 | void handleColor3ConfigChanged(QString config_name, qreal r, qreal g, qreal b); 26 | void handleColor4ConfigChanged(QString config_name, qreal r, qreal g, qreal b, qreal a); 27 | void handleBoolConfigChanged(QString config_name, bool new_value); 28 | void handleFloatConfigChanged(QString config_name, qreal new_value); 29 | void handleIntConfigChanged(QString config_name, int new_value); 30 | void handleTextConfigChanged(QString config_name, QString new_value); 31 | void handleSetConfigPressed(QString config_name); 32 | void handleSaveButtonClicked(); 33 | //void handlePressAndHold(QString value, int index); 34 | //void handleDelete(QString value, int index); 35 | 36 | signals: 37 | //void itemSelected(QString value, int index); 38 | //void itemPressAndHold(QString value, int index); 39 | //void itemDeleted(QString value, int index); 40 | 41 | private: 42 | QQuickWidget* quick_widget = nullptr; 43 | ConfigManager* config_manager; 44 | //QStringList items; 45 | //QStringListModel model; 46 | MainWidget* main_widget; 47 | ConfigModel config_model; 48 | MySortFilterProxyModel* proxy_model; 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchCopyOptions.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchCopyOptions.h" 2 | 3 | 4 | TouchCopyOptions::TouchCopyOptions(QWidget* parent) : QWidget(parent) { 5 | 6 | setAttribute(Qt::WA_NoMousePropagation); 7 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 8 | quick_widget = new QQuickWidget(this); 9 | 10 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 11 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 12 | quick_widget->setClearColor(Qt::transparent); 13 | 14 | // quick_widget->rootContext()->setContextProperty("_initialValue", initial_value); 15 | // quick_widget->rootContext()->setContextProperty("_from", from); 16 | // quick_widget->rootContext()->setContextProperty("_to", to); 17 | 18 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchCopyOptions.qml")); 19 | 20 | 21 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(copyPressed()), this, SLOT(handleCopyClicked())); 22 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(scholarPressed()), this, SLOT(handleScholarClicked())); 23 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(googlePressed()), this, SLOT(handleGoogleClicked())); 24 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(highlightPressed()), this, SLOT(handleHighlightClicked())); 25 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(searchPressed()), this, SLOT(handleSearchClicked())); 26 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(downloadPressed()), this, SLOT(handleDownloadClicked())); 27 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(smartJumpPressed()), this, SLOT(handleSmartJumpClicked())); 28 | 29 | } 30 | 31 | void TouchCopyOptions::handleCopyClicked() { 32 | emit copyClicked(); 33 | } 34 | 35 | void TouchCopyOptions::handleSearchClicked() { 36 | emit searchClicked(); 37 | } 38 | 39 | void TouchCopyOptions::handleScholarClicked() { 40 | emit scholarClicked(); 41 | } 42 | 43 | void TouchCopyOptions::handleGoogleClicked() { 44 | emit googleClicked(); 45 | } 46 | 47 | void TouchCopyOptions::handleHighlightClicked() { 48 | emit highlightClicked(); 49 | } 50 | 51 | void TouchCopyOptions::handleDownloadClicked() { 52 | emit downloadClicked(); 53 | } 54 | 55 | void TouchCopyOptions::handleSmartJumpClicked() { 56 | emit smartJumpClicked(); 57 | } 58 | 59 | 60 | void TouchCopyOptions::resizeEvent(QResizeEvent* resize_event) { 61 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 62 | // quick_widget->rootObject()->setSize(resize_event->size()); 63 | QWidget::resizeEvent(resize_event); 64 | 65 | } 66 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchCopyOptions.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchCopyOptions : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchCopyOptions(QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleCopyClicked(); 17 | void handleSearchClicked(); 18 | void handleScholarClicked(); 19 | void handleGoogleClicked(); 20 | void handleHighlightClicked(); 21 | void handleDownloadClicked(); 22 | void handleSmartJumpClicked(); 23 | 24 | signals: 25 | void copyClicked(); 26 | void searchClicked(); 27 | void scholarClicked(); 28 | void googleClicked(); 29 | void highlightClicked(); 30 | void downloadClicked(); 31 | void smartJumpClicked(); 32 | 33 | private: 34 | QQuickWidget* quick_widget = nullptr; 35 | 36 | }; 37 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchCopyOptions.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Layouts 1.1 5 | 6 | import "qrc:/pdf_viewer/touchui" 7 | 8 | //import com.myself 1.0 9 | 10 | Item{ 11 | 12 | 13 | id: root 14 | height: 50 15 | 16 | signal copyPressed() 17 | signal searchPressed() 18 | signal scholarPressed() 19 | signal googlePressed() 20 | signal highlightPressed() 21 | signal downloadPressed() 22 | signal smartJumpPressed() 23 | 24 | TouchButtonGroup{ 25 | anchors.fill: parent 26 | 27 | buttons: [ 28 | "qrc:/icons/copy.svg", 29 | "qrc:/icons/search.svg", 30 | "qrc:/icons/google-scholar.svg", 31 | "qrc:/icons/google.svg", 32 | "qrc:/icons/jump-right.svg", 33 | "qrc:/icons/paper-download.svg", 34 | "qrc:/icons/highlight.svg", 35 | ] 36 | 37 | tips: ["Copy", "Search in PDF", "Search in Google Scholar", "Search in Google", "Jump to reference", "Download", "Highlight"] 38 | onButtonClicked: function(index, val) { 39 | if (index == 0){ 40 | root.copyPressed(); 41 | } 42 | 43 | if (index == 1){ 44 | root.searchPressed(); 45 | } 46 | 47 | if (index == 2){ 48 | root.scholarPressed(); 49 | } 50 | 51 | if (index == 3){ 52 | root.googlePressed(); 53 | } 54 | 55 | if (index == 4){ 56 | root.smartJumpPressed(); 57 | } 58 | if (index == 5){ 59 | root.downloadPressed(); 60 | } 61 | if (index == 6){ 62 | root.highlightPressed(); 63 | } 64 | 65 | } 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchDeleteButton.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchDeleteButton.h" 2 | 3 | 4 | TouchDeleteButton::TouchDeleteButton(QWidget* parent) : QWidget(parent) { 5 | 6 | setAttribute(Qt::WA_NoMousePropagation); 7 | 8 | quick_widget = new QQuickWidget(this); 9 | 10 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 11 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 12 | quick_widget->setClearColor(Qt::transparent); 13 | 14 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchDeleteButton.qml")); 15 | 16 | 17 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 18 | SIGNAL(deleteButtonClicked()), 19 | this, 20 | SLOT(handleDelete())); 21 | 22 | 23 | } 24 | 25 | void TouchDeleteButton::handleDelete() { 26 | emit deletePressed(); 27 | } 28 | 29 | void TouchDeleteButton::resizeEvent(QResizeEvent* resize_event) { 30 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 31 | QWidget::resizeEvent(resize_event); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchDeleteButton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchDeleteButton : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchDeleteButton(QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleDelete(); 17 | 18 | signals: 19 | void deletePressed(); 20 | 21 | private: 22 | QQuickWidget* quick_widget = nullptr; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchDeleteButton.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | import "qrc:/pdf_viewer/touchui" 6 | 7 | 8 | TouchButtonGroup{ 9 | 10 | signal deleteButtonClicked(); 11 | 12 | id: root 13 | 14 | buttons: ["delete"] 15 | color: "red" 16 | 17 | onButtonClicked: function (index, name){ 18 | if (index == 0){ 19 | root.deleteButtonClicked(); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchDrawControls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchDrawControls : public QWidget { 10 | Q_OBJECT 11 | public: 12 | bool is_in_scratchpad = false; 13 | 14 | TouchDrawControls(float pen_size, char selected_symbol, QWidget* parent = nullptr); 15 | void resizeEvent(QResizeEvent* resize_event) override; 16 | void setDrawType(char type); 17 | void set_pen_size(float size); 18 | void set_scratchpad_mode(bool mode); 19 | 20 | public slots: 21 | void handleExitDrawMode(); 22 | void handleEnablePenDrawMode(); 23 | void handleDisablePenDrawMode(); 24 | void handleChangeColor(int); 25 | void handleEraser(); 26 | void handleScreenshot(); 27 | void handleToggleScratchpad(); 28 | void handlePenSizeChanged(qreal size); 29 | void handleSaveScratchpad(); 30 | void handleLoadScratchpad(); 31 | void handleMove(); 32 | 33 | signals: 34 | void exitDrawModePressed(); 35 | void enablePenDrawModePressed(); 36 | void disablePenDrawModePressed(); 37 | void changeColorPressed(int); 38 | void eraserPressed(); 39 | void penSizeChanged(qreal size); 40 | void screenshotPressed(); 41 | void toggleScratchpadPressed(); 42 | void saveScratchpadPressed(); 43 | void loadScratchpadPressed(); 44 | void movePressed(); 45 | 46 | private: 47 | QQuickWidget* quick_widget = nullptr; 48 | 49 | }; 50 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchGenericButtons.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchGenericButtons.h" 2 | #include 3 | 4 | 5 | TouchGenericButtons::TouchGenericButtons(std::vector buttons, std::vector tips, bool top, QWidget* parent) : QWidget(parent) { 6 | 7 | setAttribute(Qt::WA_NoMousePropagation); 8 | 9 | is_top = top; 10 | options = buttons; 11 | QList q_buttons; 12 | QList q_tips; 13 | 14 | for (auto button : buttons) { 15 | q_buttons.append(QString::fromStdWString(button)); 16 | } 17 | 18 | for (auto tip : tips) { 19 | q_tips.append(QString::fromStdWString(tip)); 20 | } 21 | 22 | //QStringListModel* buttons_model = new QStringListModel(q_buttons, this); 23 | 24 | quick_widget = new QQuickWidget(this); 25 | 26 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 27 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 28 | quick_widget->setClearColor(Qt::transparent); 29 | 30 | quick_widget->rootContext()->setContextProperty("_buttons", q_buttons); 31 | quick_widget->rootContext()->setContextProperty("_tips", q_tips); 32 | 33 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchGenericButtons.qml")); 34 | 35 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 36 | SIGNAL(genericButtonClicked(int, QString)), 37 | this, 38 | SLOT(handleButton(int, QString))); 39 | 40 | 41 | } 42 | 43 | void TouchGenericButtons::handleButton(int index, QString value) { 44 | emit buttonPressed(index, value.toStdWString()); 45 | } 46 | 47 | void TouchGenericButtons::resizeEvent(QResizeEvent* resize_event) { 48 | 49 | int parent_width = parentWidget()->size().width(); 50 | int parent_height = parentWidget()->size().height(); 51 | 52 | int width = 2 * parent_width / 3; 53 | int height = parent_height / 12; 54 | if (width > (150 * options.size())) { 55 | width = 150 * options.size(); 56 | } 57 | 58 | resize(width, height); 59 | if (is_top) { 60 | move(parent_width / 2 - width / 2, height / 2); 61 | } 62 | else { 63 | move(parent_width / 2 - width / 2, parent_height - 3 * height / 2); 64 | } 65 | quick_widget->resize(width, height); 66 | 67 | QWidget::resizeEvent(resize_event); 68 | 69 | } 70 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchGenericButtons.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchGenericButtons : public QWidget { 10 | Q_OBJECT 11 | public: 12 | std::vector options; 13 | bool is_top = false; 14 | TouchGenericButtons(std::vector buttons, std::vector tips, bool top, QWidget* parent = nullptr); 15 | void resizeEvent(QResizeEvent* resize_event) override; 16 | 17 | public slots: 18 | void handleButton(int index, QString value); 19 | 20 | signals: 21 | void buttonPressed(int index, std::wstring value); 22 | 23 | private: 24 | QQuickWidget* quick_widget = nullptr; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchGenericButtons.qml: -------------------------------------------------------------------------------- 1 |  2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | import "qrc:/pdf_viewer/touchui" 6 | 7 | 8 | TouchButtonGroup{ 9 | 10 | signal genericButtonClicked(index: int, value: string); 11 | 12 | //property list _buttons; 13 | 14 | id: root 15 | 16 | buttons: _buttons 17 | tips: _tips 18 | 19 | onButtonClicked: function (index, name){ 20 | root.genericButtonClicked(index, name); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchHighlightButtons.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchHighlightButtons : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchHighlightButtons(char selected_symbol, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | void setHighlightType(char type); 15 | 16 | public slots: 17 | void handleDelete(); 18 | void handleEdit(); 19 | void handleChangeColor(int); 20 | 21 | signals: 22 | void deletePressed(); 23 | void editPressed(); 24 | void changeColorPressed(int); 25 | 26 | private: 27 | QQuickWidget* quick_widget = nullptr; 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchHighlightButtons.qml: -------------------------------------------------------------------------------- 1 |  2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | import "qrc:/pdf_viewer/touchui" 6 | 7 | 8 | Rectangle{ 9 | signal deleteButtonClicked(); 10 | signal editButtonClicked(); 11 | signal changeColorClicked(index: int); 12 | 13 | id: root 14 | color: "#00ffffff" 15 | radius: 5 16 | property bool are_color_buttons_visible: false 17 | 18 | function on_restart(){ 19 | root.are_color_buttons_visible = false; 20 | } 21 | 22 | TouchButtonGroup{ 23 | // anchors.right: parent.horizontalCenter 24 | // anchors.rightMargin: 10 25 | anchors.horizontalCenter: parent.horizontalCenter 26 | anchors.top: parent.top 27 | anchors.bottom: parent.bottom 28 | width: Math.min(3 * parent.width / 5, 225) 29 | 30 | 31 | id: deletebutton 32 | 33 | //buttons: ["🗑️"] 34 | buttons: ["Delete", "Edit", ""] 35 | // color: "black" 36 | colors: ["black", "black", _current_color] 37 | 38 | visible: !root.are_color_buttons_visible 39 | onButtonClicked: function (index, name){ 40 | if (index == 0){ 41 | root.deleteButtonClicked(); 42 | } 43 | if (index == 1){ 44 | root.editButtonClicked(); 45 | } 46 | if (index == 2){ 47 | root.are_color_buttons_visible = true; 48 | } 49 | } 50 | } 51 | 52 | TouchSymbolColorSelector{ 53 | colors: _colors 54 | anchors.fill: parent 55 | visible: root.are_color_buttons_visible 56 | 57 | onColorClicked: function(index){ 58 | root.changeColorClicked(index); 59 | root.are_color_buttons_visible = !root.are_color_buttons_visible; 60 | } 61 | 62 | onColorHeld: function(index){ 63 | root.changeColorClicked(index + 26); 64 | root.are_color_buttons_visible = !root.are_color_buttons_visible; 65 | } 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchListView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class MySortFilterProxyModel; 12 | 13 | class TouchListView : public QWidget { 14 | Q_OBJECT 15 | public: 16 | QAbstractItemModel* model; 17 | MySortFilterProxyModel* proxy_model; 18 | QQuickWidget* quick_widget = nullptr; 19 | TouchListView(bool is_fuzzy, QStringList elements, int selected_index, QWidget* parent = nullptr, bool deletable = false); 20 | TouchListView(bool is_fuzzy, QAbstractItemModel* elements, int selected_index, QWidget* parent = nullptr, bool deletable = false, bool move = true, bool is_tree = false); 21 | void initialize(int selected_index, bool deletable, bool is_tree = false); 22 | void resizeEvent(QResizeEvent* resize_event) override; 23 | void set_keyboard_focus(); 24 | void keyPressEvent(QKeyEvent* kevent); 25 | void update_model(); 26 | 27 | public slots: 28 | void handleSelect(QString value, int index); 29 | void handlePressAndHold(QString value, int index); 30 | void handleDelete(QString value, int index); 31 | 32 | signals: 33 | void itemSelected(QString value, int index); 34 | void itemPressAndHold(QString value, int index); 35 | void itemDeleted(QString value, int index); 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchMacroEditor.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchMacroEditor.h" 2 | #include "utils.h" 3 | #include 4 | #include 5 | #include "main_widget.h" 6 | #include 7 | 8 | TouchMacroEditor::TouchMacroEditor(std::string macro, QWidget* parent, MainWidget* main_widget) : QWidget(parent) { 9 | 10 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 11 | 12 | auto commands_model = main_widget->get_new_command_list_model(); 13 | commands_model->setParent(this); 14 | QSortFilterProxyModel* proxy_model = new QSortFilterProxyModel(this); 15 | proxy_model->setSourceModel(commands_model); 16 | 17 | 18 | setAttribute(Qt::WA_NoMousePropagation); 19 | quick_widget = new QQuickWidget(this); 20 | 21 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 22 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 23 | quick_widget->setClearColor(Qt::transparent); 24 | 25 | quick_widget->rootContext()->setContextProperty("_macro", QString::fromStdString(macro)); 26 | quick_widget->rootContext()->setContextProperty("_commands_model", proxy_model); 27 | quick_widget->rootContext()->setContextProperty("_selected_index", 0); 28 | 29 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchMacroEditor.qml")); 30 | 31 | 32 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(confirmed(QString)), this, SLOT(handleConfirm(QString))); 33 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(canceled()), this, SLOT(handleCancel())); 34 | 35 | } 36 | 37 | void TouchMacroEditor::handleConfirm(QString macro) { 38 | emit macroConfirmed(macro.toStdString()); 39 | } 40 | 41 | void TouchMacroEditor::handleCancel() { 42 | emit canceled(); 43 | } 44 | 45 | void TouchMacroEditor::resizeEvent(QResizeEvent* resize_event) { 46 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 47 | QWidget::resizeEvent(resize_event); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchMacroEditor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class MainWidget; 10 | 11 | class TouchMacroEditor : public QWidget { 12 | Q_OBJECT 13 | public: 14 | TouchMacroEditor(std::string macro, QWidget* parent, MainWidget* main_widget); 15 | void resizeEvent(QResizeEvent* resize_event) override; 16 | 17 | public slots: 18 | void handleConfirm(QString macro); 19 | void handleCancel(); 20 | 21 | signals: 22 | void macroConfirmed(std::string); 23 | void canceled(); 24 | 25 | private: 26 | QQuickWidget* quick_widget = nullptr; 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchMainMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchMainMenu : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchMainMenu(bool fit_mode, bool portaling, bool fullscreen, bool ruler, bool speaking, bool locked, int current_colorscheme_index, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleSelectText(); 17 | void handleGotoPage(); 18 | void handleToc(); 19 | void handleSearch(); 20 | void handleFullscreen(); 21 | void handleBookmarks(); 22 | void handleHighlights(); 23 | void handleRuler(); 24 | void handleLightColorscheme(); 25 | void handleDarkColorscheme(); 26 | void handleCustomColorscheme(); 27 | void handleOpenPrevDoc(); 28 | void handleOpenNewDoc(); 29 | void handleCommands(); 30 | void handleSettings(); 31 | void handleAddBookmark(); 32 | void handlePortal(); 33 | void handleDeletePortal(); 34 | void handleGlobalBookmarks(); 35 | void handleGlobalHighlights(); 36 | void handleTTS(); 37 | void handleHorizontalLock(); 38 | void handleFitToPageWidth(); 39 | void handleDrawingMode(); 40 | void handleDownloadPaper(); 41 | void handleHint(); 42 | 43 | signals: 44 | void selectTextClicked(); 45 | void gotoPageClicked(); 46 | void tocClicked(); 47 | void searchClicked(); 48 | void fullscreenClicked(); 49 | void bookmarksClicked(); 50 | void highlightsClicked(); 51 | void rulerModeClicked(); 52 | void lightColorschemeClicked(); 53 | void darkColorschemeClicked(); 54 | void customColorschemeClicked(); 55 | void openPrevDocClicked(); 56 | void openNewDocClicked(); 57 | void commandsClicked(); 58 | void settingsClicked(); 59 | void addBookmarkClicked(); 60 | void portalClicked(); 61 | void deletePortalClicked(); 62 | void globalBookmarksClicked(); 63 | void globalHighlightsClicked(); 64 | void ttsClicked(); 65 | void horizontalLockClicked(); 66 | void fitToPageWidthClicked(); 67 | void drawingModeClicked(); 68 | void downloadPaperClicked(); 69 | void hintClicked(); 70 | 71 | private: 72 | QQuickWidget* quick_widget = nullptr; 73 | 74 | }; 75 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchMarkSelector.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchMarkSelector.h" 2 | 3 | 4 | TouchMarkSelector::TouchMarkSelector(QWidget* parent) : QWidget(parent) { 5 | 6 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 7 | quick_widget = new QQuickWidget(this); 8 | 9 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 10 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 11 | quick_widget->setClearColor(Qt::transparent); 12 | 13 | //quick_widget->rootContext()->setContextProperty("_initialValue", initial_value); 14 | //quick_widget->rootContext()->setContextProperty("_name", name); 15 | 16 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchMarkSelector.qml")); 17 | quick_widget->setFocus(); 18 | 19 | 20 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 21 | SIGNAL(markSelected(QString)), 22 | this, 23 | SLOT(handleMarkSelected(QString))); 24 | 25 | 26 | } 27 | 28 | void TouchMarkSelector::handleMarkSelected(QString text) { 29 | emit onMarkSelected(text); 30 | } 31 | 32 | void TouchMarkSelector::resizeEvent(QResizeEvent* resize_event) { 33 | quick_widget->resize(0, 0); 34 | resize(0, 0); 35 | QWidget::resizeEvent(resize_event); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchMarkSelector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchMarkSelector : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchMarkSelector(QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleMarkSelected(QString mark); 17 | 18 | signals: 19 | void onMarkSelected(QString mark); 20 | 21 | private: 22 | QQuickWidget* quick_widget = nullptr; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchMarkSelector.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | import "qrc:/pdf_viewer/touchui" 6 | 7 | 8 | // Rectangle{ 9 | // color: "black" 10 | // } 11 | 12 | TextInput{ 13 | 14 | signal markSelected(mark: string); 15 | 16 | id: root 17 | focus: true 18 | inputMethodHints: Qt.ImhSensitiveData | Qt.ImhPreferLowercase | Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText 19 | 20 | //buttons: ["delete"] 21 | //color: "red" 22 | 23 | onTextChanged: { 24 | markSelected(text); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchPageSelector.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchPageSelector.h" 2 | 3 | 4 | TouchPageSelector::TouchPageSelector(int from, int to, int initial_value, QWidget* parent) : QWidget(parent) { 5 | 6 | setAttribute(Qt::WA_NoMousePropagation); 7 | quick_widget = new QQuickWidget(this); 8 | 9 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 10 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 11 | quick_widget->setClearColor(Qt::transparent); 12 | 13 | quick_widget->rootContext()->setContextProperty("_value", initial_value); 14 | quick_widget->rootContext()->setContextProperty("_from", from); 15 | quick_widget->rootContext()->setContextProperty("_to", to); 16 | 17 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchPageSelector.qml")); 18 | 19 | 20 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(pageSelected(int)), this, SLOT(handleSelect(int))); 21 | 22 | } 23 | 24 | void TouchPageSelector::handleSelect(int item) { 25 | emit pageSelected(item); 26 | } 27 | 28 | void TouchPageSelector::resizeEvent(QResizeEvent* resize_event) { 29 | int rwidth = resize_event->size().width(); 30 | int rheight = resize_event->size().height(); 31 | 32 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 33 | QWidget::resizeEvent(resize_event); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchPageSelector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchPageSelector : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchPageSelector(int from, int to, int initial_value, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleSelect(int page); 17 | 18 | signals: 19 | void pageSelected(int); 20 | 21 | private: 22 | QQuickWidget* quick_widget = nullptr; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchRangeSelectUI.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchRangeSelectUI.h" 2 | 3 | 4 | TouchRangeSelectUI::TouchRangeSelectUI(float initial_top, 5 | float initial_bottom, 6 | QWidget* parent) : QWidget(parent) { 7 | 8 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 9 | setAttribute(Qt::WA_NoMousePropagation); 10 | quick_widget = new QQuickWidget(this); 11 | 12 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 13 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 14 | quick_widget->setClearColor(Qt::transparent); 15 | 16 | quick_widget->rootContext()->setContextProperty("_top", initial_top); 17 | quick_widget->rootContext()->setContextProperty("_bottom", initial_bottom); 18 | 19 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchRangeSelectUI.qml")); 20 | 21 | // force a parent resize so we have the correct size 22 | // parentWidget()->resize(parentWidget()->width(), parentWidget()->height()); 23 | // resize(parentWidget()->width(), parentWidget()->height()); 24 | 25 | 26 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 27 | SIGNAL(confirmPressed(qreal, qreal)), 28 | this, 29 | SLOT(handleRangeSelected(qreal, qreal))); 30 | 31 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 32 | SIGNAL(cancelPressed()), 33 | this, 34 | SLOT(handleRangeCanceled())); 35 | 36 | } 37 | 38 | void TouchRangeSelectUI::handleRangeSelected(qreal top, qreal bottom) { 39 | emit rangeSelected(top, bottom); 40 | } 41 | 42 | void TouchRangeSelectUI::handleRangeCanceled() { 43 | emit rangeCanceled(); 44 | } 45 | 46 | 47 | void TouchRangeSelectUI::resizeEvent(QResizeEvent* resize_event) { 48 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 49 | // quick_widget->rootObject()->setSize(resize_event->size()); 50 | QWidget::resizeEvent(resize_event); 51 | 52 | } 53 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchRangeSelectUI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchRangeSelectUI : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchRangeSelectUI(float initial_top, float initial_bottom, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleRangeSelected(qreal, qreal); 17 | void handleRangeCanceled(); 18 | 19 | signals: 20 | void rangeSelected(qreal, qreal); 21 | void rangeCanceled(); 22 | 23 | private: 24 | QQuickWidget* quick_widget = nullptr; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchRectangleSelectUI.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchRectangleSelectUI.h" 2 | 3 | 4 | TouchRectangleSelectUI::TouchRectangleSelectUI(bool initial_enabled, 5 | float initial_x, 6 | float initial_y, 7 | float initial_width, 8 | float initial_height, 9 | QWidget* parent) : QWidget(parent) { 10 | 11 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 12 | setAttribute(Qt::WA_NoMousePropagation); 13 | quick_widget = new QQuickWidget(this); 14 | 15 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 16 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 17 | quick_widget->setClearColor(Qt::transparent); 18 | 19 | quick_widget->rootContext()->setContextProperty("_enabled", initial_enabled); 20 | quick_widget->rootContext()->setContextProperty("_x", initial_x); 21 | quick_widget->rootContext()->setContextProperty("_y", initial_y); 22 | quick_widget->rootContext()->setContextProperty("_width", initial_width); 23 | quick_widget->rootContext()->setContextProperty("_height", initial_height); 24 | 25 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchRectangleSelectUI.qml")); 26 | 27 | 28 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 29 | SIGNAL(rectangleSelected(bool, qreal, qreal, qreal, qreal)), 30 | this, 31 | SLOT(handleRectangleSelected(bool, qreal, qreal, qreal, qreal))); 32 | 33 | } 34 | 35 | void TouchRectangleSelectUI::handleRectangleSelected(bool enabled, qreal left, qreal right, qreal top, qreal bottom) { 36 | emit rectangleSelected(enabled, left, right, top, bottom); 37 | } 38 | 39 | 40 | void TouchRectangleSelectUI::resizeEvent(QResizeEvent* resize_event) { 41 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 42 | // quick_widget->rootObject()->setSize(resize_event->size()); 43 | QWidget::resizeEvent(resize_event); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchRectangleSelectUI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchRectangleSelectUI : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchRectangleSelectUI(bool initial_enabled, float initial_x, float initial_y, float initial_width, float intitial_height, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleRectangleSelected(bool, qreal, qreal, qreal, qreal); 17 | 18 | signals: 19 | void rectangleSelected(bool, qreal, qreal, qreal, qreal); 20 | 21 | private: 22 | QQuickWidget* quick_widget = nullptr; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSearchButtons.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchSearchButtons.h" 2 | 3 | 4 | TouchSearchButtons::TouchSearchButtons(QWidget* parent) : QWidget(parent) { 5 | 6 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 7 | quick_widget = new QQuickWidget(this); 8 | 9 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 10 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 11 | quick_widget->setClearColor(Qt::transparent); 12 | 13 | //quick_widget->rootContext()->setContextProperty("_initialValue", initial_value); 14 | //quick_widget->rootContext()->setContextProperty("_name", name); 15 | 16 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchSearchButtons.qml")); 17 | 18 | 19 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 20 | SIGNAL(prevButtonClicked()), 21 | this, 22 | SLOT(handlePrevious())); 23 | 24 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 25 | SIGNAL(nextButtonClicked()), 26 | this, 27 | SLOT(handleNext())); 28 | 29 | QObject::connect(dynamic_cast(quick_widget->rootObject()), 30 | SIGNAL(initialButtonClicked()), 31 | this, 32 | SLOT(handleInitial())); 33 | 34 | 35 | } 36 | 37 | void TouchSearchButtons::handlePrevious() { 38 | emit previousPressed(); 39 | } 40 | void TouchSearchButtons::handleNext() { 41 | emit nextPressed(); 42 | } 43 | void TouchSearchButtons::handleInitial() { 44 | emit initialPressed(); 45 | } 46 | 47 | void TouchSearchButtons::resizeEvent(QResizeEvent* resize_event) { 48 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 49 | QWidget::resizeEvent(resize_event); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSearchButtons.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchSearchButtons : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchSearchButtons(QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handlePrevious(); 17 | void handleNext(); 18 | void handleInitial(); 19 | 20 | signals: 21 | void previousPressed(); 22 | void nextPressed(); 23 | void initialPressed(); 24 | 25 | private: 26 | QQuickWidget* quick_widget = nullptr; 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSearchButtons.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | import "qrc:/pdf_viewer/touchui" 6 | 7 | 8 | TouchButtonGroup{ 9 | 10 | signal prevButtonClicked(); 11 | signal nextButtonClicked(); 12 | signal initialButtonClicked(); 13 | id: root 14 | 15 | //buttons: ["<-", "initial", "->"] 16 | buttons: ["qrc:/icons/left.svg","qrc:/icons/home.svg","qrc:/icons/right.svg"] 17 | 18 | onButtonClicked: function (index, name){ 19 | if (index == 0){ 20 | root.prevButtonClicked(); 21 | } 22 | if (index == 1){ 23 | root.initialButtonClicked(); 24 | } 25 | if (index == 2){ 26 | root.nextButtonClicked(); 27 | } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSettings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class MainWidget; 9 | class UIRect; 10 | 11 | class TouchSettings : public QWidget { 12 | Q_OBJECT 13 | public: 14 | TouchSettings(MainWidget* parent = nullptr); 15 | void resizeEvent(QResizeEvent* resize_event) override; 16 | 17 | public slots: 18 | void handleLightApplicationBackground(); 19 | void handleDarkApplicationBackground(); 20 | void handleCustomApplicationBackground(); 21 | void handleCustomPageText(); 22 | void handleCustomPageBackground(); 23 | void handleRulerModeBounds(); 24 | void handleRulerModeColor(); 25 | void handleRulerNext(); 26 | void handleRulerPrev(); 27 | void handleBack(); 28 | void handleForward(); 29 | void handlePortal(); 30 | void handleAllConfigs(); 31 | void handleRestoreDefaults(); 32 | //void handleGotoPage(); 33 | //void handleToc(); 34 | 35 | signals: 36 | //void lightApplicationBackgroundClicked(); 37 | //void gotoPageClicked(); 38 | 39 | private: 40 | void show_dialog_for_color_n(int n, float* color_location); 41 | void show_dialog_for_rect(UIRect* location); 42 | QQuickWidget* quick_widget = nullptr; 43 | MainWidget* main_widget; 44 | 45 | }; 46 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSlider.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchSlider.h" 2 | 3 | 4 | TouchSlider::TouchSlider(int from, int to, int initial_value, QWidget* parent) : QWidget(parent) { 5 | 6 | // quick_widget = new QQuickWidget(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml"), this); 7 | quick_widget = new QQuickWidget(this); 8 | 9 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 10 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 11 | quick_widget->setClearColor(Qt::transparent); 12 | 13 | quick_widget->rootContext()->setContextProperty("_initialValue", initial_value); 14 | quick_widget->rootContext()->setContextProperty("_from", from); 15 | quick_widget->rootContext()->setContextProperty("_to", to); 16 | 17 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchSlider.qml")); 18 | 19 | 20 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(valueSelected(int)), this, SLOT(handleSelect(int))); 21 | QObject::connect(dynamic_cast(quick_widget->rootObject()), SIGNAL(canceled()), this, SLOT(handleCancel())); 22 | 23 | } 24 | 25 | void TouchSlider::handleSelect(int item) { 26 | emit itemSelected(item); 27 | } 28 | 29 | void TouchSlider::handleCancel() { 30 | emit canceled(); 31 | } 32 | 33 | 34 | void TouchSlider::resizeEvent(QResizeEvent* resize_event) { 35 | quick_widget->resize(resize_event->size().width(), resize_event->size().height()); 36 | QWidget::resizeEvent(resize_event); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSlider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchSlider : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchSlider(int from, int to, int initial_value, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | 15 | public slots: 16 | void handleSelect(int item); 17 | void handleCancel(); 18 | 19 | signals: 20 | void itemSelected(int); 21 | void canceled(); 22 | 23 | private: 24 | QQuickWidget* quick_widget = nullptr; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSlider.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | Rectangle { 6 | // anchors.fill: parent 7 | // height: 300 8 | // width: parent.width 9 | // width: 100 10 | // height: 100 11 | 12 | // implicitWidth: 100 13 | // implicitHeight: 100 14 | // anchors.fill: parent 15 | //color: "#00000000" 16 | color: "#444" 17 | radius: 10 18 | //color: "black" 19 | // flags: Qt.WA_TranslucentBackground | Qt.WA_AlwaysStackOnTop 20 | // flags: Qt.WA_AlwaysStackOnTop 21 | id: root 22 | 23 | signal valueSelected(val: int) 24 | signal canceled() 25 | 26 | Slider{ 27 | from: _from 28 | to: _to 29 | id: my_slider 30 | value: _initialValue 31 | 32 | anchors { 33 | left: parent.left 34 | right: parent.right 35 | verticalCenter: parent.verticalCenter 36 | leftMargin: 10 37 | rightMargin: 10 38 | } 39 | 40 | 41 | 42 | } 43 | 44 | Row{ 45 | 46 | anchors { 47 | horizontalCenter: parent.horizontalCenter 48 | top: my_slider.bottom 49 | } 50 | Button{ 51 | text: "Confirm" 52 | 53 | onClicked: { 54 | root.valueSelected(my_slider.value); 55 | } 56 | } 57 | Button{ 58 | text: "Cancel" 59 | 60 | onClicked: { 61 | root.canceled(); 62 | } 63 | } 64 | } 65 | 66 | } 67 | 68 | 69 | //Slider{ 70 | // width: 300 71 | // height: 300 72 | 73 | // from: _from 74 | // to: _to 75 | // id: my_slider 76 | // value: _initialValue 77 | 78 | // signal valueSelected(val: int) 79 | 80 | //// anchors { 81 | //// left: parent.left 82 | //// right: parent.right 83 | //// verticalCenter: parent.verticalCenter 84 | //// } 85 | 86 | 87 | // Button{ 88 | // text: "Confirm" 89 | // anchors { 90 | // horizontalCenter: parent.horizontalCenter 91 | // top: my_slider.bottom 92 | // } 93 | 94 | // onClicked: { 95 | // my_slider.valueSelected(my_slider.value); 96 | // // console.log("something has happened!"); 97 | // } 98 | // } 99 | 100 | //} 101 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchSymbolColorSelector.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | import QtQuick.Layouts 1.1 5 | 6 | Item{ 7 | id: root 8 | property list colors; 9 | 10 | signal colorClicked(int index) 11 | signal colorHeld(int index) 12 | 13 | Repeater{ 14 | model: 26 15 | 16 | Rectangle{ 17 | required property int index 18 | anchors.top: get_top_anchor() 19 | anchors.bottom: get_bottom_anchor() 20 | 21 | width: is_too_small() ? parent.width / 13 : parent.width / 26 22 | x: is_too_small() ? (visible ? (index % 13) * width : root.width / 2 - width / 2) : (visible ? index * width : root.width / 2 - width / 2) 23 | color: root.colors[index] 24 | 25 | function get_top_anchor(){ 26 | if (is_too_small()){ 27 | if (index < 13){ 28 | return parent.top; 29 | } 30 | else{ 31 | return parent.verticalCenter; 32 | } 33 | } 34 | else{ 35 | return parent.top; 36 | } 37 | } 38 | function get_bottom_anchor(){ 39 | if (is_too_small()){ 40 | if (index < 13){ 41 | return parent.verticalCenter; 42 | } 43 | else{ 44 | return parent.bottom; 45 | } 46 | } 47 | else{ 48 | return parent.bottom; 49 | } 50 | 51 | } 52 | function is_too_small(){ 53 | return root.width / 26 < 20; 54 | } 55 | 56 | Behavior on x { 57 | 58 | NumberAnimation { 59 | duration: 500 60 | easing.type: Easing.OutExpo 61 | } 62 | } 63 | 64 | Text{ 65 | anchors.centerIn: parent 66 | text: String.fromCharCode(97 + index) 67 | color: _colors[index].hslLightness > 0.5 ? "black" : "white" 68 | } 69 | MouseArea { 70 | anchors.fill: parent 71 | onClicked: { 72 | root.colorClicked(index); 73 | } 74 | onPressAndHold: { 75 | root.colorHeld(index); 76 | } 77 | } 78 | } 79 | 80 | } 81 | } -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchTextEdit.cpp: -------------------------------------------------------------------------------- 1 | #include "touchui/TouchTextEdit.h" 2 | #include "utils.h" 3 | 4 | 5 | TouchTextEdit::TouchTextEdit(QString name, QString initial_value, QWidget* parent) : QWidget(parent) { 6 | 7 | 8 | setAttribute(Qt::WA_NoMousePropagation); 9 | 10 | quick_widget = new QQuickWidget(this); 11 | 12 | quick_widget->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView); 13 | quick_widget->setAttribute(Qt::WA_AlwaysStackOnTop); 14 | quick_widget->setClearColor(Qt::transparent); 15 | 16 | quick_widget->rootContext()->setContextProperty("_initialValue", initial_value); 17 | quick_widget->rootContext()->setContextProperty("_name", name); 18 | 19 | quick_widget->setSource(QUrl("qrc:/pdf_viewer/touchui/TouchTextEdit.qml")); 20 | 21 | QObject::connect( 22 | dynamic_cast(quick_widget->rootObject()), 23 | SIGNAL(confirmed(QString)), 24 | this, 25 | SLOT(handleConfirm(QString))); 26 | QObject::connect( 27 | dynamic_cast(quick_widget->rootObject()), 28 | SIGNAL(cancelled()), 29 | this, 30 | SLOT(handleCancel())); 31 | quick_widget->setFocus(); 32 | 33 | } 34 | 35 | void TouchTextEdit::set_text(const std::wstring& txt) { 36 | quick_widget->rootContext()->setContextProperty("_initialValue", QString::fromStdWString(txt)); 37 | } 38 | 39 | 40 | void TouchTextEdit::handleConfirm(QString text) { 41 | emit confirmed(text); 42 | } 43 | 44 | void TouchTextEdit::handleCancel() { 45 | emit cancelled(); 46 | } 47 | 48 | 49 | void TouchTextEdit::resizeEvent(QResizeEvent* resize_event) { 50 | QWidget::resizeEvent(resize_event); 51 | 52 | int parent_width = parentWidget()->width(); 53 | int parent_height = parentWidget()->height(); 54 | 55 | float twenty_cm = 20 * logicalDpiX() / 2.54f; 56 | 57 | int w = static_cast(std::min(parent_width * 0.8f, twenty_cm)); 58 | int h = static_cast(std::min(parent_height * 0.5f, twenty_cm)); 59 | 60 | resize(w, h); 61 | quick_widget->resize(w, h); 62 | move((parent_width - w) / 2, (parent_height - h) / 2); 63 | 64 | } 65 | 66 | void TouchTextEdit::keyPressEvent(QKeyEvent* kevent) { 67 | if (kevent->key() == Qt::Key_Return) { 68 | kevent->accept(); 69 | return; 70 | } 71 | QWidget::keyPressEvent(kevent); 72 | //return true; 73 | } 74 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchTextEdit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | class TouchTextEdit : public QWidget { 10 | Q_OBJECT 11 | public: 12 | TouchTextEdit(QString name, QString initial_value, QWidget* parent = nullptr); 13 | void resizeEvent(QResizeEvent* resize_event) override; 14 | void keyPressEvent(QKeyEvent* kevent) override; 15 | void set_text(const std::wstring& txt); 16 | 17 | public slots: 18 | void handleConfirm(QString text); 19 | void handleCancel(); 20 | 21 | signals: 22 | void confirmed(QString text); 23 | void cancelled(); 24 | 25 | private: 26 | QQuickWidget* quick_widget = nullptr; 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /pdf_viewer/touchui/TouchTextEdit.qml: -------------------------------------------------------------------------------- 1 | 2 | import QtQuick 2.2 3 | import QtQuick.Controls 2.15 4 | 5 | import "qrc:/pdf_viewer/touchui" 6 | 7 | Rectangle { 8 | 9 | color: "black" 10 | 11 | signal confirmed(text: string); 12 | signal cancelled(); 13 | id: root 14 | 15 | TextInput{ 16 | id: edit 17 | anchors.left: parent.left 18 | anchors.right: parent.right 19 | anchors.top: parent.top 20 | height: 3 * parent.height / 4 21 | color: "white" 22 | text: _initialValue 23 | focus: true 24 | wrapMode: TextInput.WrapAnywhere 25 | onAccepted:{ 26 | root.confirmed(edit.text); 27 | } 28 | 29 | } 30 | 31 | TouchButtonGroup{ 32 | anchors.top: edit.bottom 33 | anchors.left: parent.left 34 | anchors.right: parent.right 35 | anchors.bottom: parent.bottom 36 | 37 | buttons: ["Cancel", "Confirm"] 38 | onButtonClicked: function(index, name){ 39 | if (index == 1){ 40 | root.confirmed(edit.text); 41 | } 42 | if (index == 0){ 43 | root.cancelled(); 44 | } 45 | } 46 | } 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /pdf_viewer/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | 28 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 30 | 31 | #include "utf8/checked.h" 32 | #include "utf8/unchecked.h" 33 | 34 | #endif // header guard 35 | -------------------------------------------------------------------------------- /resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | @EXECUTABLE@ 7 | CFBundleIconFile 8 | @ICON@ 9 | CFBundleIdentifier 10 | info.sioyek.sioyek 11 | CFBundlePackageType 12 | APPL 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | @SHORT_VERSION@ 17 | LSMinimumSystemVersion 18 | 10.15 19 | NSPrincipalClass 20 | NSApplication 21 | NSSupportsAutomaticGraphicsSwitching 22 | 23 | CFBundleDocumentTypes 24 | 25 | 26 | CFBundleTypeName 27 | PDF Document 28 | CFBundleTypeRole 29 | Viewer 30 | LSHandlerRank 31 | Alternate 32 | LSItemContentTypes 33 | 34 | com.adobe.pdf 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /resources/debian/changelog: -------------------------------------------------------------------------------- 1 | sioyek (2143354635-1) UNRELEASED; urgency=medium 2 | 3 | -- Ali Mostafavi Sun, 10 Apr 2022 14:17:41 +0430 4 | -------------------------------------------------------------------------------- /resources/debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /resources/debian/control: -------------------------------------------------------------------------------- 1 | Source: sioyek 2 | Maintainer: Ali Mostafavi 3 | Section: misc 4 | Priority: optional 5 | Standards-Version: 3.9.2 6 | Build-Depends: debhelper (>= 10) , libharfbuzz-dev, libfreetype-dev, libjbig2dec0-dev, libjpeg-dev, libmujs-dev, libopenjp2-7-dev, zlib1g-dev, qtbase5-dev, qtdeclarative5-dev, qt3d5-dev, gcc-9, libqt5opengl5-dev, libmupdf-dev, libgl-dev 7 | 8 | Package: sioyek 9 | Architecture: amd64 10 | Depends: ${shlibs:Depends}, ${misc:Depends} 11 | Description: PDF viewer 12 | Sioyek is a PDF viewer optimized for reading research papers and textbooks. 13 | -------------------------------------------------------------------------------- /resources/debian/copyright: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/resources/debian/copyright -------------------------------------------------------------------------------- /resources/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | %: 3 | dh $@ 4 | 5 | -------------------------------------------------------------------------------- /resources/debian/sioyek.dirs: -------------------------------------------------------------------------------- 1 | usr/bin 2 | etc/sioyek 3 | usr/share/sioyek 4 | usr/share/sioyek/shaders 5 | -------------------------------------------------------------------------------- /resources/debian/sioyek.install: -------------------------------------------------------------------------------- 1 | pdf_viewer/prefs.config etc/sioyek/ 2 | pdf_viewer/keys.config etc/sioyek/ 3 | tutorial.pdf usr/share/sioyek/ 4 | pdf_viewer/shaders/simple.vertex usr/share/sioyek/shaders/ 5 | pdf_viewer/shaders/custom_colors.fragment usr/share/sioyek/shaders/ 6 | pdf_viewer/shaders/dark_mode.fragment usr/share/sioyek/shaders/ 7 | pdf_viewer/shaders/debug.fragment usr/share/sioyek/shaders/ 8 | pdf_viewer/shaders/highlight.fragment usr/share/sioyek/shaders/ 9 | pdf_viewer/shaders/separator.fragment usr/share/sioyek/shaders/ 10 | pdf_viewer/shaders/simple.fragment usr/share/sioyek/shaders/ 11 | pdf_viewer/shaders/unrendered_page.fragment usr/share/sioyek/shaders/ 12 | pdf_viewer/shaders/vertical_bar_dark.fragment usr/share/sioyek/shaders/ 13 | pdf_viewer/shaders/vertical_bar.fragment usr/share/sioyek/shaders/ 14 | -------------------------------------------------------------------------------- /resources/debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /resources/fonts/JetBrainsMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/resources/fonts/JetBrainsMono.ttf -------------------------------------------------------------------------------- /resources/sioyek-icon-linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/resources/sioyek-icon-linux.png -------------------------------------------------------------------------------- /resources/sioyek.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Sioyek 3 | Comment=PDF viewer for reading research papers and technical books 4 | Keywords=pdf;viewer;reader;research; 5 | TryExec=sioyek 6 | Exec=sioyek %f 7 | StartupNotify=true 8 | Terminal=false 9 | Type=Application 10 | Icon=sioyek-icon-linux 11 | Categories=Development;Viewer; 12 | MimeType=application/pdf; 13 | -------------------------------------------------------------------------------- /scripts/embed_annotations_in_file.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from sioyek import Sioyek 3 | 4 | colormap = {'a': (0.94, 0.64, 1.00), 5 | 'b': (0.00, 0.46, 0.86), 6 | 'c': (0.60, 0.25, 0.00), 7 | 'd': (0.30, 0.00, 0.36), 8 | 'e': (0.10, 0.10, 0.10), 9 | 'f': (0.00, 0.36, 0.19), 10 | 'g': (0.17, 0.81, 0.28), 11 | 'h': (1.00, 0.80, 0.60), 12 | 'i': (0.50, 0.50, 0.50), 13 | 'j': (0.58, 1.00, 0.71), 14 | 'k': (0.56, 0.49, 0.00), 15 | 'l': (0.62, 0.80, 0.00), 16 | 'm': (0.76, 0.00, 0.53), 17 | 'n': (0.00, 0.20, 0.50), 18 | 'o': (1.00, 0.64, 0.02), 19 | 'p': (1.00, 0.66, 0.73), 20 | 'q': (0.26, 0.40, 0.00), 21 | 'r': (1.00, 0.00, 0.06), 22 | 's': (0.37, 0.95, 0.95), 23 | 't': (0.00, 0.60, 0.56), 24 | 'u': (0.88, 1.00, 0.40), 25 | 'v': (0.45, 0.04, 1.00), 26 | 'w': (0.60, 0.00, 0.00), 27 | 'x': (1.00, 1.00, 0.50), 28 | 'y': (1.00, 1.00, 0.00), 29 | 'z': (1.00, 0.31, 0.02) 30 | } 31 | 32 | if __name__ == '__main__': 33 | SIOYEK_PATH = sys.argv[1] 34 | LOCAL_DATABASE_PATH = sys.argv[2] 35 | SHARED_DATABASE_PATH = sys.argv[3] 36 | FILE_PATH = sys.argv[4] 37 | 38 | sioyek = Sioyek(SIOYEK_PATH, LOCAL_DATABASE_PATH, SHARED_DATABASE_PATH) 39 | document = sioyek.get_document(FILE_PATH) 40 | document.embed_new_annotations(save=True, colormap=colormap) 41 | document.close() 42 | sioyek.reload() 43 | sioyek.close() 44 | -------------------------------------------------------------------------------- /scripts/embedded_annotations.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This script was tested with PyMuPDF version 1.17.6. Other versions may require slight modification of the code. 3 | 4 | This script can be used to embed annotations as you create them, so they are viewable in other 5 | PDF viewers. 6 | This is basically a script that can either add a bookmark or a highlight to a page based on the command line arguments. 7 | Here is the `prefs_user.config` that I used: 8 | 9 | execute_command_b python path/to/embedded_annotations.py bookmark "%1" %{mouse_pos_document} "%5" 10 | execute_command_h python path/to/embedded_annotations.py highlight "%1" "%4" "%3" 11 | 12 | And here is a `keys_user.config` file that can be used: 13 | 14 | execute_command_b b 15 | execute_command_h;add_highlight h 16 | 17 | which basically adds both sioyek and embedded highlights and bookmarks (if `ADD_BOOKMARKS_TO_SIOYEK` is True). Alternatively, you can use 18 | a different keybinding for embedded annotations so you have control over what happens. Now you can use alt+b or alt+h to bookmark/highlight. 19 | 20 | execute_command_b 21 | execute_command_h 22 | ''' 23 | 24 | import sys 25 | import fitz 26 | import subprocess 27 | 28 | # if set to true, we re-add the bookmarks into sioyek, so we have both types of bookmarks 29 | ADD_BOOKMARKS_TO_SIOYEK = False 30 | PATH_TO_SIOYEK = r'path/to/sioyek.exe' 31 | 32 | def add_bookmark(doc_path, page_number, location, text): 33 | doc = fitz.open(doc_path) 34 | page = doc.loadPage(page_number) 35 | page.addTextAnnot(location, text) 36 | doc.saveIncr() 37 | doc.close() 38 | if ADD_BOOKMARKS_TO_SIOYEK: 39 | subprocess.run([PATH_TO_SIOYEK, '--execute-command', 'add_bookmark','--execute-command-data', text]) 40 | subprocess.run([PATH_TO_SIOYEK, '--execute-command', 'reload']) 41 | 42 | 43 | def add_highlight(doc_path, page_number, text): 44 | doc = fitz.open(doc_path) 45 | page = doc.loadPage(page_number) 46 | quads = page.searchFor(text, flags=fitz.TEXT_PRESERVE_WHITESPACE, hit_max=50) 47 | page.addHighlightAnnot(quads) 48 | doc.saveIncr() 49 | doc.close() 50 | 51 | if __name__ == '__main__': 52 | if sys.argv[1] == 'bookmark': 53 | add_bookmark(sys.argv[2], int(sys.argv[3]), (float(sys.argv[4]), float(sys.argv[5])), sys.argv[6]) 54 | 55 | if sys.argv[1] == 'highlight': 56 | add_highlight(sys.argv[2], int(sys.argv[3]), sys.argv[4]) 57 | 58 | -------------------------------------------------------------------------------- /scripts/tts/aligner.bat: -------------------------------------------------------------------------------- 1 | python -m aeneas.tools.execute_task %1 %2 "task_language=eng|os_task_file_format=json|is_text_type=plain" %3 2 | -------------------------------------------------------------------------------- /scripts/tts/aligner.ps1: -------------------------------------------------------------------------------- 1 | python -m aeneas.tools.execute_task $args[0] $args[1] "task_language=eng|os_task_file_format=json|is_text_type=plain" $args[2] 2 | -------------------------------------------------------------------------------- /scripts/tts/generator.ps1: -------------------------------------------------------------------------------- 1 | $text = Get-Content $args[0] 2 | if ($isMacOS) { 3 | say $text -o $args[1] 4 | } else { 5 | Add-Type -AssemblyName System.Speech; 6 | $synth = New-Object System.Speech.Synthesis.SpeechSynthesizer; 7 | $synth.SetOutputToWaveFile($args[1]) 8 | $synth.Speak($text); 9 | } 10 | -------------------------------------------------------------------------------- /scripts/tts/generator2.ps1: -------------------------------------------------------------------------------- 1 | $text = Get-Content $args[0] 2 | if (Get-Command "nvidia-smi" -errorAction SilentlyContinue) { 3 | tts --text "$text" --use_cuda USE_CUDA --out_path $args[1] 4 | } else { 5 | tts --text "$text" --out_path $args[1] 6 | } 7 | -------------------------------------------------------------------------------- /scripts/tts/server_follow.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | if __name__ == '__main__': 4 | r = requests.get('http://127.0.0.1:5000/follow') 5 | -------------------------------------------------------------------------------- /scripts/tts/server_read.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import sys 3 | 4 | if __name__ == '__main__': 5 | r = requests.post('http://127.0.0.1:5000/read', json={"path": sys.argv[1], "page_number": sys.argv[2], "line_text": sys.argv[3]}) 6 | -------------------------------------------------------------------------------- /scripts/tts/server_stop.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | if __name__ == '__main__': 4 | r = requests.get('http://127.0.0.1:5000/stop') 5 | -------------------------------------------------------------------------------- /scripts/tts/server_unfollow.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | if __name__ == '__main__': 4 | r = requests.get('http://127.0.0.1:5000/unfollow') 5 | -------------------------------------------------------------------------------- /tutorial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/tutorial.pdf -------------------------------------------------------------------------------- /tutorial/bibs.bib: -------------------------------------------------------------------------------- 1 | @inproceedings{branner1989mandelbrot, 2 | title={The mandelbrot set}, 3 | author={Branner, Bodil}, 4 | booktitle={Proc. symp. appl. math}, 5 | volume={39}, 6 | pages={75--105}, 7 | year={1989} 8 | } 9 | 10 | @book{mandelbrot2004fractals, 11 | title={Fractals and chaos: the Mandelbrot set and beyond}, 12 | author={Mandelbrot, Benoit B and Evertsz, Carl JG and Gutzwiller, Martin C}, 13 | volume={3}, 14 | year={2004}, 15 | publisher={Springer} 16 | } -------------------------------------------------------------------------------- /tutorial/compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | pdflatex tut.tex 3 | bibtex tut 4 | pdflatex tut.tex 5 | pdflatex tut.tex 6 | -------------------------------------------------------------------------------- /tutorial/mandlebrot_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/tutorial/mandlebrot_small.jpg -------------------------------------------------------------------------------- /windows_runtime/libcrypto-1_1-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/windows_runtime/libcrypto-1_1-x64.dll -------------------------------------------------------------------------------- /windows_runtime/libssl-1_1-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/windows_runtime/libssl-1_1-x64.dll -------------------------------------------------------------------------------- /windows_runtime/vcruntime140_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hexomancer/sioyek/fa863dd803be106c5cfa3a821a65616290c302a5/windows_runtime/vcruntime140_1.dll --------------------------------------------------------------------------------