]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/printout.py
Add GetHDC back
[wxWidgets.git] / wxPython / wx / lib / printout.py
1 #----------------------------------------------------------------------------
2 # Name:         printout.py
3 # Purpose:      preview and printing class -> table/grid printing
4 #
5 # Author:       Lorne White (email: lorne.white@telusplanet.net)
6 #
7 # Created:
8 # Version       0.75
9 # Date:         May 15, 2002
10 # Licence:      wxWindows license
11 #----------------------------------------------------------------------------
12 # Release Notes
13
14 # fixed bug for string wider than print region
15 # add index to data list after parsing total pages for paging
16 #----------------------------------------------------------------------------
17 # 12/10/2003 - Jeff Grimmett (grimmtooth@softhome.net)
18 #
19 # o 2.5 compatability update.
20 #
21
22 import  copy
23 import  os
24 import  sys
25
26 import  wx
27
28 class PrintBase:
29     def SetPrintFont(self, font):      # set the DC font parameters
30         fattr = font["Attr"]
31         if fattr[0] == 1:
32             weight = wx.BOLD
33         else:
34             weight = wx.NORMAL
35
36         if fattr[1] == 1:
37             set_style = wx.ITALIC
38         else:
39             set_style = wx.NORMAL
40
41         underline = fattr[2]
42         fcolour = self.GetFontColour(font)
43         self.DC.SetTextForeground(fcolour)
44
45         setfont = wx.Font(font["Size"], wx.SWISS, set_style, weight, underline)
46         setfont.SetFaceName(font["Name"])
47         self.DC.SetFont(setfont)
48
49     def GetFontColour(self, font):
50         fcolour = font["Colour"]
51         return wx.Colour(fcolour[0], fcolour[1], fcolour[2])
52
53     def OutTextRegion(self, textout, txtdraw = True):
54         textlines = textout.split('\n')
55         y = copy.copy(self.y) + self.pt_space_before
56         for text in textlines:
57             remain = 'X'
58             while remain != "":
59                 vout, remain = self.SetFlow(text, self.region)
60                 if self.draw == True and txtdraw == True:
61                     test_out = self.TestFull(vout)
62                     if self.align == wx.ALIGN_LEFT:
63                         self.DC.DrawText(test_out, self.indent+self.pcell_left_margin, y)
64
65                     elif self.align == wx.ALIGN_CENTRE:
66                         diff = self.GetCellDiff(test_out, self.region)
67                         self.DC.DrawText(test_out, self.indent+diff/2, y)
68
69                     elif self.align == wx.ALIGN_RIGHT:
70                         diff = self.GetCellDiff(test_out, self.region)
71                         self.DC.DrawText(test_out, self.indent+diff, y)
72
73                     else:
74                         self.DC.DrawText(test_out, self.indent+self.pcell_left_margin, y)
75                 text = remain
76                 y = y + self.space
77         return y - self.space + self.pt_space_after
78
79     def GetCellDiff(self, text, width):      # get the remaining cell size for adjustment
80         w, h = self.DC.GetTextExtent(text)
81         diff = width - w
82         if diff < 0:
83             diff = 0
84         return diff
85
86     def TestFull(self, text_test):
87         w, h = self.DC.GetTextExtent(text_test)
88         if w > self.region:     # trouble fitting into cell
89             return self.SetChar(text_test, self.region)     # fit the text to the cell size
90         else:
91             return text_test
92
93     def SetFlow(self, ln_text, width):
94         width = width - self.pcell_right_margin
95         text = ""
96         split = ln_text.split()
97         if len(split) == 1:
98             return ln_text, ""
99
100         try:
101             w, h = self.DC.GetTextExtent(" " + split[0])
102             if w >= width:
103                 return ln_text, ""
104         except:
105             pass
106
107         cnt = 0
108         for word in split:
109             bword = " " + word  # blank + word
110             length = len(bword)
111
112             w, h = self.DC.GetTextExtent(text + bword)
113             if w < width:
114                 text = text + bword
115                 cnt = cnt + 1
116             else:
117                 remain = ' '.join(split[cnt:])
118                 text = text.strip()
119                 return text, remain
120
121         remain = ' '.join(split[cnt:])
122         vout = text.strip()
123         return vout, remain
124
125     def SetChar(self, ln_text, width):  # truncate string to fit into width
126         width = width - self.pcell_right_margin - self.pcell_left_margin
127         text = ""
128         for val in ln_text:
129             w, h = self.DC.GetTextExtent(text + val)
130             if w > width:
131                 text = text + ".."
132                 return text     # fitted text value
133             text = text + val
134         return text
135
136     def OutTextPageWidth(self, textout, y_out, align, indent, txtdraw = True):
137         textlines = textout.split('\n')
138         y = copy.copy(y_out)
139
140         pagew = self.parent.page_width * self.pwidth        # full page width
141         w, h = self.DC.GetTextExtent(textout)
142         y_line = h
143
144         for text in textlines:
145             remain = 'X'
146             while remain != "":
147                 vout, remain = self.SetFlow(text, pagew)
148                 if self.draw == True and txtdraw == True:
149                     test_out = vout
150                     if align == wx.ALIGN_LEFT:
151                         self.DC.DrawText(test_out, indent, y)
152
153                     elif align == wx.ALIGN_CENTRE:
154                         diff = self.GetCellDiff(test_out, pagew)
155                         self.DC.DrawText(test_out, indent+diff/2, y)
156
157                     elif align == wx.ALIGN_RIGHT:
158                         diff = self.GetCellDiff(test_out, pagew)
159                         self.DC.DrawText(test_out, indent+diff, y)
160
161                     else:
162                         self.DC.DrawText(test_out, indent, y_out)
163                 text = remain
164                 y = y + y_line
165         return y - y_line
166
167     def GetDate(self):
168         date, time = self.GetNow()
169         return date
170
171     def GetDateTime(self):
172         date, time = self.GetNow()
173         return date + ' ' + time
174
175     def GetNow(self):
176         full = str(wx.DateTime_Now())        # get the current date and time in print format
177         flds = full.split()
178         date = flds[0]
179         time = flds[1]
180         return date, time
181
182     def SetPreview(self, preview):
183         self.preview = preview
184
185     def SetPSize(self, width, height):
186         self.pwidth = width/self.scale
187         self.pheight = height/self.scale
188
189     def SetScale(self, scale):
190         self.scale = scale
191
192     def SetPTSize(self, width, height):
193         self.ptwidth = width
194         self.ptheight = height
195
196     def getWidth(self):
197         return self.sizew
198
199     def getHeight(self):
200         return self.sizeh
201
202
203 class PrintTableDraw(wx.ScrolledWindow, PrintBase):
204     def __init__(self, parent, DC, size):
205         self.parent = parent
206         self.DC = DC
207         self.scale = parent.scale
208         self.width = size[0]
209         self.height = size[1]
210         self.SetDefaults()
211
212     def SetDefaults(self):
213         self.page = 1
214         self.total_pages = None
215
216         self.page_width = self.parent.page_width
217         self.page_height = self.parent.page_height
218
219         self.left_margin = self.parent.left_margin
220         self.right_margin = self.parent.right_margin
221
222         self.top_margin  = self.parent.top_margin
223         self.bottom_margin = self.parent.bottom_margin
224         self.cell_left_margin = self.parent.cell_left_margin
225         self.cell_right_margin = self.parent.cell_right_margin
226
227         self.label_colour = self.parent.label_colour
228
229         self.row_line_colour = self.parent.row_line_colour
230         self.row_line_size = self.parent.row_line_size
231
232         self.row_def_line_colour = self.parent.row_def_line_colour
233         self.row_def_line_size = self.parent.row_def_line_size
234
235         self.column_line_colour = self.parent.column_line_colour
236         self.column_line_size = self.parent.column_line_size
237
238         self.column_def_line_size = self.parent.column_def_line_size
239         self.column_def_line_colour = self.parent.column_def_line_colour
240
241         self.text_font = self.parent.text_font
242
243         self.label_font = self.parent.label_font
244
245     def AdjustValues(self):
246         self.vertical_offset = self.pheight * self.parent.vertical_offset
247         self.horizontal_offset = self.pheight * self.parent.horizontal_offset
248
249         self.pcell_left_margin = self.pwidth * self.cell_left_margin
250         self.pcell_right_margin = self.pwidth * self.cell_right_margin
251         self.ptop_margin = self.pheight * self.top_margin
252         self.pbottom_margin = self.pheight * self.bottom_margin
253
254         self.pheader_margin = self.pheight * self.parent.header_margin
255         self.pfooter_margin = self.pheight * self.parent.footer_margin
256
257         self.cell_colour = self.parent.set_cell_colour
258         self.cell_text = self.parent.set_cell_text
259
260         self.column = []
261         self.column_align = []
262         self.column_bgcolour = []
263         self.column_txtcolour = []
264
265         set_column_align = self.parent.set_column_align
266         set_column_bgcolour = self.parent.set_column_bgcolour
267         set_column_txtcolour = self.parent.set_column_txtcolour
268
269         pos_x = self.left_margin * self.pwidth + self.horizontal_offset     # left margin
270         self.column.append(pos_x)
271
272         if self.set_column == []:
273             table_width = self.page_width - self.left_margin - self.right_margin
274             width = table_width/(len(self.label))
275             for val in self.label:
276                 column_width = width * self.pwidth
277                 pos_x = pos_x + column_width
278                 self.column.append(pos_x)   # position of each column
279         else:
280             for val in self.set_column:
281                 column_width = val * self.pwidth
282                 pos_x = pos_x + column_width
283                 self.column.append(pos_x)   # position of each column
284
285         if pos_x > self.page_width * self.pwidth:    # check if it fits in page
286             print "Warning, Too Wide for Page"
287             return
288
289         if self.label != []:
290             if len(self.column) -1 != len(self.label):
291                 print "Column Settings Incorrect", "\nColumn Value: " + str(self.column), "\nLabel Value: " + str(self.label)
292                 return
293
294         first_value = self.data[0]
295         column_total = len(first_value)
296         if column_total != len(self.column) -1:
297             print "Column Settings Incorrect", first_value, self.column
298             return
299
300         col = 0
301         for col in range(column_total):
302             try:
303                 align = set_column_align[col]       # check if custom column alignment
304             except:
305                 align = wx.ALIGN_LEFT
306             self.column_align.append(align)
307
308             try:
309                 colour = set_column_bgcolour[col]     # check if custom column background colour
310             except:
311                 colour = self.parent.column_colour
312             self.column_bgcolour.append(colour)
313
314             try:
315                 colour = set_column_txtcolour[col]     # check if custom column text colour
316             except:
317                 colour = self.GetFontColour(self.parent.text_font)
318
319             self.column_txtcolour.append(colour)
320
321             col = col + 1
322
323     def SetPointAdjust(self):
324         f = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL)     # setup using 10 point
325         self.DC.SetFont(f)
326         f.SetFaceName(self.text_font["Name"])
327         x, y = self.DC.GetTextExtent("W")
328
329         self.label_pt_space_before = self.parent.label_pt_adj_before * y/10        # extra spacing for label per point value
330         self.label_pt_space_after = self.parent.label_pt_adj_after * y/10
331
332         self.text_pt_space_before = self.parent.text_pt_adj_before * y/10        # extra spacing for row text per point value
333         self.text_pt_space_after = self.parent.text_pt_adj_after * y/10
334
335     def SetPage(self, page):
336         self.page = page
337
338     def SetColumns(self, col):
339         self.column = col
340
341     def OutCanvas(self):
342         self.AdjustValues()
343         self.SetPointAdjust()
344
345         self.y_start = self.ptop_margin + self.vertical_offset
346         self.y_end = self.parent.page_height * self.pheight - self.pbottom_margin + self.vertical_offset
347
348         self.SetPrintFont(self.label_font)
349
350         x, y = self.DC.GetTextExtent("W")
351         self.label_space = y
352
353         self.SetPrintFont(self.text_font)
354
355         x, y = self.DC.GetTextExtent("W")
356         self.space = y
357
358         if self.total_pages is None:
359             self.GetTotalPages()    # total pages for display/printing
360
361         self.data_cnt = self.page_index[self.page-1]
362
363         self.draw = True
364         self.PrintHeader()
365         self.PrintFooter()
366         self.OutPage()
367
368     def GetTotalPages(self):
369         self.data_cnt = 0
370         self.draw = False
371         self.page_index = [0]
372
373         cnt = 0
374         while 1:
375             test = self.OutPage()
376             self.page_index.append(self.data_cnt)
377             if  test == False:
378                 break
379             cnt = cnt + 1
380
381         self.total_pages = cnt + 1
382
383     def OutPage(self):
384         self.y = self.y_start
385         self.end_x = self.column[-1]
386
387         if self.data_cnt < len(self.data):  # if there data for display on the page
388             if self.label != []:        # check if header defined
389                 self.PrintLabel()
390         else:
391             return False
392
393         for val in self.data:
394             try:
395                 row_val = self.data[self.data_cnt]
396             except:
397                 self.FinishDraw()
398                 return False
399
400             max_y = self.PrintRow(row_val, False)       # test to see if row will fit in remaining space
401             test = max_y + self.space
402
403             if test > self.y_end:
404                 break
405
406             self.ColourRowCells(max_y-self.y+self.space)       # colour the row/column
407             max_y = self.PrintRow(row_val, True)      # row fits - print text
408             self.DrawGridLine()     # top line of cell
409             self.y = max_y + self.space
410
411             if self.y > self.y_end:
412                 break
413
414             self.data_cnt = self.data_cnt + 1
415
416         self.FinishDraw()
417
418         if self.data_cnt == len(self.data):    # last value in list
419             return False
420
421         return True
422
423
424     def PrintLabel(self):
425         self.pt_space_before = self.label_pt_space_before   # set the point spacing
426         self.pt_space_after = self.label_pt_space_after
427
428         self.LabelColorRow(self.label_colour)
429         self.SetPrintFont(self.label_font)
430
431         self.col = 0
432         max_y = 0
433         for vtxt in self.label:
434             self.region = self.column[self.col+1] - self.column[self.col]
435             self.indent = self.column[self.col]
436
437             self.align = wx.ALIGN_LEFT
438
439             max_out = self.OutTextRegion(vtxt, True)
440             if max_out > max_y:
441                 max_y = max_out
442             self.col = self.col + 1
443
444         self.DrawGridLine()     # top line of label
445         self.y = max_y + self.label_space
446
447     def PrintHeader(self):      # print the header array
448         if self.draw == False:
449             return
450
451         for val in self.parent.header:
452             self.SetPrintFont(val["Font"])
453
454             header_indent = val["Indent"] * self.pwidth
455             text = val["Text"]
456
457             htype = val["Type"]
458             if htype == "Date":
459                 addtext = self.GetDate()
460             elif htype == "Date & Time":
461                 addtext = self.GetDateTime()
462             else:
463                 addtext = ""
464
465             self.OutTextPageWidth(text+addtext, self.pheader_margin, val["Align"], header_indent, True)
466
467     def PrintFooter(self):      # print the header array
468         if self.draw == False:
469             return
470
471         footer_pos = self.parent.page_height * self.pheight - self.pfooter_margin + self.vertical_offset
472         for val in self.parent.footer:
473             self.SetPrintFont(val["Font"])
474
475             footer_indent = val["Indent"] * self.pwidth
476             text = val["Text"]
477
478             ftype = val["Type"]
479             if ftype == "Pageof":
480                 addtext = "Page " + str(self.page) + " of " + str(self.total_pages)
481             elif ftype == "Page":
482                 addtext = "Page " + str(self.page)
483             elif ftype == "Num":
484                 addtext = str(self.page)
485             elif ftype == "Date":
486                 addtext = self.GetDate()
487             elif ftype == "Date & Time":
488                 addtext = self.GetDateTime()
489             else:
490                 addtext = ""
491
492             self.OutTextPageWidth(text+addtext, footer_pos, val["Align"], footer_indent, True)
493
494
495     def LabelColorRow(self, colour):
496         brush = wx.Brush(colour, wx.SOLID)
497         self.DC.SetBrush(brush)
498         height = self.label_space + self.label_pt_space_before + self.label_pt_space_after
499         self.DC.DrawRectangle(self.column[0], self.y,
500                               self.end_x-self.column[0]+1, height)
501
502     def ColourRowCells(self, height):
503         if self.draw == False:
504             return
505
506         col = 0
507         for colour in self.column_bgcolour:
508             cellcolour = self.GetCellColour(self.data_cnt, col)
509             if cellcolour is not None:
510                 colour = cellcolour
511
512             brush = wx.Brush(colour, wx.SOLID)
513             self.DC.SetBrush(brush)
514             self.DC.SetPen(wx.Pen(wx.NamedColour('WHITE'), 0))
515
516             start_x = self.column[col]
517             width = self.column[col+1] - start_x + 2
518             self.DC.DrawRectangle(start_x, self.y, width, height)
519             col = col + 1
520
521     def PrintRow(self, row_val, draw = True, align = wx.ALIGN_LEFT):
522         self.SetPrintFont(self.text_font)
523
524         self.pt_space_before = self.text_pt_space_before   # set the point spacing
525         self.pt_space_after = self.text_pt_space_after
526
527         self.col = 0
528         max_y = 0
529         for vtxt in row_val:
530             self.region = self.column[self.col+1] - self.column[self.col]
531             self.indent = self.column[self.col]
532             self.align = self.column_align[self.col]
533
534             fcolour = self.column_txtcolour[self.col]       # set font colour
535             celltext = self.GetCellText(self.data_cnt, self.col)
536             if celltext is not None:
537                 fcolour = celltext      # override the column colour
538
539             self.DC.SetTextForeground(fcolour)
540
541             max_out = self.OutTextRegion(vtxt, draw)
542             if max_out > max_y:
543                 max_y = max_out
544             self.col = self.col + 1
545         return max_y
546
547     def GetCellColour(self, row, col):      # check if custom colour defined for the cell background
548         try:
549             set = self.cell_colour[row]
550         except:
551             return None
552         try:
553             colour = set[col]
554             return colour
555         except:
556             return None
557
558     def GetCellText(self, row, col):      # check if custom colour defined for the cell text
559         try:
560             set = self.cell_text[row]
561         except:
562             return None
563         try:
564             colour = set[col]
565             return colour
566         except:
567             return None
568
569     def FinishDraw(self):
570         self.DrawGridLine()     # draw last row line
571         self.DrawColumns()      # draw all vertical lines
572
573     def DrawGridLine(self):
574         if self.draw == True:
575             try:
576                 size = self.row_line_size[self.data_cnt]
577             except:
578                 size = self.row_def_line_size
579
580             try:
581                 colour = self.row_line_colour[self.data_cnt]
582             except:
583                 colour = self.row_def_line_colour
584
585             self.DC.SetPen(wx.Pen(colour, size))
586
587             y_out = self.y
588 #            y_out = self.y + self.pt_space_before + self.pt_space_after     # adjust for extra spacing
589             self.DC.DrawLine(self.column[0], y_out, self.end_x, y_out)
590
591     def DrawColumns(self):
592         if self.draw == True:
593             col = 0
594             for val in self.column:
595                 try:
596                     size = self.column_line_size[col]
597                 except:
598                     size = self.column_def_line_size
599
600                 try:
601                     colour = self.column_line_colour[col]
602                 except:
603                     colour = self.column_def_line_colour
604
605                 indent = val
606
607                 self.DC.SetPen(wx.Pen(colour, size))
608                 self.DC.DrawLine(indent, self.y_start, indent, self.y)
609                 col = col + 1
610
611     def DrawText(self):
612         self.DoRefresh()
613
614     def DoDrawing(self, DC):
615         size = DC.GetSize()
616         self.DC = DC
617
618         DC.BeginDrawing()
619         self.DrawText()
620         DC.EndDrawing()
621
622         self.sizew = DC.MaxY()
623         self.sizeh = DC.MaxX()
624
625
626 class PrintTable:
627     def __init__(self, parentFrame=None):
628         self.data = []
629         self.set_column = []
630         self.label = []
631         self.header = []
632         self.footer = []
633
634         self.set_column_align = {}
635         self.set_column_bgcolour = {}
636         self.set_column_txtcolour = {}
637         self.set_cell_colour = {}
638         self.set_cell_text = {}
639         self.column_line_size = {}
640         self.column_line_colour = {}
641         self.row_line_size = {}
642         self.row_line_colour = {}
643
644         self.parentFrame = parentFrame
645         self.SetPreviewSize()
646
647         self.printData = wx.PrintData()
648         self.scale = 1.0
649
650         self.SetParms()
651         self.SetColors()
652         self.SetFonts()
653         self.TextSpacing()
654
655         self.SetPrinterOffset()
656         self.SetHeaderValue()
657         self.SetFooterValue()
658         self.SetMargins()
659         self.SetPortrait()
660
661     def SetPreviewSize(self, position = wx.Point(0, 0), size="Full"):
662         if size == "Full":
663             r = wx.GetClientDisplayRect()
664             self.preview_frame_size = r.GetSize()
665             self.preview_frame_pos = r.GetPosition()
666         else:
667             self.preview_frame_size = size
668             self.preview_frame_pos = position
669
670     def SetPaperId(self, paper):
671         self.printData.SetPaperId(paper)
672
673     def SetOrientation(self, orient):
674         self.printData.SetOrientation(orient)
675
676     def SetColors(self):
677         self.row_def_line_colour = wx.NamedColour('BLACK')
678         self.row_def_line_size = 1
679
680         self.column_def_line_colour = wx.NamedColour('BLACK')
681         self.column_def_line_size = 1
682         self.column_colour = wx.NamedColour('WHITE')
683
684         self.label_colour = wx.NamedColour('LIGHT GREY')
685
686     def SetFonts(self):
687         self.label_font = { "Name": self.default_font_name, "Size": 12, "Colour": [0, 0, 0], "Attr": [0, 0, 0] }
688         self.text_font = { "Name": self.default_font_name, "Size": 10, "Colour": [0, 0, 0], "Attr": [0, 0, 0] }
689
690     def TextSpacing(self):
691         self.label_pt_adj_before = 0     # point adjustment before and after the label text
692         self.label_pt_adj_after = 0
693
694         self.text_pt_adj_before = 0     # point adjustment before and after the row text
695         self.text_pt_adj_after = 0
696
697     def SetLabelSpacing(self, before, after):        # method to set the label space adjustment
698         self.label_pt_adj_before = before
699         self.label_pt_adj_after = after
700
701     def SetRowSpacing(self, before, after):         # method to set the row space adjustment
702         self.text_pt_adj_before = before
703         self.text_pt_adj_after = after
704
705     def SetPrinterOffset(self):        # offset to adjust for printer
706         self.vertical_offset = -0.1
707         self.horizontal_offset = -0.1
708
709     def SetHeaderValue(self):
710         self.header_margin = 0.25
711         self.header_font = { "Name": self.default_font_name, "Size": 11, "Colour": [0, 0, 0], "Attr": [0, 0, 0] }
712         self.header_align = wx.ALIGN_CENTRE
713         self.header_indent = 0
714         self.header_type = "Text"
715
716     def SetFooterValue(self):
717         self.footer_margin = 0.7
718         self.footer_font = { "Name": self.default_font_name, "Size": 11, "Colour": [0, 0, 0], "Attr": [0, 0, 0] }
719         self.footer_align = wx.ALIGN_CENTRE
720         self.footer_indent = 0
721         self.footer_type = "Pageof"
722
723     def SetMargins(self):
724         self.left_margin = 1.0
725         self.right_margin = 1.0     # only used if no column sizes
726
727         self.top_margin  = 0.8
728         self.bottom_margin = 1.0
729         self.cell_left_margin = 0.1
730         self.cell_right_margin = 0.1
731
732     def SetPortrait(self):
733         self.printData.SetPaperId(wx.PAPER_LETTER)
734         self.printData.SetOrientation(wx.PORTRAIT)
735         self.page_width = 8.5
736         self.page_height = 11.0
737
738     def SetLandscape(self):
739         self.printData.SetOrientation(wx.LANDSCAPE)
740         self.page_width = 11.0
741         self.page_height = 8.5
742
743     def SetParms(self):
744         self.ymax = 1
745         self.xmax = 1
746         self.page = 1
747         self.total_pg = 100
748
749         self.preview = None
750         self.page = 0
751
752         self.default_font_name = "Arial"
753         self.default_font = { "Name": self.default_font_name, "Size": 10, "Colour": [0, 0, 0], "Attr": [0, 0, 0] }
754
755     def SetColAlignment(self, col, align=wx.ALIGN_LEFT):
756         self.set_column_align[col] = align
757
758     def SetColBackgroundColour(self, col, colour):
759         self.set_column_bgcolour[col] = colour
760
761     def SetColTextColour(self, col, colour):
762         self.set_column_txtcolour[col] = colour
763
764     def SetCellColour(self, row, col, colour):      # cell background colour
765         try:
766             set = self.set_cell_colour[row]     # test if row already exists
767             try:
768                 set[col] = colour       # test if column already exists
769             except:
770                 set = { col: colour }       # create the column value
771         except:
772             set = { col: colour }           # create the column value
773
774         self.set_cell_colour[row] = set    # create dictionary item for colour settings
775
776     def SetCellText(self, row, col, colour):        # font colour for custom cells
777         try:
778             set = self.set_cell_text[row]     # test if row already exists
779             try:
780                 set[col] = colour       # test if column already exists
781             except:
782                 set = { col: colour }       # create the column value
783         except:
784             set = { col: colour }           # create the column value
785
786         self.set_cell_text[row] = set    # create dictionary item for colour settings
787
788     def SetColumnLineSize(self, col, size):      # column line size
789         self.column_line_size[col] = size    # create dictionary item for column line settings
790
791     def SetColumnLineColour(self, col, colour):
792         self.column_line_colour[col] = colour
793
794     def SetRowLineSize(self, row, size):
795         self.row_line_size[row] = size
796
797     def SetRowLineColour(self, row, colour):
798         self.row_line_colour[row] = colour
799
800     def GetColour(self, colour):        # returns colours based from wxColour value
801         red = colour.Red()
802         blue = colour.Blue()
803         green = colour.Green()
804         return [red, green, blue ]
805
806     def SetHeader(self, text = "", type = "Text", font=None, align = None, indent = None, colour = None, size = None):
807         set = { "Text": text }
808
809         if font is None:
810             set["Font"] = copy.copy(self.default_font)
811         else:
812             set["Font"] = font
813
814         if colour is not None:
815             setfont = set["Font"]
816             setfont["Colour"] = self.GetColour(colour)
817
818         if size is not None:
819             setfont = set["Font"]
820             setfont["Size"] = size
821
822         if align is None:
823             set["Align"] = self.header_align
824         else:
825             set["Align"] = align
826
827         if indent is None:
828             set["Indent"] = self.header_indent
829         else:
830             set["Indent"] = indent
831
832         if type is None:
833             set["Type"] = self.header_type
834         else:
835             set["Type"] = type
836
837         self.header.append(set)
838
839     def SetFooter(self, text = "", type = None, font=None, align = None, indent = None, colour = None, size = None):
840         set = { "Text": text }
841
842         if font is None:
843             set["Font"] = copy.copy(self.default_font)
844         else:
845             set["Font"] = font
846
847         if colour is not None:
848             setfont = set["Font"]
849             setfont["Colour"] = self.GetColour(colour)
850
851         if size is not None:
852             setfont = set["Font"]
853             setfont["Size"] = size
854
855         if align is None:
856             set["Align"] = self.footer_align
857         else:
858             set["Align"] = align
859
860         if indent is None:
861             set["Indent"] = self.footer_indent
862         else:
863             set["Indent"] = indent
864
865         if type is None:
866             set["Type"] = self.footer_type
867         else:
868             set["Type"] = type
869
870         self.footer.append(set)
871
872     def Preview(self):
873         printout = SetPrintout(self)
874         printout2 = SetPrintout(self)
875         self.preview = wx.PrintPreview(printout, printout2, self.printData)
876         if not self.preview.Ok():
877             wxMessageBox("There was a problem printing!", "Printing", wx.OK)
878             return
879
880         self.preview.SetZoom(60)        # initial zoom value
881
882         frame = wx.PreviewFrame(self.preview, self.parentFrame, "Print preview")
883
884         frame.Initialize()
885         if self.parentFrame:
886             frame.SetPosition(self.preview_frame_pos)
887             frame.SetSize(self.preview_frame_size)
888         frame.Show(True)
889
890     def Print(self):
891         pdd = wx.PrintDialogData()
892         pdd.SetPrintData(self.printData)
893         printer = wx.Printer(pdd)
894         printout = SetPrintout(self)
895         if not printer.Print(self.parentFrame, printout):
896             wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK)
897         else:
898             self.printData = printer.GetPrintDialogData().GetPrintData()
899         printout.Destroy()
900
901     def DoDrawing(self, DC):
902         size = DC.GetSize()
903         DC.BeginDrawing()
904
905         table = PrintTableDraw(self, DC, size)
906         table.data = self.data
907         table.set_column = self.set_column
908         table.label = self.label
909         table.SetPage(self.page)
910
911         if self.preview is None:
912             table.SetPSize(size[0]/self.page_width, size[1]/self.page_height)
913             table.SetPTSize(size[0], size[1])
914             table.SetPreview(False)
915         else:
916             if self.preview == 1:
917                 table.scale = self.scale
918                 table.SetPSize(size[0]/self.page_width, size[1]/self.page_height)
919             else:
920                 table.SetPSize(self.pwidth, self.pheight)
921
922             table.SetPTSize(self.ptwidth, self.ptheight)
923             table.SetPreview(self.preview)
924
925         table.OutCanvas()
926         self.page_total = table.total_pages     # total display pages
927
928         DC.EndDrawing()
929
930         self.ymax = DC.MaxY()
931         self.xmax = DC.MaxX()
932
933         self.sizeh = size[0]
934         self.sizew = size[1]
935
936     def GetTotalPages(self):
937         self.page_total = 100
938         return self.page_total
939
940     def HasPage(self, page):
941         if page <= self.page_total:
942             return True
943         else:
944             return False
945
946     def SetPage(self, page):
947         self.page = page
948
949     def SetPageSize(self, width, height):
950         self.pwidth, self.pheight = width, height
951
952     def SetTotalSize(self, width, height):
953         self.ptwidth, self.ptheight = width, height
954
955     def SetPreview(self, preview, scale):
956         self.preview = preview
957         self.scale = scale
958
959     def SetTotalSize(self, width, height):
960         self.ptwidth = width
961         self.ptheight = height
962
963 class PrintGrid:
964     def __init__(self, parent, grid, format = [], total_col = None, total_row = None):
965         if total_row is None:
966             total_row = grid.GetNumberRows()
967         if total_col is None:
968             total_col = grid.GetNumberCols()
969
970         self.total_row = total_row
971         self.total_col = total_col
972         self.grid = grid
973
974         data = []
975         for row in range(total_row):
976             row_val = []
977             value = grid.GetRowLabelValue(row)
978             row_val.append(value)
979
980             for col in range(total_col):
981                 value = grid.GetCellValue(row, col)
982                 row_val.append(value)
983             data.append(row_val)
984
985         label = [""]
986         for col in range(total_col):
987             value = grid.GetColLabelValue(col)
988             label.append(value)
989
990         self.table = PrintTable(parent)
991         self.table.cell_left_margin = 0.0
992         self.table.cell_right_margin = 0.0
993
994         self.table.label = label
995         self.table.set_column = format
996         self.table.data = data
997
998     def GetTable(self):
999         return self.table
1000
1001     def SetAttributes(self):
1002         for row in range(self.total_row):
1003             for col in range(self.total_col):
1004                 colour = self.grid.GetCellTextColour(row, col-1)
1005                 self.table.SetCellText(row, col, colour)
1006
1007                 colour = self.grid.GetCellBackgroundColour(row, col-1)
1008                 self.table.SetCellColour(row, col, colour)
1009
1010     def Preview(self):
1011         self.table.Preview()
1012
1013     def Print(self):
1014         self.table.Print()
1015
1016
1017 class SetPrintout(wx.Printout):
1018     def __init__(self, canvas):
1019         wx.Printout.__init__(self)
1020         self.canvas = canvas
1021         self.end_pg = 1000
1022
1023     def OnBeginDocument(self, start, end):
1024         return self.base_OnBeginDocument(start, end)
1025
1026     def OnEndDocument(self):
1027         self.base_OnEndDocument()
1028
1029     def HasPage(self, page):
1030         try:
1031             end = self.canvas.HasPage(page)
1032             return end
1033         except:
1034             return True
1035
1036     def GetPageInfo(self):
1037         try:
1038             self.end_pg = self.canvas.GetTotalPages()
1039         except:
1040             pass
1041
1042         end_pg = self.end_pg
1043         str_pg = 1
1044         return (str_pg, end_pg, str_pg, end_pg)
1045
1046     def OnPreparePrinting(self):
1047         self.base_OnPreparePrinting()
1048
1049     def OnBeginPrinting(self):
1050         dc = self.GetDC()
1051
1052         self.preview = self.IsPreview()
1053         if (self.preview):
1054             self.pixelsPerInch = self.GetPPIScreen()
1055         else:
1056             self.pixelsPerInch = self.GetPPIPrinter()
1057
1058         (w, h) = dc.GetSize()
1059         scaleX = float(w) / 1000
1060         scaleY = float(h) / 1000
1061         self.printUserScale = min(scaleX, scaleY)
1062
1063         self.base_OnBeginPrinting()
1064
1065     def GetSize(self):
1066         self.psizew, self.psizeh = self.GetPPIPrinter()
1067         return self.psizew, self.psizeh
1068
1069     def GetTotalSize(self):
1070         self.ptsizew, self.ptsizeh = self.GetPageSizePixels()
1071         return self.ptsizew, self.ptsizeh
1072
1073     def OnPrintPage(self, page):
1074         dc = self.GetDC()
1075         (w, h) = dc.GetSize()
1076         scaleX = float(w) / 1000
1077         scaleY = float(h) / 1000
1078         self.printUserScale = min(scaleX, scaleY)
1079         dc.SetUserScale(self.printUserScale, self.printUserScale)
1080
1081         self.preview = self.IsPreview()
1082
1083         self.canvas.SetPreview(self.preview, self.printUserScale)
1084         self.canvas.SetPage(page)
1085
1086         self.ptsizew, self.ptsizeh = self.GetPageSizePixels()
1087         self.canvas.SetTotalSize(self.ptsizew, self.ptsizeh)
1088
1089         self.psizew, self.psizeh = self.GetPPIPrinter()
1090         self.canvas.SetPageSize(self.psizew, self.psizeh)
1091
1092         self.canvas.DoDrawing(dc)
1093         return True
1094
1095
1096
1097
1098
1099