Files
foundations-of-pygtk-develo…/More_Widgets/GtkPrintOperation.py
2019-01-02 14:53:58 -05:00

142 lines
5.1 KiB
Python

#!/usr/bin/python3
import sys
import math
from os.path import expanduser
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('PangoCairo', '1.0')
from gi.repository import Gtk, cairo, Pango, PangoCairo
class Widgets:
def __init__(self):
self.window = None
self.chooser = None
self.data = None
self.settings = Gtk.PrintSettings.new()
class PrintData:
def __init__(self):
self.filename = None
self.fontsize = None
self.lines_per_page = None
self.lines = None
self.total_lines = None
self.total_pages = None
class AppWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.HEADER_HEIGHT = 20.0
self.HEADER_GAP = 8.5
w = Widgets()
w.window = self
self.set_border_width(10)
w.chooser = Gtk.FileChooserButton.new ("Select a File",
Gtk.FileChooserAction.OPEN)
w.chooser.set_current_folder(expanduser("~"))
print = Gtk.Button.new_with_label("Print")
print.connect("clicked", self.print_file, w)
hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 5)
hbox.pack_start(w.chooser, False, False, 0)
hbox.pack_start(print, False, False, 0)
self.add(hbox)
def print_file(self, button, w):
filename = w.chooser.get_filename()
if filename == None:
return
operation = Gtk.PrintOperation.new()
if w.settings != None:
operation.set_print_settings(w.settings)
w.data = PrintData()
w.data.filename = filename
w.data.font_size = 10.0
operation.connect("begin_print", self.begin_print, w)
operation.connect("draw_page", self.draw_page, w)
operation.connect("end_print", self.end_print, w)
res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG,
w.window)
if res == Gtk.PrintOperationResult.APPLY:
if w.settings != None:
w.settings = None
settings = operation.get_print_settings()
elif res == Gtk.PrintOperationResult.ERROR:
dialog = Gtk.MessageDialog.new(w.window,
Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.ERROR,
Gtk.ButtonsType.S_CLOSE,
"Print operation error.")
dialog.run()
dialog.destroy()
def begin_print(self, operation, context, w):
w.data.lines = []
f = open(w.data.filename)
for line in f:
w.data.lines.append(line)
f.close()
w.data.total_lines = len(w.data.lines)
height = context.get_height() - self.HEADER_HEIGHT - self.HEADER_GAP
w.data.lines_per_page = math.floor(height / (w.data.font_size + 3))
w.data.total_pages = (w.data.total_lines - 1) / w.data.lines_per_page + 1
operation.set_n_pages(w.data.total_pages)
def draw_page(self, operation, context, page_nr, w):
cr = context.get_cairo_context()
width = context.get_width()
layout = context.create_pango_layout()
desc = Pango.font_description_from_string("Monospace")
desc.set_size(w.data.font_size * Pango.SCALE)
layout.set_font_description(desc)
layout.set_text(w.data.filename, -1)
layout.set_width(-1)
layout.set_alignment(Pango.Alignment.LEFT)
(width, height) = layout.get_size()
text_height = height / Pango.SCALE
cr.move_to(0, (self.HEADER_HEIGHT - text_height) / 2)
PangoCairo.show_layout(cr, layout)
page_str = "%d of %d" % (page_nr + 1, w.data.total_pages)
layout.set_text(page_str, -1)
(width, height) = layout.get_size()
layout.set_alignment(Pango.Alignment.RIGHT)
cr.move_to(width - (width / Pango.SCALE),
(self.HEADER_HEIGHT - text_height) / 2)
PangoCairo.show_layout(cr, layout)
cr.move_to(0, self.HEADER_HEIGHT + self.HEADER_GAP)
line = page_nr * w.data.lines_per_page
#for (i = 0; i < w.data.lines_per_page && line < w.data.total_lines; i++)
i = 0
while i < w.data.lines_per_page and line < w.data.total_lines:
layout.set_text(w.data.lines[line], -1)
PangoCairo.show_layout(cr, layout)
cr.rel_move_to(0, w.data.font_size + 3)
line += 1
i += 1
def end_print(self, operation, context, w):
w.data.lines = None
w.data = None
class Application(Gtk.Application):
def __init__(self, *args, **kwargs):
super().__init__(*args, application_id="org.example.myapp",
**kwargs)
self.window = None
def do_activate(self):
if not self.window:
self.window = AppWindow(application=self,
title="Calendar")
self.window.show_all()
self.window.present()
if __name__ == "__main__":
app = Application()
app.run(sys.argv)