328 lines
11 KiB
Python
328 lines
11 KiB
Python
|
# -*-coding:utf-8 -*
|
||
|
|
||
|
import tkinter as tk
|
||
|
from tkinter import ttk
|
||
|
from tkinter import messagebox
|
||
|
import logging
|
||
|
logger = logging.getLogger()
|
||
|
|
||
|
class Rotate(tk.Toplevel):
|
||
|
"""
|
||
|
Window for asking rotation parameters
|
||
|
"""
|
||
|
|
||
|
def __init__(self, parent, fichobj):
|
||
|
tk.Toplevel.__init__(self, parent)
|
||
|
self.transient(parent)
|
||
|
self.grab_set()
|
||
|
self.bind("<Return>", self.ok)
|
||
|
self.bind("<Escape>", self.close)
|
||
|
|
||
|
self.fich = fichobj
|
||
|
|
||
|
self.title("Rotate {}".format(self.fich.name))
|
||
|
|
||
|
self.f = tk.Frame(self)
|
||
|
self.f.pack(fill=tk.BOTH)
|
||
|
|
||
|
# Création de nos widgets
|
||
|
self.f.columnconfigure(0, weight=1)
|
||
|
self.f.rowconfigure(5, weight=1)
|
||
|
|
||
|
info1 = tk.Label(self.f, text="Rotation :", fg="white", padx=20, bg="blue")
|
||
|
info1.grid(row=0, column=0, sticky=tk.W)
|
||
|
|
||
|
self.rota = tk.IntVar()
|
||
|
if(self.fich.rotate is not None):
|
||
|
self.rota.set(self.fich.rotate)
|
||
|
else:
|
||
|
self.rota.set(0)
|
||
|
bouton_sel = tk.Radiobutton(self.f, text="No rotation", variable=self.rota, value=0)
|
||
|
bouton_sel.grid(row=1, column=0)
|
||
|
bouton_sel = tk.Radiobutton(self.f, text="+Pi/2", variable=self.rota, value=1)
|
||
|
bouton_sel.grid(row=2, column=0)
|
||
|
bouton_sel = tk.Radiobutton(self.f, text="+Pi", variable=self.rota, value=2)
|
||
|
bouton_sel.grid(row=3, column=0)
|
||
|
bouton_sel = tk.Radiobutton(self.f, text="-Pi/2", variable=self.rota, value=3)
|
||
|
bouton_sel.grid(row=4, column=0)
|
||
|
|
||
|
bouton_do = tk.Button(self.f, text="Ok", command=self.ok)
|
||
|
bouton_do.grid(row=6, column=0)
|
||
|
|
||
|
|
||
|
def ok(self):
|
||
|
"""
|
||
|
Save and quit
|
||
|
"""
|
||
|
self.fich.rotate = self.rota.get()
|
||
|
self.destroy()
|
||
|
|
||
|
def close(self, *args):
|
||
|
self.destroy()
|
||
|
|
||
|
class Metadata(tk.Toplevel):
|
||
|
"""
|
||
|
Window for asking metadata
|
||
|
"""
|
||
|
|
||
|
def __init__(self, parent):
|
||
|
tk.Toplevel.__init__(self, parent)
|
||
|
self.transient(parent)
|
||
|
self.grab_set()
|
||
|
self.title("Metadata")
|
||
|
|
||
|
self.outobj = parent
|
||
|
|
||
|
self.f = tk.Frame(self)
|
||
|
self.f.pack(fill=tk.BOTH)
|
||
|
|
||
|
self.bind("<Return>", self.ok)
|
||
|
self.bind("<Escape>", self.close)
|
||
|
|
||
|
# Création de nos widgets
|
||
|
self.f.columnconfigure(1, weight=1)
|
||
|
self.f.rowconfigure(5, weight=1)
|
||
|
|
||
|
info1 = tk.Label(self.f, text="PDF Metadata :", fg="white", padx=20, bg="blue")
|
||
|
info1.grid(row=0, column=0, sticky=tk.W)
|
||
|
|
||
|
tk.Label(self.f, text="Title: ").grid(row=1, column=0)
|
||
|
tk.Label(self.f, text="Author: ").grid(row=2, column=0)
|
||
|
tk.Label(self.f, text="Subject: ").grid(row=3, column=0)
|
||
|
tk.Label(self.f, text="Creator: ").grid(row=4, column=0)
|
||
|
|
||
|
self.title = tk.StringVar()
|
||
|
self.author = tk.StringVar()
|
||
|
self.subject = tk.StringVar()
|
||
|
self.creator = tk.StringVar()
|
||
|
self.title.set(self.outobj.metadata['/Title'])
|
||
|
self.author.set(self.outobj.metadata['/Author'])
|
||
|
self.subject.set(self.outobj.metadata['/Subject'])
|
||
|
self.creator.set(self.outobj.metadata['/Creator'])
|
||
|
|
||
|
tk.Entry(self.f, textvariable=self.title).grid(row=1, column=1)
|
||
|
tk.Entry(self.f, textvariable=self.author).grid(row=2, column=1)
|
||
|
tk.Entry(self.f, textvariable=self.subject).grid(row=3, column=1)
|
||
|
tk.Entry(self.f, textvariable=self.creator).grid(row=4, column=1)
|
||
|
|
||
|
tk.Button(self.f, text="Annuler", command=self.quit).grid(row=6, column=0)
|
||
|
tk.Button(self.f, text="Ok", command=self.ok).grid(row=6, column=1)
|
||
|
|
||
|
|
||
|
def ok(self, *args):
|
||
|
"""
|
||
|
Save and quit
|
||
|
"""
|
||
|
self.outobj.metadata['/Title'] = self.title.get()
|
||
|
self.outobj.metadata['/Author'] = self.author.get()
|
||
|
self.outobj.metadata['/Subject'] = self.subject.get()
|
||
|
self.outobj.metadata['/Creator'] = self.creator.get()
|
||
|
|
||
|
self.quit()
|
||
|
|
||
|
def close(self, *args):
|
||
|
self.destroy()
|
||
|
|
||
|
class Progress(tk.Toplevel):
|
||
|
"""
|
||
|
Progress bar window for production of PDF
|
||
|
"""
|
||
|
|
||
|
def __init__(self, parent, nmax, text):
|
||
|
tk.Toplevel.__init__(self, parent)
|
||
|
self.transient(parent)
|
||
|
self.grab_set()
|
||
|
self.title("Producing PDF...")
|
||
|
|
||
|
self.nmax = nmax
|
||
|
|
||
|
self.outobj = parent
|
||
|
|
||
|
self.f = tk.Frame(self)
|
||
|
self.f.pack(fill=tk.BOTH)
|
||
|
|
||
|
|
||
|
info1 = tk.Label(self.f, text=text, padx=20)
|
||
|
info1.grid(row=0, column=0, sticky=tk.W)
|
||
|
|
||
|
self.progress = ttk.Progressbar(self.f, orient="horizontal", length=300)
|
||
|
self.progress["maximum"] = nmax
|
||
|
self.progress.grid(row=2, column=0)
|
||
|
|
||
|
self.message = tk.Label(self.f, text="Starting production...")
|
||
|
self.message.grid(row=3, column=0, sticky=tk.W)
|
||
|
|
||
|
def next(self):
|
||
|
self.progress["value"]+=1
|
||
|
self.progress.update_idletasks()
|
||
|
|
||
|
def close(self):
|
||
|
self.destroy()
|
||
|
|
||
|
class AskBlankPage(tk.Toplevel):
|
||
|
"""
|
||
|
Ask for position and number for adding blank pages
|
||
|
"""
|
||
|
|
||
|
def __init__(self, parent, fich, values):
|
||
|
tk.Toplevel.__init__(self, parent)
|
||
|
self.transient(parent)
|
||
|
self.grab_set()
|
||
|
self.title("Adding blank pages")
|
||
|
self.bind("<Return>", self.ok)
|
||
|
self.bind("<Escape>", self.close)
|
||
|
|
||
|
self.fich = fich
|
||
|
self.values = values
|
||
|
self.after = tk.StringVar()
|
||
|
self.nr = tk.StringVar()
|
||
|
self.nr.set("1")
|
||
|
|
||
|
self.f = tk.Frame(self)
|
||
|
self.f.pack(fill=tk.BOTH)
|
||
|
|
||
|
tk.Label(self.f, text="Add after page:", padx=20).grid(row=0, column=0, sticky=tk.W)
|
||
|
tk.Label(self.f, text="Nr of blank pages:", padx=20).grid(row=1, column=0, sticky=tk.W)
|
||
|
tk.Entry(self.f, textvariable=self.after).grid(row=0, column=1)
|
||
|
tk.Entry(self.f, textvariable=self.nr).grid(row=1, column=1)
|
||
|
|
||
|
tk.Button(self.f, text="Annuler", command=self.close).grid(row=3, column=0)
|
||
|
tk.Button(self.f, text="Ok", command=self.ok).grid(row=3, column=1)
|
||
|
|
||
|
def ok(self, *args):
|
||
|
self.values["after"] = []
|
||
|
self.values["nr"] = 0
|
||
|
for e in self.after.get().split(';'):
|
||
|
if(e.isdigit()):
|
||
|
i = int(e)
|
||
|
if(i<=0 or i>self.fich.npages+self.fich.nblankpages):
|
||
|
messagebox.showwarning(title="Warning", message="Number out of range, please correct it !")
|
||
|
return
|
||
|
else:
|
||
|
self.values["after"].append(i)
|
||
|
else:
|
||
|
messagebox.showwarning(title="Warning", message="Non-number entry (1st line), please correct it !")
|
||
|
return
|
||
|
nr = self.nr.get()
|
||
|
if(nr.isdigit()):
|
||
|
nr = int(nr)
|
||
|
if(nr>0):
|
||
|
self.values["nr"] = nr
|
||
|
else:
|
||
|
messagebox.showwarning(title="Warning", message="Non-number entry (2nd line), please correct it !")
|
||
|
return
|
||
|
self.close()
|
||
|
logger.debug("Concatenate : Add blank pages : End with values {}".format(self.values))
|
||
|
|
||
|
def close(self, *args):
|
||
|
self.quit()
|
||
|
|
||
|
class SetCrop(tk.Toplevel):
|
||
|
"""
|
||
|
Edition for crop box
|
||
|
"""
|
||
|
|
||
|
def __init__(self, parent, fich, **kwargs):
|
||
|
tk.Toplevel.__init__(self, parent)
|
||
|
self.transient(parent)
|
||
|
self.grab_set()
|
||
|
self.geometry("400x150")
|
||
|
self.bind("<Return>", self.ok)
|
||
|
self.bind("<Escape>", self.close)
|
||
|
|
||
|
self.fich = fich
|
||
|
|
||
|
self.enabled = False
|
||
|
self.llx = tk.StringVar()
|
||
|
self.lly = tk.StringVar()
|
||
|
self.urx = tk.StringVar()
|
||
|
self.ury = tk.StringVar()
|
||
|
if(self.fich.crop is not None):
|
||
|
self.enabled = True
|
||
|
self.llx.set(self.fich.crop[0][0])
|
||
|
self.lly.set(self.fich.crop[0][1])
|
||
|
self.urx.set(self.fich.crop[1][0])
|
||
|
self.ury.set(self.fich.crop[1][1])
|
||
|
|
||
|
self.title("Crop {}".format(self.fich.name))
|
||
|
|
||
|
self.f = tk.Frame(self, width=768, height=576, **kwargs)
|
||
|
self.f.pack(fill=tk.BOTH)
|
||
|
|
||
|
# Création de nos widgets
|
||
|
self.f.columnconfigure(1, weight=1)
|
||
|
self.f.columnconfigure(2, weight=1)
|
||
|
self.f.rowconfigure(4, weight=1)
|
||
|
|
||
|
self.Wenable = tk.Checkbutton(self.f, text="Enable cropping", command=self.toggle_enable)
|
||
|
self.Wenable.grid(row=0, column=0, columnspan=3)
|
||
|
if(self.enabled):
|
||
|
self.Wenable.select()
|
||
|
tk.Label(self.f, text="Lower Left bound (x and y):").grid(row=1, column=0)
|
||
|
tk.Label(self.f, text="Upper Right bound (x and y):").grid(row=2, column=0)
|
||
|
tk.Label(self.f, text="Bounds are given in fraction of page size (between 0 and 1).").grid(row=3, column=0, columnspan=3)
|
||
|
self.Wllx = tk.Entry(self.f, textvariable=self.llx)
|
||
|
self.Wllx.grid(row=1, column=1, sticky=tk.W+tk.E)
|
||
|
self.Wlly = tk.Entry(self.f, textvariable=self.lly)
|
||
|
self.Wlly.grid(row=1, column=2, sticky=tk.W+tk.E)
|
||
|
self.Wurx = tk.Entry(self.f, textvariable=self.urx)
|
||
|
self.Wurx.grid(row=2, column=1, sticky=tk.W+tk.E)
|
||
|
self.Wury = tk.Entry(self.f, textvariable=self.ury)
|
||
|
self.Wury.grid(row=2, column=2, sticky=tk.W+tk.E)
|
||
|
|
||
|
if(not self.enabled):
|
||
|
self.Wllx['state']='readonly'
|
||
|
self.Wlly['state']='readonly'
|
||
|
self.Wurx['state']='readonly'
|
||
|
self.Wury['state']='readonly'
|
||
|
|
||
|
tk.Button(self.f, text="Ok", command=self.ok).grid(row=5, column=2, sticky=tk.W+tk.E)
|
||
|
tk.Button(self.f, text="Close", command=self.close).grid(row=5, column=0)
|
||
|
|
||
|
def ok(self, *args):
|
||
|
"""
|
||
|
Save and quit
|
||
|
"""
|
||
|
if(self.enabled):
|
||
|
try:
|
||
|
llx = float(self.llx.get())
|
||
|
lly = float(self.lly.get())
|
||
|
urx = float(self.urx.get())
|
||
|
ury = float(self.ury.get())
|
||
|
except:
|
||
|
messagebox.showwarning(title="Cropping", message="You have to enter float only for x and y cropping limits !")
|
||
|
return
|
||
|
if(llx<0 or llx>1 or lly<0 or lly>1 or urx<0 or urx>1 or ury<0 or ury>1):
|
||
|
messagebox.showwarning(title="Cropping", message="Values have to be between 0 and 1 !")
|
||
|
return
|
||
|
if(llx>=urx or lly>=ury):
|
||
|
messagebox.showwarning(title="Cropping", message="Bounds not in correct order !")
|
||
|
return
|
||
|
self.fich.crop=[[llx,lly],[urx,ury]]
|
||
|
else:
|
||
|
self.fich.crop = None
|
||
|
self.close()
|
||
|
|
||
|
def close(self, *args):
|
||
|
self.quit()
|
||
|
|
||
|
def toggle_enable(self):
|
||
|
if(self.enabled):
|
||
|
self.enabled = False
|
||
|
self.Wenable.deselect()
|
||
|
self.llx.set('')
|
||
|
self.lly.set('')
|
||
|
self.urx.set('')
|
||
|
self.ury.set('')
|
||
|
self.Wllx['state']='readonly'
|
||
|
self.Wlly['state']='readonly'
|
||
|
self.Wurx['state']='readonly'
|
||
|
self.Wury['state']='readonly'
|
||
|
else:
|
||
|
self.enabled = True
|
||
|
self.Wenable.select()
|
||
|
self.Wllx['state']='normal'
|
||
|
self.Wlly['state']='normal'
|
||
|
self.Wurx['state']='normal'
|
||
|
self.Wury['state']='normal'
|