class AudioOptions(SizedFrame): def __init__(self): super(AudioOptions, self).__init__(application.frame, title='Audio Options') p = self.GetContentsPane() add_accelerator(self, 'ESCAPE', lambda event: self.Close(True)) self.default_volume = config.system['volume'] self.default_frequency = config.system['frequency'] self.default_pan = config.system['pan'] p.SetSizerType('form') wx.StaticText(p, label='&Output Device') self.device = wx.Choice(p, choices=sorted( application.output.get_device_names())) self.device.SetStringSelection(config.system['output_device_name']) self.device.Bind( wx.EVT_CHOICE, lambda event: set_output_device(self.device.GetStringSelection())) wx.StaticText(p, label='&Volume') self.volume = wx.Slider(p, style=wx.VERTICAL) self.volume.SetValue(self.default_volume) self.volume.Bind(wx.EVT_SLIDER, lambda event: set_volume(self.volume.GetValue())) wx.StaticText(p, label='&Pan') self.pan = wx.Slider(p, style=wx.HORIZONTAL) self.pan.SetValue(self.default_pan) self.pan.Bind(wx.EVT_SLIDER, lambda event: set_pan(self.pan.GetValue())) wx.StaticText(p, label='&Frequency') self.frequency = IntCtrl(p, value=self.default_frequency, min=min_frequency, max=max_frequency, limited=True) self.frequency.Bind(EVT_INT, set_frequency(self.frequency.GetValue())) add_accelerator( self.frequency, 'UP', lambda event: self.update_frequency( min(self.frequency.GetMax(), self.frequency.GetValue() + 100))) add_accelerator( self.frequency, 'DOWN', lambda event: self.update_frequency( max(self.frequency.GetMin(), self.frequency.GetValue() - 100))) self.ok = wx.Button(p, label='&OK') self.ok.Bind(wx.EVT_BUTTON, lambda event: self.Close(True)) self.restore = wx.Button(p, label='&Restore Defaults') self.restore.Bind(wx.EVT_BUTTON, self.on_restore) self.Show(True) self.Maximize(True) def update_frequency(self, value): """Update frequency.""" self.frequency.SetValue(value) set_frequency(value) def on_restore(self, event): """Cancel button was pressed.""" set_volume(100) set_pan(50) set_frequency(44100)
class NumberEntryDialog(wx.Dialog): def __init__(self, parent, message="Please enter a number.", caption="Number Entry", prompt="Number:", value=None, min=None, max=None): super(NumberEntryDialog, self).__init__(parent, title=caption) kwargs = { 'parent': self, 'min': min, 'max': max, 'value': value, 'limited': True, 'allow_none': False, } self.intctrl = IntCtrl( **{k: v for k, v in kwargs.iteritems() if v is not None}) sizer = wx.BoxSizer(wx.VERTICAL) if message: sizer.Add(wx.StaticText(self, label=message), flag=wx.ALL, border=4) hSizer = wx.BoxSizer(wx.HORIZONTAL) if prompt: hSizer.Add(wx.StaticText(self, label=prompt), flag=wx.ALIGN_CENTER_VERTICAL) hSizer.Add(self.intctrl, 1, flag=wx.EXPAND) sizer.Add(hSizer, flag=wx.ALL | wx.EXPAND, border=4) btnsizer = wx.StdDialogButtonSizer() btn = wx.Button(self, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) btn = wx.Button(self, wx.ID_CANCEL) btnsizer.AddButton(btn) btnsizer.Realize() sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) self.SetSizer(sizer) self.SetSize(200, 50 * (2 + int(bool(message)))) #self.Fit() self.CenterOnParent() def SetValue(self, v): self.intctrl.SetValue(v) def GetValue(self): return self.intctrl.GetValue()
class IntegerEditPanel(wx.Panel): edits = Integral def __init__(self, *args, **kwargs): super(IntegerEditPanel, self).__init__(*args, **kwargs) sizer = wx.BoxSizer(wx.HORIZONTAL) self.intspin = wx.SpinCtrl(self, style=wx.ALIGN_RIGHT | wx.SP_ARROW_KEYS) self.intctrl = IntCtrl(self, limited=True, allow_long=True, style=wx.ALIGN_RIGHT) self.floatctrl = wx.TextCtrl(self, style=wx.ALIGN_RIGHT) self.floatchk = wx.CheckBox(self, label='Treat as floating-point') sizer.Add(self.intspin, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.intctrl, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.floatctrl, flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.floatchk, flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=10) self.Bind(wx.EVT_CHECKBOX, self.OnFloatToggle, self.floatchk) self.SetSizer(sizer) def SetValue(self, value, kind): self.kind = kind self.Freeze() self.floatchk.Value = False self.floatctrl.Hide() if type(value).maxval > sys.maxsize: self.intspin.Hide() self.intctrl.Show() self.intctrl.SetBounds(type(value).minval, type(value).maxval) self.intctrl.SetValue(long(value)) else: self.intctrl.Hide() self.intspin.Show() self.intspin.SetRange(type(value).minval, type(value).maxval) self.intspin.SetValue(value) if kind.size in (4, 8): self.floatchk.Show() self.intfmt = kind.format[False] self.floatfmt = FLOAT32.format[ False] if kind.size == 4 else FLOAT64.format[False] else: self.floatchk.Hide() self.Layout() self.Thaw() def GetValue(self): if self.intspin.Shown: return self.kind(self.intspin.GetValue()) elif self.intctrl.Shown: try: return self.kind(self.intctrl.GetValue()) except ValueError, e: raise ValueError, "%r" % e else:
class JumpToPostDialog(SquareDialog): def __init__(self, buffer=None, *args, **kwargs): super(JumpToPostDialog, self).__init__(title=_("Jump to Item in %s" % buffer.display_name), *args, **kwargs) #First Row wx.StaticText(parent=self.pane, label=_("Enter item number to jump to, 1 to %s:") % str(len(buffer))) self.number = IntCtrl(parent=self.pane) self.number.SetValue(int(len(buffer) - buffer.index)) self.number.SetSizerProps(expand=True) self.finish_setup()
class trimdlg(wx.Dialog): def __init__(self, parent, id, title): pre = wx.PreDialog() pre.Create(parent, id, title) self.this = pre.this sizer = wx.BoxSizer(wx.VERTICAL) self.input = IntCtrl(self, -1) self.input.SetValue(0) sizer.Add(self.input, 0, wx.ALL, 5) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(wx.Button(self, wx.ID_OK), 0, wx.ALIGN_CENTRE | wx.ALL, 5), box.Add(wx.Button(self, wx.ID_CANCEL), 0, wx.ALIGN_CENTRE | wx.ALL, 5), sizer.AddSizer(box, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) self.SetSizer(sizer) sizer.Fit(self) self.SetAutoLayout(True)
class PFFittingEnginePref(PreferenceView): title = "Fitting Engine" def __init__(self): self.dirtySettings = False def refreshPanel(self, fit): pass # noinspection PyAttributeOutsideInit def populatePanel(self, panel): self.mainFrame = gui.mainFrame.MainFrame.getInstance() mainSizer = wx.BoxSizer(wx.VERTICAL) helpCursor = wx.Cursor(wx.CURSOR_QUESTION_ARROW) self.engine_settings = EOSSettings.getInstance() self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0) self.stTitle.Wrap(-1) self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString)) mainSizer.Add(self.stTitle, 0, wx.EXPAND | wx.ALL, 5) self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) self.cbGlobalForceReload = wx.CheckBox(panel, wx.ID_ANY, "Factor in reload time when calculating capacitor usage, damage, and tank.", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbGlobalForceReload, 0, wx.ALL | wx.EXPAND, 5) self.cbStrictSkillLevels = wx.CheckBox(panel, wx.ID_ANY, "Enforce strict skill level requirements", wx.DefaultPosition, wx.DefaultSize, 0) self.cbStrictSkillLevels.SetCursor(helpCursor) self.cbStrictSkillLevels.SetToolTip(wx.ToolTip( 'When enabled, skills will check their dependencies\' requirements when their levels change and reset ' + 'skills that no longer meet the requirement.\neg: Setting Drones from level V to IV will reset the Heavy ' + 'Drone Operation skill, as that requires Drones V')) mainSizer.Add(self.cbStrictSkillLevels, 0, wx.ALL | wx.EXPAND, 5) self.cbUniversalAdaptiveArmorHardener = wx.CheckBox(panel, wx.ID_ANY, "When damage profile is Uniform, set Reactive Armor " + "Hardener to match (old behavior).", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbUniversalAdaptiveArmorHardener, 0, wx.ALL | wx.EXPAND, 5) spoolup_sizer = wx.BoxSizer(wx.HORIZONTAL) self.spool_up_label = wx.StaticText(panel, wx.ID_ANY, "Global Default Spoolup Percentage:", wx.DefaultPosition, wx.DefaultSize, 0) self.spool_up_label.Wrap(-1) self.spool_up_label.SetCursor(helpCursor) self.spool_up_label.SetToolTip( wx.ToolTip('The amount of spoolup to use by default on module which support it. Can be changed on a per-module basis')) spoolup_sizer.Add(self.spool_up_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.spoolup_value = IntCtrl(panel, min=0, max=100, limited=True) spoolup_sizer.Add(self.spoolup_value , 0, wx.ALL, 5) mainSizer.Add(spoolup_sizer, 0, wx.ALL | wx.EXPAND, 0) # Future code once new cap sim is implemented ''' self.cbGlobalForceReactivationTimer = wx.CheckBox( panel, wx.ID_ANY, "Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 ) mainSizer.Add( self.cbGlobalForceReactivationTimer, 0, wx.ALL|wx.EXPAND, 5 ) text = " Ignores reactivation timer when calculating capacitor usage,\n damage, and tank." self.cbGlobalForceReactivationTimerText = wx.StaticText( panel, wx.ID_ANY, text, wx.DefaultPosition, wx.DefaultSize, 0 ) self.cbGlobalForceReactivationTimerText.Wrap( -1 ) self.cbGlobalForceReactivationTimerText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) mainSizer.Add( self.cbGlobalForceReactivationTimerText, 0, wx.ALL, 5 ) ''' # Future code for mining laser crystal ''' self.cbGlobalMiningSpecialtyCrystal = wx.CheckBox( panel, wx.ID_ANY, "Factor in reactivation timer", wx.DefaultPosition, wx.DefaultSize, 0 ) mainSizer.Add( self.cbGlobalMiningSpecialtyCrystal, 0, wx.ALL|wx.EXPAND, 5 ) text = " If enabled, displays the Specialty Crystal mining amount.\n This is the amount mined when using crystals and mining the matching asteroid." self.cbGlobalMiningSpecialtyCrystalText = wx.StaticText( panel, wx.ID_ANY, text, wx.DefaultPosition, wx.DefaultSize, 0 ) self.cbGlobalMiningSpecialtyCrystalText.Wrap( -1 ) self.cbGlobalMiningSpecialtyCrystalText.SetFont( wx.Font( 10, 70, 90, 90, False, wx.EmptyString ) ) mainSizer.Add( self.cbGlobalMiningSpecialtyCrystalText, 0, wx.ALL, 5 ) ''' self.sFit = Fit.getInstance() self.cbGlobalForceReload.SetValue(self.sFit.serviceFittingOptions["useGlobalForceReload"]) self.cbGlobalForceReload.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalForceReloadStateChange) self.cbStrictSkillLevels.SetValue(self.engine_settings.get("strictSkillLevels")) self.cbStrictSkillLevels.Bind(wx.EVT_CHECKBOX, self.OnCBStrictSkillLevelsChange) self.cbUniversalAdaptiveArmorHardener.SetValue(self.engine_settings.get("useStaticAdaptiveArmorHardener")) self.cbUniversalAdaptiveArmorHardener.Bind(wx.EVT_CHECKBOX, self.OnCBUniversalAdaptiveArmorHardenerChange) self.spoolup_value.SetValue(int(self.engine_settings.get("globalDefaultSpoolupPercentage") * 100)) self.spoolup_value.Bind(wx.lib.intctrl.EVT_INT, self.OnSpoolupChange) panel.SetSizer(mainSizer) panel.Layout() def OnSpoolupChange(self, event): self.engine_settings.set("globalDefaultSpoolupPercentage", self.spoolup_value.GetValue() / 100) def OnCBGlobalForceReloadStateChange(self, event): fitIDs = self.sFit.toggleFactorReload(value=bool(self.cbGlobalForceReload.GetValue())) wx.PostEvent(self.mainFrame, GE.FitChanged(fitIDs=tuple(fitIDs))) def OnCBStrictSkillLevelsChange(self, event): self.engine_settings.set("strictSkillLevels", self.cbStrictSkillLevels.GetValue()) def OnCBUniversalAdaptiveArmorHardenerChange(self, event): self.engine_settings.set("useStaticAdaptiveArmorHardener", self.cbUniversalAdaptiveArmorHardener.GetValue()) def getImage(self): return BitmapLoader.getBitmap("settings_fitting", "gui") def OnWindowLeave(self, event): # We don't want to do anything when they leave, # but in the future we might. pass
class PFGeneralPref(PreferenceView): title = "General" def populatePanel(self, panel): self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.dirtySettings = False self.openFitsSettings = SettingsProvider.getInstance().getSettings( "pyfaPrevOpenFits", { "enabled": False, "pyfaOpenFits": [] }) helpCursor = wx.StockCursor(wx.CURSOR_QUESTION_ARROW) mainSizer = wx.BoxSizer(wx.VERTICAL) self.stTitle = wx.StaticText(panel, wx.ID_ANY, self.title, wx.DefaultPosition, wx.DefaultSize, 0) self.stTitle.Wrap(-1) self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString)) mainSizer.Add(self.stTitle, 0, wx.ALL, 5) self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) self.cbGlobalChar = wx.CheckBox(panel, wx.ID_ANY, u"Use global character", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbGlobalChar, 0, wx.ALL | wx.EXPAND, 5) self.cbGlobalDmgPattern = wx.CheckBox(panel, wx.ID_ANY, u"Use global damage pattern", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbGlobalDmgPattern, 0, wx.ALL | wx.EXPAND, 5) self.cbCompactSkills = wx.CheckBox(panel, wx.ID_ANY, u"Compact skills needed tooltip", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbCompactSkills, 0, wx.ALL | wx.EXPAND, 5) self.cbFitColorSlots = wx.CheckBox(panel, wx.ID_ANY, u"Color fitting view by slot", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbFitColorSlots, 0, wx.ALL | wx.EXPAND, 5) self.cbReopenFits = wx.CheckBox(panel, wx.ID_ANY, u"Reopen previous fits on startup", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbReopenFits, 0, wx.ALL | wx.EXPAND, 5) self.cbRackSlots = wx.CheckBox(panel, wx.ID_ANY, u"Separate Racks", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbRackSlots, 0, wx.ALL | wx.EXPAND, 5) labelSizer = wx.BoxSizer(wx.VERTICAL) self.cbRackLabels = wx.CheckBox(panel, wx.ID_ANY, u"Show Rack Labels", wx.DefaultPosition, wx.DefaultSize, 0) labelSizer.Add(self.cbRackLabels, 0, wx.ALL | wx.EXPAND, 5) mainSizer.Add(labelSizer, 0, wx.LEFT | wx.EXPAND, 30) self.cbShowTooltip = wx.CheckBox(panel, wx.ID_ANY, u"Show tab tooltips", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbShowTooltip, 0, wx.ALL | wx.EXPAND, 5) self.cbMarketShortcuts = wx.CheckBox(panel, wx.ID_ANY, u"Show market shortcuts", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbMarketShortcuts, 0, wx.ALL | wx.EXPAND, 5) self.cbGaugeAnimation = wx.CheckBox(panel, wx.ID_ANY, u"Animate gauges", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbGaugeAnimation, 0, wx.ALL | wx.EXPAND, 5) self.cbExportCharges = wx.CheckBox(panel, wx.ID_ANY, u"Export loaded charges", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbExportCharges, 0, wx.ALL | wx.EXPAND, 5) self.cbOpenFitInNew = wx.CheckBox( panel, wx.ID_ANY, u"Open fittings in a new page by default", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbOpenFitInNew, 0, wx.ALL | wx.EXPAND, 5) self.cbShowShipBrowserTooltip = wx.CheckBox( panel, wx.ID_ANY, u"Show ship browser tooltip", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbShowShipBrowserTooltip, 0, wx.ALL | wx.EXPAND, 5) priceSizer = wx.BoxSizer(wx.HORIZONTAL) self.stDefaultSystem = wx.StaticText(panel, wx.ID_ANY, u"Default Market Prices:", wx.DefaultPosition, wx.DefaultSize, 0) self.stDefaultSystem.Wrap(-1) priceSizer.Add(self.stDefaultSystem, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.chPriceSource = wx.Choice(panel, choices=sorted(Price.sources.keys())) self.chPriceSystem = wx.Choice(panel, choices=Price.systemsList.keys()) priceSizer.Add(self.chPriceSource, 1, wx.ALL | wx.EXPAND, 5) priceSizer.Add(self.chPriceSystem, 1, wx.ALL | wx.EXPAND, 5) mainSizer.Add(priceSizer, 0, wx.ALL | wx.EXPAND, 0) delayTimer = wx.BoxSizer(wx.HORIZONTAL) self.stMarketDelay = wx.StaticText(panel, wx.ID_ANY, u"Market Search Delay (ms):", wx.DefaultPosition, wx.DefaultSize, 0) self.stMarketDelay.Wrap(-1) self.stMarketDelay.SetCursor(helpCursor) self.stMarketDelay.SetToolTip( wx.ToolTip( 'The delay between a keystroke and the market search. Can help reduce lag when typing fast in the market search box.' )) delayTimer.Add(self.stMarketDelay, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.intDelay = IntCtrl(panel, max=1000, limited=True) delayTimer.Add(self.intDelay, 0, wx.ALL, 5) mainSizer.Add(delayTimer, 0, wx.ALL | wx.EXPAND, 0) self.sFit = Fit.getInstance() self.cbGlobalChar.SetValue( self.sFit.serviceFittingOptions["useGlobalCharacter"]) self.cbGlobalDmgPattern.SetValue( self.sFit.serviceFittingOptions["useGlobalDamagePattern"]) self.cbFitColorSlots.SetValue( self.sFit.serviceFittingOptions["colorFitBySlot"] or False) self.cbRackSlots.SetValue(self.sFit.serviceFittingOptions["rackSlots"] or False) self.cbRackLabels.SetValue( self.sFit.serviceFittingOptions["rackLabels"] or False) self.cbCompactSkills.SetValue( self.sFit.serviceFittingOptions["compactSkills"] or False) self.cbReopenFits.SetValue(self.openFitsSettings["enabled"]) self.cbShowTooltip.SetValue( self.sFit.serviceFittingOptions["showTooltip"] or False) self.cbMarketShortcuts.SetValue( self.sFit.serviceFittingOptions["showMarketShortcuts"] or False) self.cbGaugeAnimation.SetValue( self.sFit.serviceFittingOptions["enableGaugeAnimation"]) self.cbExportCharges.SetValue( self.sFit.serviceFittingOptions["exportCharges"]) self.cbOpenFitInNew.SetValue( self.sFit.serviceFittingOptions["openFitInNew"]) self.chPriceSource.SetStringSelection( self.sFit.serviceFittingOptions["priceSource"]) self.chPriceSystem.SetStringSelection( self.sFit.serviceFittingOptions["priceSystem"]) self.cbShowShipBrowserTooltip.SetValue( self.sFit.serviceFittingOptions["showShipBrowserTooltip"]) self.intDelay.SetValue( self.sFit.serviceFittingOptions["marketSearchDelay"]) self.cbGlobalChar.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalCharStateChange) self.cbGlobalDmgPattern.Bind(wx.EVT_CHECKBOX, self.OnCBGlobalDmgPatternStateChange) self.cbFitColorSlots.Bind(wx.EVT_CHECKBOX, self.onCBGlobalColorBySlot) self.cbRackSlots.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackSlots) self.cbRackLabels.Bind(wx.EVT_CHECKBOX, self.onCBGlobalRackLabels) self.cbCompactSkills.Bind(wx.EVT_CHECKBOX, self.onCBCompactSkills) self.cbReopenFits.Bind(wx.EVT_CHECKBOX, self.onCBReopenFits) self.cbShowTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowTooltip) self.cbMarketShortcuts.Bind(wx.EVT_CHECKBOX, self.onCBShowShortcuts) self.cbGaugeAnimation.Bind(wx.EVT_CHECKBOX, self.onCBGaugeAnimation) self.cbExportCharges.Bind(wx.EVT_CHECKBOX, self.onCBExportCharges) self.cbOpenFitInNew.Bind(wx.EVT_CHECKBOX, self.onCBOpenFitInNew) self.chPriceSource.Bind(wx.EVT_CHOICE, self.onPricesSourceSelection) self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection) self.cbShowShipBrowserTooltip.Bind(wx.EVT_CHECKBOX, self.onCBShowShipBrowserTooltip) self.intDelay.Bind(wx.lib.intctrl.EVT_INT, self.onMarketDelayChange) self.cbRackLabels.Enable(self.sFit.serviceFittingOptions["rackSlots"] or False) panel.SetSizer(mainSizer) panel.Layout() def onMarketDelayChange(self, event): self.sFit.serviceFittingOptions[ "marketSearchDelay"] = self.intDelay.GetValue() event.Skip() def onCBGlobalColorBySlot(self, event): self.sFit.serviceFittingOptions[ "colorFitBySlot"] = self.cbFitColorSlots.GetValue() fitID = self.mainFrame.getActiveFit() self.sFit.refreshFit(fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) event.Skip() def onCBGlobalRackSlots(self, event): self.sFit.serviceFittingOptions[ "rackSlots"] = self.cbRackSlots.GetValue() self.cbRackLabels.Enable(self.cbRackSlots.GetValue()) fitID = self.mainFrame.getActiveFit() self.sFit.refreshFit(fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) event.Skip() def onCBGlobalRackLabels(self, event): self.sFit.serviceFittingOptions[ "rackLabels"] = self.cbRackLabels.GetValue() fitID = self.mainFrame.getActiveFit() self.sFit.refreshFit(fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) event.Skip() def OnCBGlobalCharStateChange(self, event): self.sFit.serviceFittingOptions[ "useGlobalCharacter"] = self.cbGlobalChar.GetValue() event.Skip() def OnCBGlobalDmgPatternStateChange(self, event): self.sFit.serviceFittingOptions[ "useGlobalDamagePattern"] = self.cbGlobalDmgPattern.GetValue() event.Skip() def onCBCompactSkills(self, event): self.sFit.serviceFittingOptions[ "compactSkills"] = self.cbCompactSkills.GetValue() fitID = self.mainFrame.getActiveFit() self.sFit.refreshFit(fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) event.Skip() def onCBReopenFits(self, event): self.openFitsSettings["enabled"] = self.cbReopenFits.GetValue() def onCBShowTooltip(self, event): self.sFit.serviceFittingOptions[ "showTooltip"] = self.cbShowTooltip.GetValue() def onCBShowShortcuts(self, event): self.sFit.serviceFittingOptions[ "showMarketShortcuts"] = self.cbMarketShortcuts.GetValue() def onCBGaugeAnimation(self, event): self.sFit.serviceFittingOptions[ "enableGaugeAnimation"] = self.cbGaugeAnimation.GetValue() def onCBExportCharges(self, event): self.sFit.serviceFittingOptions[ "exportCharges"] = self.cbExportCharges.GetValue() def onCBOpenFitInNew(self, event): self.sFit.serviceFittingOptions[ "openFitInNew"] = self.cbOpenFitInNew.GetValue() def onCBShowShipBrowserTooltip(self, event): self.sFit.serviceFittingOptions[ "showShipBrowserTooltip"] = self.cbShowShipBrowserTooltip.GetValue( ) def getImage(self): return BitmapLoader.getBitmap("prefs_settings", "gui") def onPriceSelection(self, event): system = self.chPriceSystem.GetString( self.chPriceSystem.GetSelection()) self.sFit.serviceFittingOptions["priceSystem"] = system fitID = self.mainFrame.getActiveFit() self.sFit.refreshFit(fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) event.Skip() def onPricesSourceSelection(self, event): source = self.chPriceSource.GetString( self.chPriceSource.GetSelection()) self.sFit.serviceFittingOptions["priceSource"] = source
class ControlPanel(wx.Panel): """""" def __init__(self, parent, *args, **kwargs): """""" self.parent = parent self.stitch_plan = kwargs.pop('stitch_plan') self.target_stitches_per_second = kwargs.pop('stitches_per_second') self.target_duration = kwargs.pop('target_duration') kwargs['style'] = wx.BORDER_SUNKEN wx.Panel.__init__(self, parent, *args, **kwargs) self.statusbar = self.GetTopLevelParent().statusbar self.drawing_panel = None self.num_stitches = 1 self.current_stitch = 1 self.speed = 1 self.direction = 1 # Widgets self.btnMinus = wx.Button(self, -1, label='-') self.btnMinus.Bind(wx.EVT_BUTTON, self.animation_slow_down) self.btnMinus.SetToolTip(_('Slow down (arrow down)')) self.btnPlus = wx.Button(self, -1, label='+') self.btnPlus.Bind(wx.EVT_BUTTON, self.animation_speed_up) self.btnPlus.SetToolTip(_('Speed up (arrow up)')) self.btnBackwardStitch = wx.Button(self, -1, label='<|') self.btnBackwardStitch.Bind(wx.EVT_BUTTON, self.animation_one_stitch_backward) self.btnBackwardStitch.SetToolTip(_('Go on step backward (-)')) self.btnForwardStitch = wx.Button(self, -1, label='|>') self.btnForwardStitch.Bind(wx.EVT_BUTTON, self.animation_one_stitch_forward) self.btnForwardStitch.SetToolTip(_('Go on step forward (+)')) self.directionBtn = wx.Button(self, -1, label='<<') self.directionBtn.Bind(wx.EVT_BUTTON, self.on_direction_button) self.directionBtn.SetToolTip( _('Switch direction (arrow left | arrow right)')) self.pauseBtn = wx.Button(self, -1, label=_('Pause')) self.pauseBtn.Bind(wx.EVT_BUTTON, self.on_pause_start_button) self.pauseBtn.SetToolTip(_('Pause (P)')) self.restartBtn = wx.Button(self, -1, label=_('Restart')) self.restartBtn.Bind(wx.EVT_BUTTON, self.animation_restart) self.restartBtn.SetToolTip(_('Restart (R)')) self.quitBtn = wx.Button(self, -1, label=_('Quit')) self.quitBtn.Bind(wx.EVT_BUTTON, self.animation_quit) self.quitBtn.SetToolTip(_('Quit (Q)')) self.slider = wx.Slider(self, -1, value=1, minValue=1, maxValue=2, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.slider.Bind(wx.EVT_SLIDER, self.on_slider) self.stitchBox = IntCtrl(self, -1, value=1, min=1, max=2, limited=True, allow_none=False) self.stitchBox.Bind(wx.EVT_TEXT, self.on_stitch_box) # Layout self.vbSizer = vbSizer = wx.BoxSizer(wx.VERTICAL) self.hbSizer1 = hbSizer1 = wx.BoxSizer(wx.HORIZONTAL) self.hbSizer2 = hbSizer2 = wx.BoxSizer(wx.HORIZONTAL) hbSizer1.Add(self.slider, 1, wx.EXPAND | wx.ALL, 3) hbSizer1.Add(self.stitchBox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 2) vbSizer.Add(hbSizer1, 1, wx.EXPAND | wx.ALL, 3) hbSizer2.Add(self.btnMinus, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.btnPlus, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.btnBackwardStitch, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.btnForwardStitch, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.directionBtn, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.pauseBtn, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.restartBtn, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.quitBtn, 0, wx.EXPAND | wx.ALL, 2) vbSizer.Add(hbSizer2, 0, wx.EXPAND | wx.ALL, 3) self.SetSizerAndFit(vbSizer) # Keyboard Shortcuts shortcut_keys = [ (wx.ACCEL_NORMAL, wx.WXK_RIGHT, self.animation_forward), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_RIGHT, self.animation_forward), (wx.ACCEL_NORMAL, wx.WXK_LEFT, self.animation_reverse), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_LEFT, self.animation_reverse), (wx.ACCEL_NORMAL, wx.WXK_UP, self.animation_speed_up), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_UP, self.animation_speed_up), (wx.ACCEL_NORMAL, wx.WXK_DOWN, self.animation_slow_down), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_DOWN, self.animation_slow_down), (wx.ACCEL_NORMAL, ord('+'), self.animation_one_stitch_forward), (wx.ACCEL_NORMAL, ord('='), self.animation_one_stitch_forward), (wx.ACCEL_SHIFT, ord('='), self.animation_one_stitch_forward), (wx.ACCEL_NORMAL, wx.WXK_ADD, self.animation_one_stitch_forward), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_ADD, self.animation_one_stitch_forward), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_UP, self.animation_one_stitch_forward), (wx.ACCEL_NORMAL, ord('-'), self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, ord('_'), self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, wx.WXK_SUBTRACT, self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_SUBTRACT, self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, ord('r'), self.animation_restart), (wx.ACCEL_NORMAL, ord('p'), self.on_pause_start_button), (wx.ACCEL_NORMAL, wx.WXK_SPACE, self.on_pause_start_button), (wx.ACCEL_NORMAL, ord('q'), self.animation_quit) ] accel_entries = [] for shortcut_key in shortcut_keys: eventId = wx.NewId() accel_entries.append((shortcut_key[0], shortcut_key[1], eventId)) self.Bind(wx.EVT_MENU, shortcut_key[2], id=eventId) accel_table = wx.AcceleratorTable(accel_entries) self.SetAcceleratorTable(accel_table) self.SetFocus() def set_drawing_panel(self, drawing_panel): self.drawing_panel = drawing_panel self.drawing_panel.set_speed(self.speed) def set_num_stitches(self, num_stitches): if num_stitches < 2: # otherwise the slider and intctrl get mad num_stitches = 2 self.num_stitches = num_stitches self.stitchBox.SetMax(num_stitches) self.slider.SetMax(num_stitches) self.choose_speed() def choose_speed(self): if self.target_duration: self.set_speed(int(self.num_stitches / float(self.target_duration))) else: self.set_speed(self.target_stitches_per_second) def animation_forward(self, event=None): self.directionBtn.SetLabel("<<") self.drawing_panel.forward() self.direction = 1 self.update_speed_text() def animation_reverse(self, event=None): self.directionBtn.SetLabel(">>") self.drawing_panel.reverse() self.direction = -1 self.update_speed_text() def on_direction_button(self, event): if self.direction == 1: self.animation_reverse() else: self.animation_forward() def set_speed(self, speed): self.speed = int(max(speed, 1)) self.update_speed_text() if self.drawing_panel: self.drawing_panel.set_speed(self.speed) def update_speed_text(self): self.statusbar.SetStatusText( _('Speed: %d stitches/sec') % (self.speed * self.direction), 0) self.hbSizer2.Layout() def on_slider(self, event): stitch = event.GetEventObject().GetValue() self.stitchBox.SetValue(stitch) if self.drawing_panel: self.drawing_panel.set_current_stitch(stitch) def on_current_stitch(self, stitch, command): if self.current_stitch != stitch: self.current_stitch = stitch self.slider.SetValue(stitch) self.stitchBox.SetValue(stitch) self.statusbar.SetStatusText(COMMAND_NAMES[command], 1) def on_stitch_box(self, event): stitch = self.stitchBox.GetValue() self.slider.SetValue(stitch) if self.drawing_panel: self.drawing_panel.set_current_stitch(stitch) def animation_slow_down(self, event): """""" self.set_speed(self.speed / 2.0) def animation_speed_up(self, event): """""" self.set_speed(self.speed * 2.0) def animation_pause(self, event=None): self.drawing_panel.stop() def animation_start(self, event=None): self.drawing_panel.go() def on_start(self): self.pauseBtn.SetLabel(_('Pause')) def on_stop(self): self.pauseBtn.SetLabel(_('Start')) def on_pause_start_button(self, event): """""" if self.pauseBtn.GetLabel() == _('Pause'): self.animation_pause() else: self.animation_start() def animation_one_stitch_forward(self, event): self.animation_pause() self.drawing_panel.one_stitch_forward() def animation_one_stitch_backward(self, event): self.animation_pause() self.drawing_panel.one_stitch_backward() def animation_quit(self, event): self.parent.quit() def animation_restart(self, event): self.drawing_panel.restart()
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())
class TimeitDlg(wx.Dialog): def __init__(self, *a, **k): self.pypath = k.pop('python_path') assert os.path.isfile(self.pypath) super(TimeitDlg, self).__init__(size=dlgsize, *a, **k) vbox = wx.BoxSizer(wx.VERTICAL) # --------------- statement ------------------------------------ hbox = wx.BoxSizer(wx.HORIZONTAL) self.stmtbtn = wx.Button(self, wx.ID_ANY, 'Statement <<') self.stmtbtn.closed = False hbox.Add(self.stmtbtn, \ border = 10, \ flag = wx.LEFT | wx.ALIGN_LEFT) hbox.Add(wx.StaticLine(self), \ border = 10, \ proportion = 1, \ flag = wx.RIGHT | wx.ALIGN_RIGHT | wx.ALIGN_CENTRE_VERTICAL) vbox.Add(hbox, border=10, flag=wx.TOP | wx.EXPAND) #self.stmt = wx.TextCtrl(self, wx.ID_ANY, style = wx.TE_MULTILINE | wx.HSCROLL ) self.stmt = CodeEditor(self) vbox.Add(self.stmt, \ proportion = 1, \ flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND ) # --------------- setup ---------------------------------------- hbox = wx.BoxSizer(wx.HORIZONTAL) self.setupbtn = wx.Button(self, wx.ID_ANY, 'Setup >>') self.setupbtn.closed = False hbox.Add(self.setupbtn, \ border = 10, \ flag = wx.LEFT | wx.ALIGN_LEFT) hbox.Add(wx.StaticLine(self), \ border = 10, \ proportion = 1, \ flag = wx.RIGHT | wx.ALIGN_CENTRE_VERTICAL) vbox.Add(hbox, border=10, flag=wx.TOP | wx.EXPAND) #self.setup = wx.TextCtrl(self, wx.ID_ANY, style = wx.TE_MULTILINE | wx.HSCROLL ) self.setup = CodeEditor(self) vbox.Add(self.setup, \ proportion = 1, \ flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND ) self.setup.Show(True) # --------------- arguments ------------------------------------ hbox = wx.BoxSizer(wx.HORIZONTAL) self.argsbtn = wx.Button(self, wx.ID_ANY, 'Arguments >>') self.argsbtn.closed = False hbox.Add(self.argsbtn, \ border = 10, \ flag = wx.LEFT | wx.ALIGN_LEFT) hbox.Add(wx.StaticLine(self), \ border = 10, \ proportion = 1, \ flag = wx.RIGHT | wx.ALIGN_CENTRE_VERTICAL) vbox.Add(hbox, border=10, flag=wx.TOP | wx.EXPAND) self.argsbox = wx.BoxSizer(wx.VERTICAL) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add(wx.StaticText(self, wx.ID_ANY, 'Number: '), \ flag = wx.ALIGN_LEFT) self.number = IntCtrl(self) hbox.Add(self.number, flag=wx.ALIGN_RIGHT | wx.EXPAND) self.argsbox.Add(hbox, border=10, flag=wx.TOP | wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add(wx.StaticText(self, wx.ID_ANY, 'Repeat: '), \ flag = wx.ALIGN_LEFT) self.repeat = IntCtrl(self) hbox.Add(self.repeat, flag=wx.ALIGN_RIGHT | wx.EXPAND) self.argsbox.Add(hbox, border=10, flag=wx.TOP | wx.EXPAND) vbox.Add(self.argsbox, flag=wx.EXPAND) # # --------------- Python Path ------------------------------------ # hbox = wx.BoxSizer(wx.HORIZONTAL) # self.pathbtn = wx.Button(self, wx.ID_ANY, 'Path <<') # self.pathbtn.closed = False # hbox.Add(self.pathbtn, \ # border = 10, \ # flag = wx.LEFT | wx.ALIGN_LEFT) # hbox.Add(wx.StaticLine(self), \ # border = 10, \ # proportion = 1, \ # flag = wx.RIGHT | wx.ALIGN_CENTRE_VERTICAL) # vbox.Add(hbox, border = 10, flag = wx.TOP | wx.EXPAND) # # self.pathbox = wx.BoxSizer(wx.VERTICAL) # hbox = wx.BoxSizer(wx.HORIZONTAL) # hbox.Add(wx.StaticText(self, wx.ID_ANY, 'Python Path: '), \ # flag = wx.ALIGN_LEFT) # self.path = wx.TextCtrl(self) # hbox.Add(self.path, proportion = 1, flag = wx.ALIGN_RIGHT | wx.EXPAND) # self.dirbtn = wx.Button(self, wx.ID_ANY, '...', style = wx.BU_EXACTFIT ) # hbox.Add(self.dirbtn, border = 10, flag = wx.LEFT | wx.ALIGN_CENTRE_VERTICAL) # self.pathbox.Add(hbox, border = 10, flag = wx.TOP | wx.EXPAND) # # vbox.Add(self.pathbox, flag = wx.EXPAND) # ---------------- error and output ---------------------------- hbox = wx.BoxSizer(wx.HORIZONTAL) self.resultbtn = wx.Button(self, wx.ID_ANY, 'Result >>') self.resultbtn.closed = False hbox.Add(self.resultbtn, \ border = 10, \ flag = wx.LEFT | wx.ALIGN_LEFT) hbox.Add(wx.StaticLine(self), \ border = 10, \ proportion = 1, \ flag = wx.RIGHT | wx.ALIGN_CENTRE_VERTICAL) vbox.Add(hbox, border=10, flag=wx.TOP | wx.EXPAND) self.result = wx.TextCtrl(self, \ wx.ID_ANY, style = wx.TE_MULTILINE | wx.HSCROLL | wx.VSCROLL) self.result.SetFont( wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, '')) vbox.Add(self.result, \ proportion = 1, \ flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND ) # ---------------- buttons ------------------------------------- self.clean = wx.Button(self, wx.ID_ANY, '&Clean') self.ok = wx.Button(self, wx.ID_ANY, '&OK') hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add(self.clean, border=10, flag=wx.LEFT | wx.ALIGN_RIGHT) hbox.Add(self.ok, border=10, flag=wx.LEFT | wx.ALIGN_RIGHT) vbox.Add(hbox, border=10, flag=wx.TOP | wx.ALIGN_RIGHT) self.SetSizer(vbox) self.stmtbtn.Bind(wx.EVT_BUTTON, self.OnStmtbtn) self.setupbtn.Bind(wx.EVT_BUTTON, self.OnSetupbtn) self.argsbtn.Bind(wx.EVT_BUTTON, self.OnArgsbtn) # self.pathbtn.Bind(wx.EVT_BUTTON, self.OnPathbtn) self.resultbtn.Bind(wx.EVT_BUTTON, self.OnResultbtn) # self.dirbtn.Bind(wx.EVT_BUTTON, self.OnDirbtn) self.clean.Bind(wx.EVT_BUTTON, self.OnClean) self.ok.Bind(wx.EVT_BUTTON, self.OnOk) self.Bind(wx.EVT_CLOSE, self.OnClose) self.Reset() self.OnArgsbtn(None) # self.OnStmtbtn(None) self.OnSetupbtn(None) self.OnResultbtn(None) # self.pathoption = PathOptoin() # self.path.SetValue(self.pathoption.GetPath()) # def OnPathbtn(self, evt): # if self.pathbtn.closed: # self.GetSizer().Show(self.pathbox, True, True) # self.pathbtn.SetLabel('Path <<') # else: # self.GetSizer().Show(self.pathbox, False, True) # self.pathbtn.SetLabel('Path >>') # self.Fit() # self.pathbtn.closed ^= True def OnArgsbtn(self, evt): if self.argsbtn.closed: self.GetSizer().Show(self.argsbox, True, True) self.argsbtn.SetLabel('Arguments <<') else: self.GetSizer().Show(self.argsbox, False, True) self.argsbtn.SetLabel('Arguments >>') self.Fit() self.argsbtn.closed ^= True def OnStmtbtn(self, evt): self.DoClose(self.stmtbtn, self.stmt, \ ('Statement >>', 'Statement <<')) def OnSetupbtn(self, evt): self.DoClose(self.setupbtn, self.setup, \ ('Setup >>', 'Setup <<')) def OnResultbtn(self, evt): self.DoClose(self.resultbtn, self.result, \ ('Result >>', 'Result <<')) def DoClose(self, btn, ctrl, lbls): ctrl.Show(btn.closed) btn.SetLabel(lbls[int(btn.closed)]) self.Fit() btn.closed ^= True # def OnDirbtn(self, evt): # dlg = wx.FileDialog(self, \ # message = "Choose python directory:", # defaultDir=os.getcwd(), # defaultFile="python*", # wildcard="python executable file (python*)|python*|" \ # "All files (*.*)|*.*", # style=wx.OPEN | wx.CHANGE_DIR) # if dlg.ShowModal() == wx.ID_OK: # self.path.SetValue(dlg.GetPath()) # dlg.Destroy() def OnClean(self, evt): self.Reset() def OnOk(self, evt): # path = self.path.GetValue() # if path == '' or not os.path.isfile(path): # wx.MessageDialog(self, \ # message = 'Set python path first, please.', \ # caption = 'Timeit', \ # style = wx.OK | wx.ICON_EXCLAMATION).ShowModal() # return stmt = self.stmt.GetText() setup = self.setup.GetText() if not setup.strip(): setup = 'pass' # cmd = '%s -m timeit -n %s -r %s '%( \ # path, \ # self.number.GetValue(), \ # self.repeat.GetValue()) # if setup: # cmd += '-s ' + '"%s"'%setup + ' ' # cmd += '"%s"'%stmt # print cmd # p = subprocess.Popen(cmd, shell = True, \ # cwd = os.path.dirname(path), \ # stderr = subprocess.PIPE, \ # stdout = subprocess.PIPE) # p.wait() # tmp_file = os.getcwd() + '%d.py'%self.GetId() # f = open(tmp_file, 'w') # f.write(timeit_file_template%(stmt, setup, \ # self.number.GetValue(), \ # self.repeat.GetValue())) # f.close() # p = subprocess.Popen('python '+tmp_file, \ # shell = True, \ # cwd = os.path.dirname(path), \ # stderr = subprocess.PIPE, \ # stdout = subprocess.PIPE) # p.wait() # # self.result.SetValue( \ # '============ Error ============\n' \ # + p.stderr.read() \ # + '============== Output ==========\n' \ # + p.stdout.read() ) # if self.resultbtn.closed: # self.OnResultbtn(None) import util tmp_file = util.GenWritablePath('%d.py' % self.GetId()) f = open(tmp_file, 'w') f.write(timeit_file_template%(stmt, setup, \ self.number.GetValue(), \ self.repeat.GetValue())) f.close() class TimeitProc(wx.Process): def OnTerminate(inst, pid, status): def getstr(stream): s = '' while True: c = stream.GetC() if 0 == stream.LastRead(): break s += c return s self.result.SetValue( \ '============ Error ============\n' \ + getstr(inst.GetErrorStream()) \ + '\n============ Output ============\n' \ + getstr(inst.GetInputStream())) self.result.ShowPosition(self.result.GetLastPosition()) if self.resultbtn.closed: self.OnResultbtn(None) os.remove(tmp_file) if ' ' in tmp_file: tf = '"%s"' % (tmp_file, ) else: tf = tmp_file cmd = '%s ' % self.pypath + tf proc = TimeitProc(self) proc.Redirect() wx.Execute(cmd, process=proc) def OnClose(self, evt): # self.pathoption.SetPath(self.path.GetValue()) self.Destroy() def Reset(self): self.stmt.SetValue('') self.setup.SetValue('') self.number.SetValue(1000000) self.repeat.SetValue(3) def Fit(self): if not self.IsShown(): return self.GetSizer().Fit(self) self.SetSize(dlgsize)
class RequestTablePanel(wx.Panel): def __init__(self, parent, window, controler): wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL) """ main sizer """ requestPanelSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=4) requestPanelSizer.AddGrowableCol(1) requestPanelSizer.AddGrowableRow(0) """ sizer with control buttons """ controls_sizer = wx.BoxSizer(wx.VERTICAL) requestPanelSizer.AddSizer(controls_sizer, border=5, flag=wx.ALL) for name, bitmap, help in [ ("AddVariableButton", "add_element", _("Add variable")), ("DeleteVariableButton", "remove_element", _("Remove variable")), ("UpVariableButton", "up", _("Move variable up")), ("DownVariableButton", "down", _("Move variable down")) ]: button = wx.lib.buttons.GenBitmapButton(self, bitmap=GetBitmap(bitmap), size=wx.Size(28, 28), style=wx.NO_BORDER) button.SetToolTipString(help) setattr(self, name, button) controls_sizer.AddWindow(button, border=5, flag=wx.BOTTOM) """ variable grid """ self.VariablesGrid = CustomGrid(self, style=wx.VSCROLL) self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange) self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick) self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown) requestPanelSizer.AddWindow(self.VariablesGrid, flag=wx.GROW) """ add header to grid """ mainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=4) mainSizer.AddGrowableRow(1) mainSizer.AddGrowableCol(0) headerSizer = wx.BoxSizer(wx.HORIZONTAL) self.ipAddressDefault = { "Name": "ipAddres", "Address": "10.10.10.10", "Device ID": "", "Data type": "", "Transfer method": "", "Len": "1", "Modbus type": "", "Device ID": "1", "Period (ms)": "100", "Description": DESCRIPTION_IP, } self.portDefault = { "Name": "port", "Address": "502", "Device ID": "", "Data type": "", "Transfer method": "", "Len": "1", "Modbus type": "", "Device ID": "1", "Period (ms)": "100", "Description": DESCRIPTION_PORT } # виджеты для текста IP (label) labelIP = wx.StaticText(self, label=" Ip address: ") font = wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) labelIP.SetFont(font) headerSizer.Add(labelIP) """ поле для IP """ self.ip_address = IpAddrCtrl(self, size=(120, 22)) wx.EVT_TEXT(self, self.ip_address.GetId(), self.OnChangeIp) """ wx.EVT_COMBOBOX(self, self.masterSelectCmbx.cmbbox.GetId(), self.OnChangeMasterOption) """ headerSizer.Add(self.ip_address, flag=wx.ALIGN_CENTER_VERTICAL) """ виджеты для текста порта (label) """ labelPort = wx.StaticText(self, label=" Port: ") font = wx.Font(13, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) labelPort.SetFont(font) headerSizer.Add(labelPort) """ поле для порта """ self.port = IntCtrl(self, min=0, max=65535, limited=True, size=(70, 21)) wx.EVT_TEXT(self, self.port.GetId(), self.OnChangePort) wx.EVT_TEXT(self, self.port.GetId(), self.OnChangePort) headerSizer.Add(self.port, flag=wx.ALIGN_CENTER_VERTICAL) mainSizer.AddSizer(headerSizer, flag=wx.GROW) mainSizer.AddSizer(requestPanelSizer, flag=wx.GROW) self.SetSizer(mainSizer) self.ParentWindow = window self.Controler = controler self.VariablesDefaultValue = { "Name": "", "Address": "1", "Len": "1", "Data type": "WORD", "Modbus type": HOLDING_REGISTER_READ, "Description": DESCRIPTION, "Device ID": "1", "Transfer method": "Periodic", "Period (ms)": "100" } self.Table = MBRequestDataTable(self) self.ColAlignements = [wx.ALIGN_RIGHT] + \ [wx.ALIGN_LEFT]*(len(self.VariablesDefaultValue)) self.ColSizes = [20, 150 ] + [100] * (len(self.VariablesDefaultValue) - 1) self.VariablesGrid.SetTable(self.Table) self.VariablesGrid.SetButtons({ "Add": self.AddVariableButton, "Delete": self.DeleteVariableButton, "Up": self.UpVariableButton, "Down": self.DownVariableButton }) """ handlers for adding variable """ def _AddVariable(new_row): if new_row > 0: row_content = self.Table.data[new_row - 1].copy() newAddr = int(row_content["Address"]) newLen = int(row_content["Len"]) if row_content["Data type"] in ("REAL", "INT"): newLen = newLen * 2 newAddr = newAddr + newLen row_content["Address"] = str(newAddr) result = VARIABLE_NAME_SUFFIX_MODEL.search(row_content["Name"]) if result is not None: name = row_content["Name"][:result.start(1)] suffix = result.group(1) if suffix != "": start_idx = int(suffix) else: start_idx = 0 else: name = row_content["Name"] start_idx = 0 row_content["Name"] = self.Controler.GenerateNewName( name + "%d", start_idx) else: row_content = self.VariablesDefaultValue.copy() self.Table.InsertRow(new_row, row_content) self.RefreshModel() self.RefreshView() return new_row setattr(self.VariablesGrid, "_AddRow", _AddVariable) """ handlers for deleting variable """ def _DeleteVariable(row): self.Table.RemoveRow(row) self.RefreshModel() self.RefreshView() setattr(self.VariablesGrid, "_DeleteRow", _DeleteVariable) """ handlers for moving varible """ def _MoveVariable(row, move): new_row = self.Table.MoveRow(row, move) if new_row != row: self.RefreshModel() self.RefreshView() return new_row setattr(self.VariablesGrid, "_MoveRow", _MoveVariable) self.VariablesGrid.SetRowLabelSize(0) for col in range(self.Table.GetNumberCols()): attr = wx.grid.GridCellAttr() attr.SetAlignment(self.ColAlignements[col], wx.ALIGN_CENTRE) self.VariablesGrid.SetColAttr(col, attr) self.VariablesGrid.SetColSize(col, self.ColSizes[col]) self.Table.ResetView(self.VariablesGrid) self.Bind(wx.EVT_SHOW, self.OnShow) def OnChangeMasterOption(self, event): masterOptionOnFrame = self.masterSelectCmbx.cmbbox.GetStringSelection() masterOptionInXml = [ i for i in self.Controler.GetVariables() if i["Name"] == MASTER_OPTION ] if len(masterOptionInXml) > 0: if masterOptionOnFrame != masterOptionInXml[0]: self.RefreshModel() else: self.RefreshModel() event.Skip() def GetMasterOption(self): return { "Name": "Master option", "Address": "", "Len": "", "Device ID": "", "Data type": u"WORD", "Transfer method": "", "Period (ms)": "", "Description": MASTER_OPTION, "Modbus type": "0" } def RefreshModel(self): ipAddress = self.ipAddressDefault.copy() ipAddress["Address"] = self.ip_address.GetValue() controllerVariables = self.Controler.GetVariables() controllerVariables = [ i for i in controllerVariables if i["Description"] not in (DESCRIPTION, MASTER_OPTION) ] controllerVariables += self.Table.GetData() controllerVariables.append(self.GetMasterOption()) controllerVariables.append(ipAddress) controllerVariables.append(self.portDefault) self.Controler.SetVariables(controllerVariables) self.RefreshBuffer() def RefreshView(self): varForTable = self.Controler.GetVariables() varForTable = [ i for i in varForTable if i["Description"] == DESCRIPTION ] self.Table.SetData(varForTable) self.Table.ResetView(self.VariablesGrid) varForTable = self.Controler.GetVariables() varForTable = [i for i in varForTable if i["Name"] == MASTER_OPTION] #if len(varForTable) > 0: #self.masterSelectCmbx.cmbbox.SetStringSelection(varForTable[0]["Modbus type"]) self.VariablesGrid.RefreshButtons() varForTable = self.Controler.GetVariables() varForTable = [ i for i in varForTable if i["Description"] == DESCRIPTION_IP ] if len(varForTable) == 0: varForTable = [] varForTable.append(self.ipAddressDefault) self.ip_address.SetValue(varForTable[0]["Address"]) varForTable = self.Controler.GetVariables() vars = [i for i in varForTable if i["Description"] == DESCRIPTION_PORT] if len(vars) == 0: vars = [] vars.append(self.portDefault) # if self.port.GetLineText != vars[0]["Address"]: # print vars self.port.SetValue(int(vars[0]["Address"])) def OnShow(self, event): pass # print 'kek' # используется для событий, когда изменяются поля ip-адреса и порта def OnChangeIp(self, event): ipAddress = self.ipAddressDefault.copy() ipAddress["Address"] = self.ip_address.GetValue().replace(' ', '') # port = self.portDefault.copy() # port["Address"] = self.port.GetLineText(0) controllerVariables = self.Controler.GetVariables() # valuesOnFrame = self.GetData() valueIPOnWidget = self.ip_address.GetValue() controllerVariablesIP = [ i for i in controllerVariables if i["Description"] == (DESCRIPTION_IP) ] # valuePortOnWidget = self.port.GetLineText() controllerVariablesIP = [ i for i in controllerVariables if i["Description"] == (DESCRIPTION_PORT) ] if not (ipAddress in controllerVariables): controllerVariables = [ i for i in controllerVariables if i["Description"] != DESCRIPTION_IP ] controllerVariables.append(ipAddress) # controllerVariables.append(port) self.Controler.SetVariables(controllerVariables) self.RefreshBuffer() event.Skip() def OnChangePort(self, event): portAddress = self.portDefault.copy() portAddress["Address"] = self.port.GetLineText(0) controllerVariables = self.Controler.GetVariables() if not (portAddress in controllerVariables): controllerVariables = [ i for i in controllerVariables if i["Description"] != DESCRIPTION_PORT ] controllerVariables.append(portAddress) self.Controler.SetVariables(controllerVariables) self.RefreshBuffer() event.Skip() # def GetData(self): # """ # Считывает с GUI настроенные пользователем параметры и возвращает их в виде списка # словарей # """ def OnVariablesGridCellChange(self, event): row, col = event.GetRow(), event.GetCol() colname = self.Table.GetColLabelValue(col, False) value = self.Table.GetValue(row, col) message = None if colname == "Modbus type": self.VariablesGrid.SetCellValue(row, col + 1, "WORD") if colname == "Len": modbusType = self.Table.GetValue(row, 4) # Modubs type value if modbusType in (HOLDING_REGISTER_READ, INPUT_REGISTER_READ): if int(value) > MAX_SIMULTANEOUS_REGISTERS_READ: value = MAX_SIMULTANEOUS_REGISTERS_READ self.VariablesGrid.SetCellValue( row, col, str(MAX_SIMULTANEOUS_REGISTERS_READ)) if modbusType == HOLDING_REGISTER_WRITE: if int(value) > MAX_SIMULTANEOUS_REGISTERS_WRITE: self.VariablesGrid.SetCellValue( row, col, str(MAX_SIMULTANEOUS_REGISTERS_WRITE)) if modbusType in (COIL_READ, DISCRETE_INPUT_READ): if int(value) > MAX_SIMULTANEOUS_COIL_DISC_READ: self.VariablesGrid.SetCellValue( row, col, str(MAX_SIMULTANEOUS_COIL_DISC_READ)) if modbusType == COIL_WRITE: if int(value) > MAX_SIMULTANEOUS_COIL_WRITE: self.VariablesGrid.SetCellValue( row, col, str(MAX_SIMULTANEOUS_COIL_WRITE)) if colname == "Name" and value != "": if not TestIdentifier(value): message = _("\"%s\" is not a valid identifier!") % value elif value.upper() in IEC_KEYWORDS: message = _("\"%s\" is a keyword. It can't be used!") % value elif value.upper() in [ var["Name"].upper() for var_row, var in enumerate(self.Table.data) if var_row != row ]: message = _( "A variable with \"%s\" as name already exists!") % value else: self.RefreshModel() wx.CallAfter(self.RefreshView) else: self.RefreshModel() wx.CallAfter(self.RefreshView) if message is not None: dialog = wx.MessageDialog(self, message, _("Error"), wx.OK | wx.ICON_ERROR) dialog.ShowModal() dialog.Destroy() event.Veto() else: event.Skip() def DoGetBestSize(self): return self.ParentWindow.GetPanelBestSize() def OnVariablesGridEditorShown(self, event): event.Skip() def GetVariableTypeFunction(self, base_type): def VariableTypeFunction(event): row = self.VariablesGrid.GetGridCursorRow() self.Table.SetValueByName(row, "Data type", base_type) self.Table.ResetView(self.VariablesGrid) self.RefreshModel() self.RefreshView() event.Skip() return VariableTypeFunction def OnVariablesGridCellLeftClick(self, event): if event.GetCol() == 0: row = event.GetRow() data_type = self.Table.GetValueByName(row, "Data type") var_name = self.Table.GetValueByName(row, "Name") data = wx.TextDataObject( str((var_name, "Global", data_type, self.Controler.GetCurrentLocation()))) dragSource = wx.DropSource(self.VariablesGrid) dragSource.SetData(data) dragSource.DoDragDrop() return event.Skip() def RefreshBuffer(self): self.Controler.BufferCodeFile() self.ParentWindow.RefreshTitle() self.ParentWindow.RefreshFileMenu() self.ParentWindow.RefreshEditMenu() self.ParentWindow.RefreshPageTitles()
class CairoExportDialog(wx.Dialog): """Gets Cairo export parameters from user""" # 72 points = 1 inch paper_sizes_points = OrderedDict([ ("A4", (595, 842)), ("Letter", (612, 792)), ("Tabloid", (792, 1224)), ("Ledger", (1224, 792)), ("Legal", (612, 1008)), ("Statement", (396, 612)), ("Executive", (540, 720)), ("A0", (2384, 3371)), ("A1", (1685, 2384)), ("A2", (1190, 1684)), ("A3", (842, 1190)), ("A4Small", (595, 842)), ("A5", (420, 595)), ("B4", (729, 1032)), ("B5", (516, 729)), ("Folio", (612, 936)), ("Quarto", (610, 780)), ("10x14", (720, 1008)), ]) def __init__(self, parent, *args, **kwds): kwds["style"] = wx.DEFAULT_FRAME_STYLE try: self.filetype = kwds.pop("filetype").lower() except KeyError: self.filetype = "pdf" self.parent = parent wx.Dialog.__init__(self, parent, *args, **kwds) if self.filetype != "print": # If printing and not exporting then page info is # gathered from printer dialog self.portrait_landscape_radio_box = \ wx.RadioBox(self, wx.ID_ANY, _("Layout"), choices=[_("Portrait"), _("Landscape")], majorDimension=2, style=wx.RA_SPECIFY_COLS) self.page_width_label = wx.StaticText(self, wx.ID_ANY, _("Width")) self.page_width_text_ctrl = wx.TextCtrl(self, wx.ID_ANY) self.page_height_label = wx.StaticText(self, wx.ID_ANY, _("Height")) self.page_height_text_ctrl = wx.TextCtrl(self, wx.ID_ANY) self.page_layout_choice = \ wx.Choice(self, wx.ID_ANY, choices=self.paper_sizes_points.keys()) self.sizer_2_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Page")) self.page_layout_choice.Bind(wx.EVT_CHOICE, self.on_page_layout_choice) self.top_row_label = wx.StaticText(self, wx.ID_ANY, _("Top row")) self.top_row_text_ctrl = IntCtrl(self, wx.ID_ANY) self.bottom_row_label = wx.StaticText(self, wx.ID_ANY, _("Bottom row")) self.bottom_row_text_ctrl = IntCtrl(self, wx.ID_ANY) self.left_col_label = wx.StaticText(self, wx.ID_ANY, _("Left column")) self.left_col_text_ctrl = IntCtrl(self, wx.ID_ANY) self.right_col_label = wx.StaticText(self, wx.ID_ANY, _("Right column")) self.right_col_text_ctrl = IntCtrl(self, wx.ID_ANY) self.first_tab_label = wx.StaticText(self, wx.ID_ANY, _("First table")) self.first_tab_text_ctrl = IntCtrl(self, wx.ID_ANY) self.last_tab_label = wx.StaticText(self, wx.ID_ANY, _("Last table")) self.last_tab_text_ctrl = IntCtrl(self, wx.ID_ANY) self.sizer_3_staticbox = wx.StaticBox(self, wx.ID_ANY, _("Grid")) self.empty_panel = wx.Panel(self, wx.ID_ANY) self.cancel_button = wx.Button(self, wx.ID_CANCEL, "") self.ok_button = wx.Button(self, wx.ID_OK, "") self.__set_properties() self.__do_layout() def _get_dialog_title(self): """Returns title string""" title_filetype = self.filetype[0].upper() + self.filetype[1:] if self.filetype == "print": title_export = "" else: title_export = " export" return _("{filetype}{export} options").format(filetype=title_filetype, export=title_export) def __set_properties(self): (top, left), (bottom, right) = \ self.parent.grid.actions.get_visible_area() self.SetTitle(self._get_dialog_title()) if self.filetype != "print": # If printing and not exporting then page info is # gathered from printer dialog self.portrait_landscape_radio_box.SetToolTipString( _("Choose portrait or landscape page layout")) self.portrait_landscape_radio_box.SetSelection(0) self.page_width_label.SetToolTipString(_("Page width in inches")) self.page_width_text_ctrl.SetToolTipString( _("Page width in inches")) self.page_width_text_ctrl.SetValue( str(self.paper_sizes_points["A4"][0] / 72.0)) self.page_height_label.SetToolTipString(_("Page height in inches")) self.page_height_text_ctrl.SetToolTipString( _("Page height in inches")) self.page_height_text_ctrl.SetValue( str(self.paper_sizes_points["A4"][1] / 72.0)) self.page_layout_choice.SetToolTipString( _("Choose from predefined page layouts")) self.page_layout_choice.SetSelection(0) self.top_row_label.SetToolTipString(_("Top row to be exported")) self.top_row_text_ctrl.SetToolTipString(_("Top row to be exported")) self.top_row_text_ctrl.SetValue(top) self.bottom_row_label.SetToolTipString(_("Bottom row to be exported")) self.bottom_row_text_ctrl.SetToolTipString( _("Bottom row to be exported")) self.bottom_row_text_ctrl.SetValue(bottom) self.left_col_label.SetToolTipString( _("Leftmost column to be exported")) self.left_col_text_ctrl.SetToolTipString( _("Left column to be exported")) self.left_col_text_ctrl.SetValue(left) self.right_col_label.SetToolTipString( _("Rightmost column to be exported")) self.right_col_text_ctrl.SetToolTipString( _("Right column to be exported")) self.right_col_text_ctrl.SetValue(right) self.first_tab_label.SetToolTipString(_("First table to be exported")) self.first_tab_text_ctrl.SetToolTipString( _("First table to be exported")) self.first_tab_text_ctrl.SetValue(self.parent.grid.current_table) self.last_tab_label.SetToolTipString(_("Last table to be exported")) self.last_tab_text_ctrl.SetToolTipString( _("Last table to be exported")) self.last_tab_text_ctrl.SetValue(self.parent.grid.current_table) def __do_layout(self): sizer_1 = wx.BoxSizer(wx.VERTICAL) grid_sizer_1 = wx.FlexGridSizer(3, 1, 0, 0) grid_sizer_2 = wx.FlexGridSizer(1, 3, 0, 0) self.sizer_3_staticbox.Lower() sizer_3 = wx.StaticBoxSizer(self.sizer_3_staticbox, wx.HORIZONTAL) grid_sizer_4 = wx.FlexGridSizer(3, 4, 0, 0) if self.filetype != "print": # If printing and not exporting then page info is # gathered from printer dialog self.sizer_2_staticbox.Lower() sizer_2 = wx.StaticBoxSizer(self.sizer_2_staticbox, wx.VERTICAL) grid_sizer_3 = wx.FlexGridSizer(1, 5, 0, 0) sizer_2.Add(self.portrait_landscape_radio_box, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_HORIZONTAL, 3) grid_sizer_3.Add(self.page_width_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) grid_sizer_3.Add(self.page_width_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_3.Add(self.page_height_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) grid_sizer_3.Add(self.page_height_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_3.Add(self.page_layout_choice, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_3.AddGrowableCol(1) grid_sizer_3.AddGrowableCol(3) grid_sizer_3.AddGrowableCol(4) sizer_2.Add(grid_sizer_3, 3, wx.ALL | wx.EXPAND, 3) grid_sizer_1.Add(sizer_2, 1, wx.ALL | wx.EXPAND, 3) grid_sizer_4.Add(self.top_row_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) grid_sizer_4.Add(self.top_row_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_4.Add(self.bottom_row_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) grid_sizer_4.Add(self.bottom_row_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_4.Add(self.left_col_label, 0, wx.ALL, 3) grid_sizer_4.Add(self.left_col_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_4.Add(self.right_col_label, 0, wx.ALL, 3) grid_sizer_4.Add(self.right_col_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_4.Add(self.first_tab_label, 0, wx.ALL, 3) grid_sizer_4.Add(self.first_tab_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_4.Add(self.last_tab_label, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3) grid_sizer_4.Add(self.last_tab_text_ctrl, 0, wx.ALL | wx.EXPAND, 3) grid_sizer_4.AddGrowableCol(1) grid_sizer_4.AddGrowableCol(3) sizer_3.Add(grid_sizer_4, 1, wx.ALL | wx.EXPAND, 3) grid_sizer_1.Add(sizer_3, 1, wx.ALL | wx.EXPAND, 3) grid_sizer_2.Add(self.empty_panel, 1, wx.ALL | wx.EXPAND, 3) grid_sizer_2.Add(self.cancel_button, 0, wx.ALL, 3) grid_sizer_2.Add(self.ok_button, 0, wx.ALL, 3) grid_sizer_2.AddGrowableRow(0) grid_sizer_2.AddGrowableCol(0) grid_sizer_1.Add(grid_sizer_2, 1, wx.ALL | wx.EXPAND, 3) grid_sizer_1.AddGrowableRow(0) grid_sizer_1.AddGrowableRow(1) grid_sizer_1.AddGrowableCol(0) sizer_1.Add(grid_sizer_1, 1, wx.ALL | wx.EXPAND, 3) self.SetSizer(sizer_1) sizer_1.Fit(self) self.Layout() def on_page_layout_choice(self, event): """Page layout choice event handler""" width, height = self.paper_sizes_points[event.GetString()] self.page_width_text_ctrl.SetValue(str(width / 72.0)) self.page_height_text_ctrl.SetValue(str(height / 72.0)) event.Skip() def get_info(self): """Returns a dict with the dialog PDF info Dict keys are: top_row, bottom_row, left_col, right_col, first_tab, last_tab, paper_width, paper_height """ info = {} info["top_row"] = self.top_row_text_ctrl.GetValue() info["bottom_row"] = self.bottom_row_text_ctrl.GetValue() info["left_col"] = self.left_col_text_ctrl.GetValue() info["right_col"] = self.right_col_text_ctrl.GetValue() info["first_tab"] = self.first_tab_text_ctrl.GetValue() info["last_tab"] = self.last_tab_text_ctrl.GetValue() if self.filetype != "print": # If printing and not exporting then page info is # gathered from printer dialog info["paper_width"] = float( self.page_width_text_ctrl.GetValue()) * 72.0 info["paper_height"] = float( self.page_height_text_ctrl.GetValue()) * 72.0 if self.portrait_landscape_radio_box.GetSelection() == 0: orientation = "portrait" elif self.portrait_landscape_radio_box.GetSelection() == 1: orientation = "landscape" else: raise ValueError("Orientation not in portrait or landscape") info["orientation"] = orientation return info
class ProbeConfig(wx.Panel): """This is the view and controller for a single probe configuration""" def __init__(self, parent, probe): """Initialization""" wx.Panel.__init__(self, parent, wx.ID_ANY, style=wx.BORDER_SIMPLE) self.probe = probe sizer = wx.BoxSizer(wx.VERTICAL) assoc = wx.BoxSizer(wx.HORIZONTAL) nset = wx.BoxSizer(wx.HORIZONTAL) line = wx.BoxSizer(wx.HORIZONTAL) capt = wx.BoxSizer(wx.HORIZONTAL) btns = wx.BoxSizer(wx.HORIZONTAL) self.status = wx.StaticText(self, wx.ID_ANY, "Probe is Active") font = self.status.GetFont() font.SetWeight(wx.BOLD) self.status.SetFont(font) lbl_assoc = wx.StaticText(self, wx.ID_ANY, "Associativity") self.int_assoc = IntCtrl(self, wx.ID_ANY) self.int_assoc.SetValue(self.probe.associativity) assoc.Add(lbl_assoc, 1, wx.ALIGN_CENTER | wx.RIGHT, 5) assoc.Add(self.int_assoc, 0, wx.ALIGN_RIGHT) lbl_nset = wx.StaticText(self, wx.ID_ANY, "Number of Sets") self.int_nset = IntCtrl(self, wx.ID_ANY) self.int_nset.SetValue(self.probe.num_sets) nset.Add(lbl_nset, 1, wx.ALIGN_CENTER | wx.RIGHT, 5) nset.Add(self.int_nset, 0, wx.ALIGN_RIGHT) lbl_line = wx.StaticText(self, wx.ID_ANY, "Size of Line") self.int_line = IntCtrl(self, wx.ID_ANY) self.int_line.SetValue(self.probe.line_size) line.Add(lbl_line, 1, wx.ALIGN_CENTER | wx.RIGHT, 5) line.Add(self.int_line, 0, wx.ALIGN_RIGHT) lbl_capt = wx.StaticText(self, wx.ID_ANY, "Capture Limits:") lbl_lp = wx.StaticText(self, wx.ID_ANY, "[") self.spn_lo = wx.SpinButton(self, wx.ID_ANY) lbl_cm = wx.StaticText(self, wx.ID_ANY, ",") self.spn_hi = wx.SpinButton(self, wx.ID_ANY) lbl_rp = wx.StaticText(self, wx.ID_ANY, ")") self.btn_config = wx.Button(self, wx.ID_ANY, "Configure") capt.Add(lbl_capt, 3, wx.ALIGN_CENTER) capt.Add(lbl_lp, 0, wx.ALIGN_CENTER) capt.Add(self.spn_lo, 1, wx.ALIGN_CENTER) capt.Add(lbl_cm, 0, wx.ALIGN_CENTER) capt.Add(self.spn_hi, 1, wx.ALIGN_CENTER) capt.Add(lbl_rp, 0, wx.ALIGN_CENTER) capt.Add(self.btn_config, 0, wx.ALIGN_CENTER) self.btn_enable = wx.Button(self, wx.ID_ANY, "Enable") btns.Add(self.btn_enable, 0, wx.ALL, 5) sizer.Add(self.status, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5) sizer.Add(assoc, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5) sizer.Add(nset, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5) sizer.Add(line, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5) sizer.Add(capt, 0, wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, 5) sizer.Add(btns, 0, wx.ALIGN_CENTER | wx.ALL, 5) self.SetSizer(sizer) sizer.SetSizeHints(self) # Events self.btn_enable.Bind(wx.EVT_BUTTON, self.onclick_btn_enable) self.btn_config.Bind(wx.EVT_BUTTON, self.onclick_btn_config) pub.subscribe(self.on_enable_changed, Probe.ENABLED_CHANGED) pub.subscribe(self.on_enable_changed, Probe.CONFIG_CHANGED) # Initial data self.on_enable_changed() def set_status(self): """Display the status of the probe.""" name = self.probe.name status = "Probe %s is active" % name self.status.SetLabel(status) def onclick_btn_enable(self, evt): """Enable button has been clicked.""" if not self.probe.is_enabled(): assoc = self.int_assoc.GetValue() nset = self.int_nset.GetValue() lsize = self.int_line.GetValue() self.probe.enable(assoc, nset, lsize) else: self.probe.disable() def onclick_btn_config(self, evt): """Configure button has been clicked.""" lo = self.spn_lo.GetValue() hi = self.spn_hi.GetValue() if not self.probe.configure(lo, hi): msg = wx.MessageDialog( self, 'Failed to configure probe %s' % self.probe.name, 'Failure', wx.OK) msg.ShowModal() msg.Destroy() def on_enable_changed(self, name=None): """The enable state of the scope has changed.""" if name is not None and self.probe.name != name: return enabled = self.probe.is_enabled() prb_state = "Enabled" if enabled else "Disabled" btn_status = "Disable" if enabled else "Enable" prb_status = "Probe %s is %s" % (self.probe.name, prb_state) self.status.SetLabel(prb_status) self.btn_enable.SetLabel(btn_status) self.int_assoc.Enable(not enabled) self.int_nset.Enable(not enabled) self.int_line.Enable(not enabled) self.spn_lo.Enable(enabled) self.spn_hi.Enable(enabled) self.btn_config.Enable(enabled) self.spn_lo.SetRange(0, self.probe.num_sets) self.spn_hi.SetRange(0, self.probe.num_sets) self.spn_lo.SetValue(self.probe.low_set) self.spn_hi.SetValue(self.probe.high_set)
class TextEditPanel(wx.Panel): edits = (unicode, TlkString) def __init__(self, *args, **kwargs): super(TextEditPanel, self).__init__(*args, **kwargs) sizer = wx.BoxSizer(wx.VERTICAL) self.text_ctrl = wx.TextCtrl(self, style=wx.TE_MULTILINE) self.check_zero = wx.CheckBox(self, label='Zero-terminated') self.combo_empty = wx.ComboBox( self, style=wx.CB_READONLY | wx.CB_DROPDOWN, value="empty string", choices=["empty string", "null", "zero"]) self.tlk_id = IntCtrl(self, min=0, max=0xFFFFFFFF, limited=False, allow_long=True, style=wx.ALIGN_RIGHT) # SpinCtrl for TlkString sizer.Add(self.text_ctrl, 1, wx.EXPAND) sizer2 = wx.BoxSizer(wx.HORIZONTAL) sizer2.Add(self.check_zero, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) sizer2.Add(self.combo_empty, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) sizer2.Add(self.tlk_id, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL) sizer.Add(sizer2, 0, wx.EXPAND) self.SetSizer(sizer) def SetValue(self, value, kind): self.kind = kind if issubclass(kind, TlkString): self.tlk_id.Show() self.tlk_id.SetValue(value.label) value = value.s else: self.tlk_id.Hide() self.combo_empty.SetValue("empty string") if value == None: self.text_ctrl.SetValue('') self.check_zero.SetValue(True) self.combo_empty.SetValue("null") elif value == 0: self.text_ctrl.SetValue('') self.check_zero.SetValue(True) self.combo_empty.SetValue("zero") elif value.endswith(chr(0)): self.text_ctrl.SetValue(value[:-1]) self.check_zero.SetValue(True) else: self.text_ctrl.SetValue(value) self.check_zero.SetValue(False) self.Layout() def GetValue(self): if issubclass(self.kind, ECString): s = self.text_ctrl.GetValue() if not s: cv = self.combo_empty.GetValue() if cv == 'zero': raise ValueError, 'zero is not a valid treatment of an empty string of this type' elif cv == 'null': return None elif self.check_zero.GetValue(): return chr(0) else: return '' elif self.check_zero.GetValue(): return s + chr(0) else: return s elif issubclass(self.kind, TlkString): tlkid = long(self.tlk_id.Value) s = self.text_ctrl.Value if not s: cv = self.combo_empty.Value if cv == 'zero': return self.kind(tlkid, 0) elif cv == 'null': return self.kind(tlkid, None) elif self.check_zero.Value: return self.kind(tlkid, chr(0)) else: return self.kind(tlkid, '') elif self.check_zero.Value: return self.kind(tlkid, s + chr(0)) else: return self.kind(tlkid, s)
class TaskManager(wx.Panel): def __init__(self, parent): wx.Panel.__init__(self, parent) box = wx.BoxSizer(wx.VERTICAL) self.SetSizer(box) self.dataDir = os.path.join(os.path.dirname(__file__), 'data/task') self.tasks = {} self.taskChoser = wx.ComboBox(self, style=wx.CB_READONLY) self.taskChoser.Bind(wx.EVT_COMBOBOX, self.OnSelect) box.Add(self.taskChoser) grid = wx.GridSizer(4, 2) box.Add(grid) self.taskName = wx.TextCtrl(self) self.appsInput = wx.TextCtrl(self) self.maxDistractionInput = IntCtrl(self, value=0, min=0) deleteButton = wx.Button(self, label='Delete') deleteButton.Bind(wx.EVT_BUTTON, self.OnDelete) cancelButton = wx.Button(self, label='Cancel') cancelButton.Bind(wx.EVT_BUTTON, self.OnCancel) saveButton = wx.Button(self, label='Save') saveButton.Bind(wx.EVT_BUTTON, self.OnSave) grid.AddMany([(wx.StaticText(self, label='Name:'), 0, wx.EXPAND), (self.taskName, 0, wx.EXPAND), (wx.StaticText(self, label='Apps:'), 0, wx.EXPAND), (self.appsInput, 0, wx.EXPAND), (wx.StaticText(self, label='Max. Distraction:'), 0, wx.EXPAND), (self.maxDistractionInput, 0, wx.EXPAND), (deleteButton), (cancelButton), (saveButton)]) self.refresh() def OnDelete(self, event): if self.taskName.GetValue(): dlg = wx.MessageDialog(self, "Do you really want to delete this task?", "Delete " + self.taskName.GetValue(), wx.OK | wx.CANCEL) result = dlg.ShowModal() if result == wx.ID_OK: filePath = os.path.join(self.dataDir, self.taskName.GetValue()) os.remove(filePath) del self.tasks[self.taskName.GetValue()] self.refresh() def OnSave(self, event): if self.taskName.GetValue(): filePath = os.path.join(self.dataDir, self.taskName.GetValue()) t = Task(self.taskName.GetValue(), self.appsInput.GetValue(), self.maxDistractionInput.GetValue()) t.dump(open(filePath, 'w')) self.tasks[self.taskName.GetValue()] = t self.refresh(self.taskName.GetValue()) def OnCancel(self, event): self.refresh(self.taskChoser.GetValue()) def refresh(self, selectedTask=None): taskList = os.listdir(self.dataDir) self.taskChoser.Clear() for name in taskList: self.taskChoser.Append(name) if name: filePath = os.path.join(self.dataDir, name) t = Task.load(open(filePath)) f = open(filePath, 'w') f.write(t.dumps()) self.tasks[name] = t if selectedTask: self.taskChoser.SetStringSelection(selectedTask) else: self.taskChoser.SetSelection(0) self.OnSelect(None) def OnSelect(self, event): name = self.taskChoser.GetValue() if name: self.taskName.SetValue(name) t = self.tasks[name] self.appsInput.SetValue(t.appNames) self.maxDistractionInput.SetValue(t.maxDistraction)
class PFMarketPref(PreferenceView): title = "Market & Prices" def __init__(self): self.priceSettings = MarketPriceSettings.getInstance() def populatePanel(self, panel): self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.sFit = Fit.getInstance() helpCursor = wx.Cursor(wx.CURSOR_QUESTION_ARROW) mainSizer = wx.BoxSizer(wx.VERTICAL) self.stTitle = wx.StaticText(panel, wx.ID_ANY, "Market && Prices", wx.DefaultPosition, wx.DefaultSize, 0) self.stTitle.Wrap(-1) self.stTitle.SetFont(wx.Font(12, 70, 90, 90, False, wx.EmptyString)) mainSizer.Add(self.stTitle, 0, wx.ALL, 5) self.m_staticline1 = wx.StaticLine(panel, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL) mainSizer.Add(self.m_staticline1, 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) delayTimer = wx.BoxSizer(wx.HORIZONTAL) self.stMarketDelay = wx.StaticText(panel, wx.ID_ANY, "Market Search Delay (ms):", wx.DefaultPosition, wx.DefaultSize, 0) self.stMarketDelay.Wrap(-1) if "wxGTK" not in wx.PlatformInfo: self.stMarketDelay.SetCursor(helpCursor) self.stMarketDelay.SetToolTip( wx.ToolTip( 'The delay between a keystroke and the market search. Can help reduce lag when typing fast in the market search box.' )) delayTimer.Add(self.stMarketDelay, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) self.intDelay = IntCtrl(panel, max=1000, limited=True) delayTimer.Add(self.intDelay, 0, wx.ALL, 5) mainSizer.Add(delayTimer, 0, wx.EXPAND | wx.TOP | wx.RIGHT, 10) self.intDelay.SetValue( self.sFit.serviceFittingOptions["marketSearchDelay"]) self.intDelay.Bind(wx.lib.intctrl.EVT_INT, self.onMarketDelayChange) self.cbMarketShortcuts = wx.CheckBox(panel, wx.ID_ANY, "Show market shortcuts", wx.DefaultPosition, wx.DefaultSize, 0) mainSizer.Add(self.cbMarketShortcuts, 0, wx.EXPAND | wx.TOP | wx.RIGHT, 10) self.cbMarketShortcuts.SetValue( self.sFit.serviceFittingOptions["showMarketShortcuts"] or False) self.cbMarketShortcuts.Bind(wx.EVT_CHECKBOX, self.onCBShowShortcuts) priceSizer = wx.BoxSizer(wx.HORIZONTAL) self.stDefaultSystem = wx.StaticText(panel, wx.ID_ANY, "Default Market Prices:", wx.DefaultPosition, wx.DefaultSize, 0) self.stDefaultSystem.Wrap(-1) priceSizer.Add(self.stDefaultSystem, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5) if "wxGTK" not in wx.PlatformInfo: self.stDefaultSystem.SetCursor(helpCursor) self.stDefaultSystem.SetToolTip( wx.ToolTip( 'The source you choose will be tried first, but subsequent sources will be used if the preferred source fails. ' 'The system you choose will also be tried first, and if no data is available, global price will be used.' )) self.chPriceSource = wx.Choice(panel, choices=sorted(Price.sources.keys())) self.chPriceSystem = wx.Choice(panel, choices=list(Price.systemsList.keys())) priceSizer.Add(self.chPriceSource, 1, wx.ALL | wx.EXPAND, 5) priceSizer.Add(self.chPriceSystem, 1, wx.ALL | wx.EXPAND, 5) mainSizer.Add(priceSizer, 0, wx.EXPAND | wx.TOP | wx.RIGHT, 10) self.chPriceSource.SetStringSelection( self.sFit.serviceFittingOptions["priceSource"]) self.chPriceSource.Bind(wx.EVT_CHOICE, self.onPricesSourceSelection) self.chPriceSystem.SetStringSelection( self.sFit.serviceFittingOptions["priceSystem"]) self.chPriceSystem.Bind(wx.EVT_CHOICE, self.onPriceSelection) self.tbTotalPriceBox = wx.StaticBoxSizer(wx.VERTICAL, panel, "Total Price Includes") self.tbTotalPriceDrones = wx.CheckBox(panel, -1, "Drones", wx.DefaultPosition, wx.DefaultSize, 1) self.tbTotalPriceDrones.SetValue(self.priceSettings.get("drones")) self.tbTotalPriceDrones.Bind(wx.EVT_CHECKBOX, self.OnTotalPriceDroneChange) self.tbTotalPriceBox.Add(self.tbTotalPriceDrones, 0, wx.LEFT | wx.RIGHT | wx.TOP, 5) self.tbTotalPriceCargo = wx.CheckBox(panel, -1, "Cargo", wx.DefaultPosition, wx.DefaultSize, 1) self.tbTotalPriceCargo.SetValue(self.priceSettings.get("cargo")) self.tbTotalPriceCargo.Bind(wx.EVT_CHECKBOX, self.OnTotalPriceCargoChange) self.tbTotalPriceBox.Add(self.tbTotalPriceCargo, 0, wx.LEFT | wx.RIGHT, 5) self.tbTotalPriceCharacter = wx.CheckBox(panel, -1, "Implants && Boosters", wx.DefaultPosition, wx.DefaultSize, 1) self.tbTotalPriceCharacter.SetValue( self.priceSettings.get("character")) self.tbTotalPriceCharacter.Bind(wx.EVT_CHECKBOX, self.OnTotalPriceCharacterChange) self.tbTotalPriceBox.Add(self.tbTotalPriceCharacter, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM, 5) mainSizer.Add(self.tbTotalPriceBox, 0, wx.EXPAND | wx.TOP | wx.RIGHT, 10) self.rbMarketSearch = wx.RadioBox( panel, -1, "Market Search && Recent Items", wx.DefaultPosition, wx.DefaultSize, [ "No changes to meta buttons", "Enable all meta buttons for a duration of search / recents", "Enable all meta buttons" ], 1, wx.RA_SPECIFY_COLS) self.rbMarketSearch.SetSelection( self.priceSettings.get('marketMGSearchMode')) mainSizer.Add(self.rbMarketSearch, 0, wx.RIGHT | wx.TOP | wx.EXPAND, 10) self.rbMarketSearch.Bind(wx.EVT_RADIOBOX, self.OnMarketSearchChange) self.rbMarketEmpty = wx.RadioBox( panel, -1, "Market Group Selection", wx.DefaultPosition, wx.DefaultSize, ["No changes to meta buttons", "Enable all meta buttons"], 1, wx.RA_SPECIFY_COLS) self.rbMarketEmpty.SetSelection( self.priceSettings.get('marketMGMarketSelectMode')) mainSizer.Add(self.rbMarketEmpty, 0, wx.EXPAND | wx.TOP | wx.RIGHT, 10) self.rbMarketEmpty.Bind(wx.EVT_RADIOBOX, self.OnMarketGroupSelectionChange) self.rbMarketEmpty = wx.RadioBox( panel, -1, "Empty Market View", wx.DefaultPosition, wx.DefaultSize, [ "No changes to meta buttons", "Enable leftmost available meta button", "Enable all available meta buttons" ], 1, wx.RA_SPECIFY_COLS) self.rbMarketEmpty.SetSelection( self.priceSettings.get('marketMGEmptyMode')) mainSizer.Add(self.rbMarketEmpty, 0, wx.EXPAND | wx.TOP | wx.RIGHT, 10) self.rbMarketEmpty.Bind(wx.EVT_RADIOBOX, self.OnMarketEmptyChange) self.rbMarketJump = wx.RadioBox( panel, -1, "Item Market Group Jump", wx.DefaultPosition, wx.DefaultSize, [ "No changes to meta buttons", "Enable item's meta button", "Enable item's meta button, disable others", "Enable all meta buttons" ], 1, wx.RA_SPECIFY_COLS) self.rbMarketJump.SetSelection( self.priceSettings.get('marketMGJumpMode')) mainSizer.Add(self.rbMarketJump, 0, wx.EXPAND | wx.TOP | wx.RIGHT | wx.BOTTOM, 10) self.rbMarketJump.Bind(wx.EVT_RADIOBOX, self.OnMarketJumpChange) panel.SetSizer(mainSizer) panel.Layout() def onMarketDelayChange(self, event): self.sFit.serviceFittingOptions[ "marketSearchDelay"] = self.intDelay.GetValue() event.Skip() def onCBShowShortcuts(self, event): self.sFit.serviceFittingOptions[ "showMarketShortcuts"] = self.cbMarketShortcuts.GetValue() def getImage(self): return BitmapLoader.getBitmap("settings_market", "gui") def onPriceSelection(self, event): system = self.chPriceSystem.GetString( self.chPriceSystem.GetSelection()) self.sFit.serviceFittingOptions["priceSystem"] = system fitID = self.mainFrame.getActiveFit() self.sFit.refreshFit(fitID) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) event.Skip() def onPricesSourceSelection(self, event): source = self.chPriceSource.GetString( self.chPriceSource.GetSelection()) self.sFit.serviceFittingOptions["priceSource"] = source def OnTotalPriceDroneChange(self, event): self.priceSettings.set('drones', event.GetInt()) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) def OnTotalPriceCargoChange(self, event): self.priceSettings.set('cargo', event.GetInt()) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) def OnTotalPriceCharacterChange(self, event): self.priceSettings.set('character', event.GetInt()) wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) def OnMarketJumpChange(self, event): self.priceSettings.set('marketMGJumpMode', event.GetInt()) def OnMarketEmptyChange(self, event): self.priceSettings.set('marketMGEmptyMode', event.GetInt()) def OnMarketSearchChange(self, event): self.priceSettings.set('marketMGSearchMode', event.GetInt()) def OnMarketGroupSelectionChange(self, event): self.priceSettings.set('marketMGMarketSelectMode', event.GetInt())
class Tasks(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, title=APPNAME, size=(800, 680)) # , style=NORESIZE self.SetMinSize(wx.Size(800, 680)) # sets min size self.tasks, self.settings = files.Load() # loads settings and tasks self.SetIcon(ICON) # set icon # update checking if self.settings['updateChecking']: self.settings['updateChecking'] = checkForUpdate() # initilise some variables self.selectedtask = -1 self.selectedcol = -1 self.ascending = True self.editCategoriesWindow, self.editSettingsWindow, self.taskWindow, self.editCreateTaskWindow, self.AboutWindow = None, None, None, None, None self.categories = self.settings['categories'] self.settings['numOpens'] += 1 if self.settings['numOpens'] > 5 and self.settings['messages']: hints() # shows some informative messages self.Bind(wx.EVT_CLOSE, self.Exit, self) self.InitUI() self.Maximize(True) self.Show(True) def InitUI(self): # panles used for centering mainpanel = wx.Panel(self) self.centerpanel = wx.Panel(mainpanel) sizer = wx.BoxSizer(wx.VERTICAL) self.status = self.CreateStatusBar() # top bar creation fileMenu = wx.Menu() createTaskItem = fileMenu.Append(-1, '&Create Task \tCtrl-n', 'Create a new task') deleteTaskItem = fileMenu.Append(-1, '&Delete Task \tCtrl-r', 'Remove current task') settingsItem = fileMenu.Append(-1, '&Edit Settings', 'Edit current settings') aboutItem = fileMenu.Append(-1, '&About', 'Information about the program') helpMenu = wx.Menu() githubItem = helpMenu.Append(-1, 'Source', 'Link to the Github repository') twitterItem = helpMenu.Append(-1, 'Twitter', 'Follow progress and support') surveyItem = helpMenu.Append( -1, 'Survey', 'Help improve the program with your feedback') menuBar = wx.MenuBar() menuBar.Append(fileMenu, '&File') menuBar.Append(helpMenu, '&About') self.SetMenuBar(menuBar) self.Bind(wx.EVT_MENU, lambda event: webbrowser.open(REPO), githubItem) self.Bind(wx.EVT_MENU, lambda event: webbrowser.open(TWITTER), twitterItem) self.Bind(wx.EVT_MENU, lambda event: webbrowser.open(SURVEY), surveyItem) self.Bind(wx.EVT_MENU, self.CreateTaskWindow, createTaskItem) self.Bind(wx.EVT_MENU, self.RemoveTask, deleteTaskItem) self.Bind(wx.EVT_MENU, self.EditSettings, settingsItem) self.Bind(wx.EVT_MENU, self.About, aboutItem) # drawing self.DrawTop() self.DrawLower() self.Sort(None) # finish centering sizer.AddStretchSpacer() sizer.Add(self.centerpanel, 0, wx.CENTER) sizer.AddStretchSpacer() mainpanel.SetSizer(sizer) def DrawTop(self): # create task button createTaskBtn = wx.Button(self.centerpanel, 1, 'Create Task', pos=(667, 20)) createTaskBtn.Bind(wx.EVT_BUTTON, self.CreateTaskWindow) createTaskBtn.Bind( wx.EVT_ENTER_WINDOW, lambda event: self.status.SetStatusText('Create a new task')) createTaskBtn.Bind(wx.EVT_LEAVE_WINDOW, lambda event: self.status.SetStatusText('')) # edit task button editCategoriesBtn = wx.Button(self.centerpanel, 1, 'Edit Categories', pos=(557, 20)) editCategoriesBtn.Bind(wx.EVT_BUTTON, self.CategoriesWindow) editCategoriesBtn.Bind( wx.EVT_ENTER_WINDOW, lambda event: self.status.SetStatusText('Edit Categories')) editCategoriesBtn.Bind(wx.EVT_LEAVE_WINDOW, lambda event: self.status.SetStatusText('')) # header wx.StaticText(self.centerpanel, 1, 'Tasks:', pos=(25, 20)).SetFont(FONT1) # task list self.list = wx.ListCtrl(self.centerpanel, 1, style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_SINGLE_SEL, pos=(25, 60), size=(730, 195)) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.SelectTask, self.list) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.DeselectTask, self.list) self.Bind(wx.EVT_LIST_COL_BEGIN_DRAG, lambda event: event.Veto(), self.list) # Don't let the user change the width of columns self.Bind(wx.EVT_LIST_COL_CLICK, self.ColumnClick, self.list) def DrawLower(self): # task box self.taskPanel = wx.StaticBox( self.centerpanel, 1, ' Task: ', pos=(25, 265), size=(730, 315)) # Added some spaces to give the label a bit more room # title self.taskTitle = wx.StaticText( self.taskPanel, 1, '', pos=(15, 25), size=(680, 40), style=wx.ST_NO_AUTORESIZE | wx.ST_ELLIPSIZE_END) # if overflow turn to ellipse self.taskTitle.SetFont(FONT2) # desciption self.taskDescription = wx.StaticText(self.taskPanel, 1, '', pos=(15, 55), size=(680, 105), style=wx.ST_NO_AUTORESIZE) self.taskDescription.Wrap(680) # wraps to 680 pixels # date self.taskDate = wx.StaticText(self.taskPanel, 1, '', pos=(15, 185)) self.taskDate.SetFont(FONT2) # completion self.taskCompletionInput = IntCtrl(self.taskPanel, 1, 0, pos=(110, 210), size=(35, 19), min=0, max=100) self.taskCompletionInput.Hide() self.Bind(EVT_INT, self.CompletionChanged, self.taskCompletionInput) self.taskCompletion = wx.StaticText(self.taskPanel, 1, '', pos=(15, 210)) self.taskCompletion.SetFont(FONT2) self.taskCompletionPer = wx.StaticText(self.taskPanel, 1, '', pos=(152, 210)) self.taskCompletionPer.SetFont(FONT2) # categories self.categoryLabel = wx.StaticText(self.taskPanel, 1, '', pos=(15, 235)) self.categoryLabel.SetFont(FONT2) self.categoryIcon = wx.StaticText(self.taskPanel, 1, '', pos=(85, 233)) self.categoryIcon.SetFont(FONTWING) self.categoryText = wx.StaticText(self.taskPanel, 1, '', pos=(105, 235)) self.categoryText.SetFont(FONT2) # subtaks self.subtaskLabels, self.subtaskTicks = list(), list() self.subtaskLabel = wx.StaticText(self.taskPanel, 1, '', pos=(305, 180)) self.subtaskLabel.SetFont(FONT2) for x in range(2): for y in range(3): label = wx.StaticText(self.taskPanel, 1, '', pos=(325 + (x * 115), 210 + (y * 25))) self.subtaskLabels.append(label) tick = wx.CheckBox(self.taskPanel, 1, name=str(y + (3 * x)), pos=(305 + (x * 115), 210 + (y * 25))) tick.Hide() self.Bind(wx.EVT_CHECKBOX, self.CheckSubtask, tick) self.subtaskTicks.append(tick) # edit button self.taskEdit = wx.Button(self.taskPanel, 1, 'Edit Task', pos=(15, 275)) self.taskEdit.Bind(wx.EVT_BUTTON, self.EditTaskWindow) self.taskEdit.Bind(wx.EVT_ENTER_WINDOW, lambda event: self.status.SetStatusText( 'Edit Selected Task')) # For the tips bar self.taskEdit.Bind(wx.EVT_LEAVE_WINDOW, lambda event: self.status.SetStatusText('')) self.taskEdit.Disable() # delete button self.taskDelete = wx.Button(self.taskPanel, 1, 'Delete Task', pos=(105, 275)) self.taskDelete.Bind(wx.EVT_BUTTON, self.RemoveTask) self.taskDelete.Bind(wx.EVT_ENTER_WINDOW, lambda event: self.status.SetStatusText( 'Delete Selected Task')) # For the tips bar self.taskDelete.Bind(wx.EVT_LEAVE_WINDOW, lambda event: self.status.SetStatusText('')) self.taskDelete.Disable() # shows if their is no selected task self.noTask = wx.StaticText(self.taskPanel, 1, 'No Task Selected', pos=(310, 125)) self.noTask.SetFont(FONT2) def UpdateTasks(self): self.list.ClearAll() self.AddColumns( ) # clear all also removes columns :( so have to add them back for y, task in enumerate(self.tasks): row = self.list.InsertItem(0, task[0]) # title importance = task[6] self.list.SetItem(row, 1, str(importance)) # importance if (importance > 7) and self.settings['tabelHighlighting']: self.list.SetItemBackgroundColour(row, ALERTORANGE) self.list.SetItemTextColour(row, WHITE) self.list.SetItem(row, 2, self.categories[task[7]]) # category # completion date overdue, date, time = ParseDateTime(task[4]) if overdue and self.settings[ 'tabelHighlighting']: # hightlighting overdue objects if setting is ticked self.list.SetItemBackgroundColour(row, ALERTRED) self.list.SetItemTextColour(row, WHITE) if task[3] == 2 or task[3] == 3: self.list.SetItem(row, 3, date + time) else: self.list.SetItem(row, 3, date) completion = task[8] self.list.SetItem(row, 4, str(completion)) # current completion if (completion == 100) and self.settings[ 'tabelHighlighting']: # hightlighting overdue objects if setting is ticked self.list.SetItemBackgroundColour(row, ALERTGREEN) self.list.SetItemTextColour(row, WHITE) def AddColumns(self): for x, y in enumerate(zip(TABLE_HEADERS, [145, 75, 100, 110, 90])): self.list.InsertColumn(x, y[0], width=y[1]) def Exit(self, event): if self.settings['deleteOnCompletion']: newTasks = [x for x in self.tasks if x[8] is not 100] else: newTasks = list(self.tasks) files.Save(newTasks, self.settings) # saves files for x in [ self.editCategoriesWindow, self.editSettingsWindow, self.taskWindow, self.editCreateTaskWindow, self.AboutWindow ]: # close all open windows try: x.Close(True) except Exception as e: pass self.Destroy() def SelectTask(self, event=None): if self.list.GetFirstSelected( ) == -1: # buffer for whencalled when there is nothing selected? return else: self.selectedtask = len(self.tasks) - self.list.GetFirstSelected( ) - 1 # list view is in reverse order to actual tasks list task = self.tasks[self.selectedtask] self.taskTitle.SetLabel(task[0]) # title self.taskDescription.SetLabel(task[1]) # description # date overdue, date, time = ParseDateTime(task[4]) if task[3] == 2 or task[3] == 3: self.taskDate.SetLabel('Due Date: ' + date + time) else: self.taskDate.SetLabel('Due Date: ' + date) if overdue: self.taskDate.SetForegroundColour(ALERTRED) # completion self.taskCompletion.SetLabel('Completiton:') self.taskCompletionPer.SetLabel('%') self.taskCompletionInput.Show() self.taskCompletionInput.SetValue(task[8]) # category category = task[7] self.categoryLabel.SetLabel('Category:') self.categoryIcon.SetLabel('n') self.categoryText.SetLabel(self.categories[category]) if category is not 0: self.categoryIcon.SetForegroundColour(COLOURS[category - 1]) else: self.categoryIcon.SetForegroundColour(BLACK) # subtasks if len(task[2]) is not 0: self.subtaskLabel.SetLabel('Subtasks:') for y, x in enumerate(task[2]): self.subtaskLabels[y].SetLabel(x[0]) self.subtaskTicks[y].Show() self.subtaskTicks[y].SetValue(x[1]) # remove 'no task selected' message and enable buttons self.noTask.SetLabel('') self.taskEdit.Enable() self.taskDelete.Enable() # resets all changes made in SelectTask def DeselectTask(self, event=None): self.selectedtask = -1 self.taskTitle.SetLabel('') self.taskDescription.SetLabel('') self.taskCompletion.SetLabel('') self.taskCompletionPer.SetLabel('') self.taskCompletionInput.Hide() self.taskDate.SetLabel('') self.taskDate.SetForegroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_BACKGROUND)) self.categoryLabel.SetLabel('') self.categoryIcon.SetLabel('') self.categoryText.SetLabel('') self.subtaskLabel.SetLabel('') for y in range(6): # subtasks self.subtaskLabels[y].SetLabel('') self.subtaskTicks[y].Hide() self.noTask.SetLabel('No Task Selected') self.taskEdit.Disable() self.taskDelete.Disable() def CreateTaskWindow(self, event): self.taskWindow = extgui.TaskEditor(self, self.categories) def EditTaskWindow(self, event): self.editCreateTaskWindow = extgui.TaskEditor( self, self.categories, self.tasks[self.selectedtask], True) def AddTask(self, task): # this function is called from the task editor panel self.tasks.append(task) self.DeselectTask() self.UpdateTasks() def AlterTask(self, task): # this function is called from the task editor panel self.tasks[self.selectedtask] = task self.UpdateTasks() self.DeselectTask() def RemoveTask(self, event): if self.selectedtask is not -1: del self.tasks[self.selectedtask] self.DeselectTask() self.UpdateTasks() else: wx.MessageDialog(None, 'No Task Selected', APPNAME).ShowModal() def CategoriesWindow(self, event): self.DeselectTask() self.editCategoriesWindow = extgui.CategoryDialog( self.categories[1:], self) def EditCategories(self, categories): self.categories = ['None'] + categories self.settings['categories'] = self.categories self.UpdateTasks() self.SelectTask() # problem def SetSettings(self, settings): self.settings.update(settings) self.UpdateTasks() def EditSettings(self, event): self.editSettingsWindow = extgui.SettingsDialog(self.settings, self) def About(self, event): self.AboutWindow = extgui.AboutDialog() # subtask editing def CheckSubtask(self, event): box = event.GetEventObject() self.tasks[self.selectedtask][2][int( box.GetName())][1] = box.GetValue() def CompletionChanged(self, event): x = self.taskCompletionInput.GetValue() if 0 <= x <= 100: self.tasks[self.selectedtask][8] = x self.UpdateTasks() event.Skip() def ColumnClick(self, event): # used for sorting index = event.GetColumn() if index is self.selectedcol: self.ascending = not self.ascending self.Sort(TABLE_HEADERS[index], self.ascending) else: self.selectedcol = index self.ascending = True self.Sort(TABLE_HEADERS[index], self.ascending) # sorting the task list def Sort(self, rule, ascend=True): if rule is TABLE_HEADERS[0]: self.tasks.sort(key=lambda x: x[0]) elif rule is TABLE_HEADERS[1]: self.tasks.sort(key=lambda x: x[6], reverse=True) elif rule is TABLE_HEADERS[2]: self.tasks.sort(key=lambda x: x[7]) elif rule is TABLE_HEADERS[3]: self.tasks.sort(key=lambda x: dateSort(x[4])) elif rule is TABLE_HEADERS[4]: self.tasks.sort(key=lambda x: x[8]) else: self.tasks.sort(key=lambda x: x[5]) if not ascend: self.tasks = self.tasks[::-1] self.UpdateTasks()