Skip to content

Commit f76f7e8

Browse files
committed
Add ability to override character security status via a menu
1 parent b807e2a commit f76f7e8

File tree

5 files changed

+227
-0
lines changed

5 files changed

+227
-0
lines changed

gui/builtinContextMenus/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from gui.builtinContextMenus import itemStats
2121
from gui.builtinContextMenus import itemMarketJump
2222
from gui.builtinContextMenus import fitSystemSecurity # Not really an item info but want to keep it here
23+
from gui.builtinContextMenus import fitPilotSecurity # Not really an item info but want to keep it here
2324
from gui.builtinContextMenus import shipJump
2425
# Generic item manipulations
2526
from gui.builtinContextMenus import itemRemove
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import re
2+
3+
import wx
4+
5+
import gui.fitCommands as cmd
6+
import gui.mainFrame
7+
from gui.contextMenu import ContextMenuUnconditional
8+
from service.fit import Fit
9+
10+
_t = wx.GetTranslation
11+
12+
13+
class FitPilotSecurityMenu(ContextMenuUnconditional):
14+
15+
def __init__(self):
16+
self.mainFrame = gui.mainFrame.MainFrame.getInstance()
17+
18+
def display(self, callingWindow, srcContext):
19+
if srcContext != "fittingShip":
20+
return False
21+
22+
fitID = self.mainFrame.getActiveFit()
23+
fit = Fit.getInstance().getFit(fitID)
24+
25+
if fit.ship.name not in ('Pacifier', 'Enforcer', 'Marshal', 'Sidewinder', 'Cobra', 'Python'):
26+
return
27+
28+
return True
29+
30+
def getText(self, callingWindow, itmContext):
31+
return _t("Pilot Security Status")
32+
33+
def addOption(self, menu, optionLabel, optionValue):
34+
id = ContextMenuUnconditional.nextID()
35+
self.optionIds[id] = optionValue
36+
menuItem = wx.MenuItem(menu, id, optionLabel, kind=wx.ITEM_CHECK)
37+
menu.Bind(wx.EVT_MENU, self.handleMode, menuItem)
38+
return menuItem
39+
40+
def addOptionCustom(self, menu, optionLabel):
41+
id = ContextMenuUnconditional.nextID()
42+
menuItem = wx.MenuItem(menu, id, optionLabel, kind=wx.ITEM_CHECK)
43+
menu.Bind(wx.EVT_MENU, self.handleModeCustom, menuItem)
44+
return menuItem
45+
46+
def getSubMenu(self, callingWindow, context, rootMenu, i, pitem):
47+
fitID = self.mainFrame.getActiveFit()
48+
fit = Fit.getInstance().getFit(fitID)
49+
msw = True if "wxMSW" in wx.PlatformInfo else False
50+
self.optionIds = {}
51+
sub = wx.Menu()
52+
presets = (-10, -8, -6, -4, -2, 0, 1, 2, 3, 4, 5)
53+
# Inherit
54+
char_sec_status = round(fit.character.secStatus, 2)
55+
menuItem = self.addOption(rootMenu if msw else sub, _t('Character') + f' ({char_sec_status})', None)
56+
sub.Append(menuItem)
57+
menuItem.Check(fit.pilotSecurity is None)
58+
# Custom
59+
label = _t('Custom')
60+
is_checked = False
61+
if fit.pilotSecurity is not None and fit.pilotSecurity not in presets:
62+
sec_status = round(fit.getPilotSecurity(), 2)
63+
label += f' ({sec_status})'
64+
is_checked = True
65+
menuItem = self.addOptionCustom(rootMenu if msw else sub, label)
66+
sub.Append(menuItem)
67+
menuItem.Check(is_checked)
68+
sub.AppendSeparator()
69+
# Predefined options
70+
for sec_status in presets:
71+
menuItem = self.addOption(rootMenu if msw else sub, str(sec_status), sec_status)
72+
sub.Append(menuItem)
73+
menuItem.Check(fit.pilotSecurity == sec_status)
74+
return sub
75+
76+
def handleMode(self, event):
77+
optionValue = self.optionIds[event.Id]
78+
self.mainFrame.command.Submit(cmd.GuiChangeFitPilotSecurityCommand(
79+
fitID=self.mainFrame.getActiveFit(),
80+
secStatus=optionValue))
81+
82+
def handleModeCustom(self, event):
83+
fitID = self.mainFrame.getActiveFit()
84+
fit = Fit.getInstance().getFit(fitID)
85+
sec_status = fit.getPilotSecurity()
86+
87+
with SecStatusChanger(self.mainFrame, value=sec_status) as dlg:
88+
if dlg.ShowModal() == wx.ID_OK:
89+
cleanInput = re.sub(r'[^0-9.\-+]', '', dlg.input.GetLineText(0).strip())
90+
if cleanInput:
91+
try:
92+
cleanInputFloat = float(cleanInput)
93+
except ValueError:
94+
return
95+
else:
96+
return
97+
self.mainFrame.command.Submit(cmd.GuiChangeFitPilotSecurityCommand(
98+
fitID=fitID, secStatus=max(-10.0, min(5.0, cleanInputFloat))))
99+
100+
101+
FitPilotSecurityMenu.register()
102+
103+
104+
class SecStatusChanger(wx.Dialog):
105+
106+
def __init__(self, parent, value):
107+
super().__init__(parent, title=_t('Change Security Status'), style=wx.DEFAULT_DIALOG_STYLE)
108+
self.SetMinSize((346, 156))
109+
110+
bSizer1 = wx.BoxSizer(wx.VERTICAL)
111+
112+
bSizer2 = wx.BoxSizer(wx.VERTICAL)
113+
text = wx.StaticText(self, wx.ID_ANY, _t('Security Status (min -10.0, max 5.0):'))
114+
bSizer2.Add(text, 0)
115+
116+
bSizer1.Add(bSizer2, 0, wx.ALL, 10)
117+
118+
self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
119+
if value is None:
120+
value = '0.0'
121+
else:
122+
if value == int(value):
123+
value = int(value)
124+
value = str(value)
125+
self.input.SetValue(value)
126+
127+
bSizer1.Add(self.input, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 15)
128+
129+
bSizer3 = wx.BoxSizer(wx.VERTICAL)
130+
bSizer3.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.BOTTOM | wx.EXPAND, 15)
131+
132+
bSizer3.Add(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL), 0, wx.EXPAND)
133+
bSizer1.Add(bSizer3, 0, wx.ALL | wx.EXPAND, 10)
134+
135+
self.input.Bind(wx.EVT_CHAR, self.onChar)
136+
self.input.Bind(wx.EVT_TEXT_ENTER, self.processEnter)
137+
self.SetSizer(bSizer1)
138+
self.Fit()
139+
self.CenterOnParent()
140+
self.input.SetFocus()
141+
self.input.SelectAll()
142+
143+
def processEnter(self, evt):
144+
self.EndModal(wx.ID_OK)
145+
146+
# checks to make sure it's valid number
147+
@staticmethod
148+
def onChar(event):
149+
key = event.GetKeyCode()
150+
151+
acceptable_characters = '1234567890.-+'
152+
acceptable_keycode = [3, 22, 13, 8, 127] # modifiers like delete, copy, paste
153+
if key in acceptable_keycode or key >= 255 or (key < 255 and chr(key) in acceptable_characters):
154+
event.Skip()
155+
return
156+
else:
157+
return False

gui/fitCommands/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from .gui.commandFit.add import GuiAddCommandFitsCommand
1313
from .gui.commandFit.remove import GuiRemoveCommandFitsCommand
1414
from .gui.commandFit.toggleStates import GuiToggleCommandFitStatesCommand
15+
from .gui.fitPilotSecurity import GuiChangeFitPilotSecurityCommand
1516
from .gui.fitRename import GuiRenameFitCommand
1617
from .gui.fitRestrictionToggle import GuiToggleFittingRestrictionsCommand
1718
from .gui.fitSystemSecurity import GuiChangeFitSystemSecurityCommand
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import wx
2+
from logbook import Logger
3+
4+
from service.fit import Fit
5+
6+
7+
pyfalog = Logger(__name__)
8+
9+
10+
class CalcChangeFitPilotSecurityCommand(wx.Command):
11+
12+
def __init__(self, fitID, secStatus):
13+
wx.Command.__init__(self, True, 'Change Fit Pilot Security')
14+
self.fitID = fitID
15+
self.secStatus = secStatus
16+
self.savedSecStatus = None
17+
18+
def Do(self):
19+
pyfalog.debug('Doing changing pilot security status of fit {} to {}'.format(self.fitID, self.secStatus))
20+
fit = Fit.getInstance().getFit(self.fitID, basic=True)
21+
# Fetching status via getter and then saving 'raw' security status
22+
# is intentional, to restore pre-change state properly
23+
if fit.pilotSecurity == self.secStatus:
24+
return False
25+
self.savedSecStatus = fit.pilotSecurity
26+
fit.pilotSecurity = self.secStatus
27+
return True
28+
29+
def Undo(self):
30+
pyfalog.debug('Undoing changing pilot security status of fit {} to {}'.format(self.fitID, self.secStatus))
31+
cmd = CalcChangeFitPilotSecurityCommand(fitID=self.fitID, secStatus=self.savedSecStatus)
32+
return cmd.Do()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import wx
2+
from service.fit import Fit
3+
4+
import eos.db
5+
import gui.mainFrame
6+
from gui import globalEvents as GE
7+
from gui.fitCommands.helpers import InternalCommandHistory
8+
from gui.fitCommands.calc.fitPilotSecurity import CalcChangeFitPilotSecurityCommand
9+
10+
11+
class GuiChangeFitPilotSecurityCommand(wx.Command):
12+
13+
def __init__(self, fitID, secStatus):
14+
wx.Command.__init__(self, True, 'Change Fit Pilot Security')
15+
self.internalHistory = InternalCommandHistory()
16+
self.fitID = fitID
17+
self.secStatus = secStatus
18+
19+
def Do(self):
20+
cmd = CalcChangeFitPilotSecurityCommand(fitID=self.fitID, secStatus=self.secStatus)
21+
success = self.internalHistory.submit(cmd)
22+
eos.db.flush()
23+
sFit = Fit.getInstance()
24+
sFit.recalc(self.fitID)
25+
eos.db.commit()
26+
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
27+
return success
28+
29+
def Undo(self):
30+
success = self.internalHistory.undoAll()
31+
eos.db.flush()
32+
sFit = Fit.getInstance()
33+
sFit.recalc(self.fitID)
34+
eos.db.commit()
35+
wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitIDs=(self.fitID,)))
36+
return success

0 commit comments

Comments
 (0)