From 288e03e96c2d73b908ec87f68ebe5cb8706ff278 Mon Sep 17 00:00:00 2001 From: Mansour Behabadi Date: Mon, 28 Mar 2022 00:58:01 +1100 Subject: [PATCH] New UI WIP --- .github/workflows/ci.yaml | 5 +- Readme.md | 7 +- go.mod | 22 +- go.sum | 91 +----- icon.svg | 1 + loading.png | Bin 7063 -> 0 bytes loading.svg | 49 +++ main.go | 662 +++++++++++++++++++++++++++----------- nothumb.svg | 104 ++++++ screenshot.png | Bin 27070 -> 74245 bytes session/session.go | 30 +- splash.svg | 1 + 12 files changed, 660 insertions(+), 312 deletions(-) create mode 100644 icon.svg delete mode 100644 loading.png create mode 100644 loading.svg create mode 100644 nothumb.svg create mode 100644 splash.svg diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d206d6c..df7ac09 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,7 +12,10 @@ jobs: with: go-version: '1.18' - name: Dependencies - run: sudo apt update && sudo apt install -y libgl1-mesa-dev xorg-dev + run: | + set -e + sudo apt update + sudo apt install -y libgtk-3-dev libglib2.0-dev libgdk-pixbuf2.0-dev - name: Build run: go build -o pdfrankenstein - uses: actions/upload-artifact@v1 diff --git a/Readme.md b/Readme.md index ebab5ed..6d4f394 100644 --- a/Readme.md +++ b/Readme.md @@ -10,14 +10,13 @@ a good capable PDF annotator like Adobe Acrobat does not exist. - Multiple page PDFs are supported. - Anything you can do in Inkscape. -## Thumbs are still missing! - ![sceenshot](./screenshot.png) ## Requirements -You need a recent version of [Inkscape](https://inkscape.org/) and -[qpdf](https://github.com/qpdf/qpdf). +- Recent version of [Inkscape](https://inkscape.org/) +- [poppler-utils](https://poppler.freedesktop.org/) +- [qpdf](https://github.com/qpdf/qpdf) ## Install diff --git a/go.mod b/go.mod index 1c5c472..9d2f299 100644 --- a/go.mod +++ b/go.mod @@ -2,24 +2,4 @@ module github.com/oxplot/pdfrankenstein go 1.18 -require fyne.io/fyne/v2 v2.1.3 - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 // indirect - github.com/fsnotify/fsnotify v1.4.9 // indirect - github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f // indirect - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // indirect - github.com/godbus/dbus/v5 v5.0.4 // indirect - github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 // indirect - github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 // indirect - github.com/stretchr/testify v1.5.1 // indirect - github.com/yuin/goldmark v1.3.8 // indirect - golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect - golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect - golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect - golang.org/x/text v0.3.3 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect -) +require github.com/gotk3/gotk3 v0.6.1 diff --git a/go.sum b/go.sum index be27cac..7fc94be 100644 --- a/go.sum +++ b/go.sum @@ -1,89 +1,2 @@ -fyne.io/fyne/v2 v2.1.3 h1:I5qSeENAcq67hmO5Z2hI7sEJm9bdLMDJx59Fv8qJkX0= -fyne.io/fyne/v2 v2.1.3/go.mod h1:p+E/Dh+wPW8JwR2DVcsZ9iXgR9ZKde80+Y+40Is54AQ= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I= -github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3 h1:FDqhDm7pcsLhhWl1QtD8vlzI4mm59llRvNzrFg6/LAA= -github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f h1:s0O46d8fPwk9kU4k1jj76wBquMVETx7uveQD9MCIQoU= -github.com/go-gl/gl v0.0.0-20210813123233-e4099ee2221f/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff h1:W71vTCKoxtdXgnm1ECDFkfQnpdqAO00zzGXLA5yaEX8= -github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= -github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc= -github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564 h1:HunZiaEKNGVdhTRQOVpMmj5MQnGnv+e8uZNu3xFLgyM= -github.com/srwiley/oksvg v0.0.0-20200311192757-870daf9aa564/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4= -github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9 h1:m59mIOBO4kfcNCEzJNy71UkeF4XIx2EVmL9KLwDQdmM= -github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.3.8 h1:Nw158Q8QN+CPgTmVRByhVwapp8Mm1e2blinhmx4wx5E= -github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw= -golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +github.com/gotk3/gotk3 v0.6.1 h1:GJ400a0ecEEWrzjBvzBzH+pB/esEMIGdB9zPSmBdoeo= +github.com/gotk3/gotk3 v0.6.1/go.mod h1:/hqFpkNa9T3JgNAE2fLvCdov7c5bw//FHNZrZ3Uv9/Q= diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..1a3261c --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/loading.png b/loading.png deleted file mode 100644 index 3d0ef3ee3b1f8b79c184fdd52c45f99b06991f0d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7063 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 + + + + + + + + + diff --git a/main.go b/main.go index 6adcc97..7fa4132 100644 --- a/main.go +++ b/main.go @@ -1,25 +1,20 @@ package main import ( - "bytes" + "context" _ "embed" - "flag" + "errors" "fmt" - "image" - "image/png" "log" "os" - "os/signal" "path/filepath" "strconv" "strings" + "sync" - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/app" - "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/dialog" - "fyne.io/fyne/v2/widget" + "github.com/gotk3/gotk3/gdk" + "github.com/gotk3/gotk3/glib" + "github.com/gotk3/gotk3/gtk" "github.com/oxplot/pdfrankenstein/session" ) @@ -29,236 +24,523 @@ const ( ) var ( - //go:embed loading.png + cleanCSS *gtk.CssProvider + dirtyCSS *gtk.CssProvider + //go:embed splash.svg + splash []byte + //go:embed icon.svg + appIcon []byte + //go:embed loading.svg loadingImgBytes []byte - loadingImg image.Image + loadingPix *gdk.Pixbuf + //go:embed nothumb.svg + noThumbImgBytes []byte + noThumbPix *gdk.Pixbuf ) -func init() { - var err error - loadingImg, err = png.Decode(bytes.NewReader(loadingImgBytes)) +func shrinkHome(path string) string { + home, err := os.UserHomeDir() if err != nil { - panic(err) + return path + } + dir, file := filepath.Split(path) + if strings.HasPrefix(dir, home) { + return filepath.Join("~"+dir[len(home):], file) } + return path } -type PageGrid struct { - labels []*widget.Label - thumbs []*canvas.Image - clears []*widget.Button - root *fyne.Container -} +var ( + annotSinceLastSave bool + + sessMu sync.Mutex + sess *session.Session + cancelLoad func() + + mainWin *gtk.Window + mainStack *gtk.Stack + openBut *gtk.Button + saveBut *gtk.Button + closeBut *gtk.Button + hdrBar *gtk.HeaderBar + pageFlow *gtk.FlowBox + + pageImages []*gtk.Image + pageLabels []*gtk.Label +) + +func showErrMsg(title string, msg string) { + d, err := gtk.DialogNew() + if err != nil { + log.Fatalf("unable to create dialog: %s", err) + } + defer d.Destroy() + d.SetTitle(title) + d.SetModal(true) + d.SetTransientFor(mainWin) + + b, err := d.AddButton("Close", gtk.RESPONSE_OK) + if err != nil { + log.Fatalf("unable to create dialog button: %s", err) + } + b.SetMarginTop(10) + b.SetMarginBottom(10) + b.SetMarginStart(10) + b.SetMarginEnd(10) + + l, err := gtk.LabelNew(msg) + if err != nil { + log.Fatalf("unable to create dialog label: %s", err) + } + l.SetMarginTop(10) + l.SetMarginBottom(10) + l.SetMarginStart(10) + l.SetMarginEnd(10) + con, err := d.GetContentArea() + if err != nil { + log.Fatalf("unable to get dialog content area: %s", err) + } + con.Add(l) -func NewPageGrid(pageCount int, tapHandler func(page int), clearHandler func(page int)) *PageGrid { - labels := make([]*widget.Label, pageCount) - thumbs := make([]*canvas.Image, pageCount) - clears := make([]*widget.Button, pageCount) - root := container.NewGridWrap(fyne.NewSize(150, 180)) - for i := range labels { - labels[i] = widget.NewLabel(strconv.Itoa(i + 1)) - labels[i].Alignment = fyne.TextAlignCenter - thumbs[i] = canvas.NewImageFromImage(loadingImg) - thumbs[i].FillMode = canvas.ImageFillContain - func(i int) { clears[i] = widget.NewButton("clear annots", func() { clearHandler(i) }) }(i) - clears[i].Hide() - var button *widget.Button - func(i int) { button = widget.NewButton("", func() { tapHandler(i) }) }(i) - root.Add(container.NewBorder(nil, - container.NewBorder(nil, nil, nil, clears[i], labels[i]), - nil, nil, container.NewMax(thumbs[i], button))) - } - return &PageGrid{labels, thumbs, clears, root} + d.ShowAll() + _ = d.Run() + d.Close() } -func (g *PageGrid) Root() *fyne.Container { - return g.root +func loadThumbs(ctx context.Context, loadThumb func(p int) (string, error)) { + cnt := len(pageImages) + for i := 0; i < cnt; i++ { + select { + case <-ctx.Done(): + return + default: + } + path, err := loadThumb(i) + if err != nil { + log.Printf("failed to load thumbnail: %s", err) + func(img *gtk.Image, path string) { + glib.IdleAdd(func() { + img.SetFromPixbuf(noThumbPix) + }) + }(pageImages[i], path) + } else { + func(img *gtk.Image, path string) { + glib.IdleAdd(func() { + img.SetFromFile(path) + }) + }(pageImages[i], path) + } + } } -func (g *PageGrid) SetThumbnail(page int, img image.Image) { - g.thumbs[page].Image = img +func addCSS(w gtk.IWidget, css *gtk.CssProvider) { + ctx, err := w.ToWidget().GetStyleContext() + if err != nil { + log.Fatalf("unable to get style context: %s", err) + } + ctx.AddProvider(css, gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) } -func (g *PageGrid) SetAnnotated(page int, annotated bool) { - if annotated { - g.clears[page].Show() - } else { - g.clears[page].Hide() +func removeCSS(w gtk.IWidget, css *gtk.CssProvider) { + ctx, err := w.ToWidget().GetStyleContext() + if err != nil { + log.Fatalf("unable to get style context: %s", err) } - g.root.Refresh() + ctx.RemoveProvider(css) } -func run() error { +func clearAnnotation(page int) { + d, err := gtk.DialogNewWithButtons("Clear page annotations?", mainWin, gtk.DIALOG_MODAL, + []any{"Clear", gtk.RESPONSE_OK}, + []any{"Keep", gtk.RESPONSE_CANCEL}) + if err != nil { + log.Fatalf("unable to create confirmation dialog: %s", err) + } + if d.Run() == gtk.RESPONSE_OK { + sessMu.Lock() + sess.Clear(page) + sessMu.Unlock() + pageLabels[page].SetText(strconv.Itoa(page + 1)) + removeCSS(pageLabels[page], dirtyCSS) + } + d.Close() + d.Destroy() +} - ap := app.New() - win := ap.NewWindow(progName) +func open(path string) { + var err error - var sess *session.Session - sig := make(chan os.Signal, 1) - runExit := make(chan struct{}, 1) - done := make(chan struct{}, 1) - signal.Notify(sig, os.Interrupt) - go func() { - select { - case <-sig: - break - case <-runExit: - break + if path == "" { + ofd, err := gtk.FileChooserDialogNewWith1Button( + "Open PDF File", + mainWin, + gtk.FILE_CHOOSER_ACTION_OPEN, + "Open", + gtk.RESPONSE_OK, + ) + if err != nil { + log.Fatalf("failed to open file chooser: %s", err) + } + defer ofd.Destroy() + filter, err := gtk.FileFilterNew() + if err != nil { + log.Fatalf("failed to create file filter: %s", err) } - if sess != nil { - sess.Close() + filter.AddMimeType("application/pdf") + filter.SetName("PDF Document") + ofd.SetLocalOnly(true) + ofd.AddFilter(filter) + if ofd.Run() != gtk.RESPONSE_OK { + return } - win.Close() - close(done) - }() - defer func() { - close(runExit) - <-done - }() + path = ofd.GetFilename() + ofd.Close() + } - fileNameLabel := widget.NewLabel("abc.pdf") - fileNameLabel.TextStyle.Bold = true - filePathLabel := widget.NewLabel("/home/...") - filePathLabel.Wrapping = fyne.TextWrapBreak + mainWin.SetSensitive(false) + defer mainWin.SetSensitive(true) - var openedContent *fyne.Container - var startContent *fyne.Container + sessMu.Lock() + sess, err = session.New(path) + sessMu.Unlock() + if err != nil { + log.Printf("failed to open '%s': %s", path, err) + glib.IdleAdd(func() { showErrMsg("Cannot load file", err.Error()) }) + return + } - editingMsg := container.NewCenter(widget.NewLabel("Annotate in Inkscape.\nOnce done, save and close Inkscape and continue here.")) - savingMsg := container.NewCenter(widget.NewLabel("Saving ...")) - openingMsg := container.NewCenter(widget.NewLabel("Opening ...")) - gridScroll := container.NewVScroll(widget.NewLabel("")) + dir, file := filepath.Split(shrinkHome(path)) + hdrBar.SetTitle(file) + hdrBar.SetSubtitle(dir) + openBut.Hide() + saveBut.Show() + closeBut.Show() - open := func(path string) { - var err error + // Populate the UI with pages - win.SetContent(openingMsg) - sess, err = session.New(path) - win.SetContent(startContent) + pageImages = make([]*gtk.Image, sess.PageCount()) + pageLabels = make([]*gtk.Label, sess.PageCount()) + for i := range pageImages { + o, err := gtk.OverlayNew() if err != nil { - dialog.ShowError(err, win) - return + log.Fatal("Unable to create overlay") } - var grid *PageGrid - grid = NewPageGrid(sess.PageCount(), func(page int) { - win.SetContent(editingMsg) - defer win.SetContent(openedContent) - modified, err := sess.Annotate(page) - if err != nil { - dialog.ShowError(err, win) - return - } - if modified { - grid.SetThumbnail(page, nil) - } - grid.SetAnnotated(page, sess.IsAnnotated(page)) - }, func(page int) { - sess.Clear(page) - grid.SetAnnotated(page, false) - }) + // Page thumb + + img, err := gtk.ImageNewFromPixbuf(loadingPix) + if err != nil { + log.Fatalf("failed to create image asset: %s", err) + } + img.Show() + pageImages[i] = img + eb, err := gtk.EventBoxNew() + if err != nil { + log.Fatalf("unable to create event box: %s", err) + } + eb.SetHAlign(gtk.ALIGN_START) + eb.Add(img) + eb.AddEvents(int(gdk.BUTTON_PRESS_MASK)) + func(page int) { + eb.Connect("button-press-event", func() { + annotate(page) + }) + }(i) + eb.Show() + o.Add(eb) + + // Page Label - gridScroll.Content = grid.Root() + l, err := gtk.LabelNew(strconv.Itoa(i + 1)) + if err != nil { + log.Fatalf("unable to create label: %s", err) + } + addCSS(l, cleanCSS) + pageLabels[i] = l + l.Show() + + eb, err = gtk.EventBoxNew() + if err != nil { + log.Fatalf("unable to create event box: %s", err) + } + eb.Show() + eb.SetHAlign(gtk.ALIGN_START) + eb.SetVAlign(gtk.ALIGN_END) + eb.SetMarginBottom(3) + eb.SetMarginStart(3) + eb.Add(l) + eb.AddEvents(int(gdk.BUTTON_PRESS_MASK)) + func(page int) { + eb.Connect("button-press-event", func() { + sessMu.Lock() + annotated := sess.IsAnnotated(page) + sessMu.Unlock() + if annotated { + clearAnnotation(page) + } + }) + }(i) - _, name := filepath.Split(path) - fileNameLabel.SetText("Annotating: " + name) - filePathLabel.SetText(path) - win.SetContent(openedContent) + o.AddOverlay(eb) + + o.Show() + pageFlow.Add(o) } - startContent = container.NewCenter(widget.NewButton("Open PDF File", func() { - dialog.ShowFileOpen(func(r fyne.URIReadCloser, err error) { + var ctx context.Context + ctx, cancelLoad = context.WithCancel(context.Background()) + go loadThumbs(ctx, func(p int) (string, error) { + sessMu.Lock() + defer sessMu.Unlock() + if sess == nil || sess.IsClosed() { + return "", errors.New("session is nil/closed") + } + return sess.Thumbnail(p) + }) - // Get the file path + mainStack.SetVisibleChildName("pages") +} +func annotate(page int) { + mainWin.SetSensitive(false) + mainStack.SetVisibleChildName("continue-in-inkscape") + + go func() { + defer mainWin.SetSensitive(true) + defer mainStack.SetVisibleChildName("pages") + + sessMu.Lock() + changed, err := sess.Annotate(page) + sessMu.Unlock() + + glib.IdleAdd(func() { if err != nil { - dialog.ShowError(err, win) + showErrMsg("Cannot annotate file", err.Error()) return } - if r == nil { - return - } - r.Close() - path := r.URI().String() - if !strings.HasPrefix(path, "file://") { - dialog.ShowError(fmt.Errorf("invalid file selected"), win) - return + if changed { + annotSinceLastSave = true + pageLabels[page].SetText(fmt.Sprintf("%d : clear", page+1)) + addCSS(pageLabels[page], dirtyCSS) } - path = strings.TrimPrefix(path, "file://") - open(path) + }) + }() +} - }, win) - })) +func closeFile() bool { + sessMu.Lock() + if sess == nil || sess.IsClosed() { + sessMu.Unlock() + return true + } + sessMu.Unlock() - closeSession := func() { - gridScroll.Content = widget.NewLabel("") + if annotSinceLastSave { + d, err := gtk.DialogNewWithButtons("Your changes will be lost!", mainWin, gtk.DIALOG_MODAL, + []any{"Close anyway", gtk.RESPONSE_OK}, + []any{"Keep editing", gtk.RESPONSE_CANCEL}) + if err != nil { + log.Fatalf("unable to create confirmation dialog: %s", err) + } + defer d.Destroy() + defer d.Close() + if d.Run() != gtk.RESPONSE_OK { + return false + } + } + + annotSinceLastSave = false + resetUIToStart() + sessMu.Lock() + if sess != nil { + cancelLoad() sess.Close() - sess = nil - win.SetContent(startContent) - } - - openedContent = container.NewBorder( - container.NewBorder( - nil, nil, nil, - container.NewHBox( - widget.NewButton("Save", func() { - dialog.ShowFileSave(func(w fyne.URIWriteCloser, err error) { - if err != nil { - dialog.ShowError(err, win) - return - } - if w == nil { - return - } - w.Close() - path := w.URI().String() - if !strings.HasPrefix(path, "file://") { - dialog.ShowError(fmt.Errorf("invalid file selected"), win) - return - } - path = strings.TrimPrefix(path, "file://") - win.SetContent(savingMsg) - if err := sess.Save(path); err != nil { - dialog.ShowError(err, win) - } - win.SetContent(openedContent) - }, win) - }), - widget.NewButton("Close", func() { - if sess.HasAnnotations() { - dialog.ShowConfirm("", "You will lose your annotations if you continue", func(c bool) { - if c { - closeSession() - } - }, win) - return - } - closeSession() - }), - ), - container.NewVBox( - fileNameLabel, - filePathLabel, - ), - ), - nil, nil, nil, - gridScroll, + } + sessMu.Unlock() + + return true +} + +func resetUIToStart() { + openBut.Show() + saveBut.Hide() + closeBut.Hide() + mainStack.SetVisibleChildName("splash") +} + +func save() { + ofd, err := gtk.FileChooserDialogNewWith1Button( + "Save", + mainWin, + gtk.FILE_CHOOSER_ACTION_SAVE, + "Save", + gtk.RESPONSE_OK, ) + if err != nil { + log.Fatalf("failed to open file chooser: %s", err) + } + defer ofd.Destroy() + ofd.SetLocalOnly(true) + if ofd.Run() != gtk.RESPONSE_OK { + return + } + path := ofd.GetFilename() + ofd.Close() + + sessMu.Lock() + err = sess.Save(path) + sessMu.Unlock() + if err != nil { + glib.IdleAdd(func() { showErrMsg("Cannot save file", err.Error()) }) + return + } + annotSinceLastSave = false +} + +func initUI() error { + var err error + + gtk.Init(nil) + + // Assets - win.Resize(fyne.NewSize(600, 500)) - win.SetContent(startContent) - win.Show() - if flag.Arg(0) != "" { - open(flag.Arg(0)) + loadingPix, err = gdk.PixbufNewFromBytesOnly(loadingImgBytes) + if err != nil { + return fmt.Errorf("failed to create loading pixbuf: %s", err) + } + noThumbPix, err = gdk.PixbufNewFromBytesOnly(noThumbImgBytes) + if err != nil { + return fmt.Errorf("failed to create no thumb pixbuf: %s", err) } - ap.Run() + cleanCSS, err = gtk.CssProviderNew() + if err != nil { + return fmt.Errorf("failed to create css provider: %s", err) + } + cleanCSS.LoadFromData( + `label{border-radius:3px;padding:2px 6px;background:@theme_bg_color;opacity:0.8}`) + dirtyCSS, err = gtk.CssProviderNew() + if err != nil { + return fmt.Errorf("failed to create css provider: %s", err) + } + dirtyCSS.LoadFromData(`label{color:white;background:orange;opacity:1}`) + + // Main window + + mainWin, err = gtk.WindowNew(gtk.WINDOW_TOPLEVEL) + if err != nil { + return fmt.Errorf("failed to create main window: %s", err) + } + mainWin.Connect("delete-event", func() bool { + return !closeFile() + }) + mainWin.Connect("destroy", func() { + gtk.MainQuit() + }) + iconPix, err := gdk.PixbufNewFromBytesOnly(appIcon) + if err != nil { + return fmt.Errorf("failed to create main icon pixbuf: %s", err) + } + mainWin.SetIcon(iconPix) + mainWin.Iconify() + mainWin.SetDefaultSize(640, 400) + + hdrBar, err = gtk.HeaderBarNew() + if err != nil { + return fmt.Errorf("failed to create main header bar: %s", err) + } + hdrBar.SetDecorationLayout("icon:menu,minimize,close") + hdrBar.SetShowCloseButton(true) + mainWin.SetTitlebar(hdrBar) + + mainStack, err = gtk.StackNew() + if err != nil { + return fmt.Errorf("failed to create main stack: %s", err) + } + mainWin.Add(mainStack) + + // Main buttons + + saveBut, err = gtk.ButtonNewWithLabel("Save") + if err != nil { + return fmt.Errorf("failed to create save button: %s", err) + } + saveBut.Connect("clicked", func() { save() }) + closeBut, err = gtk.ButtonNewWithLabel("Close") + if err != nil { + return fmt.Errorf("failed to create close button: %s", err) + } + closeBut.Connect("clicked", func() { closeFile() }) + openBut, err = gtk.ButtonNewWithLabel("Open PDF File") + if err != nil { + return fmt.Errorf("failed to create open button: %s", err) + } + openBut.Connect("clicked", func() { open("") }) + + hdrBar.Add(openBut) + hdrBar.Add(saveBut) + hdrBar.PackEnd(closeBut) + + // Add splash + + splashPix, err := gdk.PixbufNewFromBytesOnly(splash) + if err != nil { + return fmt.Errorf("failed to create pixbuf for splash: %s", err) + } + splashImg, err := gtk.ImageNewFromPixbuf(splashPix) + if err != nil { + return fmt.Errorf("failed to create image for splash: %s", err) + } + mainStack.AddNamed(splashImg, "splash") + mainStack.SetVisibleChildName("splash") + + // Add continue in inkscape message + + l, err := gtk.LabelNew("Continue in Inkscape.\nOnce done, save, close and return here.") + if err != nil { + return fmt.Errorf("unable to create label: %s", err) + } + mainStack.AddNamed(l, "continue-in-inkscape") + + // Add page flow + + pageFlow, err = gtk.FlowBoxNew() + if err != nil { + return fmt.Errorf("failed to create flowbox: %s", err) + } + pageFlow.SetSelectionMode(gtk.SELECTION_NONE) + pageFlow.SetMarginTop(10) + pageFlow.SetMarginBottom(10) + pageFlow.SetMarginStart(10) + pageFlow.SetMarginEnd(10) + + scr, err := gtk.ScrolledWindowNew(nil, nil) + if err != nil { + return fmt.Errorf("failed to create scrolled window: %s", err) + } + scr.Add(pageFlow) + mainStack.AddNamed(scr, "pages") + + mainWin.ShowAll() + resetUIToStart() + + return nil +} + +func run() error { + if err := initUI(); err != nil { + return fmt.Errorf("failed to initialize UI: %s", err) + } + if len(os.Args) > 1 { + glib.IdleAdd(func() { open(os.Args[1]) }) + } + gtk.Main() return nil } func main() { log.SetFlags(0) - log.SetPrefix("pdfrankenstein: ") - flag.Parse() + log.SetPrefix(strings.ToLower(progName) + ": ") if err := run(); err != nil { log.Fatal(err) } diff --git a/nothumb.svg b/nothumb.svg new file mode 100644 index 0000000..bf5b131 --- /dev/null +++ b/nothumb.svg @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/screenshot.png b/screenshot.png index 24fad3621aed801e932ea2ae632535f6ac8fc148..57886e44ee4c9f4432e68da5262f51fb9550c7f4 100644 GIT binary patch literal 74245 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 R00KV8ez*E9`!FWre*l-dVSoSt literal 27070 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 diff --git a/session/session.go b/session/session.go index ce989d0..43a382d 100644 --- a/session/session.go +++ b/session/session.go @@ -76,6 +76,7 @@ func fileCopy(src, dst string) error { return err } +// Session represents an annotation session. type Session struct { path string pageCount int @@ -84,6 +85,7 @@ type Session struct { annotated map[int]struct{} } +// New opens the given PDF file by path and returns a new session. func New(path string) (*Session, error) { // Get page count @@ -119,10 +121,12 @@ func New(path string) (*Session, error) { }, nil } +// PageCount returns the number of pages in the PDF document. func (s *Session) PageCount() int { return s.pageCount } +// Thumbnail returns the path to temporary thumbnail image of the given page. func (s *Session) Thumbnail(page int) (string, error) { if page < 0 || page >= s.pageCount { @@ -137,19 +141,20 @@ func (s *Session) Thumbnail(page int) (string, error) { return thumbPath, nil } - // Otherwise, run inkscape to generate image + // Otherwise, run pdftocairo to generate image - cmd := exec.Command("inkscape", "--pdf-page="+strconv.Itoa(page+1), "--export-type=png", - "--export-area-page", "--export-dpi=20", "--pdf-poppler", - "--export-background=white", "--export-filename="+thumbPath+".tmp", s.path) + cmd := exec.Command("pdftocairo", "-f", strconv.Itoa(page+1), "-png", + "-singlefile", "-scale-to", "200", s.path, thumbPath+".tmp") if _, err := cmd.Output(); err != nil { - return "", fmt.Errorf("failed to generate thumb for page %s of '%s': %s", page, s.path, cmdErr(err)) + return "", fmt.Errorf("failed to generate thumb for page %d of '%s': %s", page, s.path, cmdErr(err)) } - _ = os.Rename(thumbPath+".tmp", thumbPath) + _ = os.Rename(thumbPath+".tmp.png", thumbPath) return thumbPath, nil } +// Annotate blocks and launches Inkscape to annotate the page. +// It returns true if the page was annotated by the user this time around. func (s *Session) Annotate(page int) (bool, error) { if page < 0 || page >= s.pageCount { @@ -163,7 +168,7 @@ func (s *Session) Annotate(page int) (bool, error) { cmd := exec.Command("inkscape", "--pdf-page="+strconv.Itoa(page+1), "--export-type=svg", "--pdf-poppler", "--export-filename="+srcPath+".svg", s.path) if _, err := cmd.Output(); err != nil { - return false, fmt.Errorf("failed to convert page %s of '%s' to svg: %s", page, s.path, cmdErr(err)) + return false, fmt.Errorf("failed to convert page %d of '%s' to svg: %s", page, s.path, cmdErr(err)) } _ = os.Rename(srcPath+".svg", srcPath) } @@ -240,6 +245,7 @@ func (s *Session) thumbPath(page int) string { return filepath.Join(s.tmpDir, fmt.Sprintf("thumb-%d.png", page)) } +// IsAnnotated returns true if the given page has any annotations. func (s *Session) IsAnnotated(page int) bool { if page < 0 || page >= s.pageCount { panic("invalid page number") @@ -250,12 +256,14 @@ func (s *Session) IsAnnotated(page int) bool { return ok } +// HasAnnotations returns true if any of the pages has annotations. func (s *Session) HasAnnotations() bool { s.mu.Lock() defer s.mu.Unlock() return len(s.annotated) > 0 } +// Clear clears the annotations for the given page. func (s *Session) Clear(page int) { if page < 0 || page >= s.pageCount { panic("invalid page number") @@ -267,6 +275,7 @@ func (s *Session) Clear(page int) { s.mu.Unlock() } +// Save saves the annotated PDF to the given path. func (s *Session) Save(path string) error { // Shortcut for when no page is annotated @@ -342,6 +351,8 @@ func (s *Session) Save(path string) error { return fileCopy(finalPath, path) } +// Close closes the annotation session and releases all resources. +// This instance cannot be used after a call to Close(). func (s *Session) Close() { files, _ := ioutil.ReadDir(s.tmpDir) for _, f := range files { @@ -355,3 +366,8 @@ func (s *Session) Close() { s.pageCount = -1 s.path = "" } + +// IsClosed returns true if Close() has been called earlier. +func (s *Session) IsClosed() bool { + return s.pageCount == -1 +} diff --git a/splash.svg b/splash.svg new file mode 100644 index 0000000..6376615 --- /dev/null +++ b/splash.svg @@ -0,0 +1 @@ + \ No newline at end of file