Ejemplo n.º 1
0
class StockRegisterPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.CLIP_CHILDREN)

        # 计算日期选择控件的范围
        now = wx.DateTime.Today()
        beginDate = now.Subtract(wx.DateSpan(months=6))

        labelfont = wx.Font(wx.NORMAL_FONT.GetPointSize(),
                            wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                            wx.FONTWEIGHT_BOLD)
        bs1 = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, wx.ID_ANY, '信息登记')
        label.SetFont(labelfont)
        bs1.Add(label, 0, wx.ALL | wx.BOTTOM, 0)

        gbSizer = wx.GridBagSizer(5, 5)
        label = wx.StaticText(self, wx.ID_ANY, '名称:')
        self.tc_goodsname = wx.TextCtrl(self,
                                        wx.ID_ANY,
                                        '',
                                        style=wx.TE_READONLY)
        gbSizer.Add(label, (0, 0), (1, 1), wx.ALL | wx.ALIGN_RIGHT, 5)
        gbSizer.Add(self.tc_goodsname, (0, 1), (1, 1), wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '物品数量:')
        self.tc_goodsNum = IntCtrl(self)
        self.tc_goodsNum.SetMin(1)
        self.tc_goodsNum.SetNoneAllowed(True)
        self.tc_goodsNum.SetValue(None)
        self.tc_goodsNum.SetMaxLength(12)
        gbSizer.Add(label, (0, 2), (1, 1), wx.ALL | wx.ALIGN_RIGHT, 5)
        gbSizer.Add(self.tc_goodsNum, (0, 3), (1, 1), wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '类别:')
        self.tc_goodcatagory = wx.TextCtrl(self,
                                           wx.ID_ANY,
                                           '',
                                           style=wx.TE_READONLY)
        gbSizer.Add(label, (1, 0), (1, 1), wx.ALL, 5)
        gbSizer.Add(self.tc_goodcatagory, (1, 1), (1, 1), wx.ALL | wx.EXPAND,
                    5)

        label = wx.StaticText(self, wx.ID_ANY, '经办人:')
        self.tc_op = wx.TextCtrl(self, wx.ID_ANY, '')
        self.tc_op.SetMaxLength(10)
        gbSizer.Add(label, (1, 2), (1, 1), wx.ALL | wx.ALIGN_RIGHT, 5)
        gbSizer.Add(self.tc_op, (1, 3), (1, 1), wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '规格:')
        self.tc_goodsunit = wx.TextCtrl(
            self,
            wx.ID_ANY,
            '',
        )
        self.tc_goodsunit.SetMaxLength(6)
        gbSizer.Add(label, (2, 0), (1, 1), wx.ALL | wx.ALIGN_RIGHT, 5)
        gbSizer.Add(self.tc_goodsunit, (2, 1), (1, 1), wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '经办地点:')
        self.tc_address = wx.TextCtrl(self, wx.ID_ANY, '')
        self.tc_address.SetMaxLength(24)
        gbSizer.Add(label, (2, 2), (1, 1), wx.ALL | wx.ALIGN_RIGHT, 5)
        gbSizer.Add(self.tc_address, (2, 3), (1, 1), wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '单价:')
        self.tc_goodsprice = wx.TextCtrl(
            self,
            wx.ID_ANY,
            '',
        )
        self.tc_goodsprice.SetMaxLength(12)
        self.tc_goodsprice.Bind(wx.EVT_CHAR, self.OnFloatChar)
        gbSizer.Add(label, (3, 0), (1, 1), wx.ALL, 5)
        gbSizer.Add(self.tc_goodsprice, (3, 1), (1, 1), wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '登记日期:')
        self.op_date = wx.adv.DatePickerCtrl(self,
                                             size=(120, -1),
                                             style=wx.adv.DP_DROPDOWN
                                             | wx.adv.DP_SHOWCENTURY)
        #self.Bind(wx.adv.EVT_DATE_CHANGED, self.OnDateChanged, self.op_date)
        self.op_date.SetRange(beginDate, wx.DateTime.Today())
        gbSizer.Add(label, (3, 2), (1, 1), wx.ALL | wx.ALIGN_RIGHT, 5)
        gbSizer.Add(self.op_date, (3, 3), (1, 1), wx.ALL | wx.EXPAND, 5)

        gbSizer.AddGrowableCol(1)
        gbSizer.AddGrowableCol(3)

        bs2 = wx.BoxSizer(wx.HORIZONTAL)
        bs2.AddStretchSpacer(1)
        b = buttons.GenButton(self, -1, "入库")
        self.Bind(wx.EVT_BUTTON, self.OnInStock, b)
        bs2.Add(b, 0, wx.ALL, 5)
        b = buttons.GenButton(self, -1, "出库")
        self.Bind(wx.EVT_BUTTON, self.OnOutStock, b)
        bs2.Add(b, 0, wx.ALL, 5)
        b = buttons.GenButton(self, -1, "重置")
        self.Bind(wx.EVT_BUTTON, self.OnReset, b)
        bs2.Add(b, 0, wx.ALL, 5)
        bs2.AddStretchSpacer(1)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(bs1, 0, wx.ALL, 5)
        line = wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL)
        sizer.Add(line, 0,
                  wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 0)
        sizer.Add(gbSizer, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(bs2, 0, wx.ALL | wx.EXPAND, 0)

        bs3 = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, wx.ID_ANY, '出入库记录')
        label.SetFont(labelfont)
        bs3.Add(label, 0, wx.ALL, 0)

        sizer.Add(bs3, 0, wx.ALL, 5)
        line1 = wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL)
        sizer.Add(line1, 0,
                  wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 0)

        bs4 = wx.BoxSizer(wx.HORIZONTAL)
        label = wx.StaticText(self, wx.ID_ANY, '物品名称:')
        self.s_goodsname = wx.TextCtrl(self,
                                       wx.ID_ANY,
                                       size=(120, -1),
                                       style=wx.TE_PROCESS_ENTER)
        self.s_goodsname.SetMaxLength(16)
        self.Bind(wx.EVT_TEXT_ENTER, self.OnTextEnter, self.s_goodsname)

        bs4.Add(label, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                5)
        bs4.Add(self.s_goodsname, 0, wx.ALL | wx.EXPAND, 5)

        label = wx.StaticText(self, wx.ID_ANY, '登记日期:')
        self.registerDate = wx.adv.DatePickerCtrl(self,
                                                  size=(120, -1),
                                                  style=wx.adv.DP_DROPDOWN
                                                  | wx.adv.DP_SHOWCENTURY)
        self.registerDate.SetRange(
            wx.DateTime.Today().Subtract(wx.DateSpan(months=6)),
            wx.DateTime.Today())
        self.Bind(wx.adv.EVT_DATE_CHANGED, self.OnDateChanged,
                  self.registerDate)

        bs4.Add(label, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL,
                5)
        bs4.Add(self.registerDate, 0, wx.ALL | wx.EXPAND, 5)
        cBtn = wx.ContextHelpButton(self)
        cBtn.SetHelpText("默认显示当天登记的记录,并且可以对记录进行删除和修改操作。")
        bs4.Add(cBtn, 0, wx.ALL | wx.EXPAND, 5)

        bs5 = wx.BoxSizer(wx.VERTICAL)
        self.list = SockListCtrl(self,
                                 -1,
                                 style=wx.LC_REPORT | wx.LC_SINGLE_SEL
                                 | wx.BORDER_NONE | wx.LC_HRULES
                                 | wx.LC_VRULES)
        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
        #self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)
        #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)

        bs5.Add(self.list, 1, wx.ALL | wx.EXPAND, 5)

        sizer.Add(bs4, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(bs5, 1, wx.ALL | wx.EXPAND, 5)
        self.SetSizer(sizer)

        self.goodsId = None
        self.currentItem = None

        model.goodsDeatilModel.addListener(self.OnUpdate)
        self.queryStocksByDate()

    def queryStocksByDate(self):
        registerDate = self.registerDate.GetValue().Format('%Y-%m-%d')
        goodsName = self.s_goodsname.GetValue().strip()
        result = stockservice.get_stocks({
            'goods_name': goodsName,
            'startdate': registerDate
        })
        self.setData(result)

    def OnDateChanged(self, evt):
        self.queryStocksByDate()

    def OnTextEnter(self, evt):
        self.queryStocksByDate()

    def OnRightClick(self, evt):
        # 只第一次绑定事件
        if not hasattr(self, "removeId"):
            self.removeId = wx.NewIdRef()
            self.editId = wx.NewIdRef()

            self.Bind(wx.EVT_MENU, self.OnDelete, id=self.removeId)
            #self.Bind(wx.EVT_MENU, self.OnEdit, id=self.editId)

        menu = wx.Menu()
        menu.Append(self.removeId, "删除")
        #menu.Append(self.editId, "编辑")
        self.PopupMenu(menu)
        menu.Destroy()


#     def OnEdit(self, evt):
#         if self.currentItem is not None:
#             self.list.EditLabel(self.currentItem)
#         else:
#             wx.MessageBox('请选择一条记录', '温馨提示', wx.OK_DEFAULT|wx.ICON_WARNING)
#
#     def OnItemSelected(self, event):
#         self.list.OpenEditor(5, event.Index)

    def OnUpdate(self, m):
        self.tc_goodsname.SetValue(m.data['GOODS_NAME'])
        self.tc_goodsunit.SetValue(m.data['GOODS_UNIT'])
        self.tc_goodsprice.SetValue(str(m.data['GOODS_PRICE']))
        self.tc_goodcatagory.SetValue(m.data['CATAGORY_NAME'])
        self.goodsId = m.data['ID']

    def OnInStock(self, evt):
        self.SaveStock(1)

    def OnOutStock(self, evt):
        self.SaveStock(0)

    def SaveStock(self, stock_type):
        if self.goodsId is None:
            wx.MessageBox('请在左侧选择要登记的物品!', '温馨提示',
                          wx.YES_DEFAULT | wx.ICON_EXCLAMATION)
            return

        # 输入值校验
        goodnum = self.tc_goodsNum.GetValue()
        if goodnum is None:
            wx.MessageBox('请输入物品数量!', '温馨提示',
                          wx.YES_DEFAULT | wx.ICON_EXCLAMATION)
            self.tc_goodsNum.SetBackgroundColour("pink")
            self.tc_goodsNum.SetFocus()
            self.tc_goodsNum.Refresh()
            return
        elif goodnum < 1:
            wx.MessageBox('物品数量至少为1', '温馨提示',
                          wx.YES_DEFAULT | wx.ICON_EXCLAMATION)
            self.tc_goodsNum.SetBackgroundColour("pink")
            self.tc_goodsNum.SetFocus()
            self.tc_goodsNum.Refresh()
            return
        else:
            self.tc_goodsNum.SetBackgroundColour(
                wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
            self.tc_goodsNum.Refresh()

        goodunit = self.tc_goodsunit.GetValue().strip()
        if goodunit is None or goodunit == '':
            wx.MessageBox('请输入物品规格!', '温馨提示',
                          wx.YES_DEFAULT | wx.ICON_EXCLAMATION)
            self.tc_goodsunit.SetBackgroundColour("pink")
            self.tc_goodsunit.SetFocus()
            self.tc_goodsunit.Refresh()
            return
        else:
            self.tc_goodsunit.SetBackgroundColour(
                wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
            self.tc_goodsunit.Refresh()

        stock_date = self.op_date.GetValue().Format('%Y-%m-%d')
        goods_id = self.goodsId
        goodunit = self.tc_goodsunit.GetValue().strip()
        goodprice = self.tc_goodsprice.GetValue().strip()
        if goodprice != '':
            pattern = re.compile('^[0-9]*\.?[0-9]{,2}$')
            if re.match(pattern, goodprice) is None:
                wx.MessageBox('单价不符合要求的格式', '温馨提示',
                              wx.YES_DEFAULT | wx.ICON_EXCLAMATION)
                return

        goods_num = self.tc_goodsNum.GetValue()
        op_person = self.tc_op.GetValue().strip()
        op_area = self.tc_address.GetValue().strip()

        params = {
            'STOCK_TYPE': stock_type,
            'STOCK_DATE': stock_date,
            'GOODS_ID': goods_id,
            'GOODS_NUM': goods_num,
            'GOODS_UNIT': goodunit,
            'GOODS_PRICE': goodprice,
            'OP_PERSON': op_person,
            'OP_AREA': op_area
        }

        stockservice.add_stock(params)
        wx.MessageBox('物品登记成功!', '温馨提示', wx.OK | wx.ICON_INFORMATION)
        self.queryStocksByDate()

    def OnDelete(self, event):
        count = self.list.SelectedItemCount
        if count < 1:
            dial = wx.MessageDialog(self, '请选择要删除的记录!', '温馨提示', wx.OK)
            dial.ShowModal()
            dial.Destroy()
        else:
            dlg = wx.MessageDialog(None, u"确定要删除该条记录吗?删除将不可恢复", u"温馨提示",
                                   wx.YES_NO | wx.ICON_QUESTION)
            if dlg.ShowModal() == wx.ID_YES:
                index = self.list.GetFirstSelected()
                item = self.list.GetItem(index)
                stockId = item.GetData()

                result = stockservice.delete_stock(stockId)
                if result > 0:
                    self.list.DeleteItem(index)
                    dial = wx.MessageDialog(self, '记录已经成功删除!', '温馨提示', wx.OK)
                    dial.ShowModal()
                    dial.Destroy()
            dlg.Destroy()

    def setData(self, data):
        self.list.DeleteAllItems()
        self.list.data = data
        for idx, row in enumerate(data):
            index = self.list.InsertItem(self.list.GetItemCount(),
                                         str(idx + 1))
            for col, text in enumerate(row[1:]):
                if not text:
                    text = ''
                if col == 0:
                    text = '入库' if text == 1 else '出库'
                self.list.SetItem(index, col + 1, str(text))
            self.list.SetItemData(index, row[0])

        self.list.SetColumnWidth(2, wx.LIST_AUTOSIZE)

    def OnFloatChar(self, evt):
        key = evt.GetKeyCode()
        if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255 or key == 46:
            evt.Skip()
            return
        if chr(key).isdigit():
            evt.Skip()
            return
        return

    def OnReset(self, evt):
        self.goodsId = None
        self.tc_goodsname.SetValue('')
        self.tc_goodsunit.SetValue('')
        self.tc_goodsprice.SetValue('')
        self.tc_goodcatagory.SetValue('')
        self.tc_goodsNum.SetValue(None)
        self.tc_op.SetValue('')
        self.tc_address.SetValue('')
        self.op_date.SetValue(wx.DateTime.Today())
Ejemplo n.º 2
0
class DmgPatternEditorDlg(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self,
                           parent,
                           id=wx.ID_ANY,
                           title=u"Damage Pattern Editor",
                           size=wx.Size(400, 240))

        self.block = False
        self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        self.headerSizer = headerSizer = wx.BoxSizer(wx.HORIZONTAL)

        cDP = service.DamagePattern.getInstance()

        self.choices = cDP.getDamagePatternList()
        # Remove "Uniform" and "Selected Ammo" Damage Patterns
        for dp in self.choices:
            if dp.name in ("Uniform", "Selected Ammo"):
                self.choices.remove(dp)
        # Sort the remaining list and continue on
        self.choices.sort(key=lambda p: p.name)
        self.ccDmgPattern = wx.Choice(self,
                                      choices=map(lambda p: p.name,
                                                  self.choices))
        self.ccDmgPattern.Bind(wx.EVT_CHOICE, self.patternChanged)
        self.ccDmgPattern.SetSelection(0)

        self.namePicker = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER)
        self.namePicker.Bind(wx.EVT_TEXT_ENTER, self.processRename)
        self.namePicker.Hide()

        self.btnSave = wx.Button(self, wx.ID_SAVE)
        self.btnSave.Hide()
        self.btnSave.Bind(wx.EVT_BUTTON, self.processRename)

        size = None
        headerSizer.Add(self.ccDmgPattern, 1,
                        wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.LEFT, 3)
        buttons = (("new", wx.ART_NEW),
                   ("rename", bitmapLoader.getBitmap("rename", "icons")),
                   ("copy", wx.ART_COPY), ("delete", wx.ART_DELETE))
        for name, art in buttons:
            bitmap = wx.ArtProvider.GetBitmap(
                art, wx.ART_BUTTON) if name != "rename" else art
            btn = wx.BitmapButton(self, wx.ID_ANY, bitmap)
            if size is None:
                size = btn.GetSize()

            btn.SetMinSize(size)
            btn.SetMaxSize(size)

            btn.Layout()
            setattr(self, name, btn)
            btn.Enable(True)
            btn.SetToolTipString("%s pattern" % name.capitalize())
            headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL)

        mainSizer.Add(headerSizer, 0, wx.EXPAND | wx.ALL, 2)

        self.sl = wx.StaticLine(self)
        mainSizer.Add(self.sl, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5)

        contentSizer = wx.BoxSizer(wx.VERTICAL)
        self.embitmap = bitmapLoader.getBitmap("em_big", "icons")
        self.thermbitmap = bitmapLoader.getBitmap("thermal_big", "icons")
        self.kinbitmap = bitmapLoader.getBitmap("kinetic_big", "icons")
        self.expbitmap = bitmapLoader.getBitmap("explosive_big", "icons")

        dmgeditSizer = wx.FlexGridSizer(2, 4, 0, 2)
        dmgeditSizer.AddGrowableCol(1)
        dmgeditSizer.AddGrowableCol(2)
        dmgeditSizer.SetFlexibleDirection(wx.BOTH)
        dmgeditSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)

        width = -1
        defSize = wx.Size(width, -1)

        self.editEm = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition, defSize,
                              wx.TE_RIGHT)
        dmgeditSizer.Add(self.editEm, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        self.bmpEM = wx.StaticBitmap(self, wx.ID_ANY, self.embitmap)
        dmgeditSizer.Add(self.bmpEM, 0,
                         wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL,
                         5)

        self.bmpTHERM = wx.StaticBitmap(self, wx.ID_ANY, self.thermbitmap)
        dmgeditSizer.Add(
            self.bmpTHERM, 0, wx.ALIGN_CENTER_HORIZONTAL
            | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5)

        self.editThermal = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition,
                                   defSize, 0)
        dmgeditSizer.Add(self.editThermal, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        self.editKinetic = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition,
                                   defSize, wx.TE_RIGHT)
        dmgeditSizer.Add(self.editKinetic, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        self.bmpKIN = wx.StaticBitmap(self, wx.ID_ANY, self.kinbitmap)
        dmgeditSizer.Add(self.bmpKIN, 0,
                         wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL,
                         5)

        self.bmpEXP = wx.StaticBitmap(self, wx.ID_ANY, self.expbitmap)
        dmgeditSizer.Add(
            self.bmpEXP, 0, wx.ALIGN_CENTER_HORIZONTAL
            | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 5)

        self.editExplosive = IntCtrl(self, wx.ID_ANY, 0, wx.DefaultPosition,
                                     defSize, 0)
        dmgeditSizer.Add(self.editExplosive, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)

        contentSizer.Add(dmgeditSizer, 1, wx.EXPAND | wx.ALL, 5)
        self.slfooter = wx.StaticLine(self)
        contentSizer.Add(self.slfooter, 0, wx.EXPAND | wx.TOP, 5)

        footerSizer = wx.BoxSizer(wx.HORIZONTAL)

        perSizer = wx.BoxSizer(wx.VERTICAL)

        self.stPercentages = wx.StaticText(self, wx.ID_ANY, u"")
        self.stPercentages.Wrap(-1)
        perSizer.Add(self.stPercentages, 0, wx.BOTTOM | wx.LEFT, 5)

        footerSizer.Add(perSizer, 0, 0, 5)

        self.totSizer = wx.BoxSizer(wx.VERTICAL)

        self.stTotal = wx.StaticText(self, wx.ID_ANY, u"")
        self.stTotal.Wrap(-1)
        self.totSizer.Add(self.stTotal, 0,
                          wx.ALIGN_RIGHT | wx.BOTTOM | wx.RIGHT, 5)

        footerSizer.Add(self.totSizer, 1, 0, 5)

        contentSizer.Add(footerSizer, 0, wx.EXPAND, 5)

        mainSizer.Add(contentSizer, 1, wx.EXPAND, 0)

        self.SetSizer(mainSizer)

        self.Layout()
        bsize = self.GetBestSize()
        self.SetSize((-1, bsize.height))

        self.editEm.SetLimited(True)
        self.editThermal.SetLimited(True)
        self.editKinetic.SetLimited(True)
        self.editExplosive.SetLimited(True)

        self.editEm.SetMin(0)
        self.editThermal.SetMin(0)
        self.editKinetic.SetMin(0)
        self.editExplosive.SetMin(0)

        self.editEm.SetMax(99999)
        self.editThermal.SetMax(99999)
        self.editKinetic.SetMax(99999)
        self.editExplosive.SetMax(99999)

        self.new.Bind(wx.EVT_BUTTON, self.newPattern)
        self.rename.Bind(wx.EVT_BUTTON, self.renamePattern)
        self.copy.Bind(wx.EVT_BUTTON, self.copyPattern)
        self.delete.Bind(wx.EVT_BUTTON, self.deletePattern)

        self.editEm.Bind(wx.EVT_TEXT, self.ValuesUpdated)
        self.editThermal.Bind(wx.EVT_TEXT, self.ValuesUpdated)
        self.editKinetic.Bind(wx.EVT_TEXT, self.ValuesUpdated)
        self.editExplosive.Bind(wx.EVT_TEXT, self.ValuesUpdated)

        self.patternChanged()

    def ValuesUpdated(self, event=None):
        if self.block:
            return

        p = self.getActivePattern()
        p.emAmount = self._EM = self.editEm.GetValue()
        p.thermalAmount = self._THERM = self.editThermal.GetValue()
        p.kineticAmount = self._KIN = self.editKinetic.GetValue()
        p.explosiveAmount = self._EXP = self.editExplosive.GetValue()
        total = self._EM + self._THERM + self._KIN + self._EXP
        format = "EM: % 3d%% THERM: % 3d%% KIN: % 3d%% EXP: % 3d%%"
        if total > 0:
            ltext = format % (self._EM * 100 / total,
                              self._THERM * 100 / total,
                              self._KIN * 100 / total, self._EXP * 100 / total)
        else:
            ltext = format % (0, 0, 0, 0)

        ttext = "Total: % 6d" % (total)
        self.stPercentages.SetLabel(ltext)
        self.stTotal.SetLabel(ttext)
        self.totSizer.Layout()

        if event is not None:
            event.Skip()

        service.DamagePattern.getInstance().saveChanges(p)

    def restrict(self):
        self.editEm.Enable(False)
        self.editExplosive.Enable(False)
        self.editKinetic.Enable(False)
        self.editThermal.Enable(False)
        self.rename.Enable(False)
        self.delete.Enable(False)

    def unrestrict(self):
        self.editEm.Enable()
        self.editExplosive.Enable()
        self.editKinetic.Enable()
        self.editThermal.Enable()
        self.rename.Enable()
        self.delete.Enable()

    def getActivePattern(self):
        if len(self.choices) == 0:
            return None

        return self.choices[self.ccDmgPattern.GetSelection()]

    def patternChanged(self, event=None):
        p = self.getActivePattern()
        if p is None:
            return

        if p.name == "Uniform" or p.name == "Selected Ammo":
            self.restrict()
        else:
            self.unrestrict()

        self.block = True
        for field in ("em", "thermal", "kinetic", "explosive"):
            edit = getattr(self, "edit%s" % field.capitalize())
            amount = getattr(p, "%sAmount" % field)
            edit.SetValue(amount)

        self.block = False
        self.ValuesUpdated()

    def newPattern(self, event):
        cDP = service.DamagePattern.getInstance()
        p = cDP.newPattern()
        self.choices.append(p)
        id = self.ccDmgPattern.Append(p.name)
        self.ccDmgPattern.SetSelection(id)
        self.btnSave.SetLabel("Create")
        self.renamePattern()

    def renamePattern(self, event=None):
        if event is not None:
            self.btnSave.SetLabel("Rename")

        self.ccDmgPattern.Hide()
        self.namePicker.Show()
        self.headerSizer.Replace(self.ccDmgPattern, self.namePicker)
        self.namePicker.SetFocus()
        self.namePicker.SetValue(self.getActivePattern().name)

        for btn in (self.new, self.rename, self.delete, self.copy):
            btn.Hide()
            self.headerSizer.Remove(btn)

        self.headerSizer.Add(self.btnSave, 0, wx.ALIGN_CENTER)
        self.btnSave.Show()
        self.headerSizer.Layout()
        if event is not None:
            event.Skip()

    def processRename(self, event):
        newName = self.namePicker.GetLineText(0)
        self.stPercentages.SetLabel("")
        self.stTotal.SetLabel("")
        p = self.getActivePattern()
        for pattern in self.choices:
            if pattern.name == newName and p != pattern:
                self.stPercentages.SetLabel(
                    "Name already used, please pick another")
                return

        cDP = service.DamagePattern.getInstance()
        cDP.renamePattern(p, newName)

        self.headerSizer.Replace(self.namePicker, self.ccDmgPattern)
        self.ccDmgPattern.Show()
        self.namePicker.Hide()
        self.btnSave.Hide()
        self.headerSizer.Remove(self.btnSave)
        for btn in (self.new, self.rename, self.delete, self.copy):
            self.headerSizer.Add(btn, 0, wx.ALIGN_CENTER_VERTICAL)
            btn.Show()

        sel = self.ccDmgPattern.GetSelection()
        self.ccDmgPattern.Delete(sel)
        self.ccDmgPattern.Insert(newName, sel)
        self.ccDmgPattern.SetSelection(sel)
        self.ValuesUpdated()

    def copyPattern(self, event):
        cDP = service.DamagePattern.getInstance()
        p = cDP.copyPattern(self.getActivePattern())
        self.choices.append(p)
        id = self.ccDmgPattern.Append(p.name)
        self.ccDmgPattern.SetSelection(id)
        self.btnSave.SetLabel("Copy")
        self.renamePattern()
        self.patternChanged()

    def deletePattern(self, event):
        cDP = service.DamagePattern.getInstance()
        sel = self.ccDmgPattern.GetSelection()
        cDP.deletePattern(self.getActivePattern())
        self.ccDmgPattern.Delete(sel)
        self.ccDmgPattern.SetSelection(max(0, sel - 1))
        del self.choices[sel]
        self.patternChanged()

    def __del__(self):
        pass