├── .editorconfig ├── .github ├── issue_template.md └── workflows │ ├── chatgpt-codereview.yml │ └── codesee-arch-diagram.yml ├── .gitignore ├── .travis.yml ├── .whitesource ├── COPYING.FPC ├── COPYING.txt ├── GeoIP.pas ├── Inno Setup lang ├── ChineseSimplified.isl └── ChineseTraditional.isl ├── LICENSE ├── Makefile ├── Makefile.fpc ├── README.md ├── StringToVK.pas ├── VERSION.txt ├── about.lfm ├── about.pas ├── addlink.lfm ├── addlink.pas ├── addtorrent.lfm ├── addtorrent.pas ├── addtracker.lfm ├── addtracker.pas ├── baseform.lfm ├── baseform.pas ├── bencode.pas ├── colsetup.lfm ├── colsetup.pas ├── connoptions.lfm ├── connoptions.pas ├── daemonoptions.lfm ├── daemonoptions.pas ├── download.lfm ├── download.pas ├── flags.zip ├── gcontnrs.pas ├── history.txt ├── ipresolver.pas ├── lang ├── transgui.be ├── transgui.ca ├── transgui.cs ├── transgui.da ├── transgui.de ├── transgui.el ├── transgui.en ├── transgui.es ├── transgui.fi ├── transgui.fr ├── transgui.hr ├── transgui.hu ├── transgui.it ├── transgui.ko ├── transgui.lt ├── transgui.lv ├── transgui.nl ├── transgui.no ├── transgui.pl ├── transgui.pt ├── transgui.pt_br ├── transgui.ro ├── transgui.ru ├── transgui.sv ├── transgui.template ├── transgui.tr ├── transgui.uk ├── transgui.zh └── transgui.zh_tw ├── lineinfo2.pp ├── maclocale.pas ├── main.lfm ├── main.pas ├── movetorrent.lfm ├── movetorrent.pas ├── options.lfm ├── options.pas ├── passwcon.lfm ├── passwcon.pas ├── readme.txt ├── restranslator.pas ├── rpc-spec.txt ├── rpc.pas ├── setup ├── create_src.sh ├── macosx │ ├── Info.plist │ ├── PkgInfo │ ├── create_app.sh │ ├── create_app_new.sh │ ├── create_package.sh │ ├── install_deps.sh │ ├── package.plist │ └── transgui.icns ├── unix │ ├── build.sh │ └── debian-ubuntu-install_deps.sh ├── upload_asset.sh ├── win │ ├── install_deps.bat │ ├── make_setup.bat │ ├── make_zipdist.bat │ ├── openssl │ │ ├── libcrypto-1_1.dll │ │ └── libssl-1_1.dll │ └── setup.iss └── win_amd64 │ ├── install_deps.bat │ ├── make_setup.bat │ ├── make_zipdist.bat │ ├── openssl │ ├── libcrypto-1_1-x64.dll │ └── libssl-1_1-x64.dll │ └── setup.iss ├── snap ├── local │ └── transgui.desktop └── snapcraft.yaml ├── synapse ├── README.txt ├── Release.txt ├── licence.txt ├── source │ └── lib │ │ ├── asn1util.pas │ │ ├── blcksock.pas │ │ ├── clamsend.pas │ │ ├── dnssend.pas │ │ ├── ftpsend.pas │ │ ├── ftptsend.pas │ │ ├── httpsend.pas │ │ ├── imapsend.pas │ │ ├── jedi.inc │ │ ├── kylix.inc │ │ ├── laz_synapse.lpk │ │ ├── laz_synapse.pas │ │ ├── ldapsend.pas │ │ ├── mimeinln.pas │ │ ├── mimemess.pas │ │ ├── mimepart.pas │ │ ├── nntpsend.pas │ │ ├── pingsend.pas │ │ ├── pop3send.pas │ │ ├── slogsend.pas │ │ ├── smtpsend.pas │ │ ├── snmpsend.pas │ │ ├── sntpsend.pas │ │ ├── ssdotnet.inc │ │ ├── ssfpc.inc │ │ ├── ssl_cryptlib.pas │ │ ├── ssl_libssh2.pas │ │ ├── ssl_openssl.pas │ │ ├── ssl_openssl_lib.pas │ │ ├── ssl_sbb.pas │ │ ├── ssl_streamsec.pas │ │ ├── sslinux.inc │ │ ├── ssos2ws1.inc │ │ ├── ssposix.inc │ │ ├── sswin32.inc │ │ ├── synachar.pas │ │ ├── synacode.pas │ │ ├── synacrypt.pas │ │ ├── synadbg.pas │ │ ├── synafpc.pas │ │ ├── synaicnv.pas │ │ ├── synaip.pas │ │ ├── synamisc.pas │ │ ├── synaser.pas │ │ ├── synautil.pas │ │ ├── synsock.pas │ │ ├── tlntsend.pas │ │ └── tzutil.pas ├── synapse_logo.gif └── winsock2.txt ├── torrprops.lfm ├── torrprops.pas ├── transgui.ico ├── transgui.lpi ├── transgui.lpr ├── transgui.png ├── trcomp.lpk ├── trcomp.pas ├── urllistenerosx.pas ├── utils.pas ├── vargrid.pas └── varlist.pas /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.{bat,iss,txt}] 10 | end_of_line = crlf 11 | 12 | [VERSION.txt] 13 | end_of_line = lf 14 | 15 | [PkgInfo] 16 | end_of_line = crlf 17 | 18 | [*.{pas,lpi,lfm,lpr,sh}] 19 | indent_size = 2 20 | indent_style = space 21 | 22 | [*.{isl,icns}] 23 | charset = false 24 | end_of_line = false 25 | insert_final_newline = false 26 | trim_trailing_whitespace = false 27 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /.github/workflows/chatgpt-codereview.yml: -------------------------------------------------------------------------------- 1 | name: ChatGPT Code Review 2 | 3 | permissions: 4 | contents: read 5 | pull-requests: write 6 | 7 | on: 8 | pull_request: 9 | types: [opened, reopened, synchronize] 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: anc95/ChatGPT-CodeReview@main 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} 19 | MODEL: gpt-4 20 | top_p: 1 21 | temperature: 0.2 22 | -------------------------------------------------------------------------------- /.github/workflows/codesee-arch-diagram.yml: -------------------------------------------------------------------------------- 1 | # This workflow was added by CodeSee. Learn more at https://codesee.io/ 2 | # This is v2.0 of this workflow file 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request_target: 8 | types: [opened, synchronize, reopened] 9 | 10 | name: CodeSee 11 | 12 | permissions: read-all 13 | 14 | jobs: 15 | codesee: 16 | runs-on: ubuntu-latest 17 | continue-on-error: true 18 | name: Analyze the repo with CodeSee 19 | steps: 20 | - uses: Codesee-io/codesee-action@v2 21 | with: 22 | codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} 23 | codesee-url: https://app.codesee.io 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # snap package build via snapcraft 3 | /*.snap 4 | /snap/.snapcraft/ 5 | /stage/ 6 | /parts/ 7 | /prime/ 8 | 9 | ### https://raw.github.com/github/gitignore/8edb8a95c4c4b3dce71a378aaaf89275510b9cef/Global/Lazarus.gitignore 10 | 11 | # Lazarus compiler-generated binaries (safe to delete) 12 | *.exe 13 | *.dll 14 | *.so 15 | *.dylib 16 | *.lrs 17 | *.res 18 | *.compiled 19 | *.dbg 20 | *.ppu 21 | *.o 22 | *.or 23 | *.a 24 | 25 | # Lazarus autogenerated files (duplicated info) 26 | *.rst 27 | *.rsj 28 | *.lrt 29 | 30 | # Lazarus local files (user-specific info) 31 | *.lps 32 | 33 | # Lazarus backups and unit output folders. 34 | # These can be changed by user in Lazarus/project options. 35 | backup/ 36 | *.bak 37 | lib/ 38 | units/ 39 | 40 | # Application bundle for Mac OS 41 | *.app/ 42 | 43 | 44 | # Free Pascal compiler made files 45 | fpcmade* 46 | 47 | # MacOS dmg file 48 | *.dmg 49 | 50 | # Release files 51 | Release/ 52 | 53 | # transgui binary 54 | /transgui 55 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | language: minimal 4 | 5 | git: 6 | depth: 10 7 | 8 | env: 9 | global: 10 | - PROG_VER=$(head -n 1 VERSION.txt) 11 | 12 | deploy_build: &deploy 13 | - provider: releases 14 | api_key: 15 | secure: "0671vAjL2m6gqjDSdkdjiyfDwuR8uLYrE6OCaeaX9iLvqSxmKAffkLlCZXU9fevmTglEMSmarcmHtwy1AYcqBClChl0dup2YvmM+BzsTfDSjZT43asI1Ok7MJALqqCa/xPO15HH1XfvstHeuOCM16nB61VQKT1+an0T9oz96PNIr5oS/Q8owmaWHvbB18IBoeTNvUZl0OvaqjNGZJ9JnBvBTROPDvsfud1DxlPmlTaCxh+yx8yAZYX2nLOkJFlWhG4b7mtcrlitVENcdjJ90qY4c01uzH3cYNdVn4PH/z0s+cAQT36f2zSX8UpsfBxbsBpB6ANS9Ig4gPp8eOtuhfpd2lOH6fL/DwAaxh9FGbTH5n9eR4cO9bEkmW5BoUeDpcIboIVZKrtZI97/MiRtwMfQzleQuwWuDpanaMqiY+LdS6vllG4kQjGck9fWj5wbaHR/MDTlAODc5/WUYA+69MDjPK/JI34/rPIag+8ZF2pF2VLyVC1kbvpngsYkcvQTRRSWrb6Cj0i7ggrBrCOmU2RrfkiKUGarukaCel/9U2dxnmkxPpfKBVXD0v6ylcUEofMJ6ml4lcGH8XX1jTNlUQebu7uhbfyhsJA9IEyMKXX3RHaq7Tf1XyCtZYIo2sAkFG103u/zSbkVZOAa8qoWqwFO8gx5MAa7ZRJVbuBNswBk=" 16 | file: $artifact 17 | skip_cleanup: true 18 | on: 19 | tags: true 20 | 21 | linux_after_success: &linux_after_success 22 | - md5sum $artifact 23 | - shasum -a 1 $artifact 24 | - shasum -a 256 $artifact 25 | - if [ -n "$TRAVIS_TAG" ] ; then 26 | curl -F "file=@$artifact" -F apikey=${virustotal} https://www.virustotal.com/vtapi/v2/file/scan ; 27 | curl -F "file=@./transgui" -F apikey=${virustotal} https://www.virustotal.com/vtapi/v2/file/scan ; 28 | else 29 | setup/upload_asset.sh $artifact ; 30 | fi 31 | 32 | stages: 33 | - static test 34 | - build 35 | 36 | env_template: 37 | - &linux_env 38 | os: linux 39 | dist: bionic 40 | services: 41 | - docker 42 | 43 | - &linux_build_env 44 | <<: *linux_env 45 | stage: build 46 | 47 | - &nodejs_static_test_env 48 | <<: *linux_env 49 | stage: static test 50 | language: node_js 51 | node_js: 16 52 | install: 53 | - npm i -g $task 54 | before_script: 55 | - type $task 56 | 57 | matrix: 58 | include: 59 | - <<: *linux_env 60 | stage: static test 61 | env: 62 | - task=shfmt 63 | script: 64 | - docker run -it --rm -v "$(pwd)":/sh -w /sh peterdavehello/shfmt:3.4.0 shfmt -sr -i 2 -l -w -ci . 65 | - git diff --color 66 | - git diff --stat=220 --color --exit-code 67 | 68 | - <<: *linux_env 69 | stage: static test 70 | env: 71 | - task=shellcheck 72 | script: 73 | - find . -type f -name "*.sh" | xargs -n 1 shellcheck 74 | 75 | - <<: *nodejs_static_test_env 76 | env: 77 | - task=markdown-link-check 78 | script: 79 | - find . -type f -name "*.md" | xargs -n 1 markdown-link-check 80 | 81 | - <<: *nodejs_static_test_env 82 | env: 83 | - task=eclint 84 | script: 85 | - eclint check lang/ setup/ Makefile* *.txt 86 | 87 | - <<: *nodejs_static_test_env 88 | env: 89 | - task=doctoc 90 | script: 91 | - doctoc --title "## Table of Contents" --github README.md > /dev/null 92 | - if ! git diff --quiet README.md; then 93 | >&2 echo 'README.md "Table of Contents" dated! Please update it'; 94 | >&2 git diff -w README.md 95 | exit 1; 96 | fi 97 | 98 | - <<: *linux_build_env 99 | env: 100 | - task=zip-tarball-test 101 | script: 102 | - docker run -e DEBIAN_FRONTEND=noninteractive -it --rm -v "${PWD}:/transgui" debian:buster-backports bash -c "cd /transgui/ && ./setup/unix/debian-ubuntu-install_deps.sh && lazbuild -B transgui.lpi --lazarusdir=/usr/lib/lazarus/default/ && make -j$(nproc) zipdist && ls -al ./Release/transgui-$PROG_VER-x86_64-linux.zip" 103 | 104 | - <<: *linux_build_env 105 | env: 106 | - arch=amd64 107 | - artifact=./Release/transgui-$PROG_VER-x86_64-Linux.txz 108 | script: 109 | - docker run -e DEBIAN_FRONTEND=noninteractive -it --rm -v "${PWD}:/transgui" debian:buster-backports bash -c "cd /transgui/setup/unix/ && ./debian-ubuntu-install_deps.sh && apt upgrade -y && git config --global --add safe.directory /transgui && ./build.sh" 110 | after_success: *linux_after_success 111 | deploy: *deploy 112 | 113 | - <<: *linux_build_env 114 | env: 115 | - arch=i386 116 | - artifact=./Release/transgui-$PROG_VER-i686-Linux.txz 117 | script: 118 | - docker run -e DEBIAN_FRONTEND=noninteractive --privileged -it --rm -v "${PWD}:/transgui" i386/debian:buster-backports linux32 --32bit bash -c "cd /transgui/setup/unix/ && ./debian-ubuntu-install_deps.sh && apt upgrade -y && git config --global --add safe.directory /transgui && ./build.sh" 119 | after_success: *linux_after_success 120 | deploy: *deploy 121 | 122 | - <<: *linux_build_env 123 | env: 124 | - arch=rpi-armv6l 125 | - artifact=./Release/transgui-$PROG_VER-armv6l-Linux.txz 126 | addons: 127 | apt: 128 | packages: 129 | - qemu-user-static 130 | script: 131 | - docker run -e DEBIAN_FRONTEND=noninteractive -it --rm -v "${PWD}:/transgui" -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static balenalib/rpi-raspbian:buster bash -c "sed -i 's/archive.raspbian.org/mirrors.ocf.berkeley.edu\/raspbian/g' /etc/apt/sources.list && cd /transgui/setup/unix/ && ./debian-ubuntu-install_deps.sh && apt upgrade -y && git config --global --add safe.directory /transgui && ./build.sh" 132 | after_success: *linux_after_success 133 | deploy: *deploy 134 | 135 | - <<: *linux_build_env 136 | env: 137 | - arch=armv7l 138 | - artifact=./Release/transgui-$PROG_VER-armv7l-Linux.txz 139 | addons: 140 | apt: 141 | packages: 142 | - qemu-user-static 143 | script: 144 | - docker run -e DEBIAN_FRONTEND=noninteractive -it --rm -v "${PWD}:/transgui" -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static balenalib/armv7hf-debian:buster bash -c "cd /transgui/setup/unix/ && ./debian-ubuntu-install_deps.sh && apt upgrade -y && git config --global --add safe.directory /transgui && ./build.sh" 145 | after_success: *linux_after_success 146 | deploy: *deploy 147 | 148 | - os: osx 149 | osx_image: xcode11.3 150 | stage: build 151 | env: 152 | - arch=osx 153 | - sourceforge_mirror=pilotfiber 154 | - artifact=./Release/transgui-$PROG_VER.dmg 155 | install: 156 | - sh -c 'cd setup/macosx && ./install_deps.sh' 157 | script: 158 | - echo -en 'travis_fold:start:build' 159 | - sh -c 'cd setup/macosx && ./create_app_new.sh' 160 | - echo -en 'travis_fold:end:build' 161 | after_success: 162 | - md5 $artifact 163 | - shasum -a 1 $artifact 164 | - shasum -a 256 $artifact 165 | - if [ -n "$TRAVIS_TAG" ] ; then 166 | curl -F "file=@$artifact" -F apikey=${virustotal} https://www.virustotal.com/vtapi/v2/file/scan ; 167 | curl -F "file=@./transgui" -F apikey=${virustotal} https://www.virustotal.com/vtapi/v2/file/scan ; 168 | else 169 | setup/upload_asset.sh $artifact ; 170 | fi 171 | deploy: *deploy 172 | 173 | notifications: 174 | email: 175 | on_failure: true 176 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "scanSettings": { 3 | "configMode": "AUTO", 4 | "configExternalURL": "" 5 | }, 6 | "checkRunSettings": { 7 | "vulnerableCheckRunConclusionLevel": "failure" 8 | }, 9 | "issueSettings": { 10 | "minSeverityLevel": "LOW" 11 | } 12 | } -------------------------------------------------------------------------------- /COPYING.FPC: -------------------------------------------------------------------------------- 1 | This is the file COPYING.FPC, it applies to the Free Pascal Run-Time Library 2 | (RTL) and packages (packages) distributed by members of the Free Pascal 3 | Development Team. 4 | 5 | The source code of the Free Pascal Runtime Libraries and packages are 6 | distributed under the Library GNU General Public License 7 | (see the file COPYING) with the following modification: 8 | 9 | As a special exception, the copyright holders of this library give you 10 | permission to link this library with independent modules to produce an 11 | executable, regardless of the license terms of these independent modules, 12 | and to copy and distribute the resulting executable under terms of your choice, 13 | provided that you also meet, for each linked independent module, the terms 14 | and conditions of the license of that module. An independent module is a module 15 | which is not derived from or based on this library. If you modify this 16 | library, you may extend this exception to your version of the library, but you are 17 | not obligated to do so. If you do not wish to do so, delete this exception 18 | statement from your version. 19 | 20 | If you didn't receive a copy of the file COPYING, contact: 21 | Free Software Foundation 22 | 675 Mass Ave 23 | Cambridge, MA 02139 24 | USA 25 | -------------------------------------------------------------------------------- /Inno Setup lang/ChineseSimplified.isl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/Inno Setup lang/ChineseSimplified.isl -------------------------------------------------------------------------------- /Inno Setup lang/ChineseTraditional.isl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/Inno Setup lang/ChineseTraditional.isl -------------------------------------------------------------------------------- /Makefile.fpc: -------------------------------------------------------------------------------- 1 | [require] 2 | packages= 3 | 4 | [target] 5 | programs=transgui 6 | 7 | [prerules] 8 | ifneq ($(findstring $(OS_TARGET),win32,win64),) 9 | PROG_VER=$(shell type VERSION.txt) 10 | else 11 | PROG_VER=$(shell cat VERSION.txt) 12 | endif 13 | ifeq ($(LAZARUS_DIR),) 14 | # Searching Lazarus dir 15 | LAZARUS_DIR=$(strip $(dir $(realpath $(firstword $(strip $(wildcard $(addsuffix /lazbuild$(SRCEXEEXT),$(SEARCHPATH)))))))) 16 | lazarus_ok=$(strip $(wildcard $(LAZARUS_DIR)/lazbuild)) 17 | ifeq ($(lazarus_ok),) 18 | LAZARUS_DIR= 19 | # Trying home dir 20 | lazarus_ok=$(strip $(wildcard $(HOME)/lazarus/lazbuild)) 21 | ifneq ($(lazarus_ok),) 22 | LAZARUS_DIR=$(HOME)/lazarus 23 | endif 24 | endif 25 | ifeq ($(LAZARUS_DIR),) 26 | $(error Lazarus directory was not found. Use LAZARUS_DIR= switch.) 27 | endif 28 | endif 29 | 30 | $(info Using Lazarus dir: $(LAZARUS_DIR)) 31 | 32 | LAZRES=$(LAZARUS_DIR)/tools/lazres$(SRCEXEEXT) 33 | 34 | # Widgetset 35 | LCL_WIDGETSET=gtk2 36 | ifneq ($(findstring $(OS_TARGET),win32,win64),) 37 | LCL_WIDGETSET=win32 38 | endif 39 | ifneq ($(findstring $(OS_TARGET),darwin),) 40 | LCL_WIDGETSET=cocoa 41 | endif 42 | 43 | ifeq ($(DEBUG),) 44 | COMP_OPT=-O3 -g- -CX -XX -Xs -Scgi -l -vewnhibq 45 | else 46 | COMP_OPT=-O- -g -gl -gs -dCALLSTACK -Scgi -l -vewnhibq 47 | endif 48 | 49 | [compiler] 50 | unitdir=synapse/source/lib 51 | options=-MObjFPC -dLCL -dLCL$(LCL_WIDGETSET) $(COMP_OPT) 52 | options_darwin=-k-macosx_version_min -k10.5 -XR/Developer/SDKs/MacOSX10.5.sdk/ 53 | 54 | #Lazarus dirs 55 | unitdir=$(LAZARUS_DIR)/lcl/units/$(FULL_TARGET) 56 | unitdir=$(LAZARUS_DIR)/lcl/units/$(FULL_TARGET)/$(LCL_WIDGETSET) 57 | unitdir=$(LAZARUS_DIR)/components/lazutils/lib/$(FULL_TARGET) 58 | 59 | [rules] 60 | #.PHONY: extraclean 61 | 62 | transgui$(EXEEXT): $(patsubst %.lfm,%.lrs,$(wildcard *.lfm)) $(wildcard *.lfm) $(wildcard *.pas) 63 | 64 | %.lrs: %.lfm; $(LAZRES) $@ $< 65 | 66 | have_lazres=$(strip $(wildcard $(LAZRES))) 67 | ifeq ($(have_lazres),) 68 | check_lazres: 69 | $(MAKE) -C $(LAZARUS_DIR)/tools lazres$(SRCEXEEXT) 70 | else 71 | check_lazres: 72 | endif 73 | 74 | all: check_lazres fpc_all 75 | 76 | extraclean: 77 | -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX), *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT) *.or *.res) 78 | 79 | clean: extraclean fpc_clean 80 | 81 | zipdist: all 82 | -$(DEL) -r ./Release/dist 83 | -$(MKDIRPROG) ./Release 84 | $(MKDIRPROG) ./Release/dist 85 | $(MKDIRPROG) ./Release/dist/lang 86 | -strip ./transgui$(EXEEXT) 87 | $(CPPROG) ./transgui$(EXEEXT) ./Release/dist 88 | $(CPPROG) ./readme.txt ./Release/dist 89 | $(CPPROG) ./README.md ./Release/dist 90 | $(CPPROG) ./history.txt ./Release/dist 91 | $(CPPROG) ./LICENSE ./Release/dist 92 | $(CPPROG) ./transgui.png ./Release/dist 93 | $(CPPROG) ./lang/transgui.* ./Release/dist/lang 94 | -$(DEL) ./Release/transgui-$(PROG_VER)-$(FULL_TARGET).zip 95 | $(MAKE) -C ./Release/dist -f ../../Makefile int_zip ZIP_FILE=transgui-$(PROG_VER)-$(FULL_TARGET).zip 96 | -$(DEL) -r ./Release/dist 97 | 98 | int_zip: 99 | $(ZIPPROG) -9 -r ../$(ZIP_FILE) . 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Transmission Remote GUI 2 | 3 | [![Build Status](https://app.travis-ci.com/transmission-remote-gui/transgui.svg?branch=master)](https://app.travis-ci.com/transmission-remote-gui/transgui) 4 | 5 | ![Screenshot](http://i.imgur.com/XBbF4Vh.png) 6 | 7 | 8 | 9 | ## Table of Contents 10 | 11 | - [Introduction](#introduction) 12 | - [Installation](#installation) 13 | - [Linux](#linux) 14 | - [Easy way (recommended)](#easy-way-recommended) 15 | - [Harder way](#harder-way) 16 | - [Windows](#windows) 17 | - [Portable zip tarball (recommended)](#portable-zip-tarball-recommended) 18 | - [Installer](#installer) 19 | - [Using Chocolatey](#using-chocolatey) 20 | - [macOS](#macos) 21 | - [Without a package manager](#without-a-package-manager) 22 | - [Homebrew](#homebrew) 23 | - [Command line parameters](#command-line-parameters) 24 | - [Portable mode](#portable-mode) 25 | - [Fixed hotkeys](#fixed-hotkeys) 26 | - [Advanced parameters](#advanced-parameters) 27 | - [License](#license) 28 | 29 | 30 | 31 | ## Introduction 32 | 33 | Transmission Remote GUI is feature rich cross platform front-end to remotely control Transmission daemon via its RPC protocol. It is faster and has more functionality than builtin Transmission web interface. 34 | 35 | Transmission Remote GUI is developed using Lazarus RAD and Free Pascal compiler. 36 | 37 | Features: 38 | 39 | - Native application for Windows, Linux and macOS 40 | - uTorrent-like interface 41 | - Select files to download 42 | - Choose files priority 43 | - View details about connected peers 44 | - Full information about each torrent 45 | - Per torrent options 46 | 47 | ## Installation 48 | 49 | The installers are listed on the GitHub [Releases](https://github.com/transmission-remote-gui/transgui/releases/latest) page, and the installation instructions for different platform are listed as below :arrow_down: 50 | 51 | ### Linux 52 | 53 | #### Easy way (recommended) 54 | 55 | There are precompiled program's binaries for i386 and x86_64 Linux architectures. 56 | 57 | - Download and extract the release for your architecture. 58 | 59 | Now you can execute the `transgui` binary. *(Change the `transgui` file permissions to executable if needed)* 60 | 61 | Additionally, you can create a desktop or menu shortcut to the transgui executable, and run the program using the created shortcut. 62 | 63 | #### Harder way 64 | 65 | Build the program by yourself. 66 | 67 | 1. Make sure you have working Lazarus and Free Pascal compiler installed. 68 | - Free Pascal Compiler 2.6.2+ and Lazarus 1.6 is used to develop Transmission Remote GUI. 69 | 2. Download the sources archive and extract it to some folder or perform svn checkout. 70 | 3. Open terminal/command line prompt and cd to the sources folder. 71 | 4. Execute `lazbuild -B "transgui.lpi" --lazarusdir=/usr/lib/lazarus/default/` command to build the transgui.res file. 72 | 5. Execute `make` command to build the application. 73 | 6. Execute `make zipdist` command to create a release .zip archive in the `Release` sub-folder. 74 | 75 | ### Windows 76 | 77 | #### Portable zip tarball (recommended) 78 | 79 | - Zip tarball release is much more small than the installer one, which can save you some bandwidth, disk space and time, just simply download and extract the zip tarball to wherever you want, directly execute `transgui.exe` or add shortcut for it. 80 | 81 | **Note**: The first time you use this program, you may need to install some additional dependencies (if you need SSL/TLS enabled), including [Visual C++ Redistributable Package](https://www.microsoft.com/download/details.aspx?id=40784)([Direct link](https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe)) and [OpenSSL libs](https://wiki.openssl.org/index.php/Binaries)([Direct link](https://slproweb.com/products/Win32OpenSSL.html)), this only needs to be done once. 82 | 83 | #### Installer 84 | 85 | This installer has additional installation wizard and includes static OpenSSL libraries in every releases, the size would be much bigger than the zip tarball, but you don't need to take care of the OpenSSL dependencies. 86 | 87 | 1. Directly download the installer. 88 | 2. Run the installer and follow the steps to install it on your system. 89 | 90 | #### Using [Chocolatey](https://chocolatey.org) 91 | 92 | Run `choco install transgui` to install the latest version of Transmission Remote GUI. 93 | 94 | ### macOS 95 | 96 | #### Without a package manager 97 | 98 | This method needs no additional pre-requirement or dependency, just: 99 | 100 | 1. Download the app image from release page. 101 | 2. Open the image file to mount the image. 102 | 3. Directly run the application or drag the app icon to your disk / Application folder. 103 | 104 | #### Homebrew 105 | 106 | You need to have [Homebrew](https://brew.sh/) installed. Execute this command to install Transmission Remote Gui: 107 | 108 | - `brew install --cask transmission-remote-gui` 109 | 110 | ## Command line parameters 111 | 112 | You can specify path to a .torrent file or a magnet link as a command line parameter. The program will add the specified torrent. 113 | 114 | - `-hidden` : Start the program hidden. Only the program's tray icon will be visible. 115 | - `--home=` : Specifies a home directory for the program. All program's settings are stored in the home directory. You can run multiple instances of the program by specifying different home directories. 116 | 117 | ## Portable mode 118 | 119 | If the program finds the transgui.ini file in the same folder as the binary file, then it will store all configuration and data files in the program's folder, instead of the folder in a user profile. 120 | 121 | ## Fixed hotkeys 122 | 123 | - Alt + 1 : All Torrents 124 | - Alt + 2 : Downloading 125 | - Alt + 3 : Completed 126 | - Alt + 4 : Active 127 | - Alt + 5 : Inactive 128 | - Alt + 6 : Stopped 129 | - Alt + 7 : Error 130 | - Alt + 8 : Waiting 131 | - Alt + S : Searchbox (filter torrents by keywords) - Esc cancel filter and clean the box. 132 | - Alt + G : Info Pane - General Tab 133 | - Alt + K : Info Pane - Trackers Tab 134 | - Alt + P : Info Pane - Peers Tab 135 | - Alt + F : Info Pane - Files Tab 136 | 137 | ## Advanced parameters 138 | 139 | There are some parameters in the `transgui.ini file`, that can not be modified via the GUI. 140 | More info on: [#924](https://github.com/transmission-remote-gui/transgui/issues/924) (File Manager & Shortcuts) , [#1020](https://github.com/transmission-remote-gui/transgui/issues/1020) (User Defined Menu *Windows Only*) and [#1070](https://github.com/transmission-remote-gui/transgui/issues/1070) (.torrent Auto Opening) 141 | 142 | ```ini 143 | [Interface] 144 | ; Maximum number of elements in the folder history list 145 | MaxFoldersHistory=10 146 | 147 | [Interface] 148 | ;In Linux/MacOs Only if "Open Container Folder" give you error 149 | FileOpenDoc=0 150 | 151 | [Interface] 152 | ;Alternate File Manager (Windows Only) 153 | FileManagerDefault={Full path to your File Manager .exe} 154 | FileManagerDefaultParam={Alternate parameters, could be left blank} 155 | 156 | [Interface] 157 | ;System Wide Shortcut key (Windows Only) 158 | GlobalHotkey={Virtual Key Code} full list here http://docwiki.embarcadero.com/RADStudio/Seattle/en/Virtual_Key_Codes (Plus VK_A...VK_Z and VK_0..VK_9) 159 | GlobalHotkeyMod={Modifier Key} [MOD_SHIFT , MOD_CONTROL , MOD_ALT , MOD_WIN alone or combined with + sign] 160 | 161 | [Interface] 162 | WatchLocalFolder= {LOCAL Folder to watch for torrent files} 163 | WatchDestinationFolder= {REMOTE destination where the data would be saved if missing or empty last destination folder is used} 164 | WatchInterval=1 {Time period in MINUTES between folder scans for torrents, may be fractional values 0,50 = 30 seconds} 165 | 166 | [Shortcuts] 167 | ;Modify all the shortcuts of the GUI here 168 | 169 | [Usermenu] 170 | Caption1={Caption in the menu} 171 | ExeName1={Full path to the program .exe you want to add to menu} 172 | Params1="%s" {Usually "%s" but some programs may require additional parameters} 173 | Caption2={same for item 2} 174 | ExeName2={same for item 2} 175 | Params2={same for item 2} 176 | 177 | [StatusBarPanels] 178 | ;Customize the width of the statusbar panels to fit your language 179 | ;0 is the left most panel and 7 is the right most panel. 180 | 0=327 181 | 1=152 182 | 2=152 183 | 3=130 184 | 4=130 185 | 5=130 186 | 6=130 187 | 7=130 188 | 189 | [MainForm] 190 | BigToolBarHeight=48 {Height of the Big Icon Toolbar if missing default is 64} 191 | 192 | [MainForm] 193 | FromNow=1 {1=Shows the dates relatives to now , 0=Absolute Dates MM/DD/YY HH:MM:SS} 194 | ``` 195 | 196 | ## License 197 | 198 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 199 | 200 | Transmission Remote GUI is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 201 | 202 | Transmission Remote GUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 203 | -------------------------------------------------------------------------------- /VERSION.txt: -------------------------------------------------------------------------------- 1 | 5.18.0 2 | -------------------------------------------------------------------------------- /about.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | 32 | unit About; 33 | 34 | {$mode objfpc}{$H+} 35 | 36 | interface 37 | 38 | uses 39 | BaseForm, Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls, ExtCtrls, ButtonPanel, lclversion, 40 | ssl_openssl, ssl_openssl_lib; 41 | 42 | resourcestring 43 | SErrorCheckingVersion = 'Error checking for new version.'; 44 | SNewVersionFound = 'A new version of %s is available.' + LineEnding + 45 | 'Your current version: %s' + LineEnding + 46 | 'The new version: %s' + LineEnding + LineEnding + 47 | 'Do you wish to open the Downloads web page?'; 48 | SLatestVersion = 'No updates have been found.' + LineEnding + 'You are running the latest version of %s.'; 49 | 50 | type 51 | 52 | { TAboutForm } 53 | 54 | TAboutForm = class(TBaseForm) 55 | Bevel1: TBevel; 56 | Buttons: TButtonPanel; 57 | edLicense: TMemo; 58 | imgTransmission: TImage; 59 | imgSynapse: TImage; 60 | imgLazarus: TImage; 61 | txHomePage: TLabel; 62 | txAuthor: TLabel; 63 | txVersion: TLabel; 64 | txAppName: TLabel; 65 | Page: TPageControl; 66 | tabAbout: TTabSheet; 67 | tabLicense: TTabSheet; 68 | txVersFPC: TLabel; 69 | procedure FormCreate(Sender: TObject); 70 | procedure imgDonateClick(Sender: TObject); 71 | procedure imgLazarusClick(Sender: TObject); 72 | procedure imgSynapseClick(Sender: TObject); 73 | procedure txHomePageClick(Sender: TObject); 74 | private 75 | { private declarations } 76 | public 77 | { public declarations } 78 | end; 79 | 80 | procedure CheckNewVersion(Async: boolean = True); 81 | procedure GoHomePage; 82 | procedure GoGitHub; 83 | 84 | implementation 85 | 86 | uses Main, utils, httpsend; 87 | 88 | type 89 | 90 | { TCheckVersionThread } 91 | 92 | TCheckVersionThread = class(TThread) 93 | private 94 | FHttp: THTTPSend; 95 | FError: string; 96 | FVersion: string; 97 | FExit: boolean; 98 | 99 | procedure CheckResult; 100 | function GetIntVersion(const Ver: string): integer; 101 | protected 102 | procedure Execute; override; 103 | end; 104 | 105 | var 106 | CheckVersionThread: TCheckVersionThread; 107 | 108 | procedure CheckNewVersion(Async: boolean); 109 | begin 110 | if CheckVersionThread <> nil then 111 | exit; 112 | Ini.WriteInteger('Interface', 'LastNewVersionCheck', Trunc(Now)); 113 | CheckVersionThread:=TCheckVersionThread.Create(True); 114 | CheckVersionThread.FreeOnTerminate:=True; 115 | if Async then 116 | CheckVersionThread.Suspended:=False 117 | else begin 118 | CheckVersionThread.Execute; 119 | CheckVersionThread.FExit:=True; 120 | CheckVersionThread.Suspended:=False; 121 | end; 122 | end; 123 | 124 | procedure GoHomePage; 125 | begin 126 | AppBusy; 127 | OpenURL('https://github.com/transmission-remote-gui/transgui/releases'); 128 | AppNormal; 129 | end; 130 | 131 | procedure GoGitHub; 132 | begin 133 | AppBusy; 134 | OpenURL('https://github.com/transmission-remote-gui/transgui'); 135 | AppNormal; 136 | end; 137 | 138 | { TCheckVersionThread } 139 | 140 | procedure TCheckVersionThread.CheckResult; 141 | begin 142 | ForceAppNormal; 143 | if FError <> '' then begin 144 | MessageDlg(SErrorCheckingVersion + LineEnding + FError, mtError, [mbOK], 0); 145 | exit; 146 | end; 147 | 148 | if GetIntVersion(AppVersion) >= GetIntVersion(FVersion) then begin 149 | MessageDlg(Format(SLatestVersion, [AppName]), mtInformation, [mbOK], 0); 150 | exit; 151 | end; 152 | 153 | if MessageDlg(Format(SNewVersionFound, [AppName, AppVersion, FVersion]), mtConfirmation, mbYesNo, 0) <> mrYes then 154 | exit; 155 | 156 | Application.ProcessMessages; 157 | AppBusy; 158 | OpenURL('https://github.com/transmission-remote-gui/transgui/releases'); 159 | AppNormal; 160 | end; 161 | 162 | function TCheckVersionThread.GetIntVersion(const Ver: string): integer; 163 | var 164 | v: string; 165 | vi, i, j: integer; 166 | begin 167 | Result:=0; 168 | v:=Ver; 169 | for i:=1 to 3 do begin 170 | if v = '' then 171 | vi:=0 172 | else begin 173 | j:=Pos('.', v); 174 | if j = 0 then 175 | j:=MaxInt; 176 | vi:=StrToIntDef(Copy(v, 1, j - 1), 0); 177 | Delete(v, 1, j); 178 | end; 179 | Result:=Result shl 8 or vi; 180 | end; 181 | end; 182 | 183 | procedure TCheckVersionThread.Execute; 184 | begin 185 | if not FExit then begin 186 | try 187 | FHttp:=THTTPSend.Create; 188 | try 189 | if RpcObj.Http.ProxyHost <> '' then begin 190 | FHttp.ProxyHost:=RpcObj.Http.ProxyHost; 191 | FHttp.ProxyPort:=RpcObj.Http.ProxyPort; 192 | FHttp.ProxyUser:=RpcObj.Http.ProxyUser; 193 | FHttp.ProxyPass:=RpcObj.Http.ProxyPass; 194 | end; 195 | if FHttp.HTTPMethod('GET', 'https://raw.githubusercontent.com/transmission-remote-gui/transgui/master/VERSION.txt') then begin 196 | if FHttp.ResultCode = 200 then begin 197 | SetString(FVersion, FHttp.Document.Memory, FHttp.Document.Size); 198 | FVersion:=Trim(FVersion); 199 | end 200 | else 201 | FError:=Format('HTTP error: %d', [FHttp.ResultCode]); 202 | end 203 | else 204 | FError:=FHttp.Sock.LastErrorDesc; 205 | finally 206 | FHttp.Free; 207 | end; 208 | except 209 | FError:=Exception(ExceptObject).Message; 210 | end; 211 | if (FError <> '') or (GetIntVersion(FVersion) > GetIntVersion(AppVersion)) or Suspended then 212 | if Suspended then 213 | CheckResult 214 | else 215 | Synchronize(@CheckResult); 216 | end; 217 | if not Suspended then 218 | CheckVersionThread:=nil; 219 | end; 220 | 221 | { TAboutForm } 222 | 223 | procedure TAboutForm.imgSynapseClick(Sender: TObject); 224 | begin 225 | AppBusy; 226 | OpenURL('http://synapse.ararat.cz'); 227 | AppNormal; 228 | end; 229 | 230 | procedure TAboutForm.txHomePageClick(Sender: TObject); 231 | begin 232 | GoHomePage; 233 | end; 234 | 235 | procedure TAboutForm.FormCreate(Sender: TObject); 236 | {$ifdef lclcarbon} 237 | var 238 | s: string; 239 | {$endif lclcarbon} 240 | begin 241 | bidiMode := GetBiDi(); 242 | txAppName.Font.Size:=Font.Size + 2; 243 | txHomePage.Font.Size:=Font.Size; 244 | BorderStyle:=bsSizeable; 245 | txAppName.Caption:=AppName; 246 | txVersion.Caption:=Format(txVersion.Caption, [AppVersion]); 247 | Page.ActivePageIndex:=0; 248 | 249 | txVersFPC.caption := 'Fpc : ' + {$I %FPCVERSION%} + ' Lazarus : ' +lcl_version; 250 | 251 | {$ifdef lclcarbon} 252 | s:=edLicense.Text; 253 | edLicense.Text:=''; 254 | edLicense.HandleNeeded; 255 | edLicense.Text:=s; 256 | Buttons.BorderSpacing.Right:=Buttons.BorderSpacing.Right + ScaleInt(12); 257 | {$endif lclcarbon} 258 | end; 259 | 260 | procedure TAboutForm.imgDonateClick(Sender: TObject); 261 | begin 262 | GoGitHub; 263 | end; 264 | 265 | procedure TAboutForm.imgLazarusClick(Sender: TObject); 266 | begin 267 | AppBusy; 268 | OpenURL('https://www.lazarus-ide.org'); 269 | AppNormal; 270 | end; 271 | 272 | initialization 273 | {$I about.lrs} 274 | 275 | end. 276 | -------------------------------------------------------------------------------- /addlink.lfm: -------------------------------------------------------------------------------- 1 | inherited AddLinkForm: TAddLinkForm 2 | Left = 354 3 | Height = 93 4 | Top = 193 5 | Width = 574 6 | AutoSize = True 7 | BorderIcons = [biSystemMenu] 8 | BorderStyle = bsDialog 9 | Caption = 'Add torrent link' 10 | ClientHeight = 93 11 | ClientWidth = 574 12 | OnCreate = FormCreate 13 | Position = poMainFormCenter 14 | object Buttons: TButtonPanel[0] 15 | Left = 8 16 | Height = 26 17 | Top = 59 18 | Width = 558 19 | BorderSpacing.Left = 8 20 | BorderSpacing.Right = 8 21 | BorderSpacing.Bottom = 8 22 | BorderSpacing.Around = 0 23 | OKButton.Name = 'OKButton' 24 | OKButton.DefaultCaption = True 25 | HelpButton.Name = 'HelpButton' 26 | HelpButton.DefaultCaption = True 27 | CloseButton.Name = 'CloseButton' 28 | CloseButton.DefaultCaption = True 29 | CancelButton.Name = 'CancelButton' 30 | CancelButton.DefaultCaption = True 31 | TabOrder = 1 32 | Spacing = 8 33 | ShowButtons = [pbOK, pbCancel] 34 | ShowBevel = False 35 | end 36 | object Panel1: TPanel[1] 37 | Left = 8 38 | Height = 43 39 | Top = 8 40 | Width = 558 41 | Align = alClient 42 | BorderSpacing.Around = 8 43 | BevelOuter = bvNone 44 | ClientHeight = 43 45 | ClientWidth = 558 46 | TabOrder = 0 47 | object txLink: TLabel 48 | Left = 0 49 | Height = 14 50 | Top = 0 51 | Width = 183 52 | Caption = 'URL of a .torrent file or a magnet link:' 53 | ParentColor = False 54 | end 55 | object edLink: TEdit 56 | Left = 0 57 | Height = 21 58 | Top = 20 59 | Width = 558 60 | Anchors = [akTop, akLeft, akRight] 61 | TabOrder = 0 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /addlink.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | 31 | *************************************************************************************} 32 | 33 | unit AddLink; 34 | 35 | {$mode objfpc}{$H+} 36 | 37 | interface 38 | 39 | uses 40 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel, ExtCtrls, BaseForm; 41 | 42 | resourcestring 43 | SNoLink = 'No link was specified.'; 44 | 45 | type 46 | 47 | { TAddLinkForm } 48 | 49 | TAddLinkForm = class(TBaseForm) 50 | Buttons: TButtonPanel; 51 | edLink: TEdit; 52 | Panel1: TPanel; 53 | txLink: TLabel; 54 | procedure btOKClick(Sender: TObject); 55 | procedure FormCreate(Sender: TObject); 56 | private 57 | { private declarations } 58 | public 59 | { public declarations } 60 | end; 61 | 62 | implementation 63 | 64 | uses main; 65 | 66 | { TAddLinkForm } 67 | 68 | procedure TAddLinkForm.btOKClick(Sender: TObject); 69 | begin 70 | edLink.Text:=Trim(edLink.Text); 71 | if edLink.Text = '' then begin 72 | edLink.SetFocus; 73 | MessageDlg(SNoLink, mtError, [mbOK], 0); 74 | exit; 75 | end; 76 | ModalResult:=mrOK; 77 | end; 78 | 79 | procedure TAddLinkForm.FormCreate(Sender: TObject); 80 | begin 81 | Buttons.OKButton.ModalResult:=mrNone; 82 | Buttons.OKButton.OnClick:=@btOKClick; 83 | end; 84 | 85 | initialization 86 | {$I addlink.lrs} 87 | 88 | end. 89 | 90 | -------------------------------------------------------------------------------- /addtracker.lfm: -------------------------------------------------------------------------------- 1 | inherited AddTrackerForm: TAddTrackerForm 2 | Left = 411 3 | Height = 93 4 | Top = 283 5 | Width = 533 6 | AutoSize = True 7 | BorderIcons = [biSystemMenu] 8 | BorderStyle = bsDialog 9 | Caption = 'Add tracker' 10 | ClientHeight = 93 11 | ClientWidth = 533 12 | OnCreate = FormCreate 13 | Position = poMainFormCenter 14 | object Buttons: TButtonPanel[0] 15 | Left = 8 16 | Height = 26 17 | Top = 59 18 | Width = 517 19 | BorderSpacing.Left = 8 20 | BorderSpacing.Right = 8 21 | BorderSpacing.Bottom = 8 22 | BorderSpacing.Around = 0 23 | OKButton.Name = 'OKButton' 24 | OKButton.DefaultCaption = True 25 | HelpButton.Name = 'HelpButton' 26 | HelpButton.DefaultCaption = True 27 | CloseButton.Name = 'CloseButton' 28 | CloseButton.DefaultCaption = True 29 | CancelButton.Name = 'CancelButton' 30 | CancelButton.DefaultCaption = True 31 | TabOrder = 1 32 | Spacing = 8 33 | ShowButtons = [pbOK, pbCancel] 34 | ShowBevel = False 35 | end 36 | object Panel1: TPanel[1] 37 | Left = 8 38 | Height = 43 39 | Top = 8 40 | Width = 517 41 | Align = alClient 42 | BorderSpacing.Around = 8 43 | BevelOuter = bvNone 44 | ClientHeight = 43 45 | ClientWidth = 517 46 | TabOrder = 0 47 | object txTrackerURL: TLabel 48 | Left = 0 49 | Height = 14 50 | Top = 0 51 | Width = 113 52 | Caption = 'Tracker announce URL:' 53 | ParentColor = False 54 | end 55 | object edTracker: TEdit 56 | Left = 0 57 | Height = 21 58 | Top = 20 59 | Width = 516 60 | Anchors = [akTop, akLeft, akRight] 61 | TabOrder = 0 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /addtracker.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit AddTracker; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, ButtonPanel, StdCtrls, ExtCtrls, BaseForm; 39 | 40 | resourcestring 41 | STrackerProps = 'Tracker properties'; 42 | SNoTracker = 'No tracker URL was specified.'; 43 | 44 | type 45 | 46 | { TAddTrackerForm } 47 | 48 | TAddTrackerForm = class(TBaseForm) 49 | Buttons: TButtonPanel; 50 | edTracker: TEdit; 51 | Panel1: TPanel; 52 | txTrackerURL: TLabel; 53 | procedure FormCreate(Sender: TObject); 54 | procedure OKButtonClick(Sender: TObject); 55 | private 56 | { private declarations } 57 | public 58 | { public declarations } 59 | end; 60 | 61 | implementation 62 | 63 | uses main; 64 | 65 | { TAddTrackerForm } 66 | 67 | procedure TAddTrackerForm.OKButtonClick(Sender: TObject); 68 | begin 69 | edTracker.Text:=Trim(edTracker.Text); 70 | if edTracker.Text = '' then begin 71 | edTracker.SetFocus; 72 | MessageDlg(SNoTracker, mtError, [mbOK], 0); 73 | exit; 74 | end; 75 | ModalResult:=mrOk; 76 | end; 77 | 78 | procedure TAddTrackerForm.FormCreate(Sender: TObject); 79 | begin 80 | Buttons.OKButton.ModalResult:=mrNone; 81 | Buttons.OKButton.OnClick:=@OKButtonClick; 82 | end; 83 | 84 | initialization 85 | {$I addtracker.lrs} 86 | 87 | end. 88 | 89 | -------------------------------------------------------------------------------- /baseform.lfm: -------------------------------------------------------------------------------- 1 | object BaseForm: TBaseForm 2 | Left = 234 3 | Height = 240 4 | Top = 132 5 | Width = 320 6 | LCLVersion = '1.0.15.0' 7 | end 8 | -------------------------------------------------------------------------------- /baseform.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit BaseForm; 32 | 33 | {$mode objfpc} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics; 39 | 40 | type 41 | 42 | { TBaseForm } 43 | 44 | TBaseForm = class(TForm) 45 | private 46 | FNeedAutoSize: boolean; 47 | procedure DoScale(C: TControl); 48 | procedure InitScale; 49 | protected 50 | procedure DoCreate; override; 51 | public 52 | constructor Create(TheOwner: TComponent); override; 53 | end; 54 | 55 | procedure AutoSizeForm(Form: TCustomForm); 56 | function ScaleInt(i: integer): integer; 57 | 58 | var 59 | IntfScale: integer = 100; 60 | 61 | implementation 62 | 63 | uses LCLType, ButtonPanel, VarGrid, ComCtrls, StdCtrls, ExtCtrls, lclversion; 64 | 65 | var 66 | ScaleMultiplier, ScaleDivider: integer; 67 | 68 | function ScaleInt(i: integer): integer; 69 | begin 70 | Result:=i*ScaleMultiplier div ScaleDivider; 71 | end; 72 | 73 | type THackControl = class(TWinControl) end; 74 | 75 | procedure AutoSizeForm(Form: TCustomForm); 76 | var 77 | i, ht, w, h: integer; 78 | C: TControl; 79 | begin 80 | ht:=0; 81 | for i:=0 to Form.ControlCount - 1 do begin 82 | C:=Form.Controls[i]; 83 | if not C.Visible then 84 | continue; 85 | with C do begin 86 | if C is TButtonPanel then begin 87 | TButtonPanel(C).HandleNeeded; 88 | w:=0; 89 | h:=0; 90 | THackControl(C).CalculatePreferredSize(w, h, True); 91 | end 92 | else 93 | h:=Height; 94 | {$ifdef LCLcarbon} 95 | if C is TPageControl then 96 | Inc(h, ScaleInt(10)); 97 | {$endif LCLcarbon} 98 | Inc(ht, h + BorderSpacing.Top + BorderSpacing.Bottom + BorderSpacing.Around*2); 99 | end; 100 | end; 101 | ht:=ht + 2*Form.BorderWidth; 102 | 103 | Form.ClientHeight:=ht; 104 | if Form.ClientHeight <> ht then begin 105 | Form.Constraints.MinHeight:=0; 106 | Form.ClientHeight:=ht; 107 | Form.Constraints.MinHeight:=Form.Height; 108 | end; 109 | if Form.BorderStyle = bsDialog then begin 110 | Form.Constraints.MinHeight:=Form.Height; 111 | Form.Constraints.MinWidth:=Form.Width; 112 | end; 113 | end; 114 | 115 | { TBaseForm } 116 | 117 | procedure TBaseForm.DoScale(C: TControl); 118 | var 119 | i: integer; 120 | R: TRect; 121 | w, h: integer; 122 | begin 123 | with C do begin 124 | {$ifdef darwin} 125 | if C is TButtonPanel then 126 | exit; 127 | {$endif darwin} 128 | if C is TWinControl then 129 | TWinControl(C).DisableAlign; 130 | try 131 | if ScaleMultiplier <> ScaleDivider then begin 132 | ScaleConstraints(ScaleMultiplier, ScaleDivider); 133 | R := BaseBounds; 134 | R.Left := ScaleInt(R.Left); 135 | R.Top := ScaleInt(R.Top); 136 | R.Right := ScaleInt(R.Right); 137 | R.Bottom := ScaleInt(R.Bottom); 138 | if (Parent <> nil) and (Align = alNone) then begin 139 | if akRight in Anchors then 140 | Inc(R.Right, C.Parent.ClientWidth - ScaleInt(C.BaseParentClientSize.cx)); 141 | if akBottom in Anchors then 142 | Inc(R.Bottom, C.Parent.ClientHeight - ScaleInt(C.BaseParentClientSize.cy)); 143 | end; 144 | BoundsRect := R; 145 | with BorderSpacing do begin 146 | Top:=ScaleInt(Top); 147 | Left:=ScaleInt(Left); 148 | Bottom:=ScaleInt(Bottom); 149 | Right:=ScaleInt(Right); 150 | Around:=ScaleInt(Around); 151 | InnerBorder:=ScaleInt(InnerBorder); 152 | end; 153 | 154 | if C is TWinControl then 155 | with TWinControl(C).ChildSizing do begin 156 | HorizontalSpacing:=ScaleInt(HorizontalSpacing); 157 | VerticalSpacing:=ScaleInt(VerticalSpacing); 158 | LeftRightSpacing:=ScaleInt(LeftRightSpacing); 159 | TopBottomSpacing:=ScaleInt(TopBottomSpacing); 160 | end; 161 | 162 | if C is TButtonPanel then 163 | TButtonPanel(C).Spacing:=ScaleInt(TButtonPanel(C).Spacing); 164 | 165 | if C is TVarGrid then 166 | with TVarGrid(C).Columns do 167 | for i:=0 to Count - 1 do 168 | Items[i].Width:=ScaleInt(Items[i].Width); 169 | if C is TStatusBar then 170 | with TStatusBar(C) do 171 | for i:=0 to Panels.Count - 1 do 172 | Panels[i].Width:=ScaleInt(Panels[i].Width); 173 | end; 174 | 175 | // Runtime fixes 176 | 177 | // Fix right aligned label autosize 178 | if C.Visible and (C is TCustomLabel) and C.AutoSize and (TLabel(C).Alignment = taLeftJustify) and (C.Anchors*[akLeft, akRight] = [akRight]) then begin 179 | w:=0; 180 | h:=0; 181 | THackControl(C).CalculatePreferredSize(w, h, True); 182 | C.Width:=w; 183 | end; 184 | {$ifdef darwin} 185 | // Always use standard button height on OS X for proper theming 186 | if C.Visible and (C is TCustomButton) then begin 187 | w:=0; 188 | h:=0; 189 | THackControl(C).CalculatePreferredSize(w, h, True); 190 | C.Height:=h; 191 | end; 192 | // Add extra top spacing for group box 193 | i:=ScaleInt(6); 194 | if C.Parent is TCustomGroupBox then 195 | Top:=Top + i; 196 | if C is TCustomGroupBox then 197 | with TCustomGroupBox(C).ChildSizing do 198 | TopBottomSpacing:=TopBottomSpacing + i; 199 | {$endif darwin} 200 | {$ifdef LCLgtk2} 201 | // Fix panel color bug on GTK2 202 | if (C is TCustomPanel) and ParentColor and (Color = clDefault) then 203 | Color:=clForm; 204 | {$endif LCLgtk2} 205 | 206 | if C is TWinControl then 207 | with TWinControl(C) do 208 | for i:=0 to ControlCount - 1 do 209 | DoScale(Controls[i]); 210 | finally 211 | if C is TWinControl then 212 | TWinControl(C).EnableAlign; 213 | end; 214 | end; 215 | end; 216 | 217 | constructor TBaseForm.Create(TheOwner: TComponent); 218 | begin 219 | inherited Create(TheOwner); 220 | FNeedAutoSize:=AutoSize; 221 | AutoSize:=False; 222 | end; 223 | 224 | procedure TBaseForm.DoCreate; 225 | {$ifdef LCLcarbon} 226 | var 227 | i: integer; 228 | {$endif LCLcarbon} 229 | begin 230 | InitScale; 231 | HandleNeeded; 232 | Font.Height:=ScaleInt(-11); 233 | DoScale(Self); 234 | if FNeedAutoSize then 235 | AutoSizeForm(Self); 236 | {$ifdef LCLcarbon} 237 | // Destroy handles of child controls to fix the LCL Carbon bug. 238 | // Without this hack, it will not be possible to hide form's controls. 239 | for i:=0 to ControlCount - 1 do 240 | if Controls[i] is TWinControl then 241 | THackControl(Controls[i]).DestroyHandle; 242 | {$endif LCLcarbon} 243 | inherited DoCreate; 244 | end; 245 | 246 | procedure TBaseForm.InitScale; 247 | var 248 | i: integer; 249 | tm: TLCLTextMetric; 250 | begin 251 | if ScaleDivider <> 0 then exit; 252 | ScaleDivider:=11; 253 | i:=Screen.SystemFont.Height; 254 | if i = 0 then begin 255 | if Canvas.GetTextMetrics(tm) then begin 256 | ScaleMultiplier:=tm.Ascender; 257 | if ScaleMultiplier < 11 then 258 | ScaleMultiplier:=11; 259 | end 260 | else begin 261 | ScaleMultiplier:=Canvas.TextHeight('Wy'); 262 | ScaleDivider:=13; 263 | end; 264 | if ScaleMultiplier = 0 then 265 | ScaleMultiplier:=ScaleDivider; 266 | end 267 | else 268 | ScaleMultiplier:=Abs(i); 269 | ScaleMultiplier:=ScaleMultiplier*IntfScale; 270 | ScaleDivider:=ScaleDivider*100; 271 | end; 272 | 273 | initialization 274 | {$I baseform.lrs} 275 | 276 | end. 277 | 278 | -------------------------------------------------------------------------------- /colsetup.lfm: -------------------------------------------------------------------------------- 1 | inherited ColSetupForm: TColSetupForm 2 | Left = 401 3 | Height = 326 4 | Top = 193 5 | Width = 355 6 | HorzScrollBar.Page = 399 7 | VertScrollBar.Page = 299 8 | AutoSize = True 9 | BorderIcons = [biSystemMenu] 10 | BorderStyle = bsDialog 11 | Caption = 'Columns setup' 12 | ClientHeight = 326 13 | ClientWidth = 355 14 | Constraints.MinHeight = 200 15 | Constraints.MinWidth = 260 16 | OnCreate = FormCreate 17 | Position = poMainFormCenter 18 | object Buttons: TButtonPanel[0] 19 | Left = 8 20 | Height = 36 21 | Top = 282 22 | Width = 339 23 | BorderSpacing.Left = 8 24 | BorderSpacing.Right = 8 25 | BorderSpacing.Bottom = 8 26 | BorderSpacing.Around = 0 27 | OKButton.Name = 'OKButton' 28 | OKButton.DefaultCaption = True 29 | HelpButton.Name = 'HelpButton' 30 | HelpButton.DefaultCaption = True 31 | CloseButton.Name = 'CloseButton' 32 | CloseButton.DefaultCaption = True 33 | CancelButton.Name = 'CancelButton' 34 | CancelButton.DefaultCaption = True 35 | TabOrder = 1 36 | Spacing = 8 37 | ShowButtons = [pbOK, pbCancel] 38 | end 39 | object Panel1: TPanel[1] 40 | Left = 8 41 | Height = 266 42 | Top = 8 43 | Width = 339 44 | Align = alClient 45 | BorderSpacing.Around = 8 46 | BevelOuter = bvNone 47 | ClientHeight = 266 48 | ClientWidth = 339 49 | TabOrder = 0 50 | object lstColumns: TCheckListBox 51 | Left = 0 52 | Height = 266 53 | Top = 0 54 | Width = 256 55 | Anchors = [akTop, akLeft, akRight, akBottom] 56 | ItemHeight = 0 57 | OnClick = lstColumnsClick 58 | OnClickCheck = lstColumnsClickCheck 59 | TabOrder = 0 60 | end 61 | object btUp: TButton 62 | Left = 264 63 | Height = 23 64 | Top = 0 65 | Width = 75 66 | Anchors = [akTop, akRight] 67 | Caption = 'Up' 68 | OnClick = btUpClick 69 | TabOrder = 1 70 | end 71 | object btDown: TButton 72 | Left = 264 73 | Height = 23 74 | Top = 28 75 | Width = 75 76 | Anchors = [akTop, akRight] 77 | Caption = 'Down' 78 | OnClick = btDownClick 79 | TabOrder = 2 80 | end 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /colsetup.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | 32 | unit ColSetup; 33 | 34 | {$mode objfpc}{$H+} 35 | 36 | interface 37 | 38 | uses 39 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls, CheckLst, StdCtrls, ButtonPanel, ExtCtrls, VarGrid, BaseForm; 40 | 41 | type 42 | 43 | { TColSetupForm } 44 | 45 | TColSetupForm = class(TBaseForm) 46 | btDown: TButton; 47 | btUp: TButton; 48 | Buttons: TButtonPanel; 49 | lstColumns: TCheckListBox; 50 | Panel1: TPanel; 51 | procedure btDownClick(Sender: TObject); 52 | procedure btOkClick(Sender: TObject); 53 | procedure btUpClick(Sender: TObject); 54 | procedure FormCreate(Sender: TObject); 55 | procedure lstColumnsClick(Sender: TObject); 56 | procedure lstColumnsClickCheck(Sender: TObject); 57 | private 58 | FPersistentColumnId: integer; 59 | 60 | procedure UpdateUI; 61 | procedure MoveItem(Delta: integer); 62 | public 63 | { public declarations } 64 | end; 65 | 66 | function SetupColumns(LV: TVarGrid; PersistentColumnId: integer; const GridName: string): boolean; 67 | 68 | implementation 69 | 70 | uses main; 71 | 72 | function SetupColumns(LV: TVarGrid; PersistentColumnId: integer; const GridName: string): boolean; 73 | var 74 | i, j: integer; 75 | begin 76 | with TColSetupForm.Create(Application) do 77 | try 78 | if GridName <> '' then 79 | Caption:=Caption + ' - ' + GridName; 80 | FPersistentColumnId:=PersistentColumnId; 81 | for i:=0 to LV.Columns.Count - 1 do 82 | with LV.Columns[i] do begin 83 | j:=lstColumns.Items.Add(Title.Caption); 84 | lstColumns.Items.Objects[j]:=TObject(ptrint(ID)); 85 | if Width = 0 then 86 | Visible:=False; 87 | lstColumns.Checked[j]:=Visible; 88 | if ID = PersistentColumnId then 89 | lstColumns.Checked[j]:=True; 90 | end; 91 | UpdateUI; 92 | Result:=ShowModal = mrOk; 93 | if Result then begin 94 | LV.BeginUpdate; 95 | try 96 | for i:=0 to lstColumns.Items.Count - 1 do 97 | for j:=0 to LV.Columns.Count - 1 do 98 | with LV.Columns[j] do 99 | if ID = ptrint(lstColumns.Items.Objects[i]) then begin 100 | Index:=i; 101 | if ID - 1 = PersistentColumnId then 102 | lstColumns.Checked[i]:=True; 103 | if not Visible and (Visible <> lstColumns.Checked[i]) then begin 104 | Visible:=True; 105 | if Width < 32 then 106 | Width:=70; 107 | end 108 | else 109 | Visible:=lstColumns.Checked[i]; 110 | if not Visible and (LV.SortColumn = ID - 1) and (PersistentColumnId >= 0) then 111 | LV.SortColumn:=PersistentColumnId; 112 | break; 113 | end; 114 | finally 115 | LV.EndUpdate; 116 | end; 117 | end; 118 | finally 119 | Free; 120 | end; 121 | Application.ProcessMessages; 122 | end; 123 | 124 | { TColSetupForm } 125 | 126 | procedure TColSetupForm.btOkClick(Sender: TObject); 127 | var 128 | i: integer; 129 | begin 130 | for i:=0 to lstColumns.Items.Count - 1 do 131 | if lstColumns.Checked[i] then begin 132 | ModalResult:=mrOk; 133 | exit; 134 | end; 135 | MessageDlg('At least single column must be visible.', mtError, [mbOK], 0); 136 | end; 137 | 138 | procedure TColSetupForm.btDownClick(Sender: TObject); 139 | begin 140 | MoveItem(1); 141 | end; 142 | 143 | procedure TColSetupForm.btUpClick(Sender: TObject); 144 | begin 145 | MoveItem(-1); 146 | end; 147 | 148 | procedure TColSetupForm.FormCreate(Sender: TObject); 149 | begin 150 | Buttons.OKButton.ModalResult:=mrNone; 151 | Buttons.OKButton.OnClick:=@btOKClick; 152 | end; 153 | 154 | procedure TColSetupForm.lstColumnsClick(Sender: TObject); 155 | begin 156 | UpdateUI; 157 | end; 158 | 159 | procedure TColSetupForm.lstColumnsClickCheck(Sender: TObject); 160 | var 161 | i: integer; 162 | begin 163 | if FPersistentColumnId >= 0 then 164 | for i:=0 to lstColumns.Items.Count - 1 do 165 | if ptrint(lstColumns.Items.Objects[i]) = FPersistentColumnId then begin 166 | lstColumns.Checked[i]:=True; 167 | break; 168 | end; 169 | end; 170 | 171 | procedure TColSetupForm.UpdateUI; 172 | begin 173 | btUp.Enabled:=lstColumns.ItemIndex > 0; 174 | btDown.Enabled:=(lstColumns.ItemIndex >= 0) and (lstColumns.ItemIndex < lstColumns.Items.Count - 1); 175 | end; 176 | 177 | procedure TColSetupForm.MoveItem(Delta: integer); 178 | var 179 | c: boolean; 180 | OldIdx: integer; 181 | begin 182 | OldIdx:=lstColumns.ItemIndex; 183 | c:=lstColumns.Checked[OldIdx]; 184 | lstColumns.Items.Move(OldIdx, OldIdx+Delta); 185 | lstColumns.Checked[OldIdx+Delta]:=c; 186 | lstColumns.ItemIndex:=OldIdx+Delta; 187 | UpdateUI; 188 | end; 189 | 190 | initialization 191 | {$I colsetup.lrs} 192 | 193 | end. 194 | 195 | -------------------------------------------------------------------------------- /daemonoptions.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit DaemonOptions; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, LazUTF8, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, Spin, ComCtrls, CheckLst, EditBtn, MaskEdit, 39 | ButtonPanel, BaseForm; 40 | 41 | resourcestring 42 | sPortTestSuccess = 'Incoming port tested successfully.'; 43 | sPortTestFailed = 'Incoming port is closed. Check your firewall settings.'; 44 | sEncryptionDisabled = 'Encryption disabled'; 45 | sEncryptionEnabled = 'Encryption enabled'; 46 | sEncryptionRequired = 'Encryption required'; 47 | SNoDownloadDir = 'The downloads directory was not specified.'; 48 | SNoIncompleteDir = 'The directory for incomplete files was not specified.'; 49 | // SNoBlocklistURL = 'The blocklist URL was not specified.'; 50 | SInvalidTime = 'The invalid time value was entered.'; 51 | 52 | type 53 | 54 | { TDaemonOptionsForm } 55 | 56 | TDaemonOptionsForm = class(TBaseForm) 57 | btTestPort: TButton; 58 | Buttons: TButtonPanel; 59 | cbBlocklist: TCheckBox; 60 | cbDHT: TCheckBox; 61 | cbUpQueue: TCheckBox; 62 | cbEncryption: TComboBox; 63 | cbMaxDown: TCheckBox; 64 | cbMaxUp: TCheckBox; 65 | cbPEX: TCheckBox; 66 | cbPortForwarding: TCheckBox; 67 | cbRandomPort: TCheckBox; 68 | cbIncompleteDir: TCheckBox; 69 | cbPartExt: TCheckBox; 70 | cbSeedRatio: TCheckBox; 71 | cbLPD: TCheckBox; 72 | cbIdleSeedLimit: TCheckBox; 73 | cbAltEnabled: TCheckBox; 74 | cbAutoAlt: TCheckBox; 75 | cbStalled: TCheckBox; 76 | cbUTP: TCheckBox; 77 | cbDownQueue: TCheckBox; 78 | edAltTimeEnd: TMaskEdit; 79 | edDownQueue: TSpinEdit; 80 | edUpQueue: TSpinEdit; 81 | edStalledTime: TSpinEdit; 82 | tabQueue: TTabSheet; 83 | txDays: TLabel; 84 | txFrom: TLabel; 85 | edDownloadDir: TEdit; 86 | edIncompleteDir: TEdit; 87 | edBlocklistURL: TEdit; 88 | edMaxDown: TSpinEdit; 89 | edAltDown: TSpinEdit; 90 | edMaxPeers: TSpinEdit; 91 | edMaxUp: TSpinEdit; 92 | edAltUp: TSpinEdit; 93 | edPort: TSpinEdit; 94 | edSeedRatio: TFloatSpinEdit; 95 | gbBandwidth: TGroupBox; 96 | edIdleSeedLimit: TSpinEdit; 97 | gbAltSpeed: TGroupBox; 98 | edAltTimeBegin: TMaskEdit; 99 | txAltUp: TLabel; 100 | txAltDown: TLabel; 101 | txMinutes1: TLabel; 102 | txTo: TLabel; 103 | txKbs3: TLabel; 104 | txKbs4: TLabel; 105 | txMinutes: TLabel; 106 | txMB: TLabel; 107 | txCacheSize: TLabel; 108 | Page: TPageControl; 109 | edCacheSize: TSpinEdit; 110 | tabNetwork: TTabSheet; 111 | tabBandwidth: TTabSheet; 112 | tabDownload: TTabSheet; 113 | txDownloadDir: TLabel; 114 | txEncryption: TLabel; 115 | txKbs1: TLabel; 116 | txKbs2: TLabel; 117 | txPeerLimit: TLabel; 118 | txPort: TLabel; 119 | procedure btOKClick(Sender: TObject); 120 | procedure btTestPortClick(Sender: TObject); 121 | procedure cbAutoAltClick(Sender: TObject); 122 | procedure cbBlocklistClick(Sender: TObject); 123 | procedure cbIdleSeedLimitClick(Sender: TObject); 124 | procedure cbIncompleteDirClick(Sender: TObject); 125 | procedure cbMaxDownClick(Sender: TObject); 126 | procedure cbMaxUpClick(Sender: TObject); 127 | procedure cbRandomPortClick(Sender: TObject); 128 | procedure cbSeedRatioClick(Sender: TObject); 129 | procedure FormCreate(Sender: TObject); 130 | private 131 | { private declarations } 132 | public 133 | { public declarations } 134 | end; 135 | 136 | implementation 137 | 138 | uses main, utils, fpjson; 139 | 140 | { TDaemonOptionsForm } 141 | 142 | procedure TDaemonOptionsForm.cbMaxDownClick(Sender: TObject); 143 | begin 144 | edMaxDown.Enabled:=cbMaxDown.Checked; 145 | end; 146 | 147 | procedure TDaemonOptionsForm.btTestPortClick(Sender: TObject); 148 | var 149 | req, res: TJSONObject; 150 | begin 151 | AppBusy; 152 | req:=TJSONObject.Create; 153 | try 154 | req.Add('method', 'port-test'); 155 | res:=RpcObj.SendRequest(req, False); 156 | AppNormal; 157 | if res = nil then 158 | MainForm.CheckStatus(False) 159 | else 160 | if res.Objects['arguments'].Booleans['port-is-open'] then 161 | MessageDlg(sPortTestSuccess, mtInformation, [mbOk], 0) 162 | else 163 | MessageDlg(sPortTestFailed, mtError, [mbOK], 0); 164 | res.Free; 165 | finally 166 | req.Free; 167 | end; 168 | end; 169 | 170 | procedure TDaemonOptionsForm.cbAutoAltClick(Sender: TObject); 171 | var 172 | i: integer; 173 | begin 174 | edAltTimeBegin.Enabled:=cbAutoAlt.Checked; 175 | edAltTimeEnd.Enabled:=cbAutoAlt.Checked; 176 | txFrom.Enabled:=cbAutoAlt.Checked; 177 | txTo.Enabled:=cbAutoAlt.Checked; 178 | txDays.Enabled:=cbAutoAlt.Checked; 179 | for i:=1 to 7 do 180 | gbAltSpeed.FindChildControl(Format('cbDay%d', [i])).Enabled:=cbAutoAlt.Checked; 181 | end; 182 | 183 | procedure TDaemonOptionsForm.cbBlocklistClick(Sender: TObject); 184 | begin 185 | if not edBlocklistURL.Visible then 186 | exit; 187 | edBlocklistURL.Enabled:=cbBlocklist.Checked; 188 | if edBlocklistURL.Enabled then 189 | edBlocklistURL.Color:=clWindow 190 | else 191 | edBlocklistURL.ParentColor:=True; 192 | end; 193 | 194 | procedure TDaemonOptionsForm.cbIdleSeedLimitClick(Sender: TObject); 195 | begin 196 | edIdleSeedLimit.Enabled:=cbIdleSeedLimit.Checked; 197 | end; 198 | 199 | procedure TDaemonOptionsForm.btOKClick(Sender: TObject); 200 | begin 201 | edDownloadDir.Text:=Trim(edDownloadDir.Text); 202 | if edDownloadDir.Text = '' then begin 203 | Page.ActivePage:=tabDownload; 204 | edDownloadDir.SetFocus; 205 | MessageDlg(SNoDownloadDir, mtError, [mbOK], 0); 206 | exit; 207 | end; 208 | edIncompleteDir.Text:=Trim(edIncompleteDir.Text); 209 | if cbIncompleteDir.Checked and (edIncompleteDir.Text = '') then begin 210 | Page.ActivePage:=tabDownload; 211 | edIncompleteDir.SetFocus; 212 | MessageDlg(SNoIncompleteDir, mtError, [mbOK], 0); 213 | exit; 214 | end; 215 | edBlocklistURL.Text:=Trim(edBlocklistURL.Text); 216 | if cbAutoAlt.Checked then begin 217 | if StrToTimeDef(edAltTimeBegin.Text, -1) < 0 then begin 218 | Page.ActivePage:=tabBandwidth; 219 | edAltTimeBegin.SetFocus; 220 | MessageDlg(SInvalidTime, mtError, [mbOK], 0); 221 | exit; 222 | end; 223 | if StrToTimeDef(edAltTimeEnd.Text, -1) < 0 then begin 224 | Page.ActivePage:=tabBandwidth; 225 | edAltTimeEnd.SetFocus; 226 | MessageDlg(SInvalidTime, mtError, [mbOK], 0); 227 | exit; 228 | end; 229 | end; 230 | ModalResult:=mrOK; 231 | end; 232 | 233 | procedure TDaemonOptionsForm.cbIncompleteDirClick(Sender: TObject); 234 | begin 235 | edIncompleteDir.Enabled:=cbIncompleteDir.Checked; 236 | if edIncompleteDir.Enabled then 237 | edIncompleteDir.Color:=clWindow 238 | else 239 | edIncompleteDir.ParentColor:=True; 240 | end; 241 | 242 | procedure TDaemonOptionsForm.cbMaxUpClick(Sender: TObject); 243 | begin 244 | edMaxUp.Enabled:=cbMaxUp.Checked; 245 | end; 246 | 247 | procedure TDaemonOptionsForm.cbRandomPortClick(Sender: TObject); 248 | begin 249 | edPort.Enabled:=not cbRandomPort.Checked; 250 | end; 251 | 252 | procedure TDaemonOptionsForm.cbSeedRatioClick(Sender: TObject); 253 | begin 254 | edSeedRatio.Enabled:=cbSeedRatio.Checked; 255 | end; 256 | 257 | procedure TDaemonOptionsForm.FormCreate(Sender: TObject); 258 | var 259 | i, j, x, wd: integer; 260 | cb: TCheckBox; 261 | begin 262 | bidiMode := GetBiDi(); 263 | Page.ActivePageIndex:=0; 264 | cbEncryption.Items.Add(sEncryptionDisabled); 265 | cbEncryption.Items.Add(sEncryptionEnabled); 266 | cbEncryption.Items.Add(sEncryptionRequired); 267 | Buttons.OKButton.ModalResult:=mrNone; 268 | Buttons.OKButton.OnClick:=@btOKClick; 269 | 270 | x:=edAltTimeBegin.Left; 271 | wd:=(gbAltSpeed.ClientWidth - x - BorderWidth) div 7; 272 | for i:=1 to 7 do begin 273 | cb:=TCheckBox.Create(gbAltSpeed); 274 | cb.Parent:=gbAltSpeed; 275 | j:=i + 1; 276 | if j > 7 then 277 | Dec(j, 7); 278 | cb.Caption:=SysToUTF8(FormatSettings.ShortDayNames[j]); 279 | cb.Name:=Format('cbDay%d', [j]); 280 | cb.Left:=x; 281 | cb.Top:=txDays.Top - (cb.Height - txDays.Height) div 2; 282 | Inc(x, wd); 283 | end; 284 | end; 285 | 286 | initialization 287 | {$I daemonoptions.lrs} 288 | 289 | end. 290 | 291 | -------------------------------------------------------------------------------- /download.lfm: -------------------------------------------------------------------------------- 1 | inherited DownloadForm: TDownloadForm 2 | Left = 390 3 | Height = 106 4 | Top = 278 5 | Width = 404 6 | HorzScrollBar.Page = 403 7 | HorzScrollBar.Range = 392 8 | VertScrollBar.Page = 105 9 | VertScrollBar.Range = 95 10 | BorderIcons = [biSystemMenu] 11 | BorderStyle = bsDialog 12 | Caption = 'Downloading' 13 | ClientHeight = 106 14 | ClientWidth = 404 15 | OnClose = FormClose 16 | OnCreate = FormCreate 17 | OnDestroy = FormDestroy 18 | OnResize = FormResize 19 | OnShow = FormShow 20 | Position = poMainFormCenter 21 | object txFileName: TLabel[0] 22 | Left = 12 23 | Height = 14 24 | Top = 8 25 | Width = 54 26 | Caption = 'txFileName' 27 | ParentColor = False 28 | end 29 | object txBytes: TLabel[1] 30 | Left = 12 31 | Height = 14 32 | Top = 28 33 | Width = 38 34 | Caption = 'txBytes' 35 | ParentColor = False 36 | end 37 | object txPercent: TLabel[2] 38 | Left = 344 39 | Height = 14 40 | Top = 28 41 | Width = 48 42 | Alignment = taRightJustify 43 | Anchors = [akTop, akRight] 44 | Caption = 'txPercent' 45 | ParentColor = False 46 | end 47 | object btCancel: TButton[3] 48 | Left = 160 49 | Height = 23 50 | Top = 72 51 | Width = 75 52 | AutoSize = True 53 | Cancel = True 54 | Caption = 'Cancel' 55 | Constraints.MinWidth = 75 56 | Default = True 57 | OnClick = btCancelClick 58 | TabOrder = 0 59 | end 60 | object pbDownload: TProgressBar[4] 61 | Left = 12 62 | Height = 16 63 | Top = 44 64 | Width = 380 65 | Anchors = [akTop, akLeft, akRight] 66 | Smooth = True 67 | Step = 1 68 | TabOrder = 1 69 | end 70 | object UpdateTimer: TTimer[5] 71 | Interval = 300 72 | OnTimer = UpdateTimerTimer 73 | left = 36 74 | top = 68 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /download.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit download; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls, 39 | httpsend, synsock, ExtCtrls, BaseForm, utils; 40 | 41 | resourcestring 42 | SDownloadProgress = '%s of %s downloaded'; 43 | SDownloadProgress2 = '%s downloaded'; 44 | 45 | type 46 | TDownloadThread = class; 47 | 48 | { TDownloadForm } 49 | 50 | TDownloadForm = class(TBaseForm) 51 | btCancel: TButton; 52 | UpdateTimer: TTimer; 53 | txPercent: TLabel; 54 | txBytes: TLabel; 55 | txFileName: TLabel; 56 | pbDownload: TProgressBar; 57 | procedure btCancelClick(Sender: TObject); 58 | procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); 59 | procedure FormCreate(Sender: TObject); 60 | procedure FormDestroy(Sender: TObject); 61 | procedure FormResize(Sender: TObject); 62 | procedure FormShow(Sender: TObject); 63 | procedure UpdateTimerTimer(Sender: TObject); 64 | private 65 | FThread: TDownloadThread; 66 | FTotalSize: Int64; 67 | FDownloaded: Int64; 68 | FError: string; 69 | 70 | procedure UpdateStatus(Data: PtrInt); 71 | public 72 | { public declarations } 73 | end; 74 | 75 | { TDownloadThread } 76 | 77 | TDownloadThread = class(TThread) 78 | private 79 | FHttp: THTTPSend; 80 | FForm: TDownloadForm; 81 | FUrl: string; 82 | FDestFileName: string; 83 | FOut: TFileStreamUTF8; 84 | 85 | procedure DoMonitor(Sender: TObject; Writing: Boolean; const Buffer: TMemory; Len: Integer); 86 | procedure WriteToFile; 87 | protected 88 | procedure Execute; override; 89 | end; 90 | 91 | function DownloadFile(const URL, DestFolder: string; const DestFileName: string = ''; const DisplayName: string = ''): boolean; 92 | 93 | implementation 94 | 95 | uses Main, rpc; 96 | 97 | function DownloadFile(const URL, DestFolder: string; const DestFileName, DisplayName: string): boolean; 98 | var 99 | s: string; 100 | begin 101 | with TDownloadForm.Create(Application) do 102 | try 103 | s:=ExtractFileName(StringReplace(URL, '/', DirectorySeparator, [rfReplaceAll])); 104 | if DisplayName <> '' then 105 | txFileName.Caption:=DisplayName 106 | else 107 | txFileName.Caption:=s; 108 | if DestFileName <> '' then 109 | s:=DestFileName; 110 | FThread.FUrl:=URL; 111 | FThread.FDestFileName:=IncludeTrailingPathDelimiter(DestFolder) + s; 112 | FThread.Suspended:=False; 113 | Result:=ShowModal = mrOk; 114 | finally 115 | Free; 116 | end; 117 | end; 118 | 119 | { TDownloadThread } 120 | 121 | procedure TDownloadThread.DoMonitor(Sender: TObject; Writing: Boolean; const Buffer: TMemory; Len: Integer); 122 | begin 123 | if Terminated then begin 124 | FHttp.Abort; 125 | exit; 126 | end; 127 | 128 | if FHttp.DownloadSize <> 0 then begin 129 | FForm.FTotalSize:=FHttp.DownloadSize; 130 | Inc(FForm.FDownloaded, Len); 131 | WriteToFile; 132 | end; 133 | end; 134 | 135 | procedure TDownloadThread.WriteToFile; 136 | begin 137 | if FOut = nil then 138 | FOut:=TFileStreamUTF8.Create(FDestFileName, fmCreate); 139 | 140 | FHttp.Document.Position:=0; 141 | FOut.CopyFrom(FHttp.Document, FHttp.Document.Size); 142 | FHttp.Document.Clear; 143 | end; 144 | 145 | procedure TDownloadThread.Execute; 146 | var 147 | res: PtrInt; 148 | begin 149 | res:=1; 150 | try 151 | FHttp:=THTTPSend.Create; 152 | try 153 | if RpcObj.Http.ProxyHost <> '' then begin 154 | FHttp.ProxyHost:=RpcObj.Http.ProxyHost; 155 | FHttp.ProxyPort:=RpcObj.Http.ProxyPort; 156 | FHttp.ProxyUser:=RpcObj.Http.ProxyUser; 157 | FHttp.ProxyPass:=RpcObj.Http.ProxyPass; 158 | end; 159 | FHttp.Sock.OnMonitor:=@DoMonitor; 160 | if FHttp.HTTPMethod('GET', FUrl) then begin 161 | if FHttp.ResultCode = 200 then begin 162 | FForm.FDownloaded:=FHttp.DownloadSize; 163 | WriteToFile; 164 | res:=2; 165 | end 166 | else 167 | if not Terminated then 168 | FForm.FError:=Format('HTTP error: %d', [FHttp.ResultCode]); 169 | end 170 | else 171 | if not Terminated then 172 | FForm.FError:=FHttp.Sock.LastErrorDesc; 173 | finally 174 | FHttp.Free; 175 | end; 176 | except 177 | FForm.FError:=Exception(ExceptObject).Message; 178 | end; 179 | FOut.Free; 180 | if res = 1 then 181 | DeleteFile(FDestFileName); 182 | Application.QueueAsyncCall(@FForm.UpdateStatus, res); 183 | FForm.FThread:=nil; 184 | end; 185 | 186 | { TDownloadForm } 187 | 188 | procedure TDownloadForm.FormCreate(Sender: TObject); 189 | begin 190 | bidiMode := GetBiDi(); 191 | FThread:=TDownloadThread.Create(True); 192 | FThread.FreeOnTerminate:=True; 193 | FThread.FForm:=Self; 194 | UpdateTimerTimer(nil); 195 | end; 196 | 197 | procedure TDownloadForm.btCancelClick(Sender: TObject); 198 | begin 199 | btCancel.Enabled:=False; 200 | FThread.Terminate; 201 | end; 202 | 203 | procedure TDownloadForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); 204 | begin 205 | if FThread <> nil then begin 206 | CloseAction:=caNone; 207 | btCancel.Click; 208 | end; 209 | end; 210 | 211 | procedure TDownloadForm.FormDestroy(Sender: TObject); 212 | begin 213 | end; 214 | 215 | procedure TDownloadForm.FormResize(Sender: TObject); 216 | begin 217 | btCancel.Left:=(ClientWidth - btCancel.Width) div 2; 218 | end; 219 | 220 | procedure TDownloadForm.FormShow(Sender: TObject); 221 | begin 222 | FormResize(nil); 223 | end; 224 | 225 | procedure TDownloadForm.UpdateTimerTimer(Sender: TObject); 226 | begin 227 | if FTotalSize <> 0 then begin 228 | pbDownload.Max:=FTotalSize; 229 | pbDownload.Position:=FDownloaded; 230 | txPercent.Caption:=Format('%.1f%%', [FDownloaded*100/FTotalSize]); 231 | txBytes.Caption:=Format(SDownloadProgress, [GetHumanSize(FDownloaded), GetHumanSize(FTotalSize)]); 232 | txPercent.Show; 233 | end 234 | else begin 235 | txBytes.Caption:=Format(SDownloadProgress2, [GetHumanSize(FDownloaded)]); 236 | txPercent.Hide; 237 | end; 238 | end; 239 | 240 | procedure TDownloadForm.UpdateStatus(Data: PtrInt); 241 | begin 242 | if Data <> 0 then begin 243 | if Data = 2 then 244 | ModalResult:=mrOk 245 | else begin 246 | if FError <> '' then 247 | MessageDlg(FError, mtError, [mbOK], 0); 248 | ModalResult:=mrCancel; 249 | end; 250 | exit; 251 | end; 252 | end; 253 | 254 | initialization 255 | {$I download.lrs} 256 | 257 | end. 258 | 259 | -------------------------------------------------------------------------------- /flags.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/flags.zip -------------------------------------------------------------------------------- /ipresolver.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit IpResolver; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, GeoIP, syncobjs; 39 | 40 | type 41 | PHostEntry = ^THostEntry; 42 | THostEntry = record 43 | IP: string; 44 | HostName: string; 45 | CountryName: string; 46 | CountryCode: string; 47 | ImageIndex: integer; 48 | end; 49 | 50 | TResolverOption = (roResolveIP, roResolveCountry); 51 | TResolverOptions = set of TResolverOption; 52 | 53 | { TIpResolverThread } 54 | 55 | TIpResolver = class(TThread) 56 | private 57 | FLock: TCriticalSection; 58 | FResolveEvent: TEvent; 59 | FCache: TList; 60 | FResolveIp: TStringList; 61 | FGeoIp: TGeoIP; 62 | FOptions: TResolverOptions; 63 | FGeoIpCounryDB: string; 64 | protected 65 | procedure Execute; override; 66 | function NewEntry(const IpAddress: string): PHostEntry; 67 | function FindEntry(const IpAddress: string): PHostEntry; 68 | public 69 | constructor Create(const GeoIpCounryDB: string; AOptions: TResolverOptions); reintroduce; 70 | destructor Destroy; override; 71 | function Resolve(const IpAddress: string): PHostEntry; 72 | end; 73 | 74 | implementation 75 | 76 | uses synsock; 77 | 78 | { TIpResolver } 79 | 80 | procedure TIpResolver.Execute; 81 | var 82 | ip, s: string; 83 | c: PHostEntry; 84 | begin 85 | try 86 | while not Terminated do begin 87 | if FResolveEvent.WaitFor(200) = wrSignaled then begin 88 | FResolveEvent.ResetEvent; 89 | 90 | while True do begin 91 | FLock.Enter; 92 | try 93 | ip:=''; 94 | if FResolveIp.Count > 0 then begin 95 | ip:=FResolveIp[0]; 96 | FResolveIp.Delete(0); 97 | end; 98 | UniqueString(ip); 99 | finally 100 | FLock.Leave; 101 | end; 102 | 103 | if ip = '' then 104 | break; 105 | 106 | if roResolveIP in FOptions then begin 107 | s:=synsock.ResolveIPToName(ip, AF_INET, IPPROTO_IP, 0); 108 | c:=FindEntry(ip); 109 | FLock.Enter; 110 | try 111 | c^.HostName:=s; 112 | UniqueString(c^.HostName); 113 | finally 114 | FLock.Leave; 115 | end; 116 | end; 117 | end; 118 | 119 | end; 120 | end; 121 | except 122 | end; 123 | Sleep(20); 124 | end; 125 | 126 | function TIpResolver.NewEntry(const IpAddress: string): PHostEntry; 127 | begin 128 | FLock.Enter; 129 | try 130 | New(Result); 131 | Result^.ImageIndex:=0; 132 | Result^.IP:=IpAddress; 133 | UniqueString(Result^.IP); 134 | Result^.HostName:=IpAddress; 135 | UniqueString(Result^.HostName); 136 | FCache.Add(Result); 137 | finally 138 | FLock.Leave; 139 | end; 140 | end; 141 | 142 | function TIpResolver.FindEntry(const IpAddress: string): PHostEntry; 143 | var 144 | i: integer; 145 | begin 146 | FLock.Enter; 147 | try 148 | for i:=0 to FCache.Count - 1 do begin 149 | Result:=FCache[i]; 150 | if Result^.IP = IpAddress then 151 | exit; 152 | end; 153 | Result:=nil; 154 | finally 155 | FLock.Leave; 156 | end; 157 | end; 158 | 159 | constructor TIpResolver.Create(const GeoIpCounryDB: string; AOptions: TResolverOptions); 160 | begin 161 | FOptions:=AOptions; 162 | FLock:=TCriticalSection.Create; 163 | FResolveEvent:=TEvent.Create(nil, True, False, ''); 164 | FCache:=TList.Create; 165 | FResolveIp:=TStringList.Create; 166 | FGeoIpCounryDB:=GeoIpCounryDB; 167 | if (roResolveCountry in FOptions) and (FGeoIpCounryDB <> '') then 168 | FGeoIp:=TGeoIP.Create(GeoIpCounryDB); 169 | inherited Create(not (roResolveIP in FOptions)); 170 | end; 171 | 172 | destructor TIpResolver.Destroy; 173 | var 174 | i: integer; 175 | begin 176 | Terminate; 177 | if not Suspended then 178 | WaitFor; 179 | FResolveIp.Free; 180 | FResolveEvent.Free; 181 | FLock.Free; 182 | FGeoIp.Free; 183 | for i:=0 to FCache.Count - 1 do 184 | Dispose(PHostEntry(FCache[i])); 185 | FCache.Free; 186 | inherited Destroy; 187 | end; 188 | 189 | function TIpResolver.Resolve(const IpAddress: string): PHostEntry; 190 | var 191 | GeoCountry: TGeoIPCountry; 192 | begin 193 | Result:=FindEntry(IpAddress); 194 | if Result <> nil then 195 | exit; 196 | 197 | Result:=NewEntry(IpAddress); 198 | if roResolveIP in FOptions then begin 199 | FLock.Enter; 200 | try 201 | if FResolveIp.IndexOf(IpAddress) < 0 then begin 202 | FResolveIp.Add(IpAddress); 203 | FResolveEvent.SetEvent; 204 | end; 205 | finally 206 | FLock.Leave; 207 | end; 208 | end; 209 | 210 | if FGeoIp <> nil then 211 | try 212 | if FGeoIp.GetCountry(IpAddress, GeoCountry) = GEOIP_SUCCESS then begin 213 | FLock.Enter; 214 | try 215 | Result^.CountryName:=GeoCountry.CountryName; 216 | UniqueString(Result^.CountryName); 217 | Result^.CountryCode:=AnsiLowerCase(GeoCountry.CountryCode); 218 | UniqueString(Result^.CountryCode); 219 | finally 220 | FLock.Leave; 221 | end; 222 | end; 223 | except 224 | FreeAndNil(FGeoIp); 225 | DeleteFile(FGeoIpCounryDB); 226 | Result:=nil; 227 | end; 228 | end; 229 | 230 | end. 231 | 232 | -------------------------------------------------------------------------------- /lineinfo2.pp: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal run time library. 3 | Copyright (c) 2000 by Peter Vreman 4 | 5 | Stabs Line Info Retriever 6 | 7 | See the file COPYING.FPC, included in this distribution, 8 | for details about the copyright. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 | 14 | **********************************************************************} 15 | { 16 | This unit should not be compiled in objfpc mode, since this would make it 17 | dependent on objpas unit. 18 | } 19 | unit lineinfo2; 20 | interface 21 | 22 | {$S-} 23 | {$Q-} 24 | 25 | function GetLineInfo(addr:ptruint;var func,source:string;var line:longint) : boolean; 26 | 27 | implementation 28 | 29 | uses 30 | exeinfo,strings; 31 | 32 | const 33 | N_Function = $24; 34 | N_TextLine = $44; 35 | N_DataLine = $46; 36 | N_BssLine = $48; 37 | N_SourceFile = $64; 38 | N_IncludeFile = $84; 39 | 40 | maxstabs = 40; { size of the stabs buffer } 41 | 42 | var 43 | { GDB after 4.18 uses offset to function begin 44 | in text section but OS/2 version still uses 4.16 PM } 45 | StabsFunctionRelative: boolean; 46 | 47 | type 48 | pstab=^tstab; 49 | tstab=packed record 50 | strpos : longint; 51 | ntype : byte; 52 | nother : byte; 53 | ndesc : word; 54 | nvalue : dword; 55 | end; 56 | 57 | { We use static variable so almost no stack is required, and is thus 58 | more safe when an error has occured in the program } 59 | var 60 | e : TExeFile; 61 | staberr : boolean = false; 62 | stabcnt, { amount of stabs } 63 | stablen, 64 | stabofs, { absolute stab section offset in executable } 65 | stabstrlen, 66 | stabstrofs : longint; { absolute stabstr section offset in executable } 67 | dirlength : longint; { length of the dirctory part of the source file } 68 | stabs : array[0..maxstabs-1] of tstab; { buffer } 69 | funcstab, { stab with current function info } 70 | linestab, { stab with current line info } 71 | dirstab, { stab with current directory info } 72 | filestab : tstab; { stab with current file info } 73 | filename, 74 | dbgfn : string; 75 | 76 | 77 | function OpenStabs(addr : pointer) : boolean; 78 | var 79 | baseaddr : pointer; 80 | begin 81 | OpenStabs:=false; 82 | if staberr then 83 | exit; 84 | 85 | GetModuleByAddr(addr,baseaddr,filename); 86 | {$ifdef DEBUG_LINEINFO} 87 | writeln(stderr,filename,' Baseaddr: ',hexstr(ptruint(baseaddr),sizeof(baseaddr)*2)); 88 | {$endif DEBUG_LINEINFO} 89 | 90 | if not OpenExeFile(e,filename) then 91 | exit; 92 | if ReadDebugLink(e,dbgfn) then 93 | begin 94 | CloseExeFile(e); 95 | if not OpenExeFile(e,dbgfn) then 96 | exit; 97 | end; 98 | e.processaddress:=ptruint(baseaddr)-e.processaddress; 99 | StabsFunctionRelative := E.FunctionRelative; 100 | if FindExeSection(e,'.stab',stabofs,stablen) and 101 | FindExeSection(e,'.stabstr',stabstrofs,stabstrlen) then 102 | begin 103 | stabcnt:=stablen div sizeof(tstab); 104 | OpenStabs:=true; 105 | end 106 | else 107 | begin 108 | CloseExeFile(e); 109 | // staberr:=true; 110 | exit; 111 | end; 112 | end; 113 | 114 | 115 | procedure CloseStabs; 116 | begin 117 | CloseExeFile(e); 118 | end; 119 | 120 | 121 | function GetLineInfo(addr:ptruint;var func,source:string;var line:longint) : boolean; 122 | var 123 | res, 124 | stabsleft, 125 | stabscnt,i : longint; 126 | found : boolean; 127 | lastfunc : tstab; 128 | begin 129 | GetLineInfo:=false; 130 | {$ifdef DEBUG_LINEINFO} 131 | writeln(stderr,'GetLineInfo called'); 132 | {$endif DEBUG_LINEINFO} 133 | fillchar(func,high(func)+1,0); 134 | fillchar(source,high(source)+1,0); 135 | line:=0; 136 | if staberr then 137 | exit; 138 | if not e.isopen then 139 | begin 140 | if not OpenStabs(pointer(addr)) then 141 | exit; 142 | end; 143 | 144 | { correct the value to the correct address in the file } 145 | { processaddress is set in OpenStabs } 146 | addr := dword(addr - e.processaddress); 147 | 148 | {$ifdef DEBUG_LINEINFO} 149 | writeln(stderr,'Addr: ',hexstr(addr,sizeof(addr)*2)); 150 | {$endif DEBUG_LINEINFO} 151 | 152 | fillchar(funcstab,sizeof(tstab),0); 153 | fillchar(filestab,sizeof(tstab),0); 154 | fillchar(dirstab,sizeof(tstab),0); 155 | fillchar(linestab,sizeof(tstab),0); 156 | fillchar(lastfunc,sizeof(tstab),0); 157 | found:=false; 158 | seek(e.f,stabofs); 159 | stabsleft:=stabcnt; 160 | repeat 161 | if stabsleft>maxstabs then 162 | stabscnt:=maxstabs 163 | else 164 | stabscnt:=stabsleft; 165 | blockread(e.f,stabs,stabscnt*sizeof(tstab),res); 166 | stabscnt:=res div sizeof(tstab); 167 | for i:=0 to stabscnt-1 do 168 | begin 169 | case stabs[i].ntype of 170 | N_BssLine, 171 | N_DataLine, 172 | N_TextLine : 173 | begin 174 | if (stabs[i].ntype=N_TextLine) and StabsFunctionRelative then 175 | inc(stabs[i].nvalue,lastfunc.nvalue); 176 | if (stabs[i].nvalue<=addr) and 177 | (stabs[i].nvalue>linestab.nvalue) then 178 | begin 179 | { if it's equal we can stop and take the last info } 180 | if stabs[i].nvalue=addr then 181 | found:=true 182 | else 183 | linestab:=stabs[i]; 184 | end; 185 | end; 186 | N_Function : 187 | begin 188 | lastfunc:=stabs[i]; 189 | if (stabs[i].nvalue<=addr) and 190 | (stabs[i].nvalue>funcstab.nvalue) then 191 | begin 192 | funcstab:=stabs[i]; 193 | fillchar(linestab,sizeof(tstab),0); 194 | end; 195 | end; 196 | N_SourceFile, 197 | N_IncludeFile : 198 | begin 199 | if (stabs[i].nvalue<=addr) and 200 | (stabs[i].nvalue>=filestab.nvalue) then 201 | begin 202 | { if same value and type then the first one 203 | contained the directory PM } 204 | if (stabs[i].nvalue=filestab.nvalue) and 205 | (stabs[i].ntype=filestab.ntype) then 206 | dirstab:=filestab 207 | else 208 | fillchar(dirstab,sizeof(tstab),0); 209 | filestab:=stabs[i]; 210 | fillchar(linestab,sizeof(tstab),0); 211 | { if new file then func is not valid anymore PM } 212 | if stabs[i].ntype=N_SourceFile then 213 | begin 214 | fillchar(funcstab,sizeof(tstab),0); 215 | fillchar(lastfunc,sizeof(tstab),0); 216 | end; 217 | end; 218 | end; 219 | end; 220 | end; 221 | dec(stabsleft,stabscnt); 222 | until found or (stabsleft=0); 223 | 224 | { get the line,source,function info } 225 | line:=linestab.ndesc; 226 | if dirstab.ntype<>0 then 227 | begin 228 | seek(e.f,stabstrofs+dirstab.strpos); 229 | blockread(e.f,source[1],high(source)-1,res); 230 | dirlength:=strlen(@source[1]); 231 | source[0]:=chr(dirlength); 232 | end 233 | else 234 | dirlength:=0; 235 | if filestab.ntype<>0 then 236 | begin 237 | seek(e.f,stabstrofs+filestab.strpos); 238 | blockread(e.f,source[dirlength+1],high(source)-(dirlength+1),res); 239 | source[0]:=chr(strlen(@source[1])); 240 | end; 241 | if funcstab.ntype<>0 then 242 | begin 243 | seek(e.f,stabstrofs+funcstab.strpos); 244 | blockread(e.f,func[1],high(func)-1,res); 245 | func[0]:=chr(strlen(@func[1])); 246 | i:=pos(':',func); 247 | if i>0 then 248 | Delete(func,i,255); 249 | end; 250 | if e.isopen then 251 | CloseStabs; 252 | GetLineInfo:=true; 253 | end; 254 | 255 | 256 | function StabBackTraceStr(addr:Pointer):shortstring; 257 | var 258 | func, 259 | source : string; 260 | hs : string[32]; 261 | line : longint; 262 | Store : TBackTraceStrFunc; 263 | Success : boolean; 264 | begin 265 | {$ifdef DEBUG_LINEINFO} 266 | writeln(stderr,'StabBackTraceStr called'); 267 | {$endif DEBUG_LINEINFO} 268 | { reset to prevent infinite recursion if problems inside the code PM } 269 | Success:=false; 270 | Store:=BackTraceStrFunc; 271 | BackTraceStrFunc:=@SysBackTraceStr; 272 | Success:=GetLineInfo(ptruint(addr),func,source,line); 273 | { create string } 274 | {$ifdef netware} 275 | { we need addr relative to code start on netware } 276 | dec(addr,ptruint(system.NWGetCodeStart)); 277 | StabBackTraceStr:=' CodeStart + $'+HexStr(ptruint(addr),sizeof(ptruint)*2); 278 | {$else} 279 | StabBackTraceStr:=' $'+HexStr(ptruint(addr),sizeof(ptruint)*2); 280 | {$endif} 281 | if func<>'' then 282 | StabBackTraceStr:=StabBackTraceStr+' '+func; 283 | if source<>'' then 284 | begin 285 | if func<>'' then 286 | StabBackTraceStr:=StabBackTraceStr+', '; 287 | if line<>0 then 288 | begin 289 | str(line,hs); 290 | StabBackTraceStr:=StabBackTraceStr+' line '+hs; 291 | end; 292 | StabBackTraceStr:=StabBackTraceStr+' of '+source; 293 | end; 294 | if Success then 295 | BackTraceStrFunc:=Store; 296 | end; 297 | 298 | initialization 299 | // BackTraceStrFunc:=@StabBackTraceStr; 300 | 301 | finalization 302 | if e.isopen then 303 | CloseStabs; 304 | end. 305 | -------------------------------------------------------------------------------- /maclocale.pas: -------------------------------------------------------------------------------- 1 | { 2 | This file is part of the Free Pascal packages library. 3 | Copyright (c) 2013 by Yury Sidorov, member of the 4 | Free Pascal development team 5 | 6 | This unit is used to get format settings of the current 7 | Mac OS UI locale. Works on Mac OS X 10.3 or later. 8 | 9 | Function CFStringToStr() has been taken from CarbonProc LCL unit. 10 | 11 | See the file COPYING.FPC, included in this distribution, 12 | for details about the copyright. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | 18 | **********************************************************************} 19 | 20 | unit MacLocale; 21 | 22 | {$mode objfpc}{$H+} 23 | 24 | interface 25 | 26 | uses 27 | SysUtils, MacOSAll; 28 | 29 | procedure GetMacFormatSettings(var ASettings: TFormatSettings); 30 | 31 | implementation 32 | 33 | {------------------------------------------------------------------------------ 34 | Name: CFStringToStr 35 | Params: AString - Core Foundation string ref 36 | Encoding - Result data encoding format 37 | Returns: UTF-8 string 38 | 39 | Converts Core Foundation string to string 40 | ------------------------------------------------------------------------------} 41 | function CFStringToStr(AString: CFStringRef; Encoding: CFStringEncoding = kCFStringEncodingUTF8): String; 42 | var 43 | Str: Pointer; 44 | StrSize: CFIndex; 45 | StrRange: CFRange; 46 | begin 47 | if AString = nil then 48 | begin 49 | Result := ''; 50 | Exit; 51 | end; 52 | 53 | // Try the quick way first 54 | Str := CFStringGetCStringPtr(AString, Encoding); 55 | if Str <> nil then 56 | Result := PChar(Str) 57 | else 58 | begin 59 | // if that doesn't work this will 60 | StrRange.location := 0; 61 | StrRange.length := CFStringGetLength(AString); 62 | 63 | CFStringGetBytes(AString, StrRange, Encoding, 64 | Ord('?'), False, nil, 0, StrSize{%H-}); 65 | SetLength(Result, StrSize); 66 | 67 | if StrSize > 0 then 68 | CFStringGetBytes(AString, StrRange, Encoding, 69 | Ord('?'), False, @Result[1], StrSize, StrSize); 70 | end; 71 | end; 72 | 73 | function StrOfChar(c: AnsiChar; Count: integer): ansistring; 74 | begin 75 | SetLength(Result, Count); 76 | FillChar(PAnsiChar(Result)^, Count, c); 77 | end; 78 | 79 | function ConvertFormatStr(const fmt: ansistring): ansistring; 80 | var 81 | cnt: integer; 82 | c, q: AnsiChar; 83 | p: PAnsiChar; 84 | s: ansistring; 85 | begin 86 | Result:=''; 87 | q:=#0; 88 | cnt:=1; 89 | p:=PAnsiChar(fmt); 90 | while p^ <> #0 do begin 91 | s:=''; 92 | c:=p^; 93 | if c in ['''', '"'] then begin 94 | if q = #0 then 95 | q:=c 96 | else 97 | if c = q then begin 98 | q:=#0; 99 | cnt:=1; 100 | end; 101 | s:=c; 102 | end 103 | else 104 | if q <> #0 then 105 | s:=c 106 | else begin 107 | if (p + 1)^ = c then 108 | Inc(cnt) 109 | else begin 110 | case c of 111 | 'y', 'Y': 112 | begin 113 | c:='y'; 114 | if cnt > 2 then 115 | cnt:=4 116 | else 117 | cnt:=2; 118 | end; 119 | 'M', 'L': 120 | begin 121 | c:='m'; 122 | if cnt > 4 then 123 | cnt:=3; 124 | end; 125 | 'd': 126 | if cnt > 2 then 127 | cnt:=2; 128 | 'E', 'e', 'c': 129 | begin 130 | c:='d'; 131 | if (cnt < 3) or (cnt > 4) then 132 | cnt:=3; 133 | end; 134 | 'a': 135 | begin 136 | cnt:=0; 137 | s:='ampm'; 138 | end; 139 | 'h', 'H', 'k', 'K': 140 | begin 141 | c:='h'; 142 | if cnt > 2 then 143 | cnt:=2; 144 | end; 145 | 'm': 146 | begin 147 | c:='n'; 148 | if cnt > 2 then 149 | cnt:=2; 150 | end; 151 | 's': 152 | if cnt > 2 then 153 | cnt:=2; 154 | 'S': 155 | begin 156 | c:='z'; 157 | cnt:=1; 158 | end; 159 | 'G','u','Q','q','w','W','D','F','g','A','z','Z','v': 160 | cnt:=0; 161 | end; 162 | if cnt > 0 then 163 | s:=StrOfChar(c, cnt); 164 | cnt:=1; 165 | end; 166 | end; 167 | Inc(p); 168 | if s <> '' then 169 | Result:=Result + s; 170 | end; 171 | end; 172 | 173 | procedure GetMacFormatSettings(var ASettings: TFormatSettings); 174 | var 175 | loc: CFLocaleRef; 176 | 177 | function _GetFormat(dateStyle: CFDateFormatterStyle; timeStyle: CFDateFormatterStyle; const DefFormat: string): string; 178 | var 179 | fmt: CFDateFormatterRef; 180 | begin 181 | Result:=''; 182 | fmt:=CFDateFormatterCreate(nil, loc, dateStyle, timeStyle); 183 | if fmt <> nil then begin 184 | Result:=ConvertFormatStr(CFStringToStr(CFDateFormatterGetFormat(fmt))); 185 | CFRelease(fmt); 186 | end; 187 | if Result = '' then 188 | Result:=DefFormat; 189 | end; 190 | 191 | function _DateToStr(fmt: CFDateFormatterRef; const AFormat: ansistring; AYear: integer; AMonth, ADay, AHour: byte; 192 | const ADefault: ansistring): ansistring; 193 | var 194 | cs: CFStringRef; 195 | gd: CFGregorianDate; 196 | at: CFAbsoluteTime; 197 | tz: CFTimeZoneRef; 198 | begin 199 | cs:=CFStringCreateWithCString(nil, Pointer(PAnsiChar(AFormat)), kCFStringEncodingUTF8); 200 | CFDateFormatterSetFormat(fmt, cs); 201 | CFRelease(cs); 202 | FillChar(gd, SIzeOf(gd), 0); 203 | gd.year:=AYear; 204 | gd.month:=AMonth; 205 | gd.day:=ADay; 206 | gd.hour:=AHour; 207 | tz:=CFTimeZoneCopyDefault; 208 | at:=CFGregorianDateGetAbsoluteTime(gd, tz); 209 | CFRelease(tz); 210 | cs:=CFDateFormatterCreateStringWithAbsoluteTime(nil, fmt, at); 211 | Result:=CFStringToStr(cs); 212 | CFRelease(cs); 213 | if Result = '' then 214 | Result:=ADefault; 215 | end; 216 | 217 | function _GetSeparator(dateStyle: CFDateFormatterStyle; timeStyle: CFDateFormatterStyle; DefSep: char): char; 218 | var 219 | fmt: CFDateFormatterRef; 220 | s: ansistring; 221 | p: PAnsiChar; 222 | begin 223 | Result:=DefSep; 224 | fmt:=CFDateFormatterCreate(nil, loc, dateStyle, timeStyle); 225 | if fmt <> nil then begin 226 | s:=_DateToStr(fmt, CFStringToStr(CFDateFormatterGetFormat(fmt)), 2000, 1, 1, 0, DefSep); 227 | s:=Trim(s); 228 | p:=PAnsiChar(s); 229 | while p^ <> #0 do 230 | if (p^ > ' ') and (p^ < 'A') and not (p^ in ['0'..'9']) then begin 231 | Result:=p^; 232 | break; 233 | end 234 | else 235 | Inc(p); 236 | CFRelease(fmt); 237 | end; 238 | end; 239 | 240 | var 241 | s: string; 242 | fmt: CFDateFormatterRef; 243 | i: integer; 244 | begin 245 | with ASettings do begin 246 | loc:=CFLocaleCopyCurrent; 247 | if loc = nil then 248 | exit; 249 | s:=CFStringToStr(CFLocaleGetValue(loc, kCFLocaleDecimalSeparator)); 250 | if Length(s) = 1 then 251 | DecimalSeparator:=s[1]; 252 | s:=CFStringToStr(CFLocaleGetValue(loc, kCFLocaleGroupingSeparator)); 253 | if Length(s) = 1 then 254 | ThousandSeparator:=s[1] 255 | else 256 | ThousandSeparator:=' '; // Unicode char has been returned. Probably it is a whitespace 257 | CurrencyString:=CFStringToStr(CFLocaleGetValue(loc, kCFLocaleCurrencySymbol)); 258 | 259 | DateSeparator:=_GetSeparator(kCFDateFormatterShortStyle, kCFDateFormatterNoStyle, DateSeparator); 260 | TimeSeparator:=_GetSeparator(kCFDateFormatterNoStyle, kCFDateFormatterShortStyle, TimeSeparator); 261 | 262 | LongDateFormat:=_GetFormat(kCFDateFormatterLongStyle, kCFDateFormatterNoStyle, LongDateFormat); 263 | ShortDateFormat:=_GetFormat(kCFDateFormatterShortStyle, kCFDateFormatterNoStyle, ShortDateFormat); 264 | LongTimeFormat:=_GetFormat(kCFDateFormatterNoStyle, kCFDateFormatterLongStyle, LongTimeFormat); 265 | ShortTimeFormat:=_GetFormat(kCFDateFormatterNoStyle, kCFDateFormatterShortStyle, ShortTimeFormat); 266 | 267 | fmt:=CFDateFormatterCreate(nil, loc, kCFDateFormatterNoStyle, kCFDateFormatterNoStyle); 268 | if fmt <> nil then begin 269 | for i:=1 to 12 do begin 270 | LongMonthNames[i]:=_DateToStr(fmt, 'LLLL', 2006, i, 1, 0, LongMonthNames[i]); 271 | ShortMonthNames[i]:=_DateToStr(fmt, 'LLL', 2006, i, 1, 0, ShortMonthNames[i]); 272 | end; 273 | for i:=1 to 7 do begin 274 | LongDayNames[i]:=_DateToStr(fmt, 'cccc', 2006, 1, i, 0, LongDayNames[i]); 275 | ShortDayNames[i]:=_DateToStr(fmt, 'ccc', 2006, 1, i, 0, ShortDayNames[i]); 276 | end; 277 | TimeAMString:=_DateToStr(fmt, 'a', 2006, 1, 1, 1, TimeAMString); 278 | TimePMString:=_DateToStr(fmt, 'a', 2006, 1, 1, 13, TimePMString); 279 | CFRelease(fmt); 280 | end; 281 | CFRelease(loc); 282 | end; 283 | end; 284 | 285 | initialization 286 | GetMacFormatSettings(DefaultFormatSettings); 287 | 288 | end. 289 | 290 | -------------------------------------------------------------------------------- /movetorrent.lfm: -------------------------------------------------------------------------------- 1 | inherited MoveTorrentForm: TMoveTorrentForm 2 | Left = 476 3 | Height = 126 4 | Top = 200 5 | Width = 643 6 | AutoSize = True 7 | BorderIcons = [biSystemMenu] 8 | BorderStyle = bsDialog 9 | Caption = 'Torrent data location' 10 | ClientHeight = 126 11 | ClientWidth = 643 12 | OnCreate = FormCreate 13 | Position = poMainFormCenter 14 | object Buttons: TButtonPanel[0] 15 | Left = 8 16 | Height = 40 17 | Top = 78 18 | Width = 627 19 | BorderSpacing.Left = 8 20 | BorderSpacing.Right = 8 21 | BorderSpacing.Bottom = 8 22 | BorderSpacing.Around = 0 23 | OKButton.Name = 'OKButton' 24 | OKButton.DefaultCaption = True 25 | HelpButton.Name = 'HelpButton' 26 | HelpButton.DefaultCaption = True 27 | CloseButton.Name = 'CloseButton' 28 | CloseButton.DefaultCaption = True 29 | CancelButton.Name = 'CancelButton' 30 | CancelButton.DefaultCaption = True 31 | TabOrder = 1 32 | Spacing = 8 33 | ShowButtons = [pbOK, pbCancel] 34 | end 35 | object Panel1: TPanel[1] 36 | Left = 8 37 | Height = 70 38 | Top = 8 39 | Width = 627 40 | Align = alClient 41 | BorderSpacing.Left = 8 42 | BorderSpacing.Top = 8 43 | BorderSpacing.Right = 8 44 | BevelOuter = bvNone 45 | ClientHeight = 70 46 | ClientWidth = 627 47 | Constraints.MinWidth = 545 48 | TabOrder = 0 49 | object txTorrentDir: TLabel 50 | Left = 0 51 | Height = 21 52 | Top = 0 53 | Width = 528 54 | AutoSize = False 55 | Caption = 'New location for torrent data:' 56 | ParentColor = False 57 | end 58 | object edTorrentDir: TComboBox 59 | Left = 0 60 | Height = 23 61 | Top = 20 62 | Width = 528 63 | Anchors = [akTop, akLeft, akRight] 64 | AutoSize = False 65 | DropDownCount = 60 66 | ItemHeight = 0 67 | Sorted = True 68 | TabOrder = 0 69 | end 70 | object cbMoveData: TCheckBox 71 | Left = 0 72 | Height = 19 73 | Top = 47 74 | Width = 528 75 | AutoSize = False 76 | Caption = 'Move torrent data from current location to new location' 77 | Checked = True 78 | State = cbChecked 79 | TabOrder = 2 80 | end 81 | object btBrowse: TButton 82 | Left = 536 83 | Height = 23 84 | Top = 20 85 | Width = 91 86 | Anchors = [akTop, akRight] 87 | Caption = 'Browse...' 88 | Constraints.MaxWidth = 91 89 | Constraints.MinWidth = 91 90 | OnClick = btBrowseClick 91 | TabOrder = 1 92 | end 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /movetorrent.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit MoveTorrent; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel, ExtCtrls, BaseForm; 39 | 40 | resourcestring 41 | SNoTorrentDir = 'No torrent location was specified.'; 42 | SSelectFolder = 'Select torrent location'; 43 | 44 | type 45 | 46 | { TMoveTorrentForm } 47 | 48 | TMoveTorrentForm = class(TBaseForm) 49 | btBrowse: TButton; 50 | Buttons: TButtonPanel; 51 | cbMoveData: TCheckBox; 52 | edTorrentDir: TComboBox; 53 | Panel1: TPanel; 54 | txTorrentDir: TLabel; 55 | procedure btBrowseClick(Sender: TObject); 56 | procedure btOKClick(Sender: TObject); 57 | procedure FormCreate(Sender: TObject); 58 | private 59 | { private declarations } 60 | public 61 | { public declarations } 62 | end; 63 | 64 | implementation 65 | 66 | uses main; 67 | 68 | { TMoveTorrentForm } 69 | 70 | procedure TMoveTorrentForm.btOKClick(Sender: TObject); 71 | begin 72 | edTorrentDir.Text:=Trim(edTorrentDir.Text); 73 | if edTorrentDir.Text = '' then begin 74 | edTorrentDir.SetFocus; 75 | MessageDlg(SNoTorrentDir, mtError, [mbOK], 0); 76 | exit; 77 | end; 78 | ModalResult:=mrOK; 79 | end; 80 | 81 | procedure TMoveTorrentForm.btBrowseClick(Sender: TObject); 82 | var 83 | s: string; 84 | begin 85 | s:=MainForm.SelectRemoteFolder(edTorrentDir.Text, SSelectFolder); 86 | if s <> '' then 87 | edTorrentDir.Text:=s; 88 | end; 89 | 90 | procedure TMoveTorrentForm.FormCreate(Sender: TObject); 91 | begin 92 | Buttons.OKButton.ModalResult:=mrNone; 93 | Buttons.OKButton.OnClick:=@btOKClick; 94 | bidiMode := GetBiDi(); 95 | btBrowse.Left := edTorrentDir.Left + edTorrentDir.Width + 8; // fix button 96 | end; 97 | 98 | initialization 99 | {$I movetorrent.lrs} 100 | 101 | end. 102 | -------------------------------------------------------------------------------- /options.lfm: -------------------------------------------------------------------------------- 1 | inherited OptionsForm: TOptionsForm 2 | Left = 313 3 | Height = 331 4 | Top = 230 5 | Width = 564 6 | AutoSize = True 7 | BorderIcons = [biSystemMenu] 8 | BorderStyle = bsDialog 9 | Caption = 'Application options' 10 | ClientHeight = 331 11 | ClientWidth = 564 12 | OnActivate = FormActivate 13 | OnCreate = FormCreate 14 | OnDestroy = FormDestroy 15 | OnShow = FormShow 16 | Position = poMainFormCenter 17 | object Page: TPageControl[0] 18 | Left = 8 19 | Height = 329 20 | Top = 8 21 | Width = 548 22 | ActivePage = tabGeneral 23 | Align = alClient 24 | BorderSpacing.Around = 8 25 | TabIndex = 0 26 | TabOrder = 0 27 | object tabGeneral: TTabSheet 28 | Caption = 'General' 29 | ClientHeight = 253 30 | ClientWidth = 540 31 | object gbNewTorrent: TGroupBox 32 | Left = 8 33 | Height = 95 34 | Top = 118 35 | Width = 523 36 | Anchors = [akTop, akLeft, akRight] 37 | Caption = 'Add torrent' 38 | ClientHeight = 75 39 | ClientWidth = 519 40 | TabOrder = 1 41 | object cbShowAddTorrentWindow: TCheckBox 42 | Left = 10 43 | Height = 19 44 | Top = 4 45 | Width = 322 46 | Caption = 'Prompt for download options when adding a new torrent' 47 | TabOrder = 0 48 | end 49 | object cbDeleteTorrentFile: TCheckBox 50 | Left = 10 51 | Height = 19 52 | Top = 28 53 | Width = 263 54 | Caption = 'Delete a .torrent file after a successful addition' 55 | TabOrder = 1 56 | end 57 | object cbLinksFromClipboard: TCheckBox 58 | Left = 10 59 | Height = 19 60 | Top = 52 61 | Width = 285 62 | Caption = 'Automatically add torrent links from the clipboard' 63 | TabOrder = 2 64 | end 65 | end 66 | object gbData: TGroupBox 67 | Left = 8 68 | Height = 106 69 | Top = 6 70 | Width = 523 71 | Anchors = [akTop, akLeft, akRight] 72 | Caption = 'Data display' 73 | ClientHeight = 86 74 | ClientWidth = 519 75 | TabOrder = 0 76 | object txSeconds: TLabel 77 | Left = 435 78 | Height = 15 79 | Top = 6 80 | Width = 43 81 | Anchors = [akTop, akRight] 82 | Caption = 'seconds' 83 | ParentColor = False 84 | end 85 | object txRefreshInterval: TLabel 86 | Left = 10 87 | Height = 15 88 | Top = 5 89 | Width = 108 90 | Caption = 'Data refresh interval:' 91 | ParentColor = False 92 | end 93 | object txRefreshIntervalMin: TLabel 94 | Left = 10 95 | Height = 15 96 | Top = 33 97 | Width = 199 98 | Caption = 'Data refresh interval when minimized:' 99 | ParentColor = False 100 | end 101 | object txSeconds2: TLabel 102 | Left = 435 103 | Height = 15 104 | Top = 34 105 | Width = 43 106 | Anchors = [akTop, akRight] 107 | Caption = 'seconds' 108 | ParentColor = False 109 | end 110 | object edRefreshInterval: TSpinEdit 111 | Left = 358 112 | Height = 23 113 | Top = 2 114 | Width = 70 115 | Anchors = [akTop, akRight] 116 | MaxValue = 999 117 | MinValue = 1 118 | TabOrder = 0 119 | Value = 1 120 | end 121 | object edRefreshIntervalMin: TSpinEdit 122 | Left = 358 123 | Height = 23 124 | Top = 30 125 | Width = 70 126 | Anchors = [akTop, akRight] 127 | MaxValue = 999 128 | MinValue = 1 129 | TabOrder = 1 130 | Value = 1 131 | end 132 | object cbCalcAvg: TCheckBox 133 | Left = 10 134 | Height = 19 135 | Top = 60 136 | Width = 298 137 | Caption = 'Average out transfer speeds to eliminate fluctuations' 138 | TabOrder = 2 139 | end 140 | end 141 | end 142 | object tabAdvanced: TTabSheet 143 | Caption = 'Advanced' 144 | ClientHeight = 253 145 | ClientWidth = 540 146 | object txLanguage: TLabel 147 | Left = 8 148 | Height = 15 149 | Top = 148 150 | Width = 55 151 | Caption = 'Language:' 152 | ParentColor = False 153 | end 154 | object gbTray: TGroupBox 155 | Left = 8 156 | Height = 73 157 | Top = 6 158 | Width = 523 159 | Anchors = [akTop, akLeft, akRight] 160 | Caption = 'Tray icon' 161 | ChildSizing.LeftRightSpacing = 10 162 | ChildSizing.TopBottomSpacing = 4 163 | ChildSizing.VerticalSpacing = 6 164 | ChildSizing.EnlargeHorizontal = crsHomogenousChildResize 165 | ChildSizing.Layout = cclLeftToRightThenTopToBottom 166 | ChildSizing.ControlsPerLine = 2 167 | ClientHeight = 53 168 | ClientWidth = 519 169 | TabOrder = 0 170 | object cbTrayMinimize: TCheckBox 171 | Left = 10 172 | Height = 19 173 | Top = 4 174 | Width = 231 175 | Caption = 'Minimize to tray' 176 | TabOrder = 0 177 | end 178 | object cbTrayClose: TCheckBox 179 | Left = 241 180 | Height = 19 181 | Top = 4 182 | Width = 268 183 | Caption = 'Close to tray' 184 | TabOrder = 1 185 | end 186 | object cbTrayIconAlways: TCheckBox 187 | Left = 10 188 | Height = 19 189 | Top = 29 190 | Width = 231 191 | Caption = 'Tray icon always visible' 192 | TabOrder = 2 193 | end 194 | object cbTrayNotify: TCheckBox 195 | Left = 241 196 | Height = 19 197 | Top = 29 198 | Width = 268 199 | Caption = 'Show notifications in tray icon' 200 | TabOrder = 3 201 | end 202 | end 203 | object cbLanguage: TComboBox 204 | Left = 248 205 | Height = 23 206 | Top = 146 207 | Width = 136 208 | Anchors = [akTop, akLeft, akRight] 209 | DropDownCount = 60 210 | ItemHeight = 15 211 | OnEnter = cbLanguageEnter 212 | OnMouseDown = cbLanguageMouseDown 213 | Style = csDropDownList 214 | TabOrder = 4 215 | end 216 | object txIntfScale: TLabel 217 | Left = 8 218 | Height = 15 219 | Top = 121 220 | Width = 49 221 | Caption = 'Font size:' 222 | ParentColor = False 223 | end 224 | object edIntfScale: TSpinEdit 225 | Left = 248 226 | Height = 23 227 | Top = 118 228 | Width = 70 229 | Increment = 5 230 | MaxValue = 200 231 | MinValue = 75 232 | TabOrder = 3 233 | Value = 100 234 | end 235 | object txPerc: TLabel 236 | Left = 328 237 | Height = 15 238 | Top = 121 239 | Width = 10 240 | Caption = '%' 241 | ParentColor = False 242 | end 243 | object cbCheckNewVersion: TCheckBox 244 | Left = 8 245 | Height = 19 246 | Top = 92 247 | Width = 171 248 | Caption = 'Check for new version every:' 249 | OnClick = cbCheckNewVersionClick 250 | TabOrder = 1 251 | end 252 | object edCheckVersionDays: TSpinEdit 253 | Left = 248 254 | Height = 23 255 | Top = 90 256 | Width = 70 257 | MaxValue = 999 258 | MinValue = 1 259 | TabOrder = 2 260 | Value = 5 261 | end 262 | object txDays: TLabel 263 | Left = 328 264 | Height = 15 265 | Top = 93 266 | Width = 24 267 | Caption = 'days' 268 | ParentColor = False 269 | end 270 | object gbSysInt: TGroupBox 271 | Left = 8 272 | Height = 71 273 | Top = 172 274 | Width = 523 275 | Anchors = [akTop, akLeft, akRight] 276 | Caption = 'System integration' 277 | ClientHeight = 51 278 | ClientWidth = 519 279 | TabOrder = 5 280 | Visible = False 281 | object cbRegExt: TCheckBox 282 | Left = 10 283 | Height = 19 284 | Top = 4 285 | Width = 158 286 | Caption = 'Handle .torrent files by %s' 287 | TabOrder = 0 288 | end 289 | object cbRegMagnet: TCheckBox 290 | Left = 10 291 | Height = 19 292 | Top = 28 293 | Width = 163 294 | Caption = 'Handle magnet links by %s' 295 | TabOrder = 1 296 | end 297 | end 298 | object cbLangLeftRight: TComboBox 299 | Left = 392 300 | Height = 23 301 | Top = 148 302 | Width = 136 303 | Anchors = [akTop, akLeft, akRight] 304 | DropDownCount = 60 305 | ItemHeight = 15 306 | OnEnter = cbLanguageEnter 307 | OnMouseDown = cbLanguageMouseDown 308 | Style = csDropDownList 309 | TabOrder = 6 310 | end 311 | end 312 | end 313 | object Buttons: TButtonPanel[1] 314 | Left = 8 315 | Height = 26 316 | Top = 297 317 | Width = 548 318 | BorderSpacing.Left = 8 319 | BorderSpacing.Right = 8 320 | BorderSpacing.Bottom = 8 321 | BorderSpacing.Around = 0 322 | OKButton.Name = 'OKButton' 323 | OKButton.DefaultCaption = True 324 | HelpButton.Name = 'HelpButton' 325 | HelpButton.DefaultCaption = True 326 | CloseButton.Name = 'CloseButton' 327 | CloseButton.DefaultCaption = True 328 | CancelButton.Name = 'CancelButton' 329 | CancelButton.DefaultCaption = True 330 | TabOrder = 1 331 | Spacing = 8 332 | ShowButtons = [pbOK, pbCancel] 333 | ShowBevel = False 334 | end 335 | end 336 | -------------------------------------------------------------------------------- /passwcon.lfm: -------------------------------------------------------------------------------- 1 | object PasswordConnect: TPasswordConnect 2 | Left = 421 3 | Height = 99 4 | Top = 451 5 | Width = 456 6 | BorderIcons = [] 7 | Caption = 'PasswordConnect' 8 | ClientHeight = 99 9 | ClientWidth = 456 10 | Constraints.MaxHeight = 99 11 | Constraints.MaxWidth = 456 12 | Constraints.MinHeight = 99 13 | Constraints.MinWidth = 456 14 | OnCreate = FormCreate 15 | Position = poMainFormCenter 16 | LCLVersion = '1.6.4.0' 17 | object lMsg: TLabel 18 | Left = 8 19 | Height = 23 20 | Top = 8 21 | Width = 440 22 | AutoSize = False 23 | Caption = 'lMsg' 24 | ParentColor = False 25 | end 26 | object passw: TEdit 27 | Left = 8 28 | Height = 23 29 | Top = 32 30 | Width = 440 31 | AutoSize = False 32 | EchoMode = emPassword 33 | PasswordChar = '*' 34 | TabOrder = 0 35 | Text = '12345' 36 | end 37 | object Buttons: TButtonPanel 38 | Left = 8 39 | Height = 26 40 | Top = 65 41 | Width = 440 42 | BorderSpacing.Left = 8 43 | BorderSpacing.Right = 8 44 | BorderSpacing.Bottom = 8 45 | BorderSpacing.Around = 0 46 | OKButton.Name = 'OKButton' 47 | OKButton.DefaultCaption = True 48 | OKButton.OnClick = OKButtonClick 49 | HelpButton.Name = 'HelpButton' 50 | HelpButton.DefaultCaption = True 51 | CloseButton.Name = 'CloseButton' 52 | CloseButton.DefaultCaption = True 53 | CancelButton.Name = 'CancelButton' 54 | CancelButton.DefaultCaption = True 55 | CancelButton.OnClick = CancelButtonClick 56 | TabOrder = 1 57 | Spacing = 8 58 | ShowButtons = [pbOK, pbCancel] 59 | ShowBevel = False 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /passwcon.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit passwcon; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, ButtonPanel; 39 | 40 | type 41 | 42 | { TPasswordConnect } 43 | 44 | TPasswordConnect = class(TForm) 45 | Buttons: TButtonPanel; 46 | passw: TEdit; 47 | lMsg: TLabel; 48 | procedure CancelButtonClick(Sender: TObject); 49 | procedure FormCreate(Sender: TObject); 50 | procedure OKButtonClick(Sender: TObject); 51 | procedure SetText(form : string; msg : string); 52 | 53 | private 54 | { private declarations } 55 | public 56 | { public declarations } 57 | gPassw : string; 58 | end; 59 | 60 | var 61 | PasswordConnect: TPasswordConnect; 62 | 63 | implementation 64 | 65 | uses main; 66 | 67 | { TPasswordConnect } 68 | 69 | procedure TPasswordConnect.CancelButtonClick(Sender: TObject); 70 | begin 71 | 72 | end; 73 | 74 | procedure TPasswordConnect.FormCreate(Sender: TObject); 75 | begin 76 | 77 | Buttons.OKButton.ModalResult:= mrNone; 78 | bidiMode := GetBiDi; 79 | gPassw := ''; 80 | passw.Text := ''; 81 | end; 82 | 83 | procedure TPasswordConnect.OKButtonClick(Sender: TObject); 84 | begin 85 | gPassw:= passw.Text; 86 | ModalResult:=mrOk; 87 | end; 88 | 89 | 90 | procedure TPasswordConnect.SetText(form : string; msg : string); 91 | begin 92 | lMsg.Caption := msg; 93 | Caption := form; 94 | end; 95 | 96 | 97 | initialization 98 | {$I passwcon.lrs} 99 | 100 | end. 101 | 102 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Transmission Remote GUI. 2 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 3 | 4 | Transmission Remote GUI is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | Transmission Remote GUI is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | In addition, as a special exception, OpenVPN Technologies, Inc. gives 15 | permission to link the code of this program with the OpenSSL Library (or with 16 | modified versions of OpenSSL that use the same license as OpenSSL), and 17 | distribute linked combinations including the two. You must obey the GNU General 18 | Public License in all respects for all of the code used other than OpenSSL. If 19 | you modify this file, you may extend this exception to your version of the 20 | file, but you are not obligated to do so. If you do not wish to do so, delete 21 | this exception statement from your version. 22 | ********************************************************************************* 23 | 24 | Transmission Remote GUI is feature rich cross platform front-end to remotely control Transmission daemon via its RPC protocol. It is faster and has more functionality than builtin Transmission web interface. 25 | 26 | Transmission Remote GUI is developed using Lazarus RAD and Free Pascal compiler. 27 | 28 | Features: 29 | * Native application for Windows, Linux and MacOS X 30 | * uTorrent-like interface 31 | * Select files to download 32 | * Choose files priority 33 | * View details about connected peers 34 | * Full information about each torrent 35 | * Per torrent options 36 | 37 | Project home: 38 | https://github.com/transmission-remote-gui/transgui 39 | 40 | INSTALLATION 41 | 42 | The installers are listed on the GitHub Releases page: 43 | https://github.com/transmission-remote-gui/transgui/releases/latest 44 | 45 | Different platform installation instructions: 46 | 47 | LINUX: 48 | 49 | Easy way (recommended). 50 | 51 | There are precompiled program's binaries for i386 and x86_64 Linux architectures. 52 | - Download a .zip archive for your architecture. 53 | - Unzip it to your home dir. 54 | - Create a desktop or menu shortcut to the transgui executable. 55 | * (If needed, change the transgui file permissions to executable). 56 | - Run the program using the created shortcut. 57 | 58 | Harder way. 59 | 60 | Build the program by yourself. 61 | - Make sure you have working Lazarus and Free Pascal compiler installed. 62 | * Free Pascal Compiler 2.6.2 and Lazarus 1.6 is used to develop Transmission Remote GUI. You may use different versions of FPC and Lazarus at your own risk. 63 | - Download the sources archive and extract it to some folder or perform svn checkout. 64 | - Open terminal/command line prompt and cd to the sources folder; 65 | - Execute "make" command to build the application; 66 | - Execute "make zipdist" command to create a release .zip archive in the "Release" sub-folder. 67 | 68 | WINDOWS: 69 | 70 | Portable zip tarball (recommended). 71 | - Zip tarball release is much more small than the installer one, which can save you some bandwidth, disk space and time, just simply download and extract the zip tarball to wherever you want, directly execute "transgui.exe" or add shortcut for it. 72 | - Please note that, the first time you use this program, you may need to install some additional dependencies (if you need SSL/TLS enabled), including: 73 | - Visual C++ Redistributable Package 74 | - https://www.microsoft.com/download/details.aspx?id=40784 75 | - https://download.microsoft.com/download/0/5/6/056dcda9-d667-4e27-8001-8a0c6971d6b1/vcredist_x86.exe 76 | - OpenSSL libs 77 | - https://wiki.openssl.org/index.php/Binaries 78 | - https://slproweb.com/products/Win32OpenSSL.html 79 | 80 | Installer. 81 | - This installer has additional installation wizard and includes static OpenSSL libraries in every releases, the size would be much bigger than the zip tarball, but you don't need to take care of the OpenSSL dependencies. 82 | 1. Directly download the installer. 83 | 2. Run the installer and follow the steps to install it on your system. 84 | 85 | Using Chocolatey. 86 | - Run "choco install transgui" to install the latest version of Transmission Remote GUI. 87 | 88 | MACOS: 89 | 90 | Without a package manager. 91 | 1. Download the app image from release page. 92 | 2. Open the image file to mount the image. 93 | 3. Directly run the application or drag the app icon to your disk / Application folder. 94 | 95 | Using Homebrew. 96 | - You need to have Homebrew installed. Execute this command to install Transmission Remote Gui: "brew install --cask transmission-remote-gui" 97 | 98 | COMMAND LINE PARAMETERS 99 | 100 | You can specify path to a .torrent file or a magnet link as a command line parameter. The program will add the specified torrent. 101 | 102 | -hidden : Start the program hidden. Only the program's tray icon will be visible. 103 | --home= : Specifies a home directory for the program. All program's settings are stored in the home directory. You can run multiple instances of the program by specifying different home directories. 104 | 105 | PORTABLE MODE 106 | 107 | If the program finds the transgui.ini file in the same folder as the binary file, then it will store all configuration and data files in the program's folder, instead of the folder in a user profile. 108 | 109 | FIXED SHORTCUTS 110 | 111 | Alt + 1 : All Torrents 112 | Alt + 2 : Downloading 113 | Alt + 3 : Completed 114 | Alt + 4 : Active 115 | Alt + 5 : Inactive 116 | Alt + 6 : Stopped 117 | Alt + 7 : Error 118 | Alt + 8 : Waiting 119 | Alt + S : Searchbox (filter torrents by keywords) - Esc cancel filter and clean the box. 120 | Alt + G : Info Pane - General Tab 121 | Alt + K : Info Pane - Trackers Tab 122 | Alt + P : Info Pane - Peers Tab 123 | Alt + F : Info Pane - Files Tab 124 | 125 | 126 | ADVANCED PARAMETERS 127 | 128 | There are some parameters in the transgui.ini file, that can not be modified via the GUI. 129 | More info on: https://github.com/transmission-remote-gui/transgui/issues/924 (File Manager & Shortcuts) 130 | , https://github.com/transmission-remote-gui/transgui/issues/1020 (User Defined Menu -Windows Only-) 131 | and https://github.com/transmission-remote-gui/transgui/issues/1070 (.torrent Auto Opening) 132 | 133 | [Interface] 134 | ; Maximum number of elements in the folder history list 135 | MaxFoldersHistory=10 136 | 137 | [Interface] 138 | ;In Linux/MacOs Only if "Open Container Folder" give you error 139 | FileOpenDoc=0 140 | 141 | [Interface] 142 | ;Alternate File Manager (Windows Only) 143 | FileManagerDefault={Full path to your File Manager .exe} 144 | FileManagerDefaultParam={Alternate parameters, could be left blank} 145 | 146 | [Interface] 147 | ;System Wide Shortcut key (Windows Only) 148 | GlobalHotkey={Virtual Key Code} full list here http://docwiki.embarcadero.com/RADStudio/Seattle/en/Virtual_Key_Codes (Plus VK_A...VK_Z and VK_0..VK_9) 149 | GlobalHotkeyMod={Modifier Key} [MOD_SHIFT , MOD_CONTROL , MOD_ALT , MOD_WIN alone or combined with + sign] 150 | 151 | [Interface] 152 | WatchLocalFolder= {LOCAL Folder to watch for torrent files} 153 | WatchDestinationFolder= {REMOTE destination where the data would be saved if missing or empty last destination folder is used} 154 | WatchInterval=1 {Time period in MINUTES between folder scans for torrents, may be fractional values 0,50 = 30 seconds} 155 | 156 | 157 | [Shortcuts] 158 | ;Modify all the shortcuts of the GUI here 159 | 160 | [Usermenu] 161 | Caption1={Caption in the menu} 162 | ExeName1={Full path to the program .exe you want to add to menu} 163 | Params1="%s" {Usually "%s" but some programs may require additional parameters} 164 | Caption2={same for item 2} 165 | ExeName2={same for item 2} 166 | Params2={same for item 2} 167 | 168 | [StatusBarPanels] 169 | ;Customize the width of the statusbar panels to fit your language 170 | ;0 is the left most panel and 7 is the right most panel. 171 | 0=327 172 | 1=152 173 | 2=152 174 | 3=130 175 | 4=130 176 | 5=130 177 | 6=130 178 | 7=130 179 | 180 | [MainForm] 181 | BigToolBarHeight=48 {Height of the Big Icon Toolbar if missing default is 64} 182 | 183 | [MainForm] 184 | FromNow=1 {1=Shows the dates relatives to now , 0=Absolute Dates MM/DD/YY HH:MM:SS} 185 | ********************************************************************************* 186 | Big Icons 187 | 188 | Farm-Fresh Fatcow Web Hosting 189 | http://www.fatcow.com/ 190 | License Creative Commons (Attribution 3.0 United States) 191 | https://creativecommons.org/licenses/by/3.0/us/legalcode 192 | 193 | Visual Farm 194 | http://icons8.com/ 195 | License Creative Commons Attribution-No Derivative Works 3.0 Unported 196 | https://creativecommons.org/licenses/by-nd/3.0/legalcode 197 | -------------------------------------------------------------------------------- /setup/create_src.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prog_ver="$(cat ../VERSION.txt)" 4 | zipfile="../Release/transgui-$prog_ver-src.zip" 5 | 6 | mkdir -p "../Release" 7 | rm -rf TransGUI 8 | 9 | svn export .. TransGUI 10 | rm -f "$zipfile" 11 | zip -9 -r "$zipfile" TransGUI 12 | 13 | rm -r TransGUI 14 | -------------------------------------------------------------------------------- /setup/macosx/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | transgui 9 | CFBundleIconFile 10 | transgui 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleLocalizations 14 | 15 | en 16 | 17 | CFBundleName 18 | Transmission Remote GUI 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | Transmission Remote GUI @prog_ver@ 23 | CFBundleIdentifier 24 | com.transgui 25 | CFBundleSignature 26 | transgui 27 | CFBundleVersion 28 | @prog_ver@ 29 | CSResourcesFileMapped 30 | 31 | NSHighResolutionCapable 32 | 33 | CFBundleDocumentTypes 34 | 35 | 36 | CFBundleTypeName 37 | Torrent File 38 | CFBundleTypeIconFile 39 | transgui.icns 40 | CFBundleTypeRole 41 | Viewer 42 | CFBundleTypeExtensions 43 | 44 | torrent 45 | 46 | CFBundleTypeOSTypes 47 | 48 | torrent 49 | 50 | 51 | 52 | CFBundleURLTypes 53 | 54 | 55 | CFBundleTypeRole 56 | Viewer 57 | CFBundleURLIconFile 58 | magnet 59 | CFBundleURLName 60 | magnet 61 | CFBundleURLSchemes 62 | 63 | magnet 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /setup/macosx/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? 2 | -------------------------------------------------------------------------------- /setup/macosx/create_app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | 5 | prog_ver="$(cat ../../VERSION.txt)" 6 | exename=../../transgui 7 | appname="Transmission Remote GUI" 8 | appfolder="../../$appname.app" 9 | lazdir="${1:-/Developer/lazarus/}" 10 | 11 | if [ ! "$lazdir" = "" ]; then 12 | lazdir=LAZARUS_DIR="$lazdir" 13 | fi 14 | 15 | # Building Intel version 16 | make -j"$(sysctl -n hw.ncpu)" -C ../.. clean CPU_TARGET=i386 "$lazdir" 17 | make -j"$(sysctl -n hw.ncpu)" -C ../.. CPU_TARGET=i386 "$lazdir" 18 | strip "$exename" 19 | mv "$exename" "$exename.386" 20 | 21 | # Building PowerPC version 22 | make -j"$(sysctl -n hw.ncpu)" -C ../.. clean CPU_TARGET=powerpc "$lazdir" 23 | make -j"$(sysctl -n hw.ncpu)" -C ../.. CPU_TARGET=powerpc "$lazdir" 24 | strip "$exename" 25 | mv "$exename" "$exename.ppc" 26 | 27 | # Creating universal executable 28 | lipo -create "$exename.ppc" "$exename.386" -output "$exename" 29 | rm "$exename.386" "$exename.ppc" 30 | 31 | if ! [ -e $exename ]; then 32 | echo "$exename does not exist" 33 | exit 1 34 | fi 35 | 36 | rm -rf "$appfolder" 37 | 38 | echo "Creating $appfolder..." 39 | mkdir -p "$appfolder/Contents/MacOS/lang" 40 | mkdir -p "$appfolder/Contents/Resources" 41 | 42 | mv "$exename" "$appfolder/Contents/MacOS" 43 | cp ../../lang/transgui.* "$appfolder/Contents/MacOS/lang" 44 | 45 | cp PkgInfo "$appfolder/Contents" 46 | cp transgui.icns "$appfolder/Contents/Resources" 47 | sed -e "s/@prog_ver@/$prog_ver/" Info.plist > "$appfolder/Contents/Info.plist" 48 | -------------------------------------------------------------------------------- /setup/macosx/create_app_new.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | 5 | prog_ver="$(cat ../../VERSION.txt)" 6 | build="$(git rev-list --abbrev-commit --max-count=1 HEAD ../..)" 7 | lazarus_ver="$(lazbuild -v)" 8 | fpc_ver="$(fpc -i V | head -n 1)" 9 | exename=../../transgui 10 | appname="Transmission Remote GUI" 11 | dmg_dist_file="../../Release/transgui-$prog_ver.dmg" 12 | dmgfolder=./Release 13 | appfolder="$dmgfolder/$appname.app" 14 | lazdir="${1:-/Library/Lazarus/}" 15 | 16 | if [ -z "${CI-}" ]; then 17 | ./install_deps.sh 18 | fi 19 | 20 | if [ ! "$lazdir" = "" ]; then 21 | lazdir=LAZARUS_DIR="$lazdir" 22 | fi 23 | 24 | mkdir -p ../../Release/ 25 | sed -i.bak "s/'Version %s'/'Version %s Build $build'#13#10'Compiled by: $fpc_ver, Lazarus v$lazarus_ver'/" ../../about.lfm 26 | 27 | lazbuild -B ../../transgui.lpi --lazarusdir=/Library/Lazarus/ --compiler=/usr/local/bin/fpc --cpu=x86_64 --widgetset=cocoa 28 | 29 | # Building Intel version 30 | make -j"$(sysctl -n hw.ncpu)" -C ../.. clean CPU_TARGET=x86_64 "$lazdir" 31 | make -j"$(sysctl -n hw.ncpu)" -C ../.. CPU_TARGET=x86_64 "$lazdir" 32 | 33 | if ! [ -e $exename ]; then 34 | echo "$exename does not exist" 35 | exit 1 36 | fi 37 | strip "$exename" 38 | 39 | rm -rf "$appfolder" 40 | 41 | echo "Creating $appfolder..." 42 | mkdir -p "$appfolder/Contents/MacOS/lang" 43 | mkdir -p "$appfolder/Contents/Resources" 44 | 45 | mv "$exename" "$appfolder/Contents/MacOS" 46 | cp ../../lang/transgui.* "$appfolder/Contents/MacOS/lang" 47 | 48 | cp ../../history.txt "$dmgfolder" 49 | cp ../../README.md "$dmgfolder" 50 | 51 | cp PkgInfo "$appfolder/Contents" 52 | cp transgui.icns "$appfolder/Contents/Resources" 53 | sed -e "s/@prog_ver@/$prog_ver/" Info.plist > "$appfolder/Contents/Info.plist" 54 | 55 | ln -s /Applications "$dmgfolder/Drag \"Transmission Remote GUI\" here!" 56 | 57 | hdiutil create -ov -anyowners -volname "transgui-v$prog_ver" -format UDRW -srcfolder ./Release -fs HFS+ "tmp.dmg" 58 | 59 | mount_device="$(hdiutil attach -readwrite -noautoopen "tmp.dmg" | awk 'NR==1{print$1}')" 60 | mount_volume="$(mount | grep "$mount_device" | sed 's/^[^ ]* on //;s/ ([^)]*)$//')" 61 | cp transgui.icns "$mount_volume/.VolumeIcon.icns" 62 | SetFile -c icnC "$mount_volume/.VolumeIcon.icns" 63 | SetFile -a C "$mount_volume" 64 | 65 | hdiutil detach "$mount_device" 66 | rm -f "$dmg_dist_file" 67 | hdiutil convert tmp.dmg -format UDBZ -imagekey zlib-level=9 -o "$dmg_dist_file" 68 | 69 | rm tmp.dmg 70 | rm -rf "$dmgfolder" 71 | mv ../../about.lfm.bak ../../about.lfm 72 | 73 | if [ -z "${CI-}" ]; then 74 | open "$dmg_dist_file" 75 | fi 76 | -------------------------------------------------------------------------------- /setup/macosx/create_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prog_ver="$(cat ../../VERSION.txt)" 4 | pm="/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker" 5 | proot=../../proot 6 | 7 | echo Preparing package contents... 8 | 9 | rm -rf "$proot" 10 | 11 | mkdir -p "$proot/Applications" 12 | cp -R "../../Transmission Remote GUI.app" "$proot/Applications" 13 | 14 | # fix permissions 15 | # everyone can read, group can write 16 | find "$proot" -exec chmod a+r,g+w {} \; 17 | # what is executable should be executable by everyone 18 | find "$proot" -perm +o+x -exec chmod a+x {} \; 19 | # everyone can access directories 20 | find "$proot" -type d -exec chmod a+x {} \; 21 | 22 | mkdir ./Resources 23 | cp ../../LICENSE ./Resources/License.txt 24 | 25 | echo Creating package... 26 | 27 | mkdir ./image 28 | "$pm" --root "$proot" --info ./package.plist --version "$prog_ver" --title "Transmission Remote GUI $prog_ver" --resources ./Resources --target 10.4 --no-relocate --out ./image/transgui.pkg 29 | rm -r ./Resources 30 | rm -r "$proot" 31 | 32 | cp ../../history.txt ./image 33 | cp ../../README.md ./image 34 | 35 | echo Creating disk image... 36 | mkdir -p "../../Release" 37 | 38 | hdiutil create -ov -anyowners -volname "transgui-$prog_ver" -imagekey zlib-level=9 -format UDBZ -srcfolder ./image "../../Release/transgui-$prog_ver.dmg" 39 | 40 | rm -r ./image 41 | -------------------------------------------------------------------------------- /setup/macosx/install_deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -x 4 | set -e 5 | 6 | lazarus_ver="2.0.8" 7 | fpc="fpc-3.0.4-macos-x86_64-laz-2" 8 | lazarus="LazarusIDE-2.0.8-macos-x86_64" 9 | 10 | if [ -n "${sourceforge_mirror-}" ]; then 11 | mirror_string="&use_mirror=${sourceforge_mirror}" 12 | fi 13 | 14 | if [ ! -x "$(command -v fpc 2>&1)" ]; then 15 | wget "https://downloads.sourceforge.net/project/lazarus/Lazarus%20macOS%20x86-64/Lazarus%20${lazarus_ver}/$fpc.pkg?r=&ts=$(date +%s)${mirror_string-}" -O "fpc.pkg" 16 | sudo ln -s /usr/local/lib/fpc/3.0.4/ppcx64 /usr/local/bin/ppcx64 17 | sudo installer -pkg "fpc.pkg" -target / 18 | rm "fpc.pkg" 19 | fi 20 | 21 | if [ ! -x "$(command -v lazbuild 2>&1)" ]; then 22 | wget "https://downloads.sourceforge.net/project/lazarus/Lazarus%20macOS%20x86-64/Lazarus%20${lazarus_ver}/$lazarus.pkg?r=&ts=$(date +%s)${mirror_string-}" -O "lazarus.pkg" 23 | sudo installer -pkg "lazarus.pkg" -target / 24 | rm "lazarus.pkg" 25 | fi 26 | -------------------------------------------------------------------------------- /setup/macosx/package.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.transgui 7 | IFPkgFlagAuthorizationAction 8 | NoAuthorization 9 | 10 | 11 | -------------------------------------------------------------------------------- /setup/macosx/transgui.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/setup/macosx/transgui.icns -------------------------------------------------------------------------------- /setup/unix/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | ROOT="$(cd "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/../../" && pwd)" 6 | VERSION="$(cat "$ROOT/VERSION.txt")" 7 | 8 | build="$(git rev-list --abbrev-commit --max-count=1 HEAD)" 9 | lazarus_ver="$(lazbuild -v)" 10 | fpc_ver="$(fpc -i V | head -n 1)" 11 | 12 | sed -i.bak "s/'Version %s'/'Version %s Build $build'#13#10'Compiled by: $fpc_ver, Lazarus v$lazarus_ver'/" "$ROOT/about.lfm" 13 | 14 | lazbuild -B "$ROOT/transgui.lpi" --lazarusdir=/usr/lib/lazarus/default/ 15 | make -C "$ROOT" -j"$(nproc)" clean 16 | make -C "$ROOT" -j"$(nproc)" all 17 | 18 | mv "$ROOT/about.lfm.bak" "$ROOT/about.lfm" 19 | 20 | cd "$ROOT" || exit 1 21 | mkdir -p Release/ 22 | FILENAME="transgui-${VERSION}-$(uname -m)-$(uname).txz" 23 | XZ_OPT=-9 tar cJf "Release/$FILENAME" transgui README.md history.txt LICENSE transgui.png lang 24 | -------------------------------------------------------------------------------- /setup/unix/debian-ubuntu-install_deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | apt update -yqq 6 | apt install -yqq --no-install-recommends lazarus fpc xz-utils coreutils git make jq zip libssl-dev 7 | -------------------------------------------------------------------------------- /setup/upload_asset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | error() { 4 | echo >&2 -e "\\033[1;31m$*\\033[m" 5 | exit 1 6 | } 7 | 8 | rm -rf upload.log 9 | 10 | if [ "$#" = 0 ]; then 11 | error "You should give me the filename of the file you want to upload" 12 | elif [ ! "$#" = 1 ]; then 13 | error "I only accept one file per time" 14 | elif [ ! -e "$1" ]; then 15 | error "'$1' not exist" 16 | elif [ ! -r "$1" ]; then 17 | error "'$1' not readable" 18 | else 19 | echo -e "\\033[36mUploading $1 ...\\033[m" 20 | if ! curl -F "file=@$1" "https://file.io/?expires=8d" > upload.log; then 21 | error "$1 upload failed!!!" 22 | fi 23 | echo -e "\\033[32m$1 uploaded with success!!!\\033[m" 24 | echo -e "\\033[32mDownload url:\\033[m $(jq -r .link upload.log 2> /dev/null || awk -F'"' '{print $10}' upload.log) \\033[33m(expires in 1 week)\\033[m" 25 | rm upload.log 26 | fi 27 | -------------------------------------------------------------------------------- /setup/win/install_deps.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | net session >nul 2>&1 4 | 5 | if %errorLevel% NEQ 0 ( 6 | echo Need Administrator permission to install dependencies 7 | pause 8 | exit 9 | ) 10 | 11 | where choco >nul 2>&1 12 | 13 | if %errorLevel% == 0 ( 14 | echo Found Chocolatey 15 | choco --version 16 | ) else ( 17 | echo Install Chocolatey... 18 | @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" 19 | ) 20 | 21 | if exist "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" ( 22 | echo Found Inno Setup v5 23 | ) else ( 24 | choco install innosetup --version=5.6.1 -y 25 | ) 26 | 27 | if exist "C:\Program Files (x86)\Inno Download Plugin\idp.iss" ( 28 | echo Found Inno Download Plugin 29 | ) else ( 30 | choco install inno-download-plugin -y 31 | ) 32 | 33 | if exist "C:\lazarus\lazbuild.exe" ( 34 | echo Found Lazarus 35 | ) else ( 36 | choco install lazarus --x86 -y 37 | ) 38 | 39 | if exist "C:\Program Files\Git\git-cmd.exe" ( 40 | echo Found git 41 | ) else ( 42 | choco install git -y 43 | ) 44 | 45 | if exist "C:\ProgramData\chocolatey\bin\zip.exe" ( 46 | echo Found zip 47 | ) else ( 48 | choco install zip -y 49 | ) 50 | 51 | if exist "C:\ProgramData\chocolatey\bin\upx.exe" ( 52 | echo Found upx 53 | ) else ( 54 | choco install upx -y 55 | ) 56 | 57 | pause 58 | -------------------------------------------------------------------------------- /setup/win/make_setup.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo "Usage: %~nx0 " 4 | 5 | if "%1" NEQ "" ( 6 | set "LAZARUS_DIR=%1" 7 | ) else ( 8 | set "LAZARUS_DIR=C:\lazarus" 9 | ) 10 | 11 | if "%2" NEQ "" ( 12 | set "ISC=%2" 13 | ) else ( 14 | set "ISC=C:\Program Files (x86)\Inno Setup 5" 15 | ) 16 | 17 | set path=%LAZARUS_DIR%;%LAZARUS_DIR%\fpc\3.2.2\bin\i386-win32;%path% 18 | 19 | lazbuild -B ../../transgui.lpi 20 | if errorlevel 1 goto err 21 | make -C ../.. clean 22 | if errorlevel 1 goto err 23 | make -C ../.. all 24 | if errorlevel 1 goto err 25 | 26 | if not (%CODECERT%) == () ( 27 | signtool.exe sign /d "Transmission Remote GUI" /du "https://github.com/transmission-remote-gui/transgui" /f "%CODECERT%" /v ..\..\transgui.exe 28 | if errorlevel 1 goto err 29 | ) 30 | 31 | "%ISC%\iscc.exe" "/ssigntool=signtool.exe $p" setup.iss 32 | if errorlevel 1 goto err 33 | 34 | pause 35 | exit /b 0 36 | 37 | :err 38 | pause 39 | exit /b 1 40 | -------------------------------------------------------------------------------- /setup/win/make_zipdist.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo "Usage: %~nx0 " 4 | 5 | if "%1" NEQ "" ( 6 | set "LAZARUS_DIR=%1" 7 | ) else ( 8 | set "LAZARUS_DIR=C:\lazarus" 9 | ) 10 | 11 | set path=%LAZARUS_DIR%;%LAZARUS_DIR%\fpc\3.2.2\bin\i386-win32;%path% 12 | 13 | lazbuild -B ../../transgui.lpi 14 | if errorlevel 1 goto err 15 | make -C ../.. clean 16 | if errorlevel 1 goto err 17 | make -C ../.. all 18 | if errorlevel 1 goto err 19 | upx --best ../../transgui.exe 20 | if errorlevel 1 goto err 21 | make -C ../.. zipdist 22 | if errorlevel 1 goto err 23 | 24 | pause 25 | exit /b 0 26 | 27 | :err 28 | pause 29 | exit /b 1 30 | -------------------------------------------------------------------------------- /setup/win/openssl/libcrypto-1_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/setup/win/openssl/libcrypto-1_1.dll -------------------------------------------------------------------------------- /setup/win/openssl/libssl-1_1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/setup/win/openssl/libssl-1_1.dll -------------------------------------------------------------------------------- /setup/win_amd64/install_deps.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | net session >nul 2>&1 4 | 5 | if %errorLevel% NEQ 0 ( 6 | echo Need Administrator permission to install dependencies 7 | pause 8 | exit 9 | ) 10 | 11 | where choco >nul 2>&1 12 | 13 | if %errorLevel% == 0 ( 14 | echo Found Chocolatey 15 | choco --version 16 | ) else ( 17 | echo Install Chocolatey... 18 | @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" 19 | ) 20 | 21 | if exist "C:\Program Files (x86)\Inno Setup 5\ISCC.exe" ( 22 | echo Found Inno Setup v5 23 | ) else ( 24 | choco install innosetup --version=5.6.1 -y 25 | ) 26 | 27 | if exist "C:\Program Files (x86)\Inno Download Plugin\idp.iss" ( 28 | echo Found Inno Download Plugin 29 | ) else ( 30 | choco install inno-download-plugin -y 31 | ) 32 | 33 | if exist "C:\lazarus\lazbuild.exe" ( 34 | echo Found Lazarus 35 | ) else ( 36 | choco install lazarus -y 37 | ) 38 | 39 | if exist "C:\Program Files\Git\git-cmd.exe" ( 40 | echo Found git 41 | ) else ( 42 | choco install git -y 43 | ) 44 | 45 | if exist "C:\ProgramData\chocolatey\bin\zip.exe" ( 46 | echo Found zip 47 | ) else ( 48 | choco install zip -y 49 | ) 50 | 51 | if exist "C:\ProgramData\chocolatey\bin\upx.exe" ( 52 | echo Found upx 53 | ) else ( 54 | choco install upx -y 55 | ) 56 | 57 | pause 58 | -------------------------------------------------------------------------------- /setup/win_amd64/make_setup.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo "Usage: %~nx0 " 4 | 5 | if "%1" NEQ "" ( 6 | set "LAZARUS_DIR=%1" 7 | ) else ( 8 | set "LAZARUS_DIR=C:\lazarus" 9 | ) 10 | 11 | if "%2" NEQ "" ( 12 | set "ISC=%2" 13 | ) else ( 14 | set "ISC=C:\Program Files (x86)\Inno Setup 5" 15 | ) 16 | 17 | set path=%LAZARUS_DIR%;%LAZARUS_DIR%\fpc\3.2.2\bin\x86_64-win64;%path% 18 | 19 | lazbuild -B ../../transgui.lpi 20 | if errorlevel 1 goto err 21 | make -C ../.. clean 22 | if errorlevel 1 goto err 23 | make -C ../.. all 24 | if errorlevel 1 goto err 25 | 26 | if not (%CODECERT%) == () ( 27 | signtool.exe sign /d "Transmission Remote GUI" /du "https://github.com/transmission-remote-gui/transgui" /f "%CODECERT%" /v ..\..\transgui.exe 28 | if errorlevel 1 goto err 29 | ) 30 | 31 | "%ISC%\iscc.exe" "/ssigntool=signtool.exe $p" setup.iss 32 | if errorlevel 1 goto err 33 | 34 | pause 35 | exit /b 0 36 | 37 | :err 38 | pause 39 | exit /b 1 40 | -------------------------------------------------------------------------------- /setup/win_amd64/make_zipdist.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo "Usage: %~nx0 " 4 | 5 | if "%1" NEQ "" ( 6 | set "LAZARUS_DIR=%1" 7 | ) else ( 8 | set "LAZARUS_DIR=C:\lazarus" 9 | ) 10 | 11 | set path=%LAZARUS_DIR%;%LAZARUS_DIR%\fpc\3.2.2\bin\x86_64-win64;%path% 12 | 13 | lazbuild -B ../../transgui.lpi 14 | if errorlevel 1 goto err 15 | make -C ../.. clean 16 | if errorlevel 1 goto err 17 | make -C ../.. all 18 | if errorlevel 1 goto err 19 | upx --best ../../transgui.exe 20 | if errorlevel 1 goto err 21 | make -C ../.. zipdist 22 | if errorlevel 1 goto err 23 | 24 | pause 25 | exit /b 0 26 | 27 | :err 28 | pause 29 | exit /b 1 30 | -------------------------------------------------------------------------------- /setup/win_amd64/openssl/libcrypto-1_1-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/setup/win_amd64/openssl/libcrypto-1_1-x64.dll -------------------------------------------------------------------------------- /setup/win_amd64/openssl/libssl-1_1-x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/setup/win_amd64/openssl/libssl-1_1-x64.dll -------------------------------------------------------------------------------- /snap/local/transgui.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=TransGUI 4 | GenericName=Transmission Remote GUI 5 | Comment=Transmission Remote GUI 6 | Exec=@bindir@/transgui "%U" 7 | TryExec=@bindir@/transgui 8 | Icon=transgui 9 | Terminal=false 10 | Type=Application 11 | Categories=Internet;Network;FileTransfer; 12 | MimeType=application/x-bittorrent;x-scheme-handler/magnet; 13 | X-KDE-Protocols=magnet 14 | Keywords=Torrent;Transmission; 15 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: transgui 3 | version: version 4 | summary: Transmission Remote GUI 5 | version-script: cat VERSION.txt 6 | description: | 7 | Transmission Remote GUI is feature rich cross platform front-end 8 | to remotely control Transmission daemon via its RPC protocol. 9 | It is faster and has more functionality than builtin Transmission 10 | web interface. 11 | icon: transgui.png 12 | grade: stable 13 | confinement: strict 14 | 15 | parts: 16 | transgui: 17 | plugin: dump 18 | source: . 19 | prime: 20 | - etc 21 | - usr 22 | - var 23 | - lib 24 | - lang 25 | - LICENSE 26 | - transgui 27 | - transgui.desktop 28 | - README.md 29 | - history.txt 30 | - transgui.png 31 | override-build: | 32 | snapcraftctl build 33 | sed -i 's|Icon=transgui|Icon=${SNAP}/transgui.png|' ${SNAPCRAFT_PART_INSTALL}/transgui.desktop 34 | build-packages: 35 | - git 36 | - make 37 | - lazarus 38 | - coreutils 39 | stage-packages: 40 | - libx11-6 41 | - libcairo2 42 | - libssl-dev 43 | - libatk1.0-0 44 | - libgtk2.0-0 45 | - libglib2.0-0 46 | - libpango-1.0-0 47 | - libgdk-pixbuf2.0-0 48 | 49 | apps: 50 | transgui: 51 | desktop: transgui.desktop 52 | plugs: 53 | - desktop 54 | - desktop-legacy 55 | - wayland 56 | - x11 57 | - unity7 58 | - network 59 | - home 60 | command: transgui 61 | -------------------------------------------------------------------------------- /synapse/README.txt: -------------------------------------------------------------------------------- 1 | Synapse 2 | The synchronyous socket library. 3 | 4 | File content: 5 | 6 | 1.) About Synapse 7 | 2.) Distribution package 8 | 3.) Installation instructions 9 | 4.) Usage notes 10 | 11 | Synapse homesite is at http://synapse.ararat.cz/ 12 | On homesite is Wiki documentation system and other informations. 13 | 14 | 1.) About Synapse 15 | 16 | SYNAPSE library aims to create complete library of classes and functions 17 | that would markedly simplify application programming of network communication 18 | using Winsock. 19 | 20 | 2.) Distribution package 21 | 22 | Package must be unpacked with subdirectories. 23 | There are these derectories: 24 | 25 | \Html - Off-line version of Synapse support WEB 26 | \Source - Synapse source code 27 | \Source\Lib - shared units 28 | \Source\Demo - Synapse demo applications 29 | 30 | 31 | 3.) Installation instructions 32 | 33 | There aren't any difficulties with current distribution other than add 34 | \Source\Lib directory to library or search path. (...or you can simply put all 35 | required Synapse files into your project directory.) 36 | 37 | 4.) Usage notes 38 | 39 | Simply write BLCKSOCK to USES section in your source code 40 | (or any other unit from package, when you need it). 41 | To read documentation, simply open INDEX.HTM file (in HTML subdirectory) 42 | on your HTML browser. 43 | 44 | Last update 2006-09-12 45 | 46 | -------------------------------------------------------------------------------- /synapse/Release.txt: -------------------------------------------------------------------------------- 1 | Release 40 2 | 2012-04-23 3 | -------------------------------------------------------------------------------- /synapse/licence.txt: -------------------------------------------------------------------------------- 1 | Copyright (c)1999-2002, Lukas Gebauer 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | Neither the name of Lukas Gebauer nor the names of its contributors may 15 | be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 28 | DAMAGE. 29 | -------------------------------------------------------------------------------- /synapse/source/lib/kylix.inc: -------------------------------------------------------------------------------- 1 | // 2 | // This is FPC-incompatible code and was excluded from jedi.inc for this reason 3 | // 4 | // Kylix 3/C++ for some reason evaluates CompilerVersion comparisons to False, 5 | // if the constant to compare with is a floating point value - weird. 6 | // The "+" sign prevents Kylix/Delphi from issueing a warning about comparing 7 | // signed and unsigned values. 8 | // 9 | {$IF not Declared(CompilerVersion)} 10 | {$DEFINE KYLIX1} 11 | {$DEFINE COMPILER6} 12 | {$DEFINE DELPHICOMPILER6} 13 | {$DEFINE RTL140_UP} 14 | {$ELSEIF Declared(CompilerVersion) and (CompilerVersion > +14)} 15 | {$DEFINE KYLIX2} 16 | {$DEFINE COMPILER6} 17 | {$DEFINE DELPHICOMPILER6} 18 | {$DEFINE RTL142_UP} 19 | {$ELSEIF Declared(CompilerVersion) and (CompilerVersion < +15)} 20 | {$DEFINE KYLIX3} 21 | {$DEFINE COMPILER6} 22 | {$IFNDEF BCB} 23 | {$DEFINE DELPHICOMPILER6} 24 | {$ENDIF} 25 | {$DEFINE RTL145_UP} 26 | {$ELSE} 27 | Add new Kylix version 28 | {$IFEND} 29 | 30 | 31 | -------------------------------------------------------------------------------- /synapse/source/lib/laz_synapse.lpk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /synapse/source/lib/laz_synapse.pas: -------------------------------------------------------------------------------- 1 | { This file was automatically created by Lazarus. Do not edit! 2 | This source is only used to compile and install the package. 3 | } 4 | 5 | unit laz_synapse; 6 | 7 | interface 8 | 9 | uses 10 | asn1util, blcksock, clamsend, dnssend, ftpsend, ftptsend, httpsend, 11 | imapsend, ldapsend, mimeinln, mimemess, mimepart, nntpsend, pingsend, 12 | pop3send, slogsend, smtpsend, snmpsend, sntpsend, synachar, synacode, 13 | synacrypt, synadbg, synafpc, synaicnv, synaip, synamisc, synaser, synautil, 14 | synsock, tlntsend; 15 | 16 | implementation 17 | 18 | end. 19 | -------------------------------------------------------------------------------- /synapse/source/lib/ssl_streamsec.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/synapse/source/lib/ssl_streamsec.pas -------------------------------------------------------------------------------- /synapse/source/lib/synadbg.pas: -------------------------------------------------------------------------------- 1 | {==============================================================================| 2 | | Project : Ararat Synapse | 001.001.002 | 3 | |==============================================================================| 4 | | Content: Socket debug tools | 5 | |==============================================================================| 6 | | Copyright (c)2008-2011, Lukas Gebauer | 7 | | All rights reserved. | 8 | | | 9 | | Redistribution and use in source and binary forms, with or without | 10 | | modification, are permitted provided that the following conditions are met: | 11 | | | 12 | | Redistributions of source code must retain the above copyright notice, this | 13 | | list of conditions and the following disclaimer. | 14 | | | 15 | | Redistributions in binary form must reproduce the above copyright notice, | 16 | | this list of conditions and the following disclaimer in the documentation | 17 | | and/or other materials provided with the distribution. | 18 | | | 19 | | Neither the name of Lukas Gebauer nor the names of its contributors may | 20 | | be used to endorse or promote products derived from this software without | 21 | | specific prior written permission. | 22 | | | 23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 24 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 25 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 26 | | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | 27 | | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 28 | | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 29 | | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 30 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 31 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 32 | | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 33 | | DAMAGE. | 34 | |==============================================================================| 35 | | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| 36 | | Portions created by Lukas Gebauer are Copyright (c)2008-2011. | 37 | | All Rights Reserved. | 38 | |==============================================================================| 39 | | Contributor(s): | 40 | |==============================================================================| 41 | | History: see HISTORY.HTM from distribution package | 42 | | (Found at URL: http://www.ararat.cz/synapse/) | 43 | |==============================================================================} 44 | 45 | {:@abstract(Socket debug tools) 46 | 47 | Routines for help with debugging of events on the Sockets. 48 | } 49 | 50 | {$IFDEF UNICODE} 51 | {$WARN IMPLICIT_STRING_CAST OFF} 52 | {$WARN IMPLICIT_STRING_CAST_LOSS OFF} 53 | {$ENDIF} 54 | 55 | unit synadbg; 56 | 57 | interface 58 | 59 | uses 60 | blcksock, synsock, synautil, classes, sysutils, synafpc; 61 | 62 | type 63 | TSynaDebug = class(TObject) 64 | class procedure HookStatus(Sender: TObject; Reason: THookSocketReason; const Value: string); 65 | class procedure HookMonitor(Sender: TObject; Writing: Boolean; const Buffer: TMemory; Len: Integer); 66 | end; 67 | 68 | procedure AppendToLog(const value: Ansistring); 69 | 70 | var 71 | LogFile: string; 72 | 73 | implementation 74 | 75 | procedure AppendToLog(const value: Ansistring); 76 | var 77 | st: TFileStream; 78 | s: string; 79 | h, m, ss, ms: word; 80 | dt: Tdatetime; 81 | begin 82 | if fileexists(LogFile) then 83 | st := TFileStream.Create(LogFile, fmOpenReadWrite or fmShareDenyWrite) 84 | else 85 | st := TFileStream.Create(LogFile, fmCreate or fmShareDenyWrite); 86 | try 87 | st.Position := st.Size; 88 | dt := now; 89 | decodetime(dt, h, m, ss, ms); 90 | s := formatdatetime('yyyymmdd-hhnnss', dt) + format('.%.3d', [ms]) + ' ' + value; 91 | WriteStrToStream(st, s); 92 | finally 93 | st.free; 94 | end; 95 | end; 96 | 97 | class procedure TSynaDebug.HookStatus(Sender: TObject; Reason: THookSocketReason; const Value: string); 98 | var 99 | s: string; 100 | begin 101 | case Reason of 102 | HR_ResolvingBegin: 103 | s := 'HR_ResolvingBegin'; 104 | HR_ResolvingEnd: 105 | s := 'HR_ResolvingEnd'; 106 | HR_SocketCreate: 107 | s := 'HR_SocketCreate'; 108 | HR_SocketClose: 109 | s := 'HR_SocketClose'; 110 | HR_Bind: 111 | s := 'HR_Bind'; 112 | HR_Connect: 113 | s := 'HR_Connect'; 114 | HR_CanRead: 115 | s := 'HR_CanRead'; 116 | HR_CanWrite: 117 | s := 'HR_CanWrite'; 118 | HR_Listen: 119 | s := 'HR_Listen'; 120 | HR_Accept: 121 | s := 'HR_Accept'; 122 | HR_ReadCount: 123 | s := 'HR_ReadCount'; 124 | HR_WriteCount: 125 | s := 'HR_WriteCount'; 126 | HR_Wait: 127 | s := 'HR_Wait'; 128 | HR_Error: 129 | s := 'HR_Error'; 130 | else 131 | s := '-unknown-'; 132 | end; 133 | s := inttohex(PtrInt(Sender), 8) + s + ': ' + value + CRLF; 134 | AppendToLog(s); 135 | end; 136 | 137 | class procedure TSynaDebug.HookMonitor(Sender: TObject; Writing: Boolean; const Buffer: TMemory; Len: Integer); 138 | var 139 | s, d: Ansistring; 140 | begin 141 | setlength(s, len); 142 | move(Buffer^, pointer(s)^, len); 143 | if writing then 144 | d := '-> ' 145 | else 146 | d := '<- '; 147 | s :=inttohex(PtrInt(Sender), 8) + d + s + CRLF; 148 | AppendToLog(s); 149 | end; 150 | 151 | initialization 152 | begin 153 | Logfile := changefileext(paramstr(0), '.slog'); 154 | end; 155 | 156 | end. 157 | -------------------------------------------------------------------------------- /synapse/source/lib/synafpc.pas: -------------------------------------------------------------------------------- 1 | {==============================================================================| 2 | | Project : Ararat Synapse | 001.003.001 | 3 | |==============================================================================| 4 | | Content: Utils for FreePascal compatibility | 5 | |==============================================================================| 6 | | Copyright (c)1999-2013, Lukas Gebauer | 7 | | All rights reserved. | 8 | | | 9 | | Redistribution and use in source and binary forms, with or without | 10 | | modification, are permitted provided that the following conditions are met: | 11 | | | 12 | | Redistributions of source code must retain the above copyright notice, this | 13 | | list of conditions and the following disclaimer. | 14 | | | 15 | | Redistributions in binary form must reproduce the above copyright notice, | 16 | | this list of conditions and the following disclaimer in the documentation | 17 | | and/or other materials provided with the distribution. | 18 | | | 19 | | Neither the name of Lukas Gebauer nor the names of its contributors may | 20 | | be used to endorse or promote products derived from this software without | 21 | | specific prior written permission. | 22 | | | 23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 24 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 25 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 26 | | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | 27 | | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 28 | | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 29 | | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 30 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 31 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 32 | | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 33 | | DAMAGE. | 34 | |==============================================================================| 35 | | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| 36 | | Portions created by Lukas Gebauer are Copyright (c)2003-2013. | 37 | | All Rights Reserved. | 38 | |==============================================================================| 39 | | Contributor(s): | 40 | | Tomas Hajny (OS2 support) | 41 | |==============================================================================| 42 | | History: see HISTORY.HTM from distribution package | 43 | | (Found at URL: http://www.ararat.cz/synapse/) | 44 | |==============================================================================} 45 | 46 | {:@exclude} 47 | 48 | {$IFDEF FPC} 49 | {$MODE DELPHI} 50 | {$ENDIF} 51 | {$H+} 52 | //old Delphi does not have MSWINDOWS define. 53 | {$IFDEF WIN32} 54 | {$IFNDEF MSWINDOWS} 55 | {$DEFINE MSWINDOWS} 56 | {$ENDIF} 57 | {$ENDIF} 58 | 59 | unit synafpc; 60 | 61 | interface 62 | 63 | uses 64 | {$IFDEF FPC} 65 | dynlibs, sysutils; 66 | {$ELSE} 67 | {$IFDEF MSWINDOWS} 68 | Windows; 69 | {$ELSE} 70 | SysUtils; 71 | {$ENDIF} 72 | {$ENDIF} 73 | 74 | {$IFDEF FPC} 75 | type 76 | TLibHandle = dynlibs.TLibHandle; 77 | 78 | function LoadLibrary(ModuleName: PChar): TLibHandle; 79 | function FreeLibrary(Module: TLibHandle): LongBool; 80 | function GetProcAddress(Module: TLibHandle; Proc: PChar): Pointer; 81 | function GetModuleFileName(Module: TLibHandle; Buffer: PChar; BufLen: Integer): Integer; 82 | {$ELSE} //not FPC 83 | type 84 | {$IFDEF CIL} 85 | TLibHandle = Integer; 86 | PtrInt = Integer; 87 | {$ELSE} 88 | TLibHandle = HModule; 89 | {$IFDEF WIN64} 90 | PtrInt = NativeInt; 91 | {$ELSE} 92 | PtrInt = Integer; 93 | {$ENDIF} 94 | {$ENDIF} 95 | {$IFDEF VER100} 96 | LongWord = DWord; 97 | {$ENDIF} 98 | {$ENDIF} 99 | 100 | procedure Sleep(milliseconds: Cardinal); 101 | 102 | 103 | implementation 104 | 105 | {==============================================================================} 106 | {$IFDEF FPC} 107 | function LoadLibrary(ModuleName: PChar): TLibHandle; 108 | begin 109 | Result := dynlibs.LoadLibrary(Modulename); 110 | end; 111 | 112 | function FreeLibrary(Module: TLibHandle): LongBool; 113 | begin 114 | Result := dynlibs.UnloadLibrary(Module); 115 | end; 116 | 117 | function GetProcAddress(Module: TLibHandle; Proc: PChar): Pointer; 118 | begin 119 | {$IFDEF OS2GCC} 120 | Result := dynlibs.GetProcedureAddress(Module, '_' + Proc); 121 | {$ELSE OS2GCC} 122 | Result := dynlibs.GetProcedureAddress(Module, Proc); 123 | {$ENDIF OS2GCC} 124 | end; 125 | 126 | function GetModuleFileName(Module: TLibHandle; Buffer: PChar; BufLen: Integer): Integer; 127 | begin 128 | Result := 0; 129 | end; 130 | 131 | {$ELSE} 132 | {$ENDIF} 133 | 134 | procedure Sleep(milliseconds: Cardinal); 135 | begin 136 | {$IFDEF MSWINDOWS} 137 | {$IFDEF FPC} 138 | sysutils.sleep(milliseconds); 139 | {$ELSE} 140 | windows.sleep(milliseconds); 141 | {$ENDIF} 142 | {$ELSE} 143 | sysutils.sleep(milliseconds); 144 | {$ENDIF} 145 | 146 | end; 147 | 148 | end. 149 | -------------------------------------------------------------------------------- /synapse/source/lib/synautil.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/synapse/source/lib/synautil.pas -------------------------------------------------------------------------------- /synapse/source/lib/synsock.pas: -------------------------------------------------------------------------------- 1 | {==============================================================================| 2 | | Project : Ararat Synapse | 005.002.003 | 3 | |==============================================================================| 4 | | Content: Socket Independent Platform Layer | 5 | |==============================================================================| 6 | | Copyright (c)1999-2013, Lukas Gebauer | 7 | | All rights reserved. | 8 | | | 9 | | Redistribution and use in source and binary forms, with or without | 10 | | modification, are permitted provided that the following conditions are met: | 11 | | | 12 | | Redistributions of source code must retain the above copyright notice, this | 13 | | list of conditions and the following disclaimer. | 14 | | | 15 | | Redistributions in binary form must reproduce the above copyright notice, | 16 | | this list of conditions and the following disclaimer in the documentation | 17 | | and/or other materials provided with the distribution. | 18 | | | 19 | | Neither the name of Lukas Gebauer nor the names of its contributors may | 20 | | be used to endorse or promote products derived from this software without | 21 | | specific prior written permission. | 22 | | | 23 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 24 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 25 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 26 | | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR | 27 | | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 28 | | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 29 | | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 30 | | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 31 | | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 32 | | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 33 | | DAMAGE. | 34 | |==============================================================================| 35 | | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).| 36 | | Portions created by Lukas Gebauer are Copyright (c)2001-2013. | 37 | | All Rights Reserved. | 38 | |==============================================================================| 39 | | Contributor(s): | 40 | | Tomas Hajny (OS2 support) | 41 | |==============================================================================| 42 | | History: see HISTORY.HTM from distribution package | 43 | | (Found at URL: http://www.ararat.cz/synapse/) | 44 | |==============================================================================} 45 | 46 | {:@exclude} 47 | 48 | unit synsock; 49 | 50 | {$MINENUMSIZE 4} 51 | 52 | //old Delphi does not have MSWINDOWS define. 53 | {$IFDEF WIN32} 54 | {$IFNDEF MSWINDOWS} 55 | {$DEFINE MSWINDOWS} 56 | {$ENDIF} 57 | {$ENDIF} 58 | 59 | {$IFDEF CIL} 60 | {$I ssdotnet.inc} 61 | {$ELSE} 62 | {$IFDEF MSWINDOWS} 63 | {$I sswin32.inc} 64 | {$ELSE} 65 | {$IFDEF WINCE} 66 | {$I sswin32.inc} //not complete yet! 67 | {$ELSE} 68 | {$IFDEF FPC} 69 | {$IFDEF OS2} 70 | {$I ssos2ws1.inc} 71 | {$ELSE OS2} 72 | {$I ssfpc.inc} 73 | {$ENDIF OS2} 74 | {$ELSE} 75 | {$I sslinux.inc} 76 | {$ENDIF} 77 | {$ENDIF} 78 | {$ENDIF} 79 | {$ENDIF} 80 | {$IFDEF POSIX} 81 | //Posix.SysSocket 82 | {$I ssposix.inc} //experimental! 83 | {$ENDIF} 84 | 85 | end. 86 | 87 | -------------------------------------------------------------------------------- /synapse/synapse_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/synapse/synapse_logo.gif -------------------------------------------------------------------------------- /synapse/winsock2.txt: -------------------------------------------------------------------------------- 1 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2 | 3 | WINDOWS: 4 | 5 | Remember, Synapse work with Winsock2 on Windows! (on Win98 and WinNT 4.0 or higher) 6 | 7 | If you must use this unit on Win95, download Winsock2 from Microsoft 8 | and distribute it with your application! 9 | 10 | On WinNT standardly RAW sockets work if program is running under user with 11 | administrators provilegies. To use RAW sockets under another users, you must 12 | create the following registry variable and set its value to DWORD 1: 13 | 14 | HKLM\System\CurrentControlSet\Services\Afd\Parameters\DisableRawSecurity 15 | 16 | After you change the registry, you need to restart your computer! 17 | 18 | 19 | LINUX: 20 | 21 | Remember, some of functions or classes work only with root rights! 22 | If you need this for another user then root, you must assign root right 23 | for your binary file. 24 | 25 | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 26 | -------------------------------------------------------------------------------- /torrprops.lfm: -------------------------------------------------------------------------------- 1 | inherited TorrPropsForm: TTorrPropsForm 2 | Left = 364 3 | Height = 270 4 | Top = 185 5 | Width = 517 6 | HorzScrollBar.Page = 349 7 | HorzScrollBar.Range = 40 8 | VertScrollBar.Page = 155 9 | VertScrollBar.Range = 22 10 | AutoSize = True 11 | BorderIcons = [biSystemMenu] 12 | BorderStyle = bsDialog 13 | Caption = 'Torrent properties' 14 | ClientHeight = 270 15 | ClientWidth = 517 16 | Constraints.MinHeight = 186 17 | Constraints.MinWidth = 350 18 | OnCreate = FormCreate 19 | Position = poMainFormCenter 20 | object Buttons: TButtonPanel[0] 21 | Left = 8 22 | Height = 26 23 | Top = 236 24 | Width = 501 25 | BorderSpacing.Left = 8 26 | BorderSpacing.Right = 8 27 | BorderSpacing.Bottom = 8 28 | BorderSpacing.Around = 0 29 | OKButton.Name = 'OKButton' 30 | OKButton.DefaultCaption = True 31 | HelpButton.Name = 'HelpButton' 32 | HelpButton.DefaultCaption = True 33 | CloseButton.Name = 'CloseButton' 34 | CloseButton.DefaultCaption = True 35 | CancelButton.Name = 'CancelButton' 36 | CancelButton.DefaultCaption = True 37 | TabOrder = 1 38 | Spacing = 8 39 | ShowButtons = [pbOK, pbCancel] 40 | ShowBevel = False 41 | end 42 | object Page: TPageControl[1] 43 | Left = 8 44 | Height = 220 45 | Top = 8 46 | Width = 501 47 | ActivePage = tabGeneral 48 | Align = alClient 49 | BorderSpacing.Around = 8 50 | TabIndex = 0 51 | TabOrder = 0 52 | object tabGeneral: TTabSheet 53 | Caption = 'General' 54 | ClientHeight = 194 55 | ClientWidth = 493 56 | object txKbs1: TLabel 57 | Left = 420 58 | Height = 14 59 | Top = 37 60 | Width = 22 61 | Anchors = [akTop, akRight] 62 | Caption = 'KB/s' 63 | ParentColor = False 64 | end 65 | object txKbs2: TLabel 66 | Left = 420 67 | Height = 14 68 | Top = 69 69 | Width = 22 70 | Anchors = [akTop, akRight] 71 | Caption = 'KB/s' 72 | ParentColor = False 73 | end 74 | object txName: TLabel 75 | Left = 10 76 | Height = 14 77 | Top = 10 78 | Width = 32 79 | Caption = 'Name:' 80 | ParentColor = False 81 | ShowAccelChar = False 82 | end 83 | object txPeerLimit: TLabel 84 | Left = 10 85 | Height = 14 86 | Top = 101 87 | Width = 48 88 | Caption = 'Peer limit:' 89 | ParentColor = False 90 | end 91 | object txMinutes: TLabel 92 | Left = 420 93 | Height = 14 94 | Top = 163 95 | Width = 38 96 | Anchors = [akTop, akRight] 97 | Caption = 'minutes' 98 | ParentColor = False 99 | end 100 | object cbMaxDown: TCheckBox 101 | Left = 10 102 | Height = 17 103 | Top = 36 104 | Width = 147 105 | Caption = 'Maximum download speed:' 106 | OnClick = cbMaxDownClick 107 | TabOrder = 0 108 | end 109 | object edMaxDown: TSpinEdit 110 | Left = 340 111 | Height = 21 112 | Top = 34 113 | Width = 66 114 | Anchors = [akTop, akRight] 115 | Increment = 10 116 | MaxValue = 999999 117 | TabOrder = 1 118 | end 119 | object cbMaxUp: TCheckBox 120 | Left = 10 121 | Height = 17 122 | Top = 68 123 | Width = 133 124 | Caption = 'Maximum upload speed:' 125 | OnClick = cbMaxUpClick 126 | TabOrder = 2 127 | end 128 | object edMaxUp: TSpinEdit 129 | Left = 340 130 | Height = 21 131 | Top = 66 132 | Width = 66 133 | Anchors = [akTop, akRight] 134 | Increment = 10 135 | MaxValue = 999999 136 | TabOrder = 3 137 | end 138 | object edPeerLimit: TSpinEdit 139 | Left = 340 140 | Height = 21 141 | Top = 98 142 | Width = 66 143 | Anchors = [akTop, akRight] 144 | MaxValue = 999 145 | MinValue = 1 146 | TabOrder = 4 147 | Value = 1 148 | end 149 | object cbSeedRatio: TCheckBox 150 | Left = 10 151 | Height = 17 152 | Top = 131 153 | Width = 71 154 | AllowGrayed = True 155 | Caption = 'Seed ratio:' 156 | OnClick = cbSeedRatioClick 157 | TabOrder = 5 158 | end 159 | object edSeedRatio: TFloatSpinEdit 160 | Left = 340 161 | Height = 21 162 | Top = 129 163 | Width = 66 164 | Anchors = [akTop, akRight] 165 | Increment = 0.1 166 | MaxValue = 9999 167 | MinValue = 0 168 | TabOrder = 6 169 | Value = 0 170 | end 171 | object cbIdleSeedLimit: TCheckBox 172 | Left = 10 173 | Height = 17 174 | Top = 162 175 | Width = 170 176 | AllowGrayed = True 177 | Caption = 'Stop seeding when inactive for:' 178 | OnClick = cbIdleSeedLimitClick 179 | TabOrder = 7 180 | end 181 | object edIdleSeedLimit: TSpinEdit 182 | Left = 340 183 | Height = 21 184 | Top = 160 185 | Width = 66 186 | Anchors = [akTop, akRight] 187 | MaxValue = 999999 188 | MinValue = 1 189 | TabOrder = 8 190 | Value = 1 191 | end 192 | end 193 | object tabAdvanced: TTabSheet 194 | Caption = 'Advanced' 195 | ClientHeight = 194 196 | ClientWidth = 488 197 | object edTrackers: TMemo 198 | Left = 8 199 | Height = 153 200 | Top = 30 201 | Width = 471 202 | Anchors = [akTop, akLeft, akRight, akBottom] 203 | ScrollBars = ssAutoBoth 204 | TabOrder = 0 205 | WordWrap = False 206 | end 207 | object txTrackers: TLabel 208 | Left = 8 209 | Height = 14 210 | Top = 10 211 | Width = 46 212 | Caption = 'Trackers:' 213 | ParentColor = False 214 | end 215 | end 216 | end 217 | end 218 | -------------------------------------------------------------------------------- /torrprops.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit TorrProps; 32 | 33 | {$mode objfpc}{$H+} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, Spin, ButtonPanel, ComCtrls, BaseForm; 39 | 40 | type 41 | 42 | { TTorrPropsForm } 43 | 44 | TTorrPropsForm = class(TBaseForm) 45 | Buttons: TButtonPanel; 46 | cbIdleSeedLimit: TCheckBox; 47 | cbMaxDown: TCheckBox; 48 | cbMaxUp: TCheckBox; 49 | cbSeedRatio: TCheckBox; 50 | edIdleSeedLimit: TSpinEdit; 51 | edMaxUp: TSpinEdit; 52 | edPeerLimit: TSpinEdit; 53 | edSeedRatio: TFloatSpinEdit; 54 | edMaxDown: TSpinEdit; 55 | edTrackers: TMemo; 56 | txTrackers: TLabel; 57 | Page: TPageControl; 58 | tabGeneral: TTabSheet; 59 | tabAdvanced: TTabSheet; 60 | txKbs1: TLabel; 61 | txKbs2: TLabel; 62 | txMinutes: TLabel; 63 | txName: TLabel; 64 | txPeerLimit: TLabel; 65 | procedure cbIdleSeedLimitClick(Sender: TObject); 66 | procedure cbMaxDownClick(Sender: TObject); 67 | procedure cbMaxUpClick(Sender: TObject); 68 | procedure cbSeedRatioClick(Sender: TObject); 69 | procedure FormCreate(Sender: TObject); 70 | private 71 | { private declarations } 72 | public 73 | { public declarations } 74 | end; 75 | 76 | implementation 77 | 78 | uses main; 79 | 80 | { TTorrPropsForm } 81 | 82 | procedure TTorrPropsForm.cbMaxDownClick(Sender: TObject); 83 | begin 84 | edMaxDown.Enabled:=cbMaxDown.Checked; 85 | end; 86 | 87 | procedure TTorrPropsForm.cbIdleSeedLimitClick(Sender: TObject); 88 | begin 89 | edIdleSeedLimit.Enabled:=cbIdleSeedLimit.State = cbChecked; 90 | end; 91 | 92 | procedure TTorrPropsForm.cbMaxUpClick(Sender: TObject); 93 | begin 94 | edMaxUp.Enabled:=cbMaxUp.Checked; 95 | end; 96 | 97 | procedure TTorrPropsForm.cbSeedRatioClick(Sender: TObject); 98 | begin 99 | edSeedRatio.Enabled:=cbSeedRatio.State = cbChecked; 100 | end; 101 | 102 | procedure TTorrPropsForm.FormCreate(Sender: TObject); 103 | begin 104 | Page.ActivePageIndex:=0; 105 | bidiMode := GetBiDi(); 106 | end; 107 | 108 | initialization 109 | {$I torrprops.lrs} 110 | 111 | end. 112 | 113 | -------------------------------------------------------------------------------- /transgui.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/transgui.ico -------------------------------------------------------------------------------- /transgui.lpi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /transgui.lpr: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | In addition, as a special exception, the copyright holders give permission to 16 | link the code of portions of this program with the 17 | OpenSSL library under certain conditions as described in each individual 18 | source file, and distribute linked combinations including the two. 19 | 20 | You should have received a copy of the GNU General Public License 21 | along with Transmission Remote GUI; if not, write to the Free Software 22 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 | *************************************************************************************} 24 | 25 | {$ifdef windows} 26 | {$apptype gui} 27 | {$endif windows} 28 | 29 | program transgui; 30 | 31 | {$mode objfpc}{$H+} 32 | 33 | uses 34 | {$ifdef UNIX} 35 | cthreads, 36 | {$ifdef darwin} 37 | maclocale, 38 | {$else} 39 | clocale, 40 | {$endif} 41 | {$endif} 42 | Interfaces, // this includes the LCL widgetset 43 | Forms 44 | { you can add units after this }, BaseForm, Main, rpc, AddTorrent, 45 | ConnOptions, varlist, TorrProps, DaemonOptions, About, IpResolver, download, 46 | ColSetup, utils, ResTranslator, AddLink, MoveTorrent, AddTracker, Options, 47 | passwcon; 48 | 49 | //{$ifdef windows} 50 | {$R *.res} 51 | //{$endif} 52 | 53 | begin 54 | //Application.Scaled:=True; //travis doesnt compile 55 | 56 | if not CheckAppParams then exit; 57 | 58 | Application.Initialize; 59 | Application.CreateForm(TMainForm, MainForm); 60 | 61 | {$ifdef windows} 62 | Application.MainFormOnTaskBar:=true; // make taskbar button follow main form monitor 63 | {$endif} 64 | 65 | Application.Run; 66 | end. 67 | -------------------------------------------------------------------------------- /transgui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/transmission-remote-gui/transgui/8854357ece266e749e8981a93c8002465a93d8f2/transgui.png -------------------------------------------------------------------------------- /trcomp.lpk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /trcomp.pas: -------------------------------------------------------------------------------- 1 | { This file was automatically created by Lazarus. do not edit! 2 | This source is only used to compile and install the package. 3 | } 4 | 5 | unit trcomp; 6 | 7 | interface 8 | 9 | uses 10 | VarGrid, LazarusPackageIntf; 11 | 12 | implementation 13 | 14 | procedure Register; 15 | begin 16 | RegisterUnit('VarGrid', @VarGrid.Register); 17 | end; 18 | 19 | initialization 20 | RegisterPackage('trcomp', @Register); 21 | end. 22 | -------------------------------------------------------------------------------- /urllistenerosx.pas: -------------------------------------------------------------------------------- 1 | {************************************************************************************* 2 | This file is part of Transmission Remote GUI. 3 | Copyright (c) 2008-2019 by Yury Sidorov and Transmission Remote GUI working group. 4 | 5 | Transmission Remote GUI is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | Transmission Remote GUI is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with Transmission Remote GUI; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | In addition, as a special exception, the copyright holders give permission to 20 | link the code of portions of this program with the 21 | OpenSSL library under certain conditions as described in each individual 22 | source file, and distribute linked combinations including the two. 23 | 24 | You must obey the GNU General Public License in all respects for all of the 25 | code used other than OpenSSL. If you modify file(s) with this exception, you 26 | may extend this exception to your version of the file(s), but you are not 27 | obligated to do so. If you do not wish to do so, delete this exception 28 | statement from your version. If you delete this exception statement from all 29 | source files in the program, then also delete it here. 30 | *************************************************************************************} 31 | unit URLListenerOSX; 32 | {$mode objfpc}{$H+} 33 | {$modeswitch objectivec2} 34 | 35 | interface 36 | 37 | uses 38 | Classes, SysUtils, CocoaAll, InternetConfig, AppleEvents; 39 | 40 | type 41 | THandlerProc = procedure(const url: string); 42 | 43 | { TAppURLHandler } 44 | 45 | TAppURLHandler = objcclass(NSObject) 46 | public 47 | procedure getUrlwithReplyEvent(event: NSAppleEventDescriptor; eventReply: NSAppleEventDescriptor); message 'getUrl:withReplyEvent:'; 48 | public 49 | callBack: THandlerProc; 50 | end; 51 | 52 | procedure RegisterURLHandler(HandlerProc: THandlerProc); 53 | var 54 | handler : TAppURLHandler; 55 | eventManager: NSAppleEventManager; 56 | 57 | implementation 58 | 59 | { TAppURLHandler } 60 | 61 | procedure TAppURLHandler.getUrlwithReplyEvent(event: NSAppleEventDescriptor; eventReply: NSAppleEventDescriptor); 62 | var 63 | url : NSString; 64 | begin 65 | url:=event.paramDescriptorForKeyword(keyDirectObject).stringValue; 66 | callBack(url.UTF8String); 67 | end; 68 | 69 | procedure RegisterURLHandler(HandlerProc: THandlerProc); 70 | begin 71 | handler:=TAppURLHandler.alloc.init; 72 | handler.callBack:=HandlerProc; 73 | eventManager:=NSAppleEventManager.sharedAppleEventManager; 74 | eventManager.setEventHandler_andSelector_forEventClass_andEventID(handler,ObjCSelector(handler.getUrlwithReplyEvent), kInternetEventClass,kAEGetURL); 75 | end; 76 | 77 | end. 78 | --------------------------------------------------------------------------------