Add a super-basic printing implementation

This is not something I have ever wanted, but it has been requested
plenty of times. Since wx makes this easy, this adds a super bare-
bones implementation that seems to work for me, which I think is
probably worthwhile. It doesn't handle multiple pages super elegantly,
and probably needs to have a "print selection" option, but it works.

Related to one of chirp's oldest bugs: #249
This commit is contained in:
Dan Smith 2022-12-16 17:06:48 -08:00 committed by Dan Smith
parent 72eaf70333
commit 96e25b351a
5 changed files with 118 additions and 1 deletions

View file

@ -468,6 +468,9 @@ class ChirpMain(wx.Frame):
file_menu.Append(wx.MenuItem(file_menu, wx.ID_SEPARATOR))
print_item = file_menu.Append(wx.ID_PRINT)
self.Bind(wx.EVT_MENU, self._menu_print, print_item)
close_item = file_menu.Append(wx.ID_CLOSE)
close_item.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL, ord('W')))
self.Bind(wx.EVT_MENU, self._menu_close, close_item)
@ -647,6 +650,12 @@ class ChirpMain(wx.Frame):
return menu_bar
def _menu_print(self, event):
from chirp.wxui import printing
p = printing.MemoryPrinter(self, self.current_editorset.radio,
self.current_editorset.current_editor)
p.print(self.current_editorset.current_editor.get_selected_memories())
def make_toolbar(self):
tb = self.CreateToolBar()
@ -764,6 +773,7 @@ class ChirpMain(wx.Frame):
(self._goto_item, can_goto),
(self._find_next_item, can_goto),
(wx.ID_FIND, can_goto),
(wx.ID_PRINT, can_goto),
(self._export_menu_item, can_close),
]
for ident, enabled in items:

View file

@ -1023,6 +1023,9 @@ class ChirpMemEdit(common.ChirpEditor, common.ChirpSyncEditor):
r.set_memory(self._memory_cache[row])
r.save(filename)
def get_selected_memories(self):
return [self.row2mem(r) for r in self._grid.GetSelectedRows()]
class ChirpLiveMemEdit(ChirpMemEdit, common.ChirpAsyncEditor):
pass

102
chirp/wxui/printing.py Normal file
View file

@ -0,0 +1,102 @@
# Copyright 2022 Dan Smith <chirp@f.danplanet.com>
#
# 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 <http://www.gnu.org/licenses/>.
import wx.html
import yattag
from chirp.wxui import common
from chirp.wxui import report
class MemoryPrinter(wx.html.HtmlEasyPrinting):
def __init__(self, parent, radio, memedit):
super().__init__()
self._radio = radio
self._features = radio.get_features()
self._col_defs = memedit._col_defs
# Set some default printer and page options.
self.GetPrintData().SetPaperId(wx.PAPER_LETTER) # wx.PAPER_A4
self.GetPrintData().SetOrientation(wx.LANDSCAPE) # wx.PORTRAIT
# Black and white printing if False.
self.GetPrintData().SetColour(False)
self.GetPageSetupData().SetMarginTopLeft((0, 5))
self.GetPageSetupData().SetMarginBottomRight((10, 10))
self.SetFonts('Sans', 'Courier', (8,) * 7)
def _memory(self, doc, mem):
tag = doc.tag
with tag('td'):
with tag('tt'):
doc.text(mem.number)
for col_def in self._col_defs:
if not col_def.valid:
continue
with tag('td'):
with tag('tt'):
doc.text(col_def.render_value(mem))
def _memory_table(self, doc, only_memories):
tag = doc.tag
lo, hi = self._features.memory_bounds
row = 0
# This is arbitrary, unsure if it will work on all platforms
# or not
ROWS_PER_PAGE = 35
memories = []
for i in range(lo, hi + 1):
mem = self._radio.get_memory(i)
if not mem.empty:
memories.append(mem)
for i in range(0, len(memories), ROWS_PER_PAGE):
with tag('div', ('style', 'page-break-before:always')):
pass
with tag('table', ('border', '1'), ('width', '100%'),
('cellspacing', '0')):
with tag('tr'):
with tag('th'):
doc.text('#')
for col_def in self._col_defs:
if not col_def.valid:
continue
with tag('th'):
doc.text(col_def.label)
for row in range(i, i + ROWS_PER_PAGE):
try:
mem = memories[row]
except IndexError:
continue
if (only_memories and mem.number not in only_memories):
continue
with tag('tr'):
try:
self._memory(doc, mem)
except IndexError:
pass
@common.error_proof()
def print(self, only_memories=None):
report.report_model(self._radio, 'print')
if only_memories and len(only_memories) == 1:
# Only print selection if there is more than one row selected
only_memories = None
doc, tag, text = yattag.Doc().tagtext()
with tag('html'):
with tag('body'):
self._memory_table(doc, only_memories)
return self.PreviewText(doc.getvalue())

View file

@ -7,3 +7,4 @@ requests
pywin32; platform_system=="Windows"
suds
importlib-resources;python_version<"3.10"
yattag

View file

@ -15,7 +15,8 @@ setup(name='chirp',
'pyserial',
'six',
'future',
'importlib-resources;python_version<"3.10"'
'importlib-resources;python_version<"3.10"',
'yattag',
],
extras_require={
'wx': ['wxPython'],