def createProtoBoard(self): self.pb = ProtoBoard(self.cols, self.rows) self.updateProtoBoard(False) if not self.pbPrev is None: try: self.prevPosition = self.pbPrev.GetPosition() self.pbPrev.Destroy() except wx.PyDeadObjectError: self.pbPrev = None self.prevPosition = [-1, -1] self.pbPrev = ProtoBoardPreview(self.parent, self.pb, self.prevPosition, self.settings) self.pbPrev.Show() if len(self.segments) > 0: s = self.segments[-1] self.hiLightPos(s.getFirstPos())
class NewTempDialog(wx.Dialog): def __init__(self, parent): self.parent = parent self.settings = parent.settings self.images = parent.settings.images self.stype = STYPE_HTRACE self.segments = [] self.selectedSegment = wx.NOT_FOUND self.cols = 5 self.rows = 5 self.modified = False self.fileName = None self.pbPrev = None self.prevPosition = [-1, -1] wx.CallAfter(self.createProtoBoard) title = "New Proto-board template" wx.Dialog.__init__(self, parent, wx.ID_ANY, title, size=(100, 100)) self.SetBackgroundColour("white") self.Bind(wx.EVT_CLOSE, self.onClose) t1 = wx.StaticText(self, wx.ID_ANY, "Columns:") self.scCols = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scCols.SetRange(5, 100) self.scCols.SetValue(self.cols) self.Bind(wx.EVT_SPINCTRL, self.onSpinCol, self.scCols) t2 = wx.StaticText(self, wx.ID_ANY, "Rows:") self.scRows = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scRows.SetRange(5, 100) self.scRows.SetValue(self.rows) self.Bind(wx.EVT_SPINCTRL, self.onSpinRow, self.scRows) isizer = wx.FlexGridSizer(cols=4, hgap=6, vgap=6) isizer.AddMany([t1, self.scCols, t2, self.scRows]) box = wx.StaticBox(self, -1, "Item") szItems = wx.StaticBoxSizer(box, wx.VERTICAL) self.rbHTrace = wx.RadioButton(self, wx.ID_ANY, "Horizontal Trace", style=wx.RB_GROUP) self.rbVTrace = wx.RadioButton(self, wx.ID_ANY, "Vertical Trace") self.rbHSkip = wx.RadioButton(self, wx.ID_ANY, "Row without holes") self.rbVSkip = wx.RadioButton(self, wx.ID_ANY, "Column without holes") self.Bind(wx.EVT_RADIOBUTTON, self.onHTrace, self.rbHTrace) self.Bind(wx.EVT_RADIOBUTTON, self.onVTrace, self.rbVTrace) self.Bind(wx.EVT_RADIOBUTTON, self.onHSkip, self.rbHSkip) self.Bind(wx.EVT_RADIOBUTTON, self.onVSkip, self.rbVSkip) szItems.AddSpacer((10, 10)) szItems.Add(self.rbHTrace) szItems.AddSpacer((10, 10)) szItems.Add(self.rbVTrace) szItems.AddSpacer((10, 10)) szItems.Add(self.rbHSkip) szItems.AddSpacer((10, 10)) szItems.Add(self.rbVSkip) szItems.AddSpacer((10, 10)) t1 = wx.StaticText(self, wx.ID_ANY, "Point A") self.scAX = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scAX.SetRange(0, self.cols - 1) self.scAX.SetValue(0) self.scAY = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scAY.SetRange(0, self.rows - 1) self.scAY.SetValue(0) t2 = wx.StaticText(self, wx.ID_ANY, "Point B") self.scBX = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scBX.SetRange(0, self.cols - 1) self.scBX.SetValue(0) self.scBY = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scBY.SetRange(0, self.rows - 1) self.scBY.SetValue(0) szData = wx.FlexGridSizer(cols=3, hgap=6, vgap=6) szData.AddMany([t1, self.scAX, self.scAY, t2, self.scBX, self.scBY]) box = wx.StaticBox(self, -1, "Positions") szDataBox = wx.StaticBoxSizer(box, wx.VERTICAL) szDataBox.Add(szData) szDataBox.AddSpacer((10, 10)) self.cbRepeat = wx.CheckBox(self, wx.ID_ANY, "Repeat across row/column") szDataBox.Add(self.cbRepeat) self.cbRepeat.SetValue(False) hsz = wx.BoxSizer(wx.HORIZONTAL) hsz.Add(szItems) hsz.AddSpacer((20, 20)) hsz.Add(szDataBox) sizer = wx.BoxSizer(wx.VERTICAL) sizer.AddSpacer((20, 20)) sizer.Add(isizer) sizer.AddSpacer((20, 20)) sizer.Add(hsz) sizer.AddSpacer((20, 20)) hsizer = wx.BoxSizer(wx.HORIZONTAL) hsizer.AddSpacer((20, 20)) hsizer.Add(sizer) hsizer.AddSpacer((20, 20)) self.lbSegments = wx.ListBox(self, wx.ID_ANY, size=(200, 200), choices=[]) self.setSegmentList() self.lbSegments.Bind(wx.EVT_LISTBOX, self.onSegmentSelect) hsizer.Add(self.lbSegments, 1, wx.ALL, 20) hsizer.AddSpacer((20, 20)) dbSizer = wx.BoxSizer(wx.VERTICAL) dbSizer.Add(hsizer) dscSizer = wx.BoxSizer(wx.HORIZONTAL) dscSizer.AddSpacer((20, 10)) dscSizer.Add(wx.StaticText(self, wx.ID_ANY, "Description: ")) dscSizer.AddSpacer((5, 5)) self.tcDesc = wx.TextCtrl(self, wx.ID_ANY, "", size=(500, -1)) dscSizer.Add(self.tcDesc) dbSizer.Add(dscSizer) dbSizer.AddSpacer((10, 10)) tbSizer = wx.BoxSizer(wx.HORIZONTAL) tbSizer.AddSpacer((20, 20)) self.bAdd = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngAdd, size=TBDIM) self.bAdd.SetToolTipString("Add a new item to the template") self.Bind(wx.EVT_BUTTON, self.onAdd, self.bAdd) tbSizer.Add(self.bAdd) tbSizer.AddSpacer((5, 5)) self.bDel = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngDelete, size=TBDIM) self.bDel.SetToolTipString("Delete an item from the template") self.Bind(wx.EVT_BUTTON, self.onDel, self.bDel) tbSizer.Add(self.bDel) tbSizer.AddSpacer((20, 10)) self.bPrev = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngView, size=TBDIM) self.bPrev.SetToolTipString("Display preview window") self.Bind(wx.EVT_BUTTON, self.onPreview, self.bPrev) tbSizer.Add(self.bPrev) tbSizer.AddSpacer((20, 20)) self.bNew = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngNewtempfile, size=TBDIM) self.bNew.SetToolTipString("Create a new Template File") self.Bind(wx.EVT_BUTTON, self.onNew, self.bNew) tbSizer.Add(self.bNew) tbSizer.AddSpacer((5, 5)) self.bLoad = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngOpen, size=TBDIM) self.bLoad.SetToolTipString("Load a Template File") self.Bind(wx.EVT_BUTTON, self.onLoad, self.bLoad) tbSizer.Add(self.bLoad) tbSizer.AddSpacer((5, 5)) self.bSave = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngSave, size=TBDIM) self.bSave.SetToolTipString("Save Template") self.Bind(wx.EVT_BUTTON, self.onSave, self.bSave) tbSizer.Add(self.bSave) tbSizer.AddSpacer((5, 5)) self.bSaveAs = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngSaveas, size=TBDIM) self.bSaveAs.SetToolTipString("Save Template As A New File") self.Bind(wx.EVT_BUTTON, self.onSaveAs, self.bSaveAs) tbSizer.Add(self.bSaveAs) tbSizer.AddSpacer((50, 10)) self.bExit = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngExit, size=TBDIM) self.bExit.SetToolTipString("Exit") self.Bind(wx.EVT_BUTTON, self.onClose, self.bExit) tbSizer.Add(self.bExit) tbSizer.AddSpacer((10, 10)) dbSizer.Add(tbSizer) dbSizer.AddSpacer((20, 20)) self.SetSizer(dbSizer) self.Fit() self.rbHTrace.SetValue(1) self.onHTrace(None) def updateTitle(self): if self.fileName is None: self.SetTitle("New Proto-board template") else: self.SetTitle("Proto-board template file: %s" % self.fileName) def onNew(self, evt): if self.modified: if not self.abandonChanges(): return self.stype = STYPE_HTRACE self.segments = [] self.selectedSegment = wx.NOT_FOUND self.cols = 5 self.rows = 5 self.modified = False self.fileName = None self.createProtoBoard() self.tcDesc.SetValue("") self.scRows.SetValue(self.rows) self.scCols.SetValue(self.cols) self.scAX.SetRange(0, self.cols - 1) self.scAX.SetValue(0) self.scBX.SetRange(0, self.cols - 1) self.scBX.SetValue(0) self.scAY.SetRange(0, self.rows - 1) self.scAY.SetValue(0) self.scBY.SetRange(0, self.rows - 1) self.scBY.SetValue(0) self.setSegmentList() self.rbHTrace.SetValue(True) self.setHTrace() self.updateTitle() def onLoad(self, evt): if self.modified: if not self.abandonChanges(): return dlg = wx.FileDialog(self, message="Choose a proto-board template...", defaultDir=self.settings.templDir, defaultFile="", wildcard=wildcard, style=wx.OPEN) rc = dlg.ShowModal() if rc == wx.ID_OK: path = dlg.GetPath() dlg.Destroy() if rc != wx.ID_OK: return pb = self.parent.loadBoard(path) if pb is None: dlg = wx.MessageDialog( self, 'Error loading proto-board template file: ' + path, 'Load Error', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return self.fileName = path self.updateTitle() dsc = pb.getDescription() if dsc is None: self.tcDesc.SetValue("") else: self.tcDesc.SetValue(dsc) self.cols, self.rows = pb.getSize() self.scRows.SetValue(self.rows) self.scCols.SetValue(self.cols) self.scAX.SetRange(0, self.cols - 1) self.scBX.SetRange(0, self.cols - 1) self.scAY.SetRange(0, self.rows - 1) self.scBY.SetRange(0, self.rows - 1) self.segments = [] ht = pb.getHTraces() for t in ht: self.addSegment(Segment(STYPE_HTRACE, t[0], t[1], t[2])) vt = pb.getVTraces() for t in vt: self.addSegment(Segment(STYPE_VTRACE, t[0], t[1], t[2])) hs, vs = pb.getSkips() for s in hs: self.addSegment(Segment(STYPE_HSKIP, s, None, None)) for s in vs: self.addSegment(Segment(STYPE_VSKIP, s, None, None)) self.setSegmentList() self.createProtoBoard() self.setModified(False) def setModified(self, flag=True): self.modified = flag def abandonChanges(self): if self.modified: dlg = wx.MessageDialog( self, 'Are you sure you want to exit?\nPending changes will be lost', 'Changes pending', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) rc = dlg.ShowModal() dlg.Destroy() if rc == wx.ID_NO: return False return True def onSave(self, evt): if self.fileName is None: self.onSaveAs(None) return self.saveToFile(self.fileName) def onSaveAs(self, evt): dfn = "" if not self.fileName is None: dfn = self.fileName dlg = wx.FileDialog(self, message="Save proto board template as ...", defaultDir=os.getcwd(), defaultFile=dfn, wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) rc = dlg.ShowModal() if rc == wx.ID_OK: path = dlg.GetPath() dlg.Destroy() if rc != wx.ID_OK: return if self.saveToFile(path): self.fileName = path self.updateTitle() def saveToFile(self, fn): pb = ProtoBoard(self.cols, self.rows) dsc = self.tcDesc.GetValue().strip() if dsc == "": pb.setDescription(None) else: pb.setDescription(dsc) pb.clearTraces() pb.clearSkips() for s in self.segments: s.addSegment(pb) try: fp = open(fn, "w") fp.write(pb.getXml(includeDescription=True)) fp.write("\n") fp.close() except: dlg = wx.MessageDialog(self, 'Error writing to file ' + fn, 'Save Error', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False self.setModified(False) dlg = wx.MessageDialog(self, 'Proto Board template saved to ' + fn, 'Saved', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() return True def onPreview(self, evt): self.createProtoBoard() def createProtoBoard(self): self.pb = ProtoBoard(self.cols, self.rows) self.updateProtoBoard(False) if not self.pbPrev is None: try: self.prevPosition = self.pbPrev.GetPosition() self.pbPrev.Destroy() except wx.PyDeadObjectError: self.pbPrev = None self.prevPosition = [-1, -1] self.pbPrev = ProtoBoardPreview(self.parent, self.pb, self.prevPosition, self.settings) self.pbPrev.Show() if len(self.segments) > 0: s = self.segments[-1] self.hiLightPos(s.getFirstPos()) def hiLightPos(self, pos): if self.pbPrev is None: return self.pbPrev.setHiLightedPos(pos) def updateProtoBoard(self, refresh=True): self.pb.clearTraces() self.pb.clearSkips() for s in self.segments: s.addSegment(self.pb) if refresh: if not self.pbPrev is None: try: self.pbPrev.refresh() except wx.PyDeadObjectError: self.pbPrev = None def onSpinRow(self, evt): self.setModified() nr = self.scRows.GetValue() self.scAY.SetRange(0, nr - 1) self.scBY.SetRange(0, nr - 1) self.rows = nr self.limitSegments() self.createProtoBoard() def onSpinCol(self, evt): self.setModified() nc = self.scCols.GetValue() self.scAX.SetRange(0, nc - 1) self.scBX.SetRange(0, nc - 1) self.cols = nc self.limitSegments() self.createProtoBoard() def setSegmentList(self): self.lbSegments.Set([s.getStr() for s in self.segments]) def onSegmentSelect(self, evt): self.selectedSegment = self.lbSegments.GetSelection() if self.selectedSegment is None: self.hiLightPos(None) return if self.selectedSegment == wx.NOT_FOUND: self.hiLightPos(None) return if self.selectedSegment < 0 or self.selectedSegment >= len( self.segments): self.hiLightPos(None) return pos = self.segments[self.selectedSegment].getFirstPos() self.hiLightPos(pos) def limitSegments(self): delSeg = [] for sx in range(len(self.segments)): deleteSeg, chg = self.segments[sx].limitValues( self.cols, self.rows) if deleteSeg: delSeg.append(sx) if deleteSeg or chg: self.setModified() for sx in delSeg[::-1]: del self.segments[sx] self.setSegmentList() def onAdd(self, evt): self.setModified() rpt = self.cbRepeat.GetValue() if self.stype == STYPE_HTRACE: ax = self.scAX.GetValue() ay = self.scAY.GetValue() bx = self.scBX.GetValue() by = self.scBY.GetValue() tlen = bx - ax + 1 if ax > bx: t = ax ax = bx bx = t if ay > by: t = ay ay = by by = t if rpt: while True: for r in range(ay, by + 1): self.addSegment(Segment(self.stype, ax, bx, r)) ax += tlen bx += tlen if bx >= self.cols: break else: for r in range(ay, by + 1): self.addSegment(Segment(self.stype, ax, bx, r)) elif self.stype == STYPE_VTRACE: ax = self.scAX.GetValue() ay = self.scAY.GetValue() bx = self.scBX.GetValue() by = self.scBY.GetValue() tlen = by - ay + 1 if ax > bx: t = ax ax = bx bx = t if ay > by: t = ay ay = by by = t if rpt: while True: for c in range(ax, bx + 1): self.addSegment(Segment(self.stype, c, ay, by)) ay += tlen by += tlen if by >= self.rows: break else: for c in range(ax, bx + 1): self.addSegment(Segment(self.stype, c, ay, by)) elif self.stype == STYPE_HSKIP: self.addSegment( Segment(self.stype, self.scAY.GetValue(), None, None)) elif self.stype == STYPE_VSKIP: self.addSegment( Segment(self.stype, self.scAX.GetValue(), None, None)) self.setSegmentList() self.selectedSegment = len(self.segments) - 1 self.lbSegments.SetSelection(self.selectedSegment) self.updateProtoBoard() def addSegment(self, seg): for s in self.segments: if s.getValues() == seg.getValues(): return False self.segments.append(seg) return True def onDel(self, evt): if self.selectedSegment is None: return if self.selectedSegment == wx.NOT_FOUND: return if self.selectedSegment < 0: return if self.selectedSegment >= len(self.segments): return self.setModified() del self.segments[self.selectedSegment] self.setSegmentList() if self.selectedSegment >= len(self.segments): self.selectedSegment = len(self.segments) - 1 if self.selectedSegment < 0: self.selectedSegment = wx.NOT_FOUND else: self.lbSegments.SetSelection(self.selectedSegment) else: self.lbSegments.SetSelection(self.selectedSegment) self.updateProtoBoard() def onHTrace(self, evt): self.setHTrace() def setHTrace(self): self.stype = STYPE_HTRACE self.scAX.Enable(True) self.scAY.Enable(True) self.scBX.Enable(True) self.scBY.Enable(True) def onVTrace(self, evt): self.stype = STYPE_VTRACE self.scAX.Enable(True) self.scAY.Enable(True) self.scBX.Enable(True) self.scBY.Enable(True) def onHSkip(self, evt): self.stype = STYPE_HSKIP self.scAX.Enable(False) self.scAY.Enable(True) self.scBX.Enable(False) self.scBY.Enable(False) def onVSkip(self, evt): self.stype = STYPE_VSKIP self.scAX.Enable(True) self.scAY.Enable(False) self.scBX.Enable(False) self.scBY.Enable(False) def onClose(self, evt): if self.modified: if not self.abandonChanges(): return if not self.pbPrev is None: try: self.pbPrev.Destroy() except wx.PyDeadObjectError: self.pbPrev = None self.EndModal(wx.ID_OK)
class NewTempDialog(wx.Dialog): def __init__(self, parent): self.parent = parent self.settings = parent.settings self.images = parent.settings.images self.stype = STYPE_HTRACE self.segments = [] self.selectedSegment = wx.NOT_FOUND self.cols = 5 self.rows = 5 self.modified = False self.fileName = None self.pbPrev = None self.prevPosition = [-1, -1] wx.CallAfter(self.createProtoBoard) title = "New Proto-board template" wx.Dialog.__init__(self, parent, wx.ID_ANY, title, size=(100, 100)) self.SetBackgroundColour("white") self.Bind(wx.EVT_CLOSE, self.onClose) t1 = wx.StaticText(self, wx.ID_ANY, "Columns:") self.scCols = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scCols.SetRange(5,100) self.scCols.SetValue(self.cols) self.Bind(wx.EVT_SPINCTRL, self.onSpinCol, self.scCols) t2 = wx.StaticText(self, wx.ID_ANY, "Rows:") self.scRows = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scRows.SetRange(5,100) self.scRows.SetValue(self.rows) self.Bind(wx.EVT_SPINCTRL, self.onSpinRow, self.scRows) isizer = wx.FlexGridSizer(cols=4, hgap=6, vgap=6) isizer.AddMany([ t1, self.scCols, t2, self.scRows ]) box = wx.StaticBox(self, -1, "Item") szItems = wx.StaticBoxSizer(box, wx.VERTICAL) self.rbHTrace = wx.RadioButton(self, wx.ID_ANY, "Horizontal Trace", style = wx.RB_GROUP) self.rbVTrace = wx.RadioButton(self, wx.ID_ANY, "Vertical Trace") self.rbHSkip = wx.RadioButton(self, wx.ID_ANY, "Row without holes") self.rbVSkip = wx.RadioButton(self, wx.ID_ANY, "Column without holes") self.Bind(wx.EVT_RADIOBUTTON, self.onHTrace, self.rbHTrace ) self.Bind(wx.EVT_RADIOBUTTON, self.onVTrace, self.rbVTrace ) self.Bind(wx.EVT_RADIOBUTTON, self.onHSkip, self.rbHSkip ) self.Bind(wx.EVT_RADIOBUTTON, self.onVSkip, self.rbVSkip ) szItems.AddSpacer((10, 10)) szItems.Add(self.rbHTrace) szItems.AddSpacer((10, 10)) szItems.Add(self.rbVTrace) szItems.AddSpacer((10, 10)) szItems.Add(self.rbHSkip) szItems.AddSpacer((10, 10)) szItems.Add(self.rbVSkip) szItems.AddSpacer((10, 10)) t1 = wx.StaticText(self, wx.ID_ANY, "Point A") self.scAX = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scAX.SetRange(0,self.cols-1) self.scAX.SetValue(0) self.scAY = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scAY.SetRange(0,self.rows-1) self.scAY.SetValue(0) t2 = wx.StaticText(self, wx.ID_ANY, "Point B") self.scBX = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scBX.SetRange(0,self.cols-1) self.scBX.SetValue(0) self.scBY = wx.SpinCtrl(self, wx.ID_ANY, size=(50, -1)) self.scBY.SetRange(0,self.rows-1) self.scBY.SetValue(0) szData = wx.FlexGridSizer(cols=3, hgap=6, vgap=6) szData.AddMany([ t1, self.scAX, self.scAY, t2, self.scBX, self.scBY]) box = wx.StaticBox(self, -1, "Positions") szDataBox = wx.StaticBoxSizer(box, wx.VERTICAL) szDataBox.Add(szData) szDataBox.AddSpacer((10, 10)) self.cbRepeat = wx.CheckBox(self, wx.ID_ANY, "Repeat across row/column") szDataBox.Add(self.cbRepeat) self.cbRepeat.SetValue(False) hsz = wx.BoxSizer(wx.HORIZONTAL) hsz.Add(szItems) hsz.AddSpacer((20, 20)) hsz.Add(szDataBox) sizer = wx.BoxSizer(wx.VERTICAL) sizer.AddSpacer((20, 20)) sizer.Add(isizer) sizer.AddSpacer((20, 20)) sizer.Add(hsz) sizer.AddSpacer((20, 20)) hsizer = wx.BoxSizer(wx.HORIZONTAL) hsizer.AddSpacer((20, 20)) hsizer.Add(sizer) hsizer.AddSpacer((20, 20)) self.lbSegments = wx.ListBox(self, wx.ID_ANY, size=(200, 200), choices=[]) self.setSegmentList() self.lbSegments.Bind(wx.EVT_LISTBOX, self.onSegmentSelect) hsizer.Add(self.lbSegments, 1, wx.ALL, 20) hsizer.AddSpacer((20, 20)) dbSizer = wx.BoxSizer(wx.VERTICAL) dbSizer.Add(hsizer) dscSizer = wx.BoxSizer(wx.HORIZONTAL) dscSizer.AddSpacer((20, 10)) dscSizer.Add(wx.StaticText(self, wx.ID_ANY, "Description: ")) dscSizer.AddSpacer((5,5)) self.tcDesc = wx.TextCtrl(self, wx.ID_ANY, "", size=(500, -1)) dscSizer.Add(self.tcDesc) dbSizer.Add(dscSizer) dbSizer.AddSpacer((10, 10)) tbSizer = wx.BoxSizer(wx.HORIZONTAL) tbSizer.AddSpacer((20, 20)) self.bAdd = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngAdd, size=TBDIM) self.bAdd.SetToolTipString("Add a new item to the template") self.Bind(wx.EVT_BUTTON, self.onAdd, self.bAdd) tbSizer.Add(self.bAdd) tbSizer.AddSpacer((5, 5)) self.bDel = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngDelete, size=TBDIM) self.bDel.SetToolTipString("Delete an item from the template") self.Bind(wx.EVT_BUTTON, self.onDel, self.bDel) tbSizer.Add(self.bDel) tbSizer.AddSpacer((20, 10)) self.bPrev = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngView, size=TBDIM) self.bPrev.SetToolTipString("Display preview window") self.Bind(wx.EVT_BUTTON, self.onPreview, self.bPrev) tbSizer.Add(self.bPrev) tbSizer.AddSpacer((20, 20)) self.bNew = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngNewtempfile, size=TBDIM) self.bNew.SetToolTipString("Create a new Template File") self.Bind(wx.EVT_BUTTON, self.onNew, self.bNew) tbSizer.Add(self.bNew) tbSizer.AddSpacer((5, 5)) self.bLoad = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngOpen, size=TBDIM) self.bLoad.SetToolTipString("Load a Template File") self.Bind(wx.EVT_BUTTON, self.onLoad, self.bLoad) tbSizer.Add(self.bLoad) tbSizer.AddSpacer((5, 5)) self.bSave = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngSave, size=TBDIM) self.bSave.SetToolTipString("Save Template") self.Bind(wx.EVT_BUTTON, self.onSave, self.bSave) tbSizer.Add(self.bSave) tbSizer.AddSpacer((5, 5)) self.bSaveAs = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngSaveas, size=TBDIM) self.bSaveAs.SetToolTipString("Save Template As A New File") self.Bind(wx.EVT_BUTTON, self.onSaveAs, self.bSaveAs) tbSizer.Add(self.bSaveAs) tbSizer.AddSpacer((50, 10)) self.bExit = wx.BitmapButton(self, wx.ID_ANY, self.settings.images.pngExit, size=TBDIM) self.bExit.SetToolTipString("Exit") self.Bind(wx.EVT_BUTTON, self.onClose, self.bExit) tbSizer.Add(self.bExit) tbSizer.AddSpacer((10, 10)) dbSizer.Add(tbSizer) dbSizer.AddSpacer((20, 20)) self.SetSizer(dbSizer) self.Fit() self.rbHTrace.SetValue(1) self.onHTrace(None) def updateTitle(self): if self.fileName is None: self.SetTitle("New Proto-board template") else: self.SetTitle("Proto-board template file: %s" % self.fileName) def onNew(self, evt): if self.modified: if not self.abandonChanges(): return self.stype = STYPE_HTRACE self.segments = [] self.selectedSegment = wx.NOT_FOUND self.cols = 5 self.rows = 5 self.modified = False self.fileName = None self.createProtoBoard() self.tcDesc.SetValue("") self.scRows.SetValue(self.rows) self.scCols.SetValue(self.cols) self.scAX.SetRange(0, self.cols-1) self.scAX.SetValue(0) self.scBX.SetRange(0, self.cols-1) self.scBX.SetValue(0) self.scAY.SetRange(0, self.rows-1) self.scAY.SetValue(0) self.scBY.SetRange(0, self.rows-1) self.scBY.SetValue(0) self.setSegmentList() self.rbHTrace.SetValue(True) self.setHTrace() self.updateTitle() def onLoad(self, evt): if self.modified: if not self.abandonChanges(): return dlg = wx.FileDialog( self, message="Choose a proto-board template...", defaultDir=self.settings.templDir, defaultFile="", wildcard=wildcard, style=wx.OPEN ) rc = dlg.ShowModal() if rc == wx.ID_OK: path = dlg.GetPath() dlg.Destroy() if rc != wx.ID_OK: return pb = self.parent.loadBoard(path) if pb is None: dlg = wx.MessageDialog(self, 'Error loading proto-board template file: ' + path, 'Load Error', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return self.fileName = path self.updateTitle() dsc = pb.getDescription() if dsc is None: self.tcDesc.SetValue("") else: self.tcDesc.SetValue(dsc) self.cols, self.rows = pb.getSize() self.scRows.SetValue(self.rows) self.scCols.SetValue(self.cols) self.scAX.SetRange(0, self.cols-1) self.scBX.SetRange(0, self.cols-1) self.scAY.SetRange(0, self.rows-1) self.scBY.SetRange(0, self.rows-1) self.segments = [] ht = pb.getHTraces() for t in ht: self.addSegment(Segment(STYPE_HTRACE, t[0], t[1], t[2])) vt = pb.getVTraces() for t in vt: self.addSegment(Segment(STYPE_VTRACE, t[0], t[1], t[2])) hs, vs = pb.getSkips() for s in hs: self.addSegment(Segment(STYPE_HSKIP, s, None, None)) for s in vs: self.addSegment(Segment(STYPE_VSKIP, s, None, None)) self.setSegmentList() self.createProtoBoard() self.setModified(False) def setModified(self, flag=True): self.modified = flag def abandonChanges(self): if self.modified: dlg = wx.MessageDialog(self, 'Are you sure you want to exit?\nPending changes will be lost', 'Changes pending', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) rc = dlg.ShowModal() dlg.Destroy() if rc == wx.ID_NO: return False return True def onSave(self, evt): if self.fileName is None: self.onSaveAs(None) return self.saveToFile(self.fileName) def onSaveAs(self, evt): dfn = "" if not self.fileName is None: dfn = self.fileName dlg = wx.FileDialog( self, message="Save proto board template as ...", defaultDir=os.getcwd(), defaultFile=dfn, wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT ) rc = dlg.ShowModal() if rc == wx.ID_OK: path = dlg.GetPath() dlg.Destroy() if rc != wx.ID_OK: return if self.saveToFile(path): self.fileName = path self.updateTitle() def saveToFile(self, fn): pb = ProtoBoard(self.cols, self.rows) dsc = self.tcDesc.GetValue().strip() if dsc == "": pb.setDescription(None) else: pb.setDescription(dsc) pb.clearTraces() pb.clearSkips() for s in self.segments: s.addSegment(pb) try: fp = open(fn, "w") fp.write(pb.getXml(includeDescription=True)) fp.write("\n") fp.close() except: dlg = wx.MessageDialog(self, 'Error writing to file ' + fn, 'Save Error', wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() return False self.setModified(False) dlg = wx.MessageDialog(self, 'Proto Board template saved to ' + fn, 'Saved', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() return True def onPreview(self, evt): self.createProtoBoard() def createProtoBoard(self): self.pb = ProtoBoard(self.cols, self.rows) self.updateProtoBoard(False) if not self.pbPrev is None: try: self.prevPosition = self.pbPrev.GetPosition() self.pbPrev.Destroy() except wx.PyDeadObjectError: self.pbPrev = None self.prevPosition = [-1, -1] self.pbPrev = ProtoBoardPreview(self.parent, self.pb, self.prevPosition, self.settings) self.pbPrev.Show() if len(self.segments) > 0: s = self.segments[-1] self.hiLightPos(s.getFirstPos()) def hiLightPos(self, pos): if self.pbPrev is None: return self.pbPrev.setHiLightedPos(pos) def updateProtoBoard(self, refresh=True): self.pb.clearTraces() self.pb.clearSkips() for s in self.segments: s.addSegment(self.pb) if refresh: if not self.pbPrev is None: try: self.pbPrev.refresh() except wx.PyDeadObjectError: self.pbPrev = None def onSpinRow(self, evt): self.setModified() nr = self.scRows.GetValue() self.scAY.SetRange(0, nr-1) self.scBY.SetRange(0, nr-1) self.rows = nr self.limitSegments() self.createProtoBoard() def onSpinCol(self, evt): self.setModified() nc = self.scCols.GetValue() self.scAX.SetRange(0, nc-1) self.scBX.SetRange(0, nc-1) self.cols = nc self.limitSegments() self.createProtoBoard() def setSegmentList(self): self.lbSegments.Set([s.getStr() for s in self.segments]) def onSegmentSelect(self, evt): self.selectedSegment = self.lbSegments.GetSelection() if self.selectedSegment is None: self.hiLightPos(None) return if self.selectedSegment == wx.NOT_FOUND: self.hiLightPos(None) return if self.selectedSegment < 0 or self.selectedSegment >= len(self.segments): self.hiLightPos(None) return pos = self.segments[self.selectedSegment].getFirstPos() self.hiLightPos(pos) def limitSegments(self): delSeg = [] for sx in range(len(self.segments)): deleteSeg, chg = self.segments[sx].limitValues(self.cols, self.rows) if deleteSeg: delSeg.append(sx) if deleteSeg or chg: self.setModified() for sx in delSeg[::-1]: del self.segments[sx] self.setSegmentList() def onAdd(self, evt): self.setModified() rpt = self.cbRepeat.GetValue() if self.stype == STYPE_HTRACE: ax = self.scAX.GetValue() ay = self.scAY.GetValue() bx = self.scBX.GetValue() by = self.scBY.GetValue() tlen = bx - ax + 1 if ax > bx: t = ax ax = bx bx = t if ay > by: t = ay ay = by by = t if rpt: while True: for r in range(ay, by+1): self.addSegment(Segment(self.stype, ax, bx, r)) ax += tlen bx += tlen if bx >= self.cols: break else: for r in range(ay, by+1): self.addSegment(Segment(self.stype, ax, bx, r)) elif self.stype == STYPE_VTRACE: ax = self.scAX.GetValue() ay = self.scAY.GetValue() bx = self.scBX.GetValue() by = self.scBY.GetValue() tlen = by - ay + 1 if ax > bx: t = ax ax = bx bx = t if ay > by: t = ay ay = by by = t if rpt: while True: for c in range(ax, bx+1): self.addSegment(Segment(self.stype, c, ay, by)) ay += tlen by += tlen if by >= self.rows: break else: for c in range(ax, bx+1): self.addSegment(Segment(self.stype, c, ay, by)) elif self.stype == STYPE_HSKIP: self.addSegment(Segment(self.stype, self.scAY.GetValue(), None, None)) elif self.stype == STYPE_VSKIP: self.addSegment(Segment(self.stype, self.scAX.GetValue(), None, None)) self.setSegmentList() self.selectedSegment = len(self.segments)-1 self.lbSegments.SetSelection(self.selectedSegment) self.updateProtoBoard() def addSegment(self, seg): for s in self.segments: if s.getValues() == seg.getValues(): return False self.segments.append(seg) return True def onDel(self, evt): if self.selectedSegment is None: return if self.selectedSegment == wx.NOT_FOUND: return if self.selectedSegment < 0: return if self.selectedSegment >= len(self.segments): return self.setModified() del self.segments[self.selectedSegment] self.setSegmentList() if self.selectedSegment >= len(self.segments): self.selectedSegment = len(self.segments) - 1 if self.selectedSegment < 0: self.selectedSegment = wx.NOT_FOUND else: self.lbSegments.SetSelection(self.selectedSegment) else: self.lbSegments.SetSelection(self.selectedSegment) self.updateProtoBoard() def onHTrace(self, evt): self.setHTrace() def setHTrace(self): self.stype = STYPE_HTRACE self.scAX.Enable(True) self.scAY.Enable(True) self.scBX.Enable(True) self.scBY.Enable(True) def onVTrace(self, evt): self.stype = STYPE_VTRACE self.scAX.Enable(True) self.scAY.Enable(True) self.scBX.Enable(True) self.scBY.Enable(True) def onHSkip(self, evt): self.stype = STYPE_HSKIP self.scAX.Enable(False) self.scAY.Enable(True) self.scBX.Enable(False) self.scBY.Enable(False) def onVSkip(self, evt): self.stype = STYPE_VSKIP self.scAX.Enable(True) self.scAY.Enable(False) self.scBX.Enable(False) self.scBY.Enable(False) def onClose(self, evt): if self.modified: if not self.abandonChanges(): return if not self.pbPrev is None: try: self.pbPrev.Destroy() except wx.PyDeadObjectError: self.pbPrev = None self.EndModal(wx.ID_OK)