From b0991112183dda12b93027f256d244538adb3f39 Mon Sep 17 00:00:00 2001 From: "Christian T. Jacobs" Date: Wed, 28 Jun 2017 20:23:31 +0100 Subject: [PATCH] Print logs on a landscape page. Also improved the page layout. --- CHANGELOG.md | 1 + pyqso/logbook.py | 2 +- pyqso/printer.py | 52 ++++++++++++++++++++++++++++++------------- tests/test_printer.py | 2 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66582b1..ad8336f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Moved all unit tests to a dedicated tests directory. - Duplicate QSOs are now defined as having the same CALL, QSO_DATE and TIME_ON values. FREQ and MODE are no longer considered. - Improved the runtime performance of duplicate QSO removal. +- Logs are now printed on a landscape page so that more QSO details can be included. The page layout has been improved. ### Fixed - Any characters in the DX cluster server's reponse that cannot be decoded are now replaced with a replacement marker in the DX cluster frame. diff --git a/pyqso/logbook.py b/pyqso/logbook.py index ac94e72..24c682d 100644 --- a/pyqso/logbook.py +++ b/pyqso/logbook.py @@ -738,7 +738,7 @@ class Logbook: records = log.records if(records is not None): printer = Printer(self.application) - printer.print_records(records) + printer.print_records(records, title="Log: %s" % log.name) else: error(parent=self.application.window, message="Could not retrieve the records from the SQL database. No records have been printed.") return diff --git a/pyqso/printer.py b/pyqso/printer.py index 578bbc8..913e153 100644 --- a/pyqso/printer.py +++ b/pyqso/printer.py @@ -18,6 +18,8 @@ # along with PyQSO. If not, see . from gi.repository import Gtk, Pango, PangoCairo +import logging + from pyqso.auxiliary_dialogs import error @@ -35,7 +37,9 @@ class Printer(object): self.action = Gtk.PrintOperationAction.PRINT_DIALOG self.operation = Gtk.PrintOperation() - self.operation.set_default_page_setup(Gtk.PageSetup()) + ps = Gtk.PageSetup() + ps.set_orientation(Gtk.PageOrientation.LANDSCAPE) + self.operation.set_default_page_setup(ps) self.operation.set_unit(Gtk.Unit.MM) self.operation.connect("begin_print", self.begin_print) @@ -43,16 +47,27 @@ class Printer(object): return - def print_records(self, records): + def print_records(self, records, title=None): """ Perform the print operation. :arg dict records: The records to be printed. + :arg str title: Optional title for the document. Default is None. + :returns: The result of the print operation. + :rtype: Gtk.PrintOperationResult """ + # Add the title, if given. + if(title): + self.text_to_print = title + "\n\n" + else: + self.text_to_print = "" + # Assemble the header and records into one string. - self.text_to_print = "Callsign\t---\tDate\t---\tTime\t---\tFrequency\t---\tMode\n" + line_format = "%-5s\t%-15s\t%-8s\t%-6s\t%-15s\t%-12s\t%-8s\t%-8s\n" + self.text_to_print += line_format % ("Index", "Callsign", "Date", "Time", "Frequency", "Mode", "RST Sent", "RST Rcvd") + self.text_to_print += line_format % ("-----", "--------", "----", "----", "---------", "----", "--------", "--------") for r in records: - self.text_to_print += str(r["CALL"]) + "\t---\t" + str(r["QSO_DATE"]) + "\t---\t" + str(r["TIME_ON"]) + "\t---\t" + str(r["FREQ"]) + "\t---\t" + str(r["MODE"]) + "\n" + self.text_to_print += line_format % (str(r["id"]), str(r["CALL"]), str(r["QSO_DATE"]), str(r["TIME_ON"]), str(r["FREQ"]), str(r["MODE"]), str(r["RST_SENT"]), str(r["RST_RCVD"])) result = self.operation.run(self.action, parent=self.application.window) if(result == Gtk.PrintOperationResult.ERROR): @@ -66,24 +81,26 @@ class Printer(object): :arg Gtk.PrintOperation operation: The printing API. :arg Gtk.PrintContext context: Used to draw/render the pages to print. """ - width = context.get_width() - height = context.get_height() + width = context.get_width() # Measured in pixels. + height = context.get_height() # Measured in pixels. layout = context.create_pango_layout() - layout.set_font_description(Pango.FontDescription("normal 10")) + layout.set_font_description(Pango.FontDescription("monospace expanded 10")) layout.set_width(int(width*Pango.SCALE)) layout.set_text(self.text_to_print, -1) - number_of_pages = 0 + number_of_pages = 1 page_height = 0 for line in range(0, layout.get_line_count()): layout_line = layout.get_line(line) - ink_rectangle, logical_rectangle = layout_line.get_extents() - self.line_height = logical_rectangle.height/1024.0 + 3 + ink_rectangle, logical_rectangle = layout_line.get_pixel_extents() + self.line_height = logical_rectangle.height + 3.0 page_height += self.line_height - if(page_height + self.line_height > height): + if((page_height + 2*self.line_height) >= height): + # Go on to the next page. number_of_pages += 1 - page_height = self.line_height - operation.set_n_pages(number_of_pages + 1) + page_height = 0.0 + operation.set_n_pages(number_of_pages) + logging.debug("Printing %d pages..." % number_of_pages) self.text_to_print = self.text_to_print.split("\n") return @@ -97,16 +114,19 @@ class Printer(object): cr = context.get_cairo_context() cr.set_source_rgb(0, 0, 0) layout = context.create_pango_layout() + layout.set_font_description(Pango.FontDescription("monospace expanded 10")) + layout.set_width(int(context.get_width()*Pango.SCALE)) - current_line_number = 0 + current_line_number = 1 for line in self.text_to_print: layout.set_text(line, -1) cr.move_to(5, current_line_number*self.line_height) PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout) current_line_number += 1 - if(current_line_number*self.line_height > context.get_height()): - for j in range(0, current_line_number): + if((current_line_number+1)*self.line_height >= context.get_height()): + for j in range(0, current_line_number-1): self.text_to_print.pop(0) # Remove what has been printed already before draw_page is called again break + return diff --git a/tests/test_printer.py b/tests/test_printer.py index 82358d5..68a09ef 100644 --- a/tests/test_printer.py +++ b/tests/test_printer.py @@ -42,7 +42,7 @@ class TestPrinter(unittest.TestCase): self.printer.action = Gtk.PrintOperationAction.EXPORT pdf = "Printer.test_print_records.pdf" self.printer.operation.set_export_filename(pdf) - records = [{"CALL": "MYCALL", "QSO_DATE": "24062017", "TIME_ON": "1519", "FREQ": "145.550", "MODE": "FM"}] + records = [{"id": 1, "CALL": "MYCALL", "QSO_DATE": "24062017", "TIME_ON": "1519", "FREQ": "145.550", "MODE": "FM", "RST_SENT": "59", "RST_RCVD": "57"}] result = self.printer.print_records(records) assert(result != Gtk.PrintOperationResult.ERROR) assert(result == Gtk.PrintOperationResult.APPLY)