# Name: buttonpanel.py # Package: wx.lib.pdfviewer # # Purpose: A button panel class for pdf viewer # # Author: David Hughes dfh@forestfield.co.uk # Copyright: Forestfield Software Ltd # Licence: Same as wxPython host # History: Created 26 Jun 2009 # #---------------------------------------------------------------------------- import sys, os, time import images import wx import wx.lib.agw.buttonpanel as bp class pdfButtonPanel(bp.ButtonPanel): " Containing panel is completely occupied by a button panel " def __init__(self, parent, id, pos, size, style): "Panel for user to select pdf viewer actions" self.viewer = None # reference to viewer is set by their common parent self.numpages = None bp.ButtonPanel.__init__(self, parent, id, "", agwStyle=bp.BP_USE_GRADIENT, alignment=bp.BP_ALIGN_LEFT) self.SetProperties() self.CreateButtons() def CreateButtons(self): " Add buttons and controls" self.pagelabel = wx.StaticText(self, -1, 'Page') self.page = wx.TextCtrl(self, -1, size=(30, -1), style=wx.TE_CENTRE|wx.TE_PROCESS_ENTER) self.page.Bind(wx.EVT_KILL_FOCUS, self.OnPage) self.Bind(wx.EVT_TEXT_ENTER, self.OnPage, self.page) self.maxlabel = wx.StaticText(self, -1, ' ') self.zoom = wx.ComboBox(self, -1, style=wx.CB_DROPDOWN|wx.TE_PROCESS_ENTER) self.comboval = (('Actual size', 1.0), ('Fit width', -1), ('Fit page', -2), ('25%', 0.25), ('50%', 0.5), ('75%', 0.75), ('100%', 1.0), ('125%', 1.25), ('150%', 1.5), ('200%', 2.0), ('400%', 4.0), ('800%', 8.0), ('1000%', 10.0)) for item in self.comboval: self.zoom.Append(item[0], item[1]) # string value and client data self.Bind(wx.EVT_COMBOBOX, self.OnZoomSet, self.zoom) self.Bind(wx.EVT_TEXT_ENTER, self.OnZoomSet, self.zoom) self.zoom.Bind(wx.EVT_KILL_FOCUS, self.OnZoomSet) panelitems = [ ('btn', images.PrintIt.GetBitmap(), wx.ITEM_NORMAL, "Print", self.OnPrint), ('sep',), ('btn', images.SaveIt.GetBitmap(), wx.ITEM_NORMAL, "Save", self.OnSave), ('sep',), ('btn', images.First.GetBitmap(), wx.ITEM_NORMAL, "First page", self.OnFirst), ('btn', images.Prev.GetBitmap(), wx.ITEM_NORMAL, "Previous page", self.OnPrev), ('btn', images.Next.GetBitmap(), wx.ITEM_NORMAL, "Next page", self.OnNext), ('btn', images.Last.GetBitmap(), wx.ITEM_NORMAL, "Last page", self.OnLast), ('Ctrl', self.pagelabel), ('ctrl', self.page), ('ctrl', self.maxlabel), ('sep',), ('btn', images.ZoomOut.GetBitmap(), wx.ITEM_NORMAL, "Zoom out", self.OnZoomOut), ('btn', images.ZoomIn.GetBitmap(), wx.ITEM_NORMAL, "Zoom in", self.OnZoomIn), ('ctrl', self.zoom), ('btn', images.Width.GetBitmap(), wx.ITEM_NORMAL, "Fit page width", self.OnWidth), ('btn', images.Height.GetBitmap(), wx.ITEM_NORMAL, "Fit page height", self.OnHeight), ] self.Freeze() for item in panelitems: if item[0].lower() == 'btn': type, image, kind, popup, handler = item btn = bp.ButtonInfo(self, wx.NewId(),image, kind=kind, shortHelp=popup, longHelp='') self.AddButton(btn) self.Bind(wx.EVT_BUTTON, handler, id=btn.GetId()) elif item[0].lower() == 'sep': self.AddSeparator() elif item[0].lower() == 'space': self.AddSpacer(item[1]) elif item[0].lower() == 'ctrl': self.AddControl(item[1]) self.Thaw() self.DoLayout() def SetProperties(self): " Setup the buttonpanel colours, borders etc." bpArt = self.GetBPArt() bpArt.SetGradientType(bp.BP_GRADIENT_VERTICAL) bpArt.SetColor(bp.BP_GRADIENT_COLOUR_FROM, wx.Colour(119, 136, 153)) #light slate bpArt.SetColor(bp.BP_GRADIENT_COLOUR_TO, wx.Colour(245, 245, 245)) # white smoke bpArt.SetColor(bp.BP_BORDER_COLOUR, wx.Colour(119, 136, 153)) bpArt.SetColor(bp.BP_BUTTONTEXT_COLOUR, wx.Colour(0,0,0)) # not used bpArt.SetColor(bp.BP_SEPARATOR_COLOUR, bp.BrightenColour(wx.Colour(60, 11, 112), 0.85)) bpArt.SetColor(bp.BP_SELECTION_BRUSH_COLOUR, wx.Colour(225, 225, 255)) # used? bpArt.SetColor(bp.BP_SELECTION_PEN_COLOUR, wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION)) def Update(self, pagenum, numpages, zoomscale): """ Called from viewer to initialize and update controls. In viewer, page range is 0 to numpages-1. In button controls it is 1 to numpages """ self.pageno = pagenum + 1 self.page.SetValue('%d' % self.pageno) if numpages <> self.numpages: self.maxlabel.SetLabel('of %d' % numpages) self.numpages = numpages self.percentzoom = zoomscale * 100 self.zoom.SetValue('%.0f%%' % self.percentzoom) self.zoomtext = self.zoom.GetValue() # save last good value def OnSave(self, event): "Save PDF" self.viewer.Save() def OnPrint(self, event): "Print PDF" self.viewer.Print() def OnFirst(self, event): " Show first page of report" if self.pageno > 1: self.pageno = 1 self.ChangePage() def OnPrev(self, event): " Show previous page of report" if self.pageno > 1: self.pageno -= 1 self.ChangePage() def OnNext(self, event): " Show next page of report" if self.pageno < self.numpages: self.pageno += 1 self.ChangePage() def OnLast(self, event): " Show last page of report" if self.pageno < self.numpages: self.pageno = self.numpages self.ChangePage() def OnPage(self,event): " Go to page if valid page number entered" try: newpage = int(self.page.GetValue()) if 1 <= newpage <= self.numpages: if newpage <> self.pageno: self.pageno = newpage self.ChangePage() except ValueError: pass if hasattr(self, 'pageno'): self.page.SetValue('%d' % self.pageno) else: self.page.SetValue('') def OnZoomOut(self, event): "Decrease page magnification" self.viewer.SetZoom(max(0.1, self.percentzoom*0.5/100.0)) def OnZoomIn(self, event): "Increase page magnification" self.viewer.SetZoom(min(self.percentzoom*2/100.0, 10)) def OnZoomSet(self, event): " Process zoom combo-box event. Either a list selection or value entered" MINZ = 0 MAXZ = 1000 newzoom_scale = None num = self.zoom.GetSelection() if num >= 0: # selection from list newzoom_scale = self.zoom.GetClientData(num) else: # combo text astring = self.zoom.GetValue().strip().replace('%','') # ignore percent sign try: numvalue = float(astring) if numvalue < MINZ or numvalue > MAXZ: numvalue = None except ValueError: numvalue = None if numvalue: # numeric value newzoom_scale = numvalue/100.0 else: # valid text? textvalue = self.zoom.GetValue() for k in range(len(self.comboval)): if textvalue.lower() == self.comboval[k][0].lower(): newzoom_scale = self.comboval[k][1] break if newzoom_scale: self.viewer.SetZoom(newzoom_scale) # will send update to set zoomtext else: self.zoom.SetValue(self.zoomtext) # restore last good value event.Skip() def OnWidth(self, event): "Fit display to page width" self.viewer.SetZoom(-1) def OnHeight(self, event): "Fit display to page height" self.viewer.SetZoom(-2) def ChangePage(self): " Update viewer and self.page control with new page number" self.page.SetValue('%d' % self.pageno) self.viewer.GoPage(self.pageno - 1)