Revert "PDF editor improvements (#2529)"

This reverts commit e4c1f30b9d.
This commit is contained in:
Raphael Michel
2022-03-17 16:43:18 +01:00
parent e4c1f30b9d
commit ab0f76c7bb
6 changed files with 74 additions and 273 deletions

View File

@@ -37,7 +37,6 @@ import hashlib
import itertools import itertools
import logging import logging
import os import os
import re
import subprocess import subprocess
import tempfile import tempfile
import uuid import uuid
@@ -55,7 +54,6 @@ from django.utils.functional import SimpleLazyObject
from django.utils.html import conditional_escape from django.utils.html import conditional_escape
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from i18nfield.strings import LazyI18nString
from PyPDF2 import PdfFileReader from PyPDF2 import PdfFileReader
from pytz import timezone from pytz import timezone
from reportlab.graphics import renderPDF from reportlab.graphics import renderPDF
@@ -204,11 +202,6 @@ DEFAULT_VARIABLES = OrderedDict((
"editor_sample": 'foo@bar.com', "editor_sample": 'foo@bar.com',
"evaluate": lambda op, order, ev: op.attendee_email or (op.addon_to.attendee_email if op.addon_to else '') "evaluate": lambda op, order, ev: op.attendee_email or (op.addon_to.attendee_email if op.addon_to else '')
}), }),
("pseudonymization_id", {
"label": _("Pseudonymization ID (lead scanning)"),
"editor_sample": "GG89JUJDTA",
"evaluate": lambda orderposition, order, event: orderposition.pseudonymization_id,
}),
("event_name", { ("event_name", {
"label": _("Event name"), "label": _("Event name"),
"editor_sample": _("Sample event name"), "editor_sample": _("Sample event name"),
@@ -623,14 +616,12 @@ class Renderer:
preserveAspectRatio=True, anchor='n', preserveAspectRatio=True, anchor='n',
mask='auto') mask='auto')
def _draw_barcodearea(self, canvas: Canvas, op: OrderPosition, order: Order, o: dict): def _draw_barcodearea(self, canvas: Canvas, op: OrderPosition, o: dict):
content = o.get('content', 'secret') content = o.get('content', 'secret')
if content == 'secret': if content == 'secret':
# do not use get_text_content because it uses a shortened version of secret
# and does not deal with our default value here properly
content = op.secret content = op.secret
else: elif content == 'pseudonymization_id':
content = self._get_text_content(op, order, o) content = op.pseudonymization_id
level = 'H' level = 'H'
if len(content) > 32: if len(content) > 32:
@@ -657,45 +648,20 @@ class Renderer:
return self._get_text_content(op, order, o, True) return self._get_text_content(op, order, o, True)
ev = self._get_ev(op, order) ev = self._get_ev(op, order)
if not o['content']: if not o['content']:
return '(error)' return '(error)'
if o['content'] == 'other':
if o['content'] == 'other' or o['content'] == 'other_i18n': return o['text']
if o['content'] == 'other_i18n':
text = str(LazyI18nString(o['text_i18n']))
else:
text = o['text']
def replace(x):
if x.group(1) not in self.variables:
return x.group(0)
if x.group(1) == 'secret':
# Do not use shortened version
return op.secret
try:
return self.variables[x.group(1)]['evaluate'](op, order, ev)
except:
logger.exception('Failed to process variable.')
return '(error)'
# We do not use str.format like in emails so we (a) can evaluate lazily and (b) can re-implement this
# 1:1 on other platforms that render PDFs through our API (libpretixprint)
return re.sub(r'\{([a-zA-Z0-9_]+)\}', replace, text)
elif o['content'].startswith('itemmeta:'): elif o['content'].startswith('itemmeta:'):
return op.item.meta_data.get(o['content'][9:]) or '' return op.item.meta_data.get(o['content'][9:]) or ''
elif o['content'].startswith('meta:'): elif o['content'].startswith('meta:'):
return ev.meta_data.get(o['content'][5:]) or '' return ev.meta_data.get(o['content'][5:]) or ''
elif o['content'] in self.variables: elif o['content'] in self.variables:
try: try:
return self.variables[o['content']]['evaluate'](op, order, ev) return self.variables[o['content']]['evaluate'](op, order, ev)
except: except:
logger.exception('Failed to process variable.') logger.exception('Failed to process variable.')
return '(error)' return '(error)'
return '' return ''
def _draw_imagearea(self, canvas: Canvas, op: OrderPosition, order: Order, o: dict): def _draw_imagearea(self, canvas: Canvas, op: OrderPosition, order: Order, o: dict):
@@ -788,20 +754,10 @@ class Renderer:
p.drawOn(canvas, 0, -h - ad[1]) p.drawOn(canvas, 0, -h - ad[1])
canvas.restoreState() canvas.restoreState()
def draw_page(self, canvas: Canvas, order: Order, op: OrderPosition, show_page=True, only_page=None): def draw_page(self, canvas: Canvas, order: Order, op: OrderPosition, show_page=True):
page_count = self.bg_pdf.getNumPages()
if not only_page and not show_page:
raise ValueError("only_page=None and show_page=False cannot be combined")
for page in range(page_count):
if only_page and only_page != page + 1:
continue
for o in self.layout: for o in self.layout:
if o.get('page', 1) != page + 1:
continue
if o['type'] == "barcodearea": if o['type'] == "barcodearea":
self._draw_barcodearea(canvas, op, order, o) self._draw_barcodearea(canvas, op, o)
elif o['type'] == "imagearea": elif o['type'] == "imagearea":
self._draw_imagearea(canvas, op, order, o) self._draw_imagearea(canvas, op, order, o)
elif o['type'] == "textarea": elif o['type'] == "textarea":
@@ -809,7 +765,7 @@ class Renderer:
elif o['type'] == "poweredby": elif o['type'] == "poweredby":
self._draw_poweredby(canvas, op, o) self._draw_poweredby(canvas, op, o)
if self.bg_pdf: if self.bg_pdf:
canvas.setPageSize((self.bg_pdf.getPage(page).mediaBox[2], self.bg_pdf.getPage(page).mediaBox[3])) canvas.setPageSize((self.bg_pdf.getPage(0).mediaBox[2], self.bg_pdf.getPage(0).mediaBox[3]))
if show_page: if show_page:
canvas.showPage() canvas.showPage()
@@ -824,7 +780,7 @@ class Renderer:
subprocess.run([ subprocess.run([
settings.PDFTK, settings.PDFTK,
os.path.join(d, 'front.pdf'), os.path.join(d, 'front.pdf'),
'multibackground', 'background',
os.path.join(d, 'back.pdf'), os.path.join(d, 'back.pdf'),
'output', 'output',
os.path.join(d, 'out.pdf'), os.path.join(d, 'out.pdf'),
@@ -838,8 +794,8 @@ class Renderer:
new_pdf = PdfFileReader(buffer) new_pdf = PdfFileReader(buffer)
output = PdfFileWriter() output = PdfFileWriter()
for i, page in enumerate(new_pdf.pages): for page in new_pdf.pages:
bg_page = copy.copy(self.bg_pdf.getPage(i)) bg_page = copy.copy(self.bg_pdf.getPage(0))
bg_page.mergePage(page) bg_page.mergePage(page)
output.addPage(bg_page) output.addPage(bg_page)

View File

@@ -23,7 +23,7 @@
</script> </script>
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-9">
<div class="panel panel-default panel-pdf-editor"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<div class="pull-right flip"> <div class="pull-right flip">
<div class="btn-group"> <div class="btn-group">
@@ -48,8 +48,6 @@
{% trans "Editor" %} {% trans "Editor" %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<ul class="nav nav-pills" id="page_nav">
</ul>
<div id="editor-canvas-area"> <div id="editor-canvas-area">
<canvas id="pdf-canvas" <canvas id="pdf-canvas"
data-pdf-url="{{ pdf }}" data-pdf-url="{{ pdf }}"
@@ -195,7 +193,7 @@
<span class="btn btn-default fileinput-button background-button"> <span class="btn btn-default fileinput-button background-button">
<i class="fa fa-upload"></i> <i class="fa fa-upload"></i>
<span>{% trans "Upload custom background" %}</span> <span>{% trans "Upload custom background" %}</span>
<input id="fileupload" type="file" name="background" accept="application/pdf"> <input id="fileupload" type="file" name="background">
</span> </span>
</div> </div>
<div class="col-sm-12 help-inline"> <div class="col-sm-12 help-inline">
@@ -206,14 +204,6 @@
{% endblocktrans %} {% endblocktrans %}
</p> </p>
</div> </div>
<div class="col-sm-12">
<p>
<a class="btn btn-default background-download-button" href="{{ pdf }}" target="_blank">
<i class="fa fa-download"></i>
<span>{% trans "Download current background" %}</span>
</a>
</p>
</div>
</div> </div>
<div class="row control-group pdf-info"> <div class="row control-group pdf-info">
<div class="col-sm-12"> <div class="col-sm-12">
@@ -367,9 +357,9 @@
</select> </select>
</div> </div>
</div> </div>
<div class="row control-group text textcontent"> <div class="row control-group text">
<div class="col-sm-12"> <div class="col-sm-12">
<label>{% trans "Content" %}</label><br> <label>{% trans "Text content" %}</label><br>
<select class="input-block-level form-control" id="toolbox-content"> <select class="input-block-level form-control" id="toolbox-content">
{% for varname, var in variables.items %} {% for varname, var in variables.items %}
<option data-sample="{{ var.editor_sample }}" value="{{ varname }}">{{ var.label }}</option> <option data-sample="{{ var.editor_sample }}" value="{{ varname }}">{{ var.label }}</option>
@@ -384,16 +374,10 @@
{% trans "Item attribute:" %} {{ p.name }} {% trans "Item attribute:" %} {{ p.name }}
</option> </option>
{% endfor %} {% endfor %}
<option value="other_i18n">{% trans "Other… (multilingual)" %}</option>
<option value="other">{% trans "Other…" %}</option> <option value="other">{% trans "Other…" %}</option>
</select> </select>
<textarea type="text" value="" class="input-block-level form-control" <textarea type="text" value="" class="input-block-level form-control"
id="toolbox-content-other"></textarea> id="toolbox-content-other"></textarea>
<div class="i18n-form-group" id="toolbox-content-other-i18n">
{% for l in request.event.settings.locales %}
<textarea id="toolbox-content-other-{{ l }}" rows="3" class="input-block-level form-control" title="{{ l }}" lang="{{ l }}"></textarea>
{% endfor %}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -417,20 +401,13 @@
<span class="fa fa-qrcode"></span> <span class="fa fa-qrcode"></span>
{% trans "QR code for Lead Scanning" %} {% trans "QR code for Lead Scanning" %}
</button> </button>
<button class="btn btn-default btn-block" id="editor-add-qrcode-other"
data-content="secret"
disabled>
<span class="fa fa-qrcode"></span>
{% trans "Other QR code" %}
</button>
<button class="btn btn-default btn-block" id="editor-add-poweredby" <button class="btn btn-default btn-block" id="editor-add-poweredby"
data-content="dark" data-content="dark"
disabled> disabled>
<span class="fa fa-image"></span> <span class="fa fa-image"></span>
{% trans "pretix Logo" %} {% trans "pretix Logo" %}
</button> </button>
<button class="btn btn-default btn-block" id="editor-add-image" disabled <button class="btn btn-default btn-block" id="editor-add-image" disabled>
data-toggle="tooltip" title="{% trans "You can use this to add user-uploaded pictures from questions or pictures generated by plugins. If you want to embed a logo or other images, use a custom background instead." %}">
<span class="fa fa-image"></span> <span class="fa fa-image"></span>
{% trans "Dynamic image" %} {% trans "Dynamic image" %}
</button> </button>

View File

@@ -23,7 +23,6 @@ import json
import logging import logging
import mimetypes import mimetypes
from datetime import timedelta from datetime import timedelta
from decimal import Decimal
from io import BytesIO from io import BytesIO
from django.conf import settings from django.conf import settings
@@ -39,8 +38,7 @@ from django.utils.crypto import get_random_string
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic import TemplateView from django.views.generic import TemplateView
from PyPDF2 import PdfFileReader, PdfFileWriter from PyPDF2 import PdfFileWriter
from PyPDF2.utils import PdfReadError
from reportlab.lib.units import mm from reportlab.lib.units import mm
from pretix.base.i18n import language from pretix.base.i18n import language
@@ -84,15 +82,15 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
return None, f return None, f
def _get_preview_position(self): def _get_preview_position(self):
item = self.request.event.items.create(name=_("Sample product"), default_price=Decimal('42.23'), item = self.request.event.items.create(name=_("Sample product"), default_price=42.23,
description=_("Sample product description")) description=_("Sample product description"))
item2 = self.request.event.items.create(name=_("Sample workshop"), default_price=Decimal('23.40')) item2 = self.request.event.items.create(name=_("Sample workshop"), default_price=23.40)
from pretix.base.models import Order from pretix.base.models import Order
order = self.request.event.orders.create(status=Order.STATUS_PENDING, datetime=now(), order = self.request.event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
email='sample@pretix.eu', email='sample@pretix.eu',
locale=self.request.event.settings.locale, locale=self.request.event.settings.locale,
expires=now(), code="PREVIEW1234", total=Decimal('119.00')) expires=now(), code="PREVIEW1234", total=119)
scheme = PERSON_NAME_SCHEMES[self.request.event.settings.name_scheme] scheme = PERSON_NAME_SCHEMES[self.request.event.settings.name_scheme]
sample = {k: str(v) for k, v in scheme['sample'].items()} sample = {k: str(v) for k, v in scheme['sample'].items()}
@@ -193,17 +191,6 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
c.file = fileobj c.file = fileobj
c.save() c.save()
c.refresh_from_db() c.refresh_from_db()
try:
bg_bytes = c.file.read()
PdfFileReader(BytesIO(bg_bytes), strict=False)
except PdfReadError as e:
return JsonResponse({
"status": "error",
"error": _('Unfortunately, we were unable to process this PDF file ({reason}).').format(
reason=str(e)
)
})
return JsonResponse({ return JsonResponse({
"status": "ok", "status": "ok",
"id": c.id, "id": c.id,

View File

@@ -181,7 +181,7 @@ def render_pdf(event, positions, opt):
offsety = opt['margins'][2] + (opt['rows'] - 1 - i // opt['cols']) * opt['offsets'][1] offsety = opt['margins'][2] + (opt['rows'] - 1 - i // opt['cols']) * opt['offsets'][1]
p.translate(offsetx, offsety) p.translate(offsetx, offsety)
with language(op.order.locale, op.order.event.settings.region): with language(op.order.locale, op.order.event.settings.region):
r.draw_page(p, op.order, op, show_page=False, only_page=1) r.draw_page(p, op.order, op, show_page=False)
p.translate(-offsetx, -offsety) p.translate(-offsetx, -offsety)
if opt['pagesize']: if opt['pagesize']:

View File

@@ -66,11 +66,9 @@ fabric.Barcodearea = fabric.util.createClass(fabric.Rect, {
ctx.font = '16px Helvetica'; ctx.font = '16px Helvetica';
ctx.fillStyle = '#fff'; ctx.fillStyle = '#fff';
if (this.content === "pseudonymization_id") { if (this.content === "pseudonymization_id") {
ctx.fillText(this.content, -this.width / 2, -this.height / 2 + 20); ctx.fillText(gettext('Lead Scan QR'), -this.width / 2, -this.height / 2 + 20);
} else if (!this.content || this.content === "secret") {
ctx.fillText(gettext('Check-in QR'), -this.width / 2, -this.height / 2 + 20);
} else { } else {
ctx.fillText(this.content, -this.width / 2, -this.height / 2 + 20); ctx.fillText(gettext('Check-in QR'), -this.width / 2, -this.height / 2 + 20);
} }
}, },
}); });
@@ -104,15 +102,11 @@ var editor = {
objects: [], objects: [],
history: [], history: [],
clipboard: [], clipboard: [],
pdf: null,
pdf_page: null, pdf_page: null,
pdf_page_number: 1,
pdf_page_count: 1,
pdf_scale: 1, pdf_scale: 1,
pdf_viewport: null, pdf_viewport: null,
_history_pos: 0, _history_pos: 0,
_history_modification_in_progress: false, _history_modification_in_progress: false,
_other_page_objects: [],
dirty: false, dirty: false,
pdf_url: null, pdf_url: null,
uploaded_file_id: null, uploaded_file_id: null,
@@ -136,7 +130,7 @@ var editor = {
}, },
dump: function (objs) { dump: function (objs) {
var d = !objs ? JSON.parse(JSON.stringify(editor._other_page_objects)) : []; var d = [];
objs = objs || editor.fabric.getObjects(); objs = objs || editor.fabric.getObjects();
for (var i in objs) { for (var i in objs) {
@@ -155,7 +149,6 @@ var editor = {
} }
d.push({ d.push({
type: "textarea", type: "textarea",
page: editor.pdf_page_number,
locale: $("#pdf-info-locale").val(), locale: $("#pdf-info-locale").val(),
left: editor._px2mm(left).toFixed(2), left: editor._px2mm(left).toFixed(2),
bottom: editor._px2mm(bottom).toFixed(2), bottom: editor._px2mm(bottom).toFixed(2),
@@ -169,14 +162,12 @@ var editor = {
downward: o.downward || false, downward: o.downward || false,
content: o.content, content: o.content,
text: o.text, text: o.text,
text_i18n: o.text_i18n || {},
rotation: o.angle, rotation: o.angle,
align: o.textAlign, align: o.textAlign,
}); });
} else if (o.type === "imagearea") { } else if (o.type === "imagearea") {
d.push({ d.push({
type: "imagearea", type: "imagearea",
page: editor.pdf_page_number,
left: editor._px2mm(left).toFixed(2), left: editor._px2mm(left).toFixed(2),
bottom: editor._px2mm(editor.pdf_viewport.height - o.height * o.scaleY - top).toFixed(2), bottom: editor._px2mm(editor.pdf_viewport.height - o.height * o.scaleY - top).toFixed(2),
height: editor._px2mm(o.height * o.scaleY).toFixed(2), height: editor._px2mm(o.height * o.scaleY).toFixed(2),
@@ -186,18 +177,15 @@ var editor = {
} else if (o.type === "barcodearea") { } else if (o.type === "barcodearea") {
d.push({ d.push({
type: "barcodearea", type: "barcodearea",
page: editor.pdf_page_number,
left: editor._px2mm(left).toFixed(2), left: editor._px2mm(left).toFixed(2),
bottom: editor._px2mm(editor.pdf_viewport.height - o.height * o.scaleY - top).toFixed(2), bottom: editor._px2mm(editor.pdf_viewport.height - o.height * o.scaleY - top).toFixed(2),
size: editor._px2mm(o.height * o.scaleY).toFixed(2), size: editor._px2mm(o.height * o.scaleY).toFixed(2),
content: o.content, content: o.content,
text: o.text,
nowhitespace: o.nowhitespace || false, nowhitespace: o.nowhitespace || false,
}); });
} else if (o.type === "poweredby") { } else if (o.type === "poweredby") {
d.push({ d.push({
type: "poweredby", type: "poweredby",
page: editor.pdf_page_number,
left: editor._px2mm(left).toFixed(2), left: editor._px2mm(left).toFixed(2),
bottom: editor._px2mm(editor.pdf_viewport.height - o.height * o.scaleY - top).toFixed(2), bottom: editor._px2mm(editor.pdf_viewport.height - o.height * o.scaleY - top).toFixed(2),
size: editor._px2mm(o.height * o.scaleY).toFixed(2), size: editor._px2mm(o.height * o.scaleY).toFixed(2),
@@ -209,11 +197,6 @@ var editor = {
}, },
_add_from_data: function (d) { _add_from_data: function (d) {
var targetPage = d.page || 1;
if (targetPage !== editor.pdf_page_number) {
editor._other_page_objects.push(d);
return
}
if (d.type === "barcodearea") { if (d.type === "barcodearea") {
o = editor._add_qrcode(); o = editor._add_qrcode();
o.content = d.content; o.content = d.content;
@@ -247,9 +230,6 @@ var editor = {
} }
if (d.content === "other") { if (d.content === "other") {
o.setText(d.text); o.setText(d.text);
} else if (d.content === "other_i18n") {
o.text_i18n = d.text_i18n
o.setText(d.text_i18n[Object.keys(d.text_i18n)[0]]);
} else { } else {
o.setText(editor._get_text_sample(d.content)); o.setText(editor._get_text_sample(d.content));
} }
@@ -271,7 +251,6 @@ var editor = {
load: function(data) { load: function(data) {
editor.fabric.clear(); editor.fabric.clear();
editor._other_page_objects = [];
for (var i in data) { for (var i in data) {
var d = data[i], o; var d = data[i], o;
editor._add_from_data(d); editor._add_from_data(d);
@@ -289,11 +268,20 @@ var editor = {
return $('#toolbox-content option[value='+key+']').attr('data-sample') || ''; return $('#toolbox-content option[value='+key+']').attr('data-sample') || '';
}, },
_load_page: function (page_number, dump) { _load_pdf: function (dump) {
var previous_dump = editor._fabric_loaded ? editor.dump() : []; // TODO: Loading indicators
var url = editor.pdf_url;
// TODO: Handle cross-origin issues if static files are on a different origin
PDFJS.workerSrc = editor.$pdfcv.attr("data-worker-url");
// Fetch the required page // Asynchronous download of PDF
editor.pdf.getPage(page_number).then(function (page) { var loadingTask = PDFJS.getDocument(url);
loadingTask.promise.then(function (pdf) {
console.log('PDF loaded');
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function (page) {
console.log('Page loaded'); console.log('Page loaded');
var canvas = document.getElementById('pdf-canvas'); var canvas = document.getElementById('pdf-canvas');
@@ -317,61 +305,10 @@ var editor = {
}; };
var renderTask = page.render(renderContext); var renderTask = page.render(renderContext);
renderTask.then(function () { renderTask.then(function () {
editor.pdf_page_number = page_number
editor._init_page_nav();
console.log('Page rendered'); console.log('Page rendered');
if (dump || !editor._fabric_loaded) {
editor._init_fabric(dump); editor._init_fabric(dump);
} else {
editor.load(previous_dump);
}
}); });
}); });
},
_init_page_nav: function () {
if (editor.pdf_page_count === 1) {
$("#page_nav").hide();
} else {
$("#page_nav").html("");
for (i = 1; i <= editor.pdf_page_count; i++) {
var $li = $("<li>").addClass("nav-item");
var $a = $("<a>").text(i).attr("href", "#").attr("data-page", i).appendTo($li);
if (i === editor.pdf_page_number) {
$li.addClass("active")
}
$("#page_nav").append($li)
$a.on("click", function (event) {
console.log("switch to page", $(this).attr("data-page"));
editor.fabric.deactivateAll();
editor._load_page(parseInt($(this).attr("data-page")));
event.preventDefault();
return true;
})
}
$("#page_nav").show();
}
},
_load_pdf: function (dump) {
// TODO: Loading indicators
var url = editor.pdf_url;
// TODO: Handle cross-origin issues if static files are on a different origin
PDFJS.workerSrc = editor.$pdfcv.attr("data-worker-url");
// Asynchronous download of PDF
var loadingTask = PDFJS.getDocument(url);
loadingTask.promise.then(function (pdf) {
console.log('PDF loaded');
editor.pdf = pdf;
editor.pdf_page_count = pdf.numPages;
if (editor.pdf_page_count > 10) {
alert('Please do not upload files with more than 10 pages for performance reasons.')
}
editor._init_page_nav();
editor._load_page(1, dump);
}, function (reason) { }, function (reason) {
var msg = gettext('The PDF background file could not be loaded for the following reason:'); var msg = gettext('The PDF background file could not be loaded for the following reason:');
editor._error(msg + ' ' + reason); editor._error(msg + ' ' + reason);
@@ -395,7 +332,6 @@ var editor = {
editor._update_toolbox(); editor._update_toolbox();
$("#toolbox-content-other").hide(); $("#toolbox-content-other").hide();
$("#toolbox-content-other-i18n").hide();
$(".add-buttons button").prop('disabled', false); $(".add-buttons button").prop('disabled', false);
if (dump) { if (dump) {
@@ -486,25 +422,16 @@ var editor = {
$("#toolbox").find("button[data-action=right]").toggleClass('active', o.textAlign === 'right'); $("#toolbox").find("button[data-action=right]").toggleClass('active', o.textAlign === 'right');
$("#toolbox-textwidth").val(editor._px2mm(o.width).toFixed(2)); $("#toolbox-textwidth").val(editor._px2mm(o.width).toFixed(2));
$("#toolbox-textrotation").val((o.angle || 0.0).toFixed(1)); $("#toolbox-textrotation").val((o.angle || 0.0).toFixed(1));
} if (o.type === "textarea") {
if (o.type === "textarea" || o.type === "barcodearea") {
if (!o.content && o.type == "barcodearea") {
o.content = "secret";
}
$("#toolbox-content").val(o.content); $("#toolbox-content").val(o.content);
$("#toolbox-content-other").toggle($("#toolbox-content").val() === "other"); $("#toolbox-content-other").toggle($("#toolbox-content").val() === "other");
$("#toolbox-content-other-i18n").toggle($("#toolbox-content").val() === "other_i18n");
if (o.content === "other") { if (o.content === "other") {
$("#toolbox-content-other").val(o.text); $("#toolbox-content-other").val(o.text);
} else if (o.content === "other_i18n") {
$("#toolbox-content-other-i18n textarea").each(function () {
$(this).val(o.text_i18n[$(this).attr("lang")] || '');
});
} else { } else {
$("#toolbox-content-other").val(""); $("#toolbox-content-other").val("");
} }
} }
}
}, },
_update_values_from_toolbox: function () { _update_values_from_toolbox: function () {
@@ -534,20 +461,6 @@ var editor = {
o.setScaleY(1); o.setScaleY(1);
o.set('top', new_top) o.set('top', new_top)
o.nowhitespace = $("#toolbox-qrwhitespace").prop("checked") || false; o.nowhitespace = $("#toolbox-qrwhitespace").prop("checked") || false;
$("#toolbox-content-other").toggle($("#toolbox-content").val() === "other");
$("#toolbox-content-other-i18n").toggle($("#toolbox-content").val() === "other_i18n");
o.content = $("#toolbox-content").val();
if ($("#toolbox-content").val() === "other") {
o.text = $("#toolbox-content-other").val();
} else if ($("#toolbox-content").val() === "other_i18n") {
o.text_i18n = {}
$("#toolbox-content-other-i18n textarea").each(function () {
o.text_i18n[$(this).attr("lang")] = $(this).val();
});
} else {
o.text = editor._get_text_sample($("#toolbox-content").val());
}
} else if (o.type === "imagearea") { } else if (o.type === "imagearea") {
var new_w = editor._mm2px($("#toolbox-width").val()); var new_w = editor._mm2px($("#toolbox-width").val());
var new_h = editor._mm2px($("#toolbox-height").val()); var new_h = editor._mm2px($("#toolbox-height").val());
@@ -590,16 +503,9 @@ var editor = {
o.downward = $("#toolbox").find("button[data-action=downward]").is('.active'); o.downward = $("#toolbox").find("button[data-action=downward]").is('.active');
o.rotate(parseFloat($("#toolbox-textrotation").val())); o.rotate(parseFloat($("#toolbox-textrotation").val()));
$("#toolbox-content-other").toggle($("#toolbox-content").val() === "other"); $("#toolbox-content-other").toggle($("#toolbox-content").val() === "other");
$("#toolbox-content-other-i18n").toggle($("#toolbox-content").val() === "other_i18n");
o.content = $("#toolbox-content").val(); o.content = $("#toolbox-content").val();
if ($("#toolbox-content").val() === "other") { if ($("#toolbox-content").val() === "other") {
o.setText($("#toolbox-content-other").val()); o.setText($("#toolbox-content-other").val());
} else if ($("#toolbox-content").val() === "other_i18n") {
o.text_i18n = {}
$("#toolbox-content-other-i18n textarea").each(function () {
o.text_i18n[$(this).attr("lang")] = $(this).val();
});
o.setText($("#toolbox-content-other-i18n textarea").first().val());
} else { } else {
o.setText(editor._get_text_sample($("#toolbox-content").val())); o.setText(editor._get_text_sample($("#toolbox-content").val()));
} }
@@ -712,7 +618,6 @@ var editor = {
lockUniScaling: true, lockUniScaling: true,
fill: '#666', fill: '#666',
content: $(this).attr("data-content"), content: $(this).attr("data-content"),
text: '',
nowhitespace: true, nowhitespace: true,
}); });
rect.setControlsVisibility({'mtr': false}); rect.setControlsVisibility({'mtr': false});
@@ -759,7 +664,6 @@ var editor = {
editor._history_modification_in_progress = true; editor._history_modification_in_progress = true;
var objs = []; var objs = [];
for (var i in editor.clipboard) { for (var i in editor.clipboard) {
editor.clipboard[i].page = editor.pdf_page_number;
objs.push(editor._add_from_data(editor.clipboard[i])); objs.push(editor._add_from_data(editor.clipboard[i]));
} }
editor.fabric.discardActiveObject(); editor.fabric.discardActiveObject();
@@ -825,11 +729,6 @@ var editor = {
case 46: /* Delete */ case 46: /* Delete */
editor._delete(); editor._delete();
break; break;
case 65: /* A */
if (e.ctrlKey) {
editor._selectAll();
}
break;
case 89: /* Y */ case 89: /* Y */
if (e.ctrlKey) { if (e.ctrlKey) {
editor._redo(); editor._redo();
@@ -876,15 +775,6 @@ var editor = {
editor.dirty = true; editor.dirty = true;
}, },
_selectAll: function () {
var group = new fabric.Group(editor.fabric.getObjects(), {
originX: 'center',
originY: 'center',
});
group.setCoords();
editor.fabric.setActiveGroup(group);
},
_undo: function undo() { _undo: function undo() {
if (editor._history_pos < editor.history.length - 1) { if (editor._history_pos < editor.history.length - 1) {
editor._history_modification_in_progress = true; editor._history_modification_in_progress = true;
@@ -937,7 +827,6 @@ var editor = {
d = editor.dump(); d = editor.dump();
editor.fabric.dispose(); editor.fabric.dispose();
editor._load_pdf(d); editor._load_pdf(d);
$(".background-download-button").attr("href", url);
}, },
_source_show: function () { _source_show: function () {
@@ -984,7 +873,7 @@ var editor = {
editor.$fcv = $("#fabric-canvas"); editor.$fcv = $("#fabric-canvas");
editor.$cva = $("#editor-canvas-area"); editor.$cva = $("#editor-canvas-area");
editor._load_pdf(); editor._load_pdf();
$("#editor-add-qrcode, #editor-add-qrcode-lead, #editor-add-qrcode-other").click(editor._add_qrcode); $("#editor-add-qrcode, #editor-add-qrcode-lead").click(editor._add_qrcode);
$("#editor-add-image").click(editor._add_imagearea); $("#editor-add-image").click(editor._add_imagearea);
$("#editor-add-text").click(editor._add_text); $("#editor-add-text").click(editor._add_text);
$("#editor-add-poweredby").click(function() {editor._add_poweredby("dark")}); $("#editor-add-poweredby").click(function() {editor._add_poweredby("dark")});

View File

@@ -25,7 +25,6 @@ body {
} }
#toolbox[data-type] .position, #toolbox[data-type] .position,
#toolbox[data-type=barcodearea] .squaresize, #toolbox[data-type=barcodearea] .squaresize,
#toolbox[data-type=barcodearea] .textcontent,
#toolbox[data-type=imagearea] .rectsize, #toolbox[data-type=imagearea] .rectsize,
#toolbox[data-type=imagearea] .imagecontent, #toolbox[data-type=imagearea] .imagecontent,
#toolbox[data-type=poweredby] .poweredby, #toolbox[data-type=poweredby] .poweredby,
@@ -70,10 +69,3 @@ body {
margin-top: 10px; margin-top: 10px;
margin-bottom: 0; margin-bottom: 0;
} }
.panel-pdf-editor .panel-body {
padding: 0;
}
.panel-pdf-editor .panel-body .nav-pills {
padding: 15px;
background: #eee;
}