2020-05-20 23:13:28 +02:00
|
|
|
# Copyright 2017-2018 Xuan Sang LE <xsang.le AT gmail DOT com>
|
|
|
|
|
|
|
|
# AnTOS Web desktop is is licensed under the GNU General Public
|
|
|
|
# License v3.0, see the LICENCE file for more information
|
|
|
|
|
|
|
|
# This program is free software: you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of
|
|
|
|
# the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
# General Public License for more details.
|
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
#along with this program. If not, see https://www.gnu.org/licenses/.
|
|
|
|
|
|
|
|
class Preview extends this.OS.GUI.BaseApplication
|
|
|
|
constructor: (args) ->
|
|
|
|
super "Preview", args
|
|
|
|
|
|
|
|
main: () ->
|
2020-05-21 21:56:16 +02:00
|
|
|
@currfile = undefined
|
2020-05-20 23:13:28 +02:00
|
|
|
@currfile = @args[0].path.asFileHandle() if @args and @args.length > 0
|
|
|
|
@view = @find "view"
|
|
|
|
@status = @find "status"
|
2020-05-21 21:56:16 +02:00
|
|
|
@zoom = @find "zoom"
|
|
|
|
@btnext = @find "btnext"
|
|
|
|
@btprev = @find "btprev"
|
|
|
|
@btreset = @find "btreset"
|
|
|
|
@txtpage = @find "txtpage"
|
|
|
|
|
|
|
|
@zoom.set "onchange", (e) => @setViewScale e.data
|
|
|
|
|
|
|
|
@btreset.set "onbtclick", (e) =>
|
|
|
|
@zoom.set "value", 100
|
|
|
|
@setViewScale 100
|
|
|
|
|
|
|
|
@btnext.set "onbtclick", (e) =>
|
|
|
|
val = parseInt $(@txtpage).val()
|
|
|
|
return if isNaN val
|
|
|
|
$(@txtpage).val val + 1
|
|
|
|
@gotoPage()
|
|
|
|
@btprev.set "onbtclick", (e) =>
|
|
|
|
val = parseInt $(@txtpage).val()
|
|
|
|
return if isNaN val
|
|
|
|
$(@txtpage).val val - 1
|
|
|
|
@gotoPage()
|
|
|
|
|
|
|
|
$(@txtpage).keyup (e) =>
|
|
|
|
return unless e.which is 13
|
|
|
|
return unless @pdf
|
|
|
|
@gotoPage()
|
|
|
|
|
2020-05-20 23:13:28 +02:00
|
|
|
PDFJS.workerSrc = "#{@path()}/pdf.worker.js".asFileHandle().getlink()
|
2020-05-21 21:56:16 +02:00
|
|
|
@pdf = undefined
|
|
|
|
@img = undefined
|
2020-05-20 23:13:28 +02:00
|
|
|
|
|
|
|
@bindKey "ALT-O", () => @actionFile "#{@name}-Open"
|
|
|
|
@bindKey "CTRL-X", () => @actionFile "#{@name}-Close"
|
2020-05-21 21:56:16 +02:00
|
|
|
@zoom.set "max", 200
|
|
|
|
@zoom.set "value", 100
|
2020-05-20 23:13:28 +02:00
|
|
|
@open @currfile
|
|
|
|
|
|
|
|
|
|
|
|
open: (file) ->
|
|
|
|
return unless file
|
|
|
|
@currfile = file unless @currfile is file
|
|
|
|
file.onready().then () =>
|
|
|
|
file.info.size = (file.info.size / 1024).toFixed(2)
|
2020-05-21 21:56:16 +02:00
|
|
|
@renderFile()
|
2020-05-20 23:13:28 +02:00
|
|
|
.catch (err) =>
|
|
|
|
@error __("File not found {0}", file.path), err
|
|
|
|
|
2020-05-21 21:56:16 +02:00
|
|
|
|
|
|
|
gotoPage: () ->
|
|
|
|
return unless @pdf
|
|
|
|
val = parseInt $(@txtpage).val()
|
|
|
|
return if isNaN(val)
|
|
|
|
return if val <= 0 or val > @pdf.numPages
|
|
|
|
($ @view).empty()
|
|
|
|
@renderPDFPages val, (@zoom.get("value") / 100), false
|
|
|
|
.catch (e) => @error __("Unable to render page {0}", val), e
|
|
|
|
|
|
|
|
renderFile: () ->
|
|
|
|
mime = @currfile.info.mime
|
2020-05-20 23:13:28 +02:00
|
|
|
return unless mime
|
2020-05-21 21:56:16 +02:00
|
|
|
@pdf = undefined
|
|
|
|
@img = undefined
|
2020-05-20 23:13:28 +02:00
|
|
|
($ @view).empty()
|
2020-05-21 21:56:16 +02:00
|
|
|
@zoom.set "value", 100
|
2020-05-20 23:13:28 +02:00
|
|
|
if mime.match /^[^\/]+\/.*pdf.*/g
|
2020-05-21 21:56:16 +02:00
|
|
|
@renderPDF()
|
2020-05-20 23:13:28 +02:00
|
|
|
else if mime.match /image\/.*svg.*/g
|
2020-05-21 21:56:16 +02:00
|
|
|
@renderSVG()
|
2020-05-20 23:13:28 +02:00
|
|
|
else if mime.match /image\/.*/g
|
2020-05-21 21:56:16 +02:00
|
|
|
@renderImage()
|
2020-05-20 23:13:28 +02:00
|
|
|
else
|
|
|
|
@notify __("Mime type {0} is not supported", file.info.mime)
|
|
|
|
|
|
|
|
setStatus: (t) ->
|
|
|
|
($ @status).html t
|
|
|
|
|
2020-05-21 21:56:16 +02:00
|
|
|
setViewScale: (value) ->
|
|
|
|
return unless @currfile
|
|
|
|
mime = @currfile.info.mime
|
|
|
|
scale = (value / 100)
|
|
|
|
if mime.match /^[^\/]+\/.*pdf.*/g
|
|
|
|
return unless @pdf
|
|
|
|
($ @view).empty()
|
|
|
|
@load @renderPDFPages 1, scale
|
|
|
|
.catch (e) => @error __("Unable to set view scale"), e
|
|
|
|
|
|
|
|
else if mime.match /image\/.*svg.*/g
|
|
|
|
$($(@view).children()[0])
|
|
|
|
.css "width", "#{Math.round(value)}%"
|
|
|
|
.css "height", "#{Math.round(value)}%"
|
|
|
|
|
|
|
|
else if mime.match /image\/.*/g
|
|
|
|
return unless @img
|
|
|
|
canvas = $(@view).children()[0]
|
|
|
|
context = canvas.getContext '2d'
|
|
|
|
w = @img.width * scale
|
|
|
|
h = @img.height * scale
|
|
|
|
canvas.height = h
|
|
|
|
canvas.width = w
|
|
|
|
context.clearRect(0, 0, canvas.width, canvas.height)
|
|
|
|
context.scale scale, scale
|
|
|
|
context.drawImage @img, 0, 0
|
|
|
|
|
|
|
|
renderPDFPages: (n, scale, recursive) ->
|
|
|
|
new Promise (resolve, reject) =>
|
|
|
|
status = "#{@currfile.info.name} (#{@currfile.info.size} Kb)"
|
|
|
|
return resolve() if n > @pdf.numPages
|
|
|
|
@pdf.getPage(n).then (page) =>
|
|
|
|
viewport = page.getViewport scale
|
|
|
|
div = ($ "<div/>")
|
|
|
|
.attr("id", "page-" + (page.pageIndex + 1))
|
|
|
|
.attr("scale", scale)
|
|
|
|
.addClass "pdf-page"
|
|
|
|
($ @view).append div
|
|
|
|
canvas = ($ "<canvas>")[0]
|
|
|
|
div.append canvas
|
|
|
|
context = canvas.getContext '2d'
|
|
|
|
canvas.height = viewport.height
|
|
|
|
canvas.width = viewport.width
|
|
|
|
renderContext =
|
|
|
|
canvasContext: context
|
|
|
|
viewport: viewport
|
|
|
|
page.render renderContext
|
|
|
|
page._canvas = canvas
|
|
|
|
@setStatus "#{status} - page #{n}/#{@pdf.numPages} loaded"
|
|
|
|
if recursive
|
|
|
|
@renderPDFPages n + 1, scale, recursive
|
|
|
|
.then () -> resolve()
|
2020-05-22 17:19:10 +02:00
|
|
|
.catch (e) -> reject __e e
|
2020-05-21 21:56:16 +02:00
|
|
|
else
|
|
|
|
resolve()
|
2020-05-22 17:19:10 +02:00
|
|
|
.catch (e) -> reject __e e
|
2020-05-21 21:56:16 +02:00
|
|
|
|
|
|
|
renderPDF: () ->
|
2020-05-21 14:51:47 +02:00
|
|
|
@load new Promise (resolve, reject) =>
|
2020-05-21 21:56:16 +02:00
|
|
|
@currfile.read("binary").then (d) =>
|
2020-05-21 14:51:47 +02:00
|
|
|
($ @view).removeClass()
|
|
|
|
PDFJS.getDocument { data: d }
|
|
|
|
.then (pdf) =>
|
2020-05-21 21:56:16 +02:00
|
|
|
@pdf = pdf
|
|
|
|
@renderPDFPages 1, 1, false
|
|
|
|
.then () =>
|
|
|
|
$(@txtpage).val("1")
|
|
|
|
resolve()
|
2020-05-22 17:19:10 +02:00
|
|
|
.catch (e) -> reject __e e
|
|
|
|
.catch (e) -> reject __e e
|
|
|
|
.catch (e) -> reject __e e
|
2020-05-21 21:56:16 +02:00
|
|
|
.catch (e) => @error __("Unable to view file: {0}", @currfile.path), e
|
2020-05-20 23:13:28 +02:00
|
|
|
|
2020-05-21 21:56:16 +02:00
|
|
|
renderSVG: () ->
|
2020-05-20 23:13:28 +02:00
|
|
|
($ @view).attr("class", "image")
|
2020-05-21 21:56:16 +02:00
|
|
|
@currfile.read().then (d) =>
|
2020-05-20 23:13:28 +02:00
|
|
|
@view.innerHTML = d
|
|
|
|
$($(@view).children()[0])
|
|
|
|
.css "width", "100%"
|
|
|
|
.css "height", "100%"
|
2020-05-21 21:56:16 +02:00
|
|
|
.catch (e) => @error __("Unable to read file: {0}", @currfile.path), e
|
2020-05-20 23:13:28 +02:00
|
|
|
|
2020-05-21 21:56:16 +02:00
|
|
|
renderImage: () ->
|
2020-05-20 23:13:28 +02:00
|
|
|
($ @view).attr("class", "image")
|
|
|
|
|
2020-05-21 21:56:16 +02:00
|
|
|
@currfile.read("binary").then (d) =>
|
2020-05-20 23:13:28 +02:00
|
|
|
img = new Image()
|
|
|
|
canvas = ($ "<canvas/>")[0]
|
|
|
|
($ @view).append canvas
|
|
|
|
|
|
|
|
#($ me.view).append img
|
|
|
|
img.onload = () =>
|
|
|
|
context = canvas.getContext '2d'
|
|
|
|
canvas.height = img.height
|
|
|
|
canvas.width = img.width
|
2020-05-21 21:56:16 +02:00
|
|
|
@img = img
|
2020-05-20 23:13:28 +02:00
|
|
|
#console.log canvas.width, canvas.height
|
|
|
|
context.drawImage img, 0, 0
|
2020-05-21 21:56:16 +02:00
|
|
|
@setStatus "#{@currfile.info.name} (#{@currfile.info.size} Kb) - #{img.width}x#{img.height}"
|
2020-05-20 23:13:28 +02:00
|
|
|
|
2020-05-21 21:56:16 +02:00
|
|
|
blob = new Blob [d], { type: @currfile.info.mime }
|
2020-05-20 23:13:28 +02:00
|
|
|
img.src = URL.createObjectURL blob
|
2020-05-21 21:56:16 +02:00
|
|
|
.catch (e) => @error __("Unable to read file: {0}", @currfile.path), e
|
2020-05-20 23:13:28 +02:00
|
|
|
|
|
|
|
menu: () ->
|
|
|
|
menu = [{
|
|
|
|
text: "__(File)",
|
|
|
|
child: [
|
|
|
|
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
|
|
|
|
{ text: "__(Close)", dataid: "#{@name}-Close", shortcut: "C-X" },
|
|
|
|
],
|
|
|
|
onchildselect: (e) => @actionFile e.data.item.get("data").dataid
|
|
|
|
}]
|
|
|
|
menu
|
|
|
|
|
|
|
|
actionFile: (e) ->
|
|
|
|
switch e
|
|
|
|
when "#{@name}-Open"
|
|
|
|
@openDialog("FileDialog", {
|
|
|
|
title: __("Open file"),
|
|
|
|
mimes: @meta().mimes
|
|
|
|
}).then ( d ) =>
|
|
|
|
@open d.file.path.asFileHandle()
|
|
|
|
|
|
|
|
when "#{@name}-Close"
|
|
|
|
@quit()
|
|
|
|
|
|
|
|
this.OS.register "Preview", Preview
|