PLCOpenEditor.py
changeset 213 4931959ea256
parent 212 e36ba4f15fc8
child 217 ddb5b2e499e2
--- a/PLCOpenEditor.py	Wed Jun 04 17:48:26 2008 +0200
+++ b/PLCOpenEditor.py	Mon Jun 23 18:48:49 2008 +0200
@@ -221,6 +221,13 @@
         AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE,
               kind=wx.ITEM_NORMAL, text=u'Generate Program\tCTRL+G')
         parent.AppendSeparator()
+        AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
+              kind=wx.ITEM_NORMAL, text=u'Page Setup')
+        AppendMenu(parent, help='', id=wx.ID_PREVIEW,
+              kind=wx.ITEM_NORMAL, text=u'Preview')
+        AppendMenu(parent, help='', id=wx.ID_PRINT,
+              kind=wx.ITEM_NORMAL, text=u'Print')
+        parent.AppendSeparator()
         AppendMenu(parent, help='', id=wx.ID_PROPERTIES,
               kind=wx.ITEM_NORMAL, text=u'Properties')
         parent.AppendSeparator()
@@ -234,6 +241,9 @@
         self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS)
         self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu,
               id=ID_PLCOPENEDITORFILEMENUGENERATE)
+        self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
+        self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
+        self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
         self.Bind(wx.EVT_MENU, self.OnPropertiesMenu, id=wx.ID_PROPERTIES)
         self.Bind(wx.EVT_MENU, self.OnQuitMenu, id=wx.ID_EXIT)
     
@@ -477,6 +487,13 @@
         self.DrawingMode = FREEDRAWING_MODE
         #self.DrawingMode = DRIVENDRAWING_MODE
         
+        self.PrintData = wx.PrintData()
+        self.PrintData.SetPaperId(wx.PAPER_A4)
+        self.PrintData.SetPrintMode(wx.PRINT_MODE_PRINTER)
+        self.PageSetupData = wx.PageSetupDialogData(self.PrintData)
+        self.PageSetupData.SetMarginTopLeft(wx.Point(10, 15))
+        self.PageSetupData.SetMarginBottomRight(wx.Point(10, 20))
+        
         if not self.ModeSolo or fileOpen is not None:
             self.RefreshProjectTree()
         
@@ -652,14 +669,28 @@
     def RefreshFileMenu(self):
         if self.FileMenu:
             if self.Controler.HasOpenedProject():
+                selected = self.GetPageSelection()
+                if selected >= 0:
+                    graphic_viewer = isinstance(self.GetPage(selected), Viewer)
+                else:
+                    graphic_viewer = False
                 if self.GetPageCount() > 0:
                     self.FileMenu.Enable(wx.ID_CLOSE, True)
+                    if graphic_viewer:
+                        self.FileMenu.Enable(wx.ID_PREVIEW, True)
+                        self.FileMenu.Enable(wx.ID_PRINT, True)
+                    else:
+                        self.FileMenu.Enable(wx.ID_PREVIEW, False)
+                        self.FileMenu.Enable(wx.ID_PRINT, False)
                 else:
                     self.FileMenu.Enable(wx.ID_CLOSE, False)
+                    self.FileMenu.Enable(wx.ID_PREVIEW, False)
+                    self.FileMenu.Enable(wx.ID_PRINT, False)
                 self.FileMenu.Enable(wx.ID_CLOSE_ALL, True)
                 self.FileMenu.Enable(wx.ID_SAVE, True)
                 self.FileMenu.Enable(wx.ID_SAVEAS, True)
                 self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True)
+                self.FileMenu.Enable(wx.ID_PAGE_SETUP, True)
                 self.FileMenu.Enable(wx.ID_PROPERTIES, True)
             else:
                 self.FileMenu.Enable(wx.ID_CLOSE, False)
@@ -667,6 +698,9 @@
                 self.FileMenu.Enable(wx.ID_SAVE, False)
                 self.FileMenu.Enable(wx.ID_SAVEAS, False)
                 self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False)
+                self.FileMenu.Enable(wx.ID_PAGE_SETUP, False)
+                self.FileMenu.Enable(wx.ID_PREVIEW, False)
+                self.FileMenu.Enable(wx.ID_PRINT, False)
                 self.FileMenu.Enable(wx.ID_PROPERTIES, False)
 
     def OnNewProjectMenu(self, event):
@@ -806,6 +840,49 @@
             self.RefreshTitle()
         dialog.Destroy()
 
+    def OnPageSetupMenu(self, event):
+        dialog = wx.PageSetupDialog(self, self.PageSetupData)
+        if dialog.ShowModal() == wx.ID_OK:
+            self.PageSetupData = wx.PageSetupDialogData(dialog.GetPageSetupData())
+            self.PrintData = wx.PrintData(self.PageSetupData.GetPrintData())
+        dialog.Destroy()
+        event.Skip()
+
+    def OnPreviewMenu(self, event):
+        selected = self.GetPageSelection()        
+        if selected != -1:
+            data = wx.PrintDialogData(self.PrintData)
+            properties = self.Controler.GetProjectProperties()
+            page_size = map(int, properties["pageSize"])
+            margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
+            printout = GraphicPrintout(self.GetPage(selected), page_size, margins, True)
+            printout2 = GraphicPrintout(self.GetPage(selected), page_size, margins, True)
+            preview = wx.PrintPreview(printout, printout2, data)
+
+            if preview.Ok():
+                preview_frame = wx.PreviewFrame(preview, frame, "Print preview")
+
+                preview_frame.Initialize()
+                
+                preview_frame.Show(True)
+        event.Skip()
+
+    def OnPrintMenu(self, event):
+        selected = self.GetPageSelection()        
+        if selected != -1:
+            dialog_data = wx.PrintDialogData(self.PrintData)
+            dialog_data.SetToPage(1)
+            properties = self.Controler.GetProjectProperties()
+            page_size = map(int, properties["pageSize"])
+            margins = (self.PageSetupData.GetMarginTopLeft(), self.PageSetupData.GetMarginBottomRight())
+            printer = wx.Printer(dialog_data)
+            printout = GraphicPrintout(self.GetPage(selected), page_size, margins)
+            
+            if not printer.Print(self, printout, True):
+                wx.MessageBox("There was a problem printing.\nPerhaps your current printer is not set correctly?", "Printing", wx.OK)
+            printout.Destroy()
+        event.Skip()
+
     def OnPropertiesMenu(self, event):
         self.ShowProperties()
         event.Skip()
@@ -3804,6 +3881,86 @@
             self.ParentWindow.RefreshTitle()
             self.ParentWindow.RefreshEditMenu()
 
+UPPER_DIV = lambda x, y: (x / y) + {True : 0, False : 1}[(x % y) == 0]
+
+class GraphicPrintout(wx.Printout):
+    def __init__(self, viewer, page_size, margins, preview = False):
+        wx.Printout.__init__(self)
+        self.Viewer = viewer
+        self.PageSize = page_size
+        self.Preview = preview
+        self.Margins = margins
+        self.FontSize = 14
+        self.TextMargin = 5
+        
+        maxx, maxy = viewer.GetMaxSize()
+        self.PageGrid = (UPPER_DIV(maxx, page_size[0]), UPPER_DIV(maxy, page_size[1]))
+        
+    def GetPageNumber(self):
+        return self.PageGrid[0] * self.PageGrid[1]
+    
+    def HasPage(self, page):
+        return page <= self.GetPageNumber()
+        
+    def GetPageInfo(self):
+        page_number = self.GetPageNumber()
+        return (1, page_number, 1, page_number)
+
+    def OnBeginDocument(self, startPage, endPage):
+        dc = self.GetDC()
+        if not self.Preview and isinstance(dc, wx.PostScriptDC):
+            dc.SetResolution(720)
+            self.FontSize = 140
+            self.TextMargin = 50
+        super(GraphicPrintout, self).OnBeginDocument(startPage, endPage)
+
+    def OnPrintPage(self, page):
+        dc = self.GetDC()
+        dc.printing = not self.Preview
+        
+        # Get the size of the DC in pixels
+        ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
+        ppiScreenX, ppiScreenY = self.GetPPIScreen()
+        pw, ph = self.GetPageSizePixels()
+        dw, dh = dc.GetSizeTuple()
+        Xscale = (float(dw) * float(ppiPrinterX)) / (float(pw) * 25.4)
+        Yscale = (float(dh) * float(ppiPrinterY)) / (float(ph) * 25.4)
+        
+        margin_left = self.Margins[0].x * Xscale
+        margin_top = self.Margins[0].y * Yscale
+        area_width = dw - self.Margins[1].x * Xscale - margin_left
+        area_height = dh - self.Margins[1].y * Yscale - margin_top
+        
+        dc.SetPen(wx.BLACK_PEN)
+        dc.SetBrush(wx.TRANSPARENT_BRUSH)    
+        dc.DrawRectangle(margin_left, margin_top, area_width, area_height)
+        
+        dc.SetFont(wx.Font(self.FontSize, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
+        dc.SetTextForeground(wx.BLACK)
+        block_name = " - ".join(self.Viewer.GetTagName().split("::")[1:])
+        text_width, text_height = dc.GetTextExtent(block_name)
+        dc.DrawText(block_name, margin_left, margin_top - text_height - self.TextMargin)
+        dc.DrawText("Page: %d" % page, margin_left, margin_top + area_height + self.TextMargin)
+        
+        # Calculate the position on the DC for centering the graphic
+        posX = area_width * ((page - 1) % self.PageGrid[0])
+        posY = area_height * ((page - 1) / self.PageGrid[0])
+
+        scaleX = float(area_width) / float(self.PageSize[0])
+        scaleY = float(area_height) / float(self.PageSize[1])
+        scale = min(scaleX, scaleY)
+
+        # Set the scale and origin
+        dc.SetDeviceOrigin(-posX + margin_left, -posY + margin_top)
+        dc.SetUserScale(scale, scale)
+        dc.SetClippingRegion(posX, posY, self.PageSize[0], self.PageSize[1])
+        
+        #-------------------------------------------
+        
+        self.Viewer.DoDrawing(dc, True)
+        
+        return True
+
 #-------------------------------------------------------------------------------
 #                               Exception Handler
 #-------------------------------------------------------------------------------