diff --git a/gui/builtinAdditionPanes/boosterView.py b/gui/builtinAdditionPanes/boosterView.py index d6a8a00d5..41bdfbafb 100644 --- a/gui/builtinAdditionPanes/boosterView.py +++ b/gui/builtinAdditionPanes/boosterView.py @@ -90,7 +90,11 @@ class BoosterView(d.Display): if keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE): row = self.GetFirstSelected() if row != -1: - self.removeBooster(self.boosters[self.GetItemData(row)]) + try: + booster = self.boosters[self.GetItemData(row)] + except IndexError: + return + self.removeBooster(booster) event.Skip() @@ -148,11 +152,18 @@ class BoosterView(d.Display): if row != -1: col = self.getColumn(event.Position) if col != self.getColIndex(State): - self.removeBooster(self.boosters[self.GetItemData(row)]) + try: + booster = self.boosters[self.GetItemData(row)] + except IndexError: + return + self.removeBooster(booster) def removeBooster(self, booster): fitID = self.mainFrame.getActiveFit() - self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand(fitID=fitID, position=self.original.index(booster))) + if booster in self.original: + position = self.original.index(booster) + self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand( + fitID=fitID, position=position)) def click(self, event): event.Skip() @@ -161,13 +172,23 @@ class BoosterView(d.Display): col = self.getColumn(event.Position) if col == self.getColIndex(State): fitID = self.mainFrame.getActiveFit() - booster = self.boosters[self.GetItemData(row)] - self.mainFrame.command.Submit(cmd.GuiToggleBoosterStateCommand(fitID=fitID, position=self.original.index(booster))) + try: + booster = self.boosters[self.GetItemData(row)] + except IndexError: + return + if booster in self.original: + position = self.original.index(booster) + self.mainFrame.command.Submit(cmd.GuiToggleBoosterStateCommand( + fitID=fitID, + position=position)) def spawnMenu(self, event): sel = self.GetFirstSelected() if sel != -1: - booster = self.boosters[sel] + try: + booster = self.boosters[sel] + except IndexError: + return None srcContext = "boosterItem" itemContext = "Booster" menu = ContextMenu.getMenu((booster,), (srcContext, itemContext)) diff --git a/gui/builtinAdditionPanes/cargoView.py b/gui/builtinAdditionPanes/cargoView.py index d48caacea..e6ab56150 100644 --- a/gui/builtinAdditionPanes/cargoView.py +++ b/gui/builtinAdditionPanes/cargoView.py @@ -78,16 +78,20 @@ class CargoView(d.Display): if data[0] == "fitting": self.swapModule(x, y, int(data[1])) elif data[0] == "market": - fit = self.mainFrame.getActiveFit() - if fit: - self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(fit, int(data[1]), 1)) + fitID = self.mainFrame.getActiveFit() + if fitID: + self.mainFrame.command.Submit(cmd.GuiAddCargoCommand( + fitID=fitID, itemID=int(data[1]), amount=1)) def startDrag(self, event): row = event.GetIndex() if row != -1: data = wx.TextDataObject() - dataStr = "cargo:{}".format(self.cargo[row].itemID) + try: + dataStr = "cargo:{}".format(self.cargo[row].itemID) + except IndexError: + return data.SetText(dataStr) dropSource = wx.DropSource(self) @@ -101,7 +105,10 @@ class CargoView(d.Display): row = self.GetFirstSelected() if row != -1: fitID = self.mainFrame.getActiveFit() - cargo = self.cargo[self.GetItemData(row)] + try: + cargo = self.cargo[self.GetItemData(row)] + except IndexError: + return self.mainFrame.command.Submit(cmd.GuiRemoveCargoCommand(fitID=fitID, itemID=cargo.itemID)) event.Skip() @@ -111,10 +118,18 @@ class CargoView(d.Display): fit = sFit.getFit(self.mainFrame.getActiveFit()) dstRow, _ = self.HitTest((x, y)) + if dstRow > -1: + try: + dstCargoItemID = getattr(self.cargo[dstRow], 'itemID', None) + except IndexError: + dstCargoItemID = None + else: + dstCargoItemID = None + self.mainFrame.command.Submit(cmd.GuiLocalModuleToCargoCommand( fitID=self.mainFrame.getActiveFit(), - modPosition=fit.modules[modIdx].modPosition, - cargoItemID=self.cargo[dstRow].itemID if dstRow > -1 else None, + modPosition=modIdx, + cargoItemID=dstCargoItemID, copy=wx.GetMouseState().cmdDown)) def fitChanged(self, event): @@ -155,13 +170,19 @@ class CargoView(d.Display): col = self.getColumn(event.Position) if col != self.getColIndex(State): fitID = self.mainFrame.getActiveFit() - cargo = self.cargo[self.GetItemData(row)] - self.mainFrame.command.Submit(cmd.GuiRemoveCargoCommand(fitID, cargo.itemID)) + try: + cargo = self.cargo[self.GetItemData(row)] + except IndexError: + return + self.mainFrame.command.Submit(cmd.GuiRemoveCargoCommand(fitID=fitID, itemID=cargo.itemID)) def spawnMenu(self, event): sel = self.GetFirstSelected() if sel != -1: - cargo = self.cargo[sel] + try: + cargo = self.cargo[sel] + except IndexError: + return sMkt = Market.getInstance() sourceContext = "cargoItem" itemContext = sMkt.getCategoryByItem(cargo.item).name diff --git a/gui/builtinAdditionPanes/commandView.py b/gui/builtinAdditionPanes/commandView.py index 5001824c4..5d67b490a 100644 --- a/gui/builtinAdditionPanes/commandView.py +++ b/gui/builtinAdditionPanes/commandView.py @@ -99,14 +99,17 @@ class CommandView(d.Display): fitID = self.mainFrame.getActiveFit() row = self.GetFirstSelected() if row != -1: - self.mainFrame.command.Submit(cmd.GuiRemoveCommandFitCommand(fitID, self.get(row).ID)) + commandFit = self.get(row) + if commandFit is not None: + self.mainFrame.command.Submit(cmd.GuiRemoveCommandFitCommand( + fitID=fitID, commandFitID=commandFit.ID)) def handleDrag(self, type, fitID): # Those are drags coming from pyfa sources, NOT builtin wx drags if type == "fit": activeFit = self.mainFrame.getActiveFit() if activeFit: - self.mainFrame.command.Submit(cmd.GuiAddCommandFitCommand(activeFit, fitID)) + self.mainFrame.command.Submit(cmd.GuiAddCommandFitCommand(fitID=activeFit, commandFitID=fitID)) def startDrag(self, event): row = event.GetIndex() @@ -166,13 +169,13 @@ class CommandView(d.Display): def get(self, row): if row == -1: return None - numFits = len(self.fits) - if numFits == 0: return None - - return self.fits[row] + try: + return self.fits[row] + except IndexError: + return None def click(self, event): event.Skip() diff --git a/gui/builtinAdditionPanes/droneView.py b/gui/builtinAdditionPanes/droneView.py index 4a4f554cd..b63b71d54 100644 --- a/gui/builtinAdditionPanes/droneView.py +++ b/gui/builtinAdditionPanes/droneView.py @@ -102,7 +102,10 @@ class DroneView(Display): self.hoveredRow = row self.hoveredColumn = col if row != -1 and col != -1 and col < len(self.DEFAULT_COLS): - mod = self.drones[self.GetItemData(row)] + try: + mod = self.drones[self.GetItemData(row)] + except IndexError: + return if self.DEFAULT_COLS[col] == "Miscellanea": tooltip = self.activeColumns[col].getToolTip(mod) if tooltip is not None: @@ -120,7 +123,10 @@ class DroneView(Display): if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE: row = self.GetFirstSelected() if row != -1: - drone = self.drones[self.GetItemData(row)] + try: + drone = self.drones[self.GetItemData(row)] + except IndexError: + return self.removeDroneStack(drone) event.Skip() @@ -155,11 +161,16 @@ class DroneView(Display): def _merge(self, srcRow, dstRow): fitID = self.mainFrame.getActiveFit() - fit = Fit.getInstance().getFit(fitID) - self.mainFrame.command.Submit(cmd.GuiMergeLocalDroneStacksCommand( - fitID=fitID, - srcPosition=fit.drones.index(self.drones[srcRow]), - dstPosition=fit.drones.index(self.drones[dstRow]))) + try: + srcDrone = self.drones[srcRow] + dstDrone = self.drones[dstRow] + except IndexError: + return + if srcDrone in self.original and dstDrone in self.original: + srcPosition = self.original.index(srcDrone) + dstPosition = self.original.index(dstDrone) + self.mainFrame.command.Submit(cmd.GuiMergeLocalDroneStacksCommand( + fitID=fitID, srcPosition=srcPosition, dstPosition=dstPosition)) DRONE_ORDER = ('Light Scout Drones', 'Medium Scout Drones', 'Heavy Attack Drones', 'Sentry Drones', 'Combat Utility Drones', @@ -229,7 +240,10 @@ class DroneView(Display): col = self.getColumn(event.Position) if col != self.getColIndex(State): mstate = wx.GetMouseState() - drone = self.drones[self.GetItemData(row)] + try: + drone = self.drones[self.GetItemData(row)] + except IndexError: + return if mstate.cmdDown or mstate.altDown: self.removeDroneStack(drone) else: @@ -237,11 +251,17 @@ class DroneView(Display): def removeDrone(self, drone): fitID = self.mainFrame.getActiveFit() - self.mainFrame.command.Submit(cmd.GuiRemoveLocalDroneCommand(fitID, self.original.index(drone), 1)) + if drone in self.original: + position = self.original.index(drone) + self.mainFrame.command.Submit(cmd.GuiRemoveLocalDroneCommand( + fitID=fitID, position=position, amount=1)) def removeDroneStack(self, drone): fitID = self.mainFrame.getActiveFit() - self.mainFrame.command.Submit(cmd.GuiRemoveLocalDroneCommand(fitID, self.original.index(drone), math.inf)) + if drone in self.original: + position = self.original.index(drone) + self.mainFrame.command.Submit(cmd.GuiRemoveLocalDroneCommand( + fitID=fitID, position=position, amount=math.inf)) def click(self, event): event.Skip() @@ -250,13 +270,22 @@ class DroneView(Display): col = self.getColumn(event.Position) if col == self.getColIndex(State): fitID = self.mainFrame.getActiveFit() - drone = self.drones[row] - self.mainFrame.command.Submit(cmd.GuiToggleLocalDroneStateCommand(fitID, self.original.index(drone))) + try: + drone = self.drones[row] + except IndexError: + return + if drone in self.original: + position = self.original.index(drone) + self.mainFrame.command.Submit(cmd.GuiToggleLocalDroneStateCommand( + fitID=fitID, position=position)) def spawnMenu(self, event): sel = self.GetFirstSelected() if sel != -1: - drone = self.drones[sel] + try: + drone = self.drones[sel] + except IndexError: + return sMkt = Market.getInstance() sourceContext = "droneItem" itemContext = sMkt.getCategoryByItem(drone.item).name diff --git a/gui/builtinAdditionPanes/fighterView.py b/gui/builtinAdditionPanes/fighterView.py index 1c71bbdcd..88ad7902d 100644 --- a/gui/builtinAdditionPanes/fighterView.py +++ b/gui/builtinAdditionPanes/fighterView.py @@ -162,7 +162,10 @@ class FighterDisplay(d.Display): self.hoveredRow = row self.hoveredColumn = col if row != -1 and col != -1 and col < len(self.DEFAULT_COLS): - mod = self.fighters[self.GetItemData(row)] + try: + mod = self.fighters[self.GetItemData(row)] + except IndexError: + return if self.DEFAULT_COLS[col] == "Miscellanea": tooltip = self.activeColumns[col].getToolTip(mod) if tooltip is not None: @@ -180,7 +183,10 @@ class FighterDisplay(d.Display): if keycode == wx.WXK_DELETE or keycode == wx.WXK_NUMPAD_DELETE: row = self.GetFirstSelected() if row != -1: - fighter = self.fighters[self.GetItemData(row)] + try: + fighter = self.fighters[self.GetItemData(row)] + except IndexError: + return self.removeFighter(fighter) event.Skip() @@ -273,12 +279,17 @@ class FighterDisplay(d.Display): if row != -1: col = self.getColumn(event.Position) if col != self.getColIndex(State): - fighter = self.fighters[self.GetItemData(row)] + try: + fighter = self.fighters[self.GetItemData(row)] + except IndexError: + return self.removeFighter(fighter) def removeFighter(self, fighter): fitID = self.mainFrame.getActiveFit() - self.mainFrame.command.Submit(cmd.GuiRemoveLocalFighterCommand(fitID, self.original.index(fighter))) + if fighter in self.original: + position = self.original.index(fighter) + self.mainFrame.command.Submit(cmd.GuiRemoveLocalFighterCommand(fitID=fitID, position=position)) def click(self, event): event.Skip() @@ -287,14 +298,21 @@ class FighterDisplay(d.Display): col = self.getColumn(event.Position) if col == self.getColIndex(State): fitID = self.mainFrame.getActiveFit() - fighter = self.fighters[row] - self.mainFrame.command.Submit(cmd.GuiToggleLocalFighterStateCommand(fitID, self.original.index(fighter))) + try: + fighter = self.fighters[row] + except IndexError: + return + if fighter in self.original: + position = self.original.index(fighter) + self.mainFrame.command.Submit(cmd.GuiToggleLocalFighterStateCommand(fitID=fitID, position=position)) def spawnMenu(self, event): sel = self.GetFirstSelected() if sel != -1: - fighter = self.fighters[sel] - + try: + fighter = self.fighters[sel] + except IndexError: + return sMkt = Market.getInstance() sourceContext = "fighterItem" itemContext = sMkt.getCategoryByItem(fighter.item).name diff --git a/gui/builtinAdditionPanes/implantView.py b/gui/builtinAdditionPanes/implantView.py index fd86a905e..1dfea89d3 100644 --- a/gui/builtinAdditionPanes/implantView.py +++ b/gui/builtinAdditionPanes/implantView.py @@ -132,16 +132,21 @@ class ImplantDisplay(d.Display): """ if data[0] == "market": - if self.mainFrame.command.Submit(cmd.GuiAddImplantCommand(self.mainFrame.getActiveFit(), int(data[1]))): + if self.mainFrame.command.Submit(cmd.GuiAddImplantCommand( + fitID=self.mainFrame.getActiveFit(), itemID=int(data[1]))): self.mainFrame.additionsPane.select("Implants") def kbEvent(self, event): + event.Skip() keycode = event.GetKeyCode() if keycode in (wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE): row = self.GetFirstSelected() if row != -1: - self.removeImplant(self.implants[self.GetItemData(row)]) - event.Skip() + try: + implant = self.implants[self.GetItemData(row)] + except IndexError: + return + self.removeImplant(implant) def fitChanged(self, event): sFit = Fit.getInstance() @@ -187,7 +192,8 @@ class ImplantDisplay(d.Display): event.Skip() return - self.mainFrame.command.Submit(cmd.GuiAddImplantCommand(fitID, event.itemID)) + self.mainFrame.command.Submit(cmd.GuiAddImplantCommand( + fitID=fitID, itemID=event.itemID)) # Select in any case - as we might've added implant which has been there already and command failed self.mainFrame.additionsPane.select('Implants') @@ -202,14 +208,19 @@ class ImplantDisplay(d.Display): if row != -1: col = self.getColumn(event.Position) if col != self.getColIndex(State): - self.removeImplant(self.implants[self.GetItemData(row)]) + try: + implant = self.implants[self.GetItemData(row)] + except IndexError: + return + self.removeImplant(implant) def removeImplant(self, implant): fitID = self.mainFrame.getActiveFit() sFit = Fit.getInstance() fit = sFit.getFit(fitID) - if fit.implantLocation == ImplantLocation.FIT: - self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand(fitID, self.original.index(implant))) + if fit.implantLocation == ImplantLocation.FIT and implant in self.original: + position = self.original.index(implant) + self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand(fitID=fitID, position=position)) def click(self, event): event.Skip() @@ -223,8 +234,14 @@ class ImplantDisplay(d.Display): col = self.getColumn(event.Position) if col == self.getColIndex(State): fitID = self.mainFrame.getActiveFit() - implant = self.implants[self.GetItemData(row)] - self.mainFrame.command.Submit(cmd.GuiToggleImplantStateCommand(fitID=fitID, position=self.original.index(implant))) + try: + implant = self.implants[self.GetItemData(row)] + except IndexError: + return + if implant in self.original: + position = self.original.index(implant) + self.mainFrame.command.Submit(cmd.GuiToggleImplantStateCommand( + fitID=fitID, position=position)) def spawnMenu(self, event): sel = self.GetFirstSelected() @@ -237,7 +254,10 @@ class ImplantDisplay(d.Display): return if sel != -1: - implant = self.implants[sel] + try: + implant = self.implants[sel] + except IndexError: + return sMkt = Market.getInstance() sourceContext = "implantItem" if fit.implantSource == ImplantLocation.FIT else "implantItemChar" itemContext = sMkt.getCategoryByItem(implant.item).name diff --git a/gui/builtinAdditionPanes/projectedView.py b/gui/builtinAdditionPanes/projectedView.py index 473da003c..04d815d96 100644 --- a/gui/builtinAdditionPanes/projectedView.py +++ b/gui/builtinAdditionPanes/projectedView.py @@ -128,14 +128,20 @@ class ProjectedView(d.Display): self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFitCommand( fitID=fitID, projectedFitID=thing.ID)) elif isinstance(thing, es_Module): - self.mainFrame.command.Submit(cmd.GuiRemoveProjectedModuleCommand( - fitID=fitID, position=Fit.getInstance().getFit(fitID).projectedModules.index(thing))) + fit = Fit.getInstance().getFit(fitID) + if thing in fit.projectedModules: + position = fit.projectedModules.index(thing) + self.mainFrame.command.Submit(cmd.GuiRemoveProjectedModuleCommand( + fitID=fitID, position=position)) elif isinstance(thing, es_Drone): self.mainFrame.command.Submit(cmd.GuiRemoveProjectedDroneCommand( fitID=fitID, itemID=thing.itemID, amount=math.inf)) elif isinstance(thing, es_Fighter): - self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFighterCommand( - fitID=fitID, position=Fit.getInstance().getFit(fitID).projectedFighters.index(thing))) + fit = Fit.getInstance().getFit(fitID) + if thing in fit.projectedFighters: + position = fit.projectedFighters.index(thing) + self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFighterCommand( + fitID=fitID, position=position)) def handleDrag(self, type, fitID): # Those are drags coming from pyfa sources, NOT builtin wx drags @@ -261,16 +267,20 @@ class ProjectedView(d.Display): self.mainFrame.command.Submit(cmd.GuiToggleProjectedFitStateCommand( fitID=fitID, projectedFitID=thing.ID)) elif isinstance(thing, es_Module): - self.mainFrame.command.Submit(cmd.GuiChangeProjectedModuleStateCommand( - fitID=fitID, - position=Fit.getInstance().getFit(fitID).projectedModules.index(thing), - click='right' if button == 3 else 'left')) + fit = Fit.getInstance().getFit(fitID) + if thing in fit.projectedModules: + position = fit.projectedModules.index(thing) + self.mainFrame.command.Submit(cmd.GuiChangeProjectedModuleStateCommand( + fitID=fitID, position=position, click='right' if button == 3 else 'left')) elif isinstance(thing, es_Drone) and button != 3: self.mainFrame.command.Submit(cmd.GuiToggleProjectedDroneStateCommand( fitID=fitID, itemID=thing.itemID)) elif isinstance(thing, es_Fighter) and button != 3: - self.mainFrame.command.Submit(cmd.GuiToggleProjectedFighterStateCommand( - fitID=fitID, position=Fit.getInstance().getFit(fitID).projectedFighters.index(thing))) + fit = Fit.getInstance().getFit(fitID) + if thing in fit.projectedFighters: + position = fit.projectedFighters.index(thing) + self.mainFrame.command.Submit(cmd.GuiToggleProjectedFighterStateCommand( + fitID=fitID, position=position)) def spawnMenu(self, event): fitID = self.mainFrame.getActiveFit() @@ -328,8 +338,11 @@ class ProjectedView(d.Display): self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFitCommand( fitID=fitID, projectedFitID=thing.ID)) elif isinstance(thing, es_Module): - self.mainFrame.command.Submit(cmd.GuiRemoveProjectedModuleCommand( - fitID=fitID, position=Fit.getInstance().getFit(fitID).projectedModules.index(thing))) + fit = Fit.getInstance().getFit(fitID) + if thing in fit.projectedModules: + position = fit.projectedModules.index(thing) + self.mainFrame.command.Submit(cmd.GuiRemoveProjectedModuleCommand( + fitID=fitID, position=position)) elif isinstance(thing, es_Drone): mstate = wx.GetMouseState() self.mainFrame.command.Submit(cmd.GuiRemoveProjectedDroneCommand( @@ -337,5 +350,8 @@ class ProjectedView(d.Display): itemID=thing.itemID, amount=math.inf if mstate.cmdDown or mstate.altDown else 1)) elif isinstance(thing, es_Fighter): - self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFighterCommand( - fitID=fitID, position=Fit.getInstance().getFit(fitID).projectedFighters.index(thing))) + fit = Fit.getInstance().getFit(fitID) + if thing in fit.projectedFighters: + position = fit.projectedFighters.index(thing) + self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFighterCommand( + fitID=fitID, position=position)) diff --git a/gui/builtinContextMenus/boosterSideEffects.py b/gui/builtinContextMenus/boosterSideEffects.py index 529a3d2f6..a17e16032 100644 --- a/gui/builtinContextMenus/boosterSideEffects.py +++ b/gui/builtinContextMenus/boosterSideEffects.py @@ -9,6 +9,7 @@ from service.settings import ContextMenuSettings class BoosterSideEffect(ContextMenu): + def __init__(self): self.mainFrame = gui.mainFrame.MainFrame.getInstance() self.settings = ContextMenuSettings.getInstance() @@ -58,14 +59,17 @@ class BoosterSideEffect(ContextMenu): def handleMode(self, event): effect = self.effectIds[event.Id] - if effect is False or effect not in self.booster.sideEffects: + booster = self.booster + if effect is False or effect not in booster.sideEffects: event.Skip() return fitID = self.mainFrame.getActiveFit() fit = Fit.getInstance().getFit(fitID) - index = fit.boosters.index(self.booster) - self.mainFrame.command.Submit(cmd.GuiToggleBoosterSideEffectStateCommand(fitID, index, effect.effectID)) + if booster in fit.boosters: + index = fit.boosters.index(booster) + self.mainFrame.command.Submit(cmd.GuiToggleBoosterSideEffectStateCommand( + fitID=fitID, position=index, effectID=effect.effectID)) BoosterSideEffect.register() diff --git a/gui/builtinContextMenus/cargoAdd.py b/gui/builtinContextMenus/cargoAdd.py index aa6589f62..d58c48c30 100644 --- a/gui/builtinContextMenus/cargoAdd.py +++ b/gui/builtinContextMenus/cargoAdd.py @@ -31,7 +31,8 @@ class AddToCargo(ContextMenu): typeID = int(selection[0].ID) - self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(fitID, typeID, 1)) + self.mainFrame.command.Submit(cmd.GuiAddCargoCommand( + fitID=fitID, itemID=typeID, amount=1)) self.mainFrame.additionsPane.select("Cargo") diff --git a/gui/builtinContextMenus/cargoAddAmmo.py b/gui/builtinContextMenus/cargoAddAmmo.py index 19534f907..a34bcb82c 100644 --- a/gui/builtinContextMenus/cargoAddAmmo.py +++ b/gui/builtinContextMenus/cargoAddAmmo.py @@ -25,7 +25,8 @@ class AddToCargoAmmo(ContextMenu): def activate(self, fullContext, selection, i): fitID = self.mainFrame.getActiveFit() typeID = int(selection[0].ID) - self.mainFrame.command.Submit(cmd.GuiAddCargoCommand(fitID, typeID, 1000)) + self.mainFrame.command.Submit(cmd.GuiAddCargoCommand( + fitID=fitID, itemID=typeID, amount=1000)) self.mainFrame.additionsPane.select("Cargo") diff --git a/gui/builtinContextMenus/commandFitAdd.py b/gui/builtinContextMenus/commandFitAdd.py index b33e8545f..32acec931 100644 --- a/gui/builtinContextMenus/commandFitAdd.py +++ b/gui/builtinContextMenus/commandFitAdd.py @@ -98,7 +98,7 @@ class AddCommandFit(ContextMenu): return fitID = self.mainFrame.getActiveFit() - self.mainFrame.command.Submit(cmd.GuiAddCommandFitCommand(fitID, fit.ID)) + self.mainFrame.command.Submit(cmd.GuiAddCommandFitCommand(fitID=fitID, commandFitID=fit.ID)) AddCommandFit.populateFits(None) diff --git a/gui/builtinContextMenus/droneAddStack.py b/gui/builtinContextMenus/droneAddStack.py index dcf1117d1..f9739b59e 100644 --- a/gui/builtinContextMenus/droneAddStack.py +++ b/gui/builtinContextMenus/droneAddStack.py @@ -20,7 +20,6 @@ class DroneAddStack(ContextMenu): return False item = selection[0] - print(item.category.name) if item.category.name != 'Drone': return False diff --git a/gui/builtinContextMenus/droneSplitStack.py b/gui/builtinContextMenus/droneSplitStack.py index 31eb9e276..22b1fa04b 100644 --- a/gui/builtinContextMenus/droneSplitStack.py +++ b/gui/builtinContextMenus/droneSplitStack.py @@ -22,7 +22,6 @@ class DroneSplitStack(ContextMenu): return "Split {0} Stack".format(itmContext) def activate(self, fullContext, selection, i): - srcContext = fullContext[0] drone = selection[0] dlg = DroneStackSplit(self.mainFrame, drone.amount) @@ -35,10 +34,10 @@ class DroneSplitStack(ContextMenu): fit = Fit.getInstance().getFit(fitID) cleanInput = re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip()) - self.mainFrame.command.Submit(cmd.GuiSplitLocalDroneStackCommand( - fitID=fitID, - position=fit.drones.index(drone), - amount=int(cleanInput))) + if drone in fit.drones: + position = fit.drones.index(drone) + self.mainFrame.command.Submit(cmd.GuiSplitLocalDroneStackCommand( + fitID=fitID, position=position, amount=int(cleanInput))) DroneSplitStack.register() diff --git a/gui/builtinContextMenus/fighterAbilities.py b/gui/builtinContextMenus/fighterAbilities.py index 73b4686c9..f58c55126 100644 --- a/gui/builtinContextMenus/fighterAbilities.py +++ b/gui/builtinContextMenus/fighterAbilities.py @@ -58,11 +58,15 @@ class FighterAbilities(ContextMenu): fitID = self.mainFrame.getActiveFit() fit = Fit.getInstance().getFit(fitID) if self.isProjected: - self.mainFrame.command.Submit(cmd.GuiToggleProjectedFighterAbilityStateCommand( - fitID=fitID, position=fit.projectedFighters.index(self.fighter), effectID=ability.effectID)) + if self.fighter in fit.projectedFighters: + position = fit.projectedFighters.index(self.fighter) + self.mainFrame.command.Submit(cmd.GuiToggleProjectedFighterAbilityStateCommand( + fitID=fitID, position=position, effectID=ability.effectID)) else: - self.mainFrame.command.Submit(cmd.GuiToggleLocalFighterAbilityStateCommand( - fitID=fitID, position=fit.fighters.index(self.fighter), effectID=ability.effectID)) + if self.fighter in fit.fighters: + position = fit.fighters.index(self.fighter) + self.mainFrame.command.Submit(cmd.GuiToggleLocalFighterAbilityStateCommand( + fitID=fitID, position=position, effectID=ability.effectID)) diff --git a/gui/builtinContextMenus/itemAmountChange.py b/gui/builtinContextMenus/itemAmountChange.py index aaf06fc10..89fbc8c38 100644 --- a/gui/builtinContextMenus/itemAmountChange.py +++ b/gui/builtinContextMenus/itemAmountChange.py @@ -31,7 +31,10 @@ class ChangeItemAmount(ContextMenu): fitID = mainFrame.getActiveFit() srcContext = fullContext[0] if isinstance(thing, es_Fit): - value = thing.getProjectionInfo(fitID).amount + try: + value = thing.getProjectionInfo(fitID).amount + except AttributeError: + return elif isinstance(thing, es_Fighter): value = thing.amountActive else: @@ -48,19 +51,31 @@ class ChangeItemAmount(ContextMenu): cleanInput = int(float(re.sub(r'[^0-9.]', '', dlg.input.GetLineText(0).strip()))) if isinstance(thing, es_Cargo): - self.mainFrame.command.Submit(cmd.GuiChangeCargoAmountCommand(fitID, thing.itemID, cleanInput)) + self.mainFrame.command.Submit(cmd.GuiChangeCargoAmountCommand( + fitID=fitID, itemID=thing.itemID, amount=cleanInput)) elif isinstance(thing, Drone): if srcContext == "projectedDrone": - self.mainFrame.command.Submit(cmd.GuiChangeProjectedDroneAmountCommand(fitID, thing.itemID, cleanInput)) + self.mainFrame.command.Submit(cmd.GuiChangeProjectedDroneAmountCommand( + fitID=fitID, itemID=thing.itemID, amount=cleanInput)) else: - self.mainFrame.command.Submit(cmd.GuiChangeLocalDroneAmountCommand(fitID, fit.drones.index(thing), cleanInput)) + if thing in fit.drones: + position = fit.drones.index(thing) + self.mainFrame.command.Submit(cmd.GuiChangeLocalDroneAmountCommand( + fitID=fitID, position=position, amount=cleanInput)) elif isinstance(thing, es_Fit): - self.mainFrame.command.Submit(cmd.GuiChangeProjectedFitAmountCommand(fitID, thing.ID, cleanInput)) + self.mainFrame.command.Submit(cmd.GuiChangeProjectedFitAmountCommand( + fitID=fitID, projectedFitID=thing.ID, amount=cleanInput)) elif isinstance(thing, es_Fighter): if srcContext == "projectedFighter": - self.mainFrame.command.Submit(cmd.GuiChangeProjectedFighterAmountCommand(fitID, fit.projectedFighters.index(thing), cleanInput)) + if thing in fit.projectedFighters: + position = fit.projectedFighters.index(thing) + self.mainFrame.command.Submit(cmd.GuiChangeProjectedFighterAmountCommand( + fitID=fitID, position=position, amount=cleanInput)) else: - self.mainFrame.command.Submit(cmd.GuiChangeLocalFighterAmountCommand(fitID, fit.fighters.index(thing), cleanInput)) + if thing in fit.fighters: + position = fit.fighters.index(thing) + self.mainFrame.command.Submit(cmd.GuiChangeLocalFighterAmountCommand( + fitID=fitID, position=position, amount=cleanInput)) ChangeItemAmount.register() diff --git a/gui/builtinContextMenus/itemRemove.py b/gui/builtinContextMenus/itemRemove.py index b70ce3679..6bf27414a 100644 --- a/gui/builtinContextMenus/itemRemove.py +++ b/gui/builtinContextMenus/itemRemove.py @@ -33,41 +33,64 @@ class RemoveItem(ContextMenu): fit = sFit.getFit(fitID) if srcContext == "fittingModule": + positions = [] + for position, mod in enumerate(fit.modules): + if mod in selection: + positions.append(position) self.mainFrame.command.Submit(cmd.GuiRemoveLocalModuleCommand( - fitID=fitID, modules=[module for module in selection if module is not None])) - elif srcContext == "fittingCharge": - self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleChargesCommand( - fitID=fitID, modules=selection, chargeItemID=None)) + fitID=fitID, positions=positions)) elif srcContext == "droneItem": - self.mainFrame.command.Submit(cmd.GuiRemoveLocalDroneCommand( - fitID=fitID, position=fit.drones.index(selection[0]), amount=math.inf)) + drone = selection[0] + if drone in fit.drones: + position = fit.drones.index(drone) + self.mainFrame.command.Submit(cmd.GuiRemoveLocalDroneCommand( + fitID=fitID, position=position, amount=math.inf)) elif srcContext == "fighterItem": - self.mainFrame.command.Submit(cmd.GuiRemoveLocalFighterCommand( - fitID=fitID, position=fit.fighters.index(selection[0]))) + fighter = selection[0] + if fighter in fit.fighters: + position = fit.fighters.index(fighter) + self.mainFrame.command.Submit(cmd.GuiRemoveLocalFighterCommand( + fitID=fitID, position=position)) elif srcContext == "implantItem": - self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand( - fitID=fitID, position=fit.implants.index(selection[0]))) + implant = selection[0] + if implant in fit.implants: + position = fit.implants.index(implant) + self.mainFrame.command.Submit(cmd.GuiRemoveImplantCommand( + fitID=fitID, position=position)) elif srcContext == "boosterItem": - self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand( - fitID=fitID, position=fit.boosters.index(selection[0]))) + booster = selection[0] + if booster in fit.boosters: + position = fit.boosters.index(booster) + self.mainFrame.command.Submit(cmd.GuiRemoveBoosterCommand( + fitID=fitID, position=position)) elif srcContext == "cargoItem": + cargo = selection[0] self.mainFrame.command.Submit(cmd.GuiRemoveCargoCommand( - fitID=fitID, itemID=selection[0].itemID)) + fitID=fitID, itemID=cargo.itemID)) elif srcContext == "projectedFit": + projectedFit = selection[0] self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFitCommand( - fitID=fitID, projectedFitID=selection[0].ID)) + fitID=fitID, projectedFitID=projectedFit.ID)) elif srcContext == "projectedModule": - self.mainFrame.command.Submit(cmd.GuiRemoveProjectedModuleCommand( - fitID=fitID, position=fit.projectedModules.index(selection[0]))) + mod = selection[0] + if mod in fit.projectedModules: + position = fit.projectedModules.index(mod) + self.mainFrame.command.Submit(cmd.GuiRemoveProjectedModuleCommand( + fitID=fitID, position=position)) elif srcContext == "projectedDrone": + drone = selection[0] self.mainFrame.command.Submit(cmd.GuiRemoveProjectedDroneCommand( - fitID=fitID, itemID=selection[0].itemID, amount=math.inf)) + fitID=fitID, itemID=drone.itemID, amount=math.inf)) elif srcContext == "projectedFighter": - self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFighterCommand( - fitID=fitID, position=fit.projectedFighters.index(selection[0]))) + fighter = selection[0] + if fighter in fit.projectedFighters: + position = fit.projectedFighters.index(fighter) + self.mainFrame.command.Submit(cmd.GuiRemoveProjectedFighterCommand( + fitID=fitID, position=position)) elif srcContext == "commandFit": + commandFit = selection[0] self.mainFrame.command.Submit(cmd.GuiRemoveCommandFitCommand( - fitID=fitID, commandFitID=selection[0].ID)) + fitID=fitID, commandFitID=commandFit.ID)) RemoveItem.register() diff --git a/gui/builtinContextMenus/itemVariationChange.py b/gui/builtinContextMenus/itemVariationChange.py index 992d070fb..94e2841a8 100644 --- a/gui/builtinContextMenus/itemVariationChange.py +++ b/gui/builtinContextMenus/itemVariationChange.py @@ -138,7 +138,10 @@ class ChangeItemToVariation(ContextMenu): fitID = self.mainFrame.getActiveFit() fit = Fit.getInstance().getFit(fitID) if context == 'fittingModule': - positions = [mod.modPosition for mod in self.selection] + positions = [] + for position, mod in enumerate(fit.modules): + if mod in self.selection: + positions.append(position) self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleMetasCommand( fitID=fitID, positions=positions, newItemID=item.ID)) elif context == 'droneItem': diff --git a/gui/builtinContextMenus/moduleAmmoChange.py b/gui/builtinContextMenus/moduleAmmoChange.py index f20040963..cd4c1bc1c 100644 --- a/gui/builtinContextMenus/moduleAmmoChange.py +++ b/gui/builtinContextMenus/moduleAmmoChange.py @@ -221,11 +221,11 @@ class ChangeModuleAmmo(ContextMenu): fitID = self.mainFrame.getActiveFit() sFit = Fit.getInstance() + fit = sFit.getFit(fitID) mstate = wx.GetMouseState() + # Switch in selection or all modules, depending on modifier key state and settings switchAll = sFit.serviceFittingOptions['ammoChangeAll'] is not (mstate.cmdDown or mstate.altDown) - # Switch in selection or all modules, depending on ctrl key state and settings if switchAll: - fit = sFit.getFit(fitID) if self.context == 'fittingModule': command = cmd.GuiChangeLocalModuleChargesCommand modContainer = fit.modules @@ -237,37 +237,43 @@ class ChangeModuleAmmo(ContextMenu): sMkt = Market.getInstance() selectedModule = self.modules[0] mainMktGroupID = getattr(sMkt.getMarketGroupByItem(selectedModule.item), 'ID', None) - mods = [] - for mod in modContainer: + positions = [] + for position, mod in enumerate(modContainer): # Always include selected module itself if mod is selectedModule: - mods.append(mod) + positions.append(position) continue if mod.itemID is None: continue # Modules which have the same item ID if mod.itemID == selectedModule.itemID: - mods.append(mod) + positions.append(position) continue # And modules from the same market group too modMktGroupID = getattr(sMkt.getMarketGroupByItem(mod.item), 'ID', None) if modMktGroupID is not None and modMktGroupID == mainMktGroupID: - mods.append(mod) + positions.append(position) continue self.mainFrame.command.Submit(command( fitID=fitID, - modules=mods, + positions=positions, chargeItemID=charge.ID if charge is not None else None)) else: if self.context == 'fittingModule': command = cmd.GuiChangeLocalModuleChargesCommand + modContainer = fit.modules elif self.context == 'projectedModule': command = cmd.GuiChangeProjectedModuleChargesCommand + modContainer = fit.projectedModules else: return + positions = [] + for position, mod in enumerate(modContainer): + if mod in self.modules: + positions.append(position) self.mainFrame.command.Submit(command( fitID=fitID, - modules=self.modules, + positions=positions, chargeItemID=charge.ID if charge is not None else None)) diff --git a/gui/builtinContextMenus/moduleFill.py b/gui/builtinContextMenus/moduleFill.py index 85aa5cde7..66dd43d5f 100644 --- a/gui/builtinContextMenus/moduleFill.py +++ b/gui/builtinContextMenus/moduleFill.py @@ -29,11 +29,11 @@ class FillWithModule(ContextMenu): if srcContext == "fittingModule": fit = Fit.getInstance().getFit(fitID) - self.mainFrame.command.Submit(cmd.GuiFillWithLocalModulesCommand( - fitID=fitID, - position=fit.modules.index(selection[0]))) - return # the command takes care of the PostEvent - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + mod = selection[0] + if mod in fit.modules: + position = fit.modules.index(mod) + self.mainFrame.command.Submit(cmd.GuiFillWithLocalModulesCommand( + fitID=fitID, position=position)) FillWithModule.register() diff --git a/gui/builtinContextMenus/moduleMutations.py b/gui/builtinContextMenus/moduleMutations.py index 25d9fe33e..d92e0edcd 100644 --- a/gui/builtinContextMenus/moduleMutations.py +++ b/gui/builtinContextMenus/moduleMutations.py @@ -5,6 +5,7 @@ import gui.mainFrame from gui.contextMenu import ContextMenu from gui.fitCommands import GuiConvertMutatedLocalModuleCommand, GuiRevertMutatedLocalModuleCommand from service.settings import ContextMenuSettings +from service.fit import Fit class ChangeModuleMutation(ContextMenu): @@ -55,17 +56,21 @@ class ChangeModuleMutation(ContextMenu): def handleMenu(self, event): mutaplasmid, mod = self.eventIDs[event.Id] - - self.mainFrame.command.Submit(GuiConvertMutatedLocalModuleCommand( - fitID=self.mainFrame.getActiveFit(), - position=mod.modPosition, - mutaplasmid=mutaplasmid)) + fitID = self.mainFrame.getActiveFit() + fit = Fit.getInstance().getFit(fitID) + if mod in fit.modules: + position = fit.modules.index(mod) + self.mainFrame.command.Submit(GuiConvertMutatedLocalModuleCommand( + fitID=fitID, position=position, mutaplasmid=mutaplasmid)) def activate(self, fullContext, selection, i): mod = selection[0] - self.mainFrame.command.Submit(GuiRevertMutatedLocalModuleCommand( - fitID=self.mainFrame.getActiveFit(), - position=mod.modPosition)) + fitID = self.mainFrame.getActiveFit() + fit = Fit.getInstance().getFit(fitID) + if mod in fit.modules: + position = fit.modules.index(mod) + self.mainFrame.command.Submit(GuiRevertMutatedLocalModuleCommand( + fitID=fitID, position=position)) def getBitmap(self, context, selection): return None diff --git a/gui/builtinContextMenus/moduleSpool.py b/gui/builtinContextMenus/moduleSpool.py index 9b1e71991..1f783f2ed 100644 --- a/gui/builtinContextMenus/moduleSpool.py +++ b/gui/builtinContextMenus/moduleSpool.py @@ -7,6 +7,7 @@ import gui.mainFrame from eos.utils.spoolSupport import SpoolType, SpoolOptions from gui.contextMenu import ContextMenu from service.settings import ContextMenuSettings +from service.fit import Fit class ChangeModuleSpool(ContextMenu): @@ -75,18 +76,18 @@ class ChangeModuleSpool(ContextMenu): spoolAmount = self.cycleMap[event.Id] else: return + fitID = self.mainFrame.getActiveFit() + fit = Fit.getInstance().getFit(fitID) if self.context == 'fittingModule': - self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleSpoolCommand( - fitID=self.mainFrame.getActiveFit(), - position=self.mod.modPosition, - spoolType=spoolType, - spoolAmount=spoolAmount)) + if self.mod in fit.modules: + position = fit.modules.index(self.mod) + self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleSpoolCommand( + fitID=fitID, position=position, spoolType=spoolType, spoolAmount=spoolAmount)) elif self.context == 'projectedModule': - self.mainFrame.command.Submit(cmd.GuiChangeProjectedModuleSpoolCommand( - fitID=self.mainFrame.getActiveFit(), - position=self.mod.modPosition, - spoolType=spoolType, - spoolAmount=spoolAmount)) + if self.mod in fit.projectedModules: + position = fit.projectedModules.index(self.mod) + self.mainFrame.command.Submit(cmd.GuiChangeProjectedModuleSpoolCommand( + fitID=fitID, position=position, spoolType=spoolType, spoolAmount=spoolAmount)) ChangeModuleSpool.register() diff --git a/gui/builtinShipBrowser/fitItem.py b/gui/builtinShipBrowser/fitItem.py index 8be39c269..77c4f36ea 100644 --- a/gui/builtinShipBrowser/fitItem.py +++ b/gui/builtinShipBrowser/fitItem.py @@ -185,13 +185,13 @@ class FitItem(SFItem.SFBrowserItem): if activeFit: sFit = Fit.getInstance() projectedFit = sFit.getFit(self.fitID) - if self.mainFrame.command.Submit(cmd.GuiAddProjectedCommand(activeFit, projectedFit.ID, 'fit')): + if self.mainFrame.command.Submit(cmd.GuiAddProjectedFitCommand(fitID=activeFit, projectedFitID=projectedFit.ID)): self.mainFrame.additionsPane.select("Projected") def OnAddCommandFit(self, event): activeFit = self.mainFrame.getActiveFit() if activeFit: - if self.mainFrame.command.Submit(cmd.GuiAddCommandFitCommand(activeFit, self.fitID)): + if self.mainFrame.command.Submit(cmd.GuiAddCommandFitCommand(fitID=activeFit, commandFitID=self.fitID)): self.mainFrame.additionsPane.select("Command") def OnMouseCaptureLost(self, event): diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index f4e923c53..54fbb8244 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -374,7 +374,7 @@ class FittingView(d.Display): if len(modules) > 0: self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleChargesCommand(fitID, modules, itemID)) else: - self.mainFrame.command.Submit(cmd.GuiAddLocalModuleCommand(fitID, itemID)) + self.mainFrame.command.Submit(cmd.GuiAddLocalModuleCommand(fitID=fitID, itemID=itemID)) event.Skip() @@ -396,7 +396,14 @@ class FittingView(d.Display): if not isinstance(modules, list): modules = [modules] - self.mainFrame.command.Submit(cmd.GuiRemoveLocalModuleCommand(self.activeFitID, modules)) + fit = Fit.getInstance().getFit(self.activeFitID) + positions = [] + for position, mod in enumerate(fit.modules): + if mod in modules: + positions.append(position) + + self.mainFrame.command.Submit(cmd.GuiRemoveLocalModuleCommand( + fitID=self.activeFitID, positions=positions)) def addModule(self, x, y, itemID): """Add a module from the market browser (from dragging it)""" @@ -408,7 +415,8 @@ class FittingView(d.Display): if not isinstance(mod, Module): # make sure we're not adding something to a T3D Mode return - self.mainFrame.command.Submit(cmd.GuiAddLocalModuleCommand(fitID, itemID, self.mods[dstRow].modPosition)) + self.mainFrame.command.Submit(cmd.GuiAddLocalModuleCommand( + fitID=fitID, itemID=itemID, position=self.mods[dstRow].modPosition)) def swapCargo(self, x, y, cargoItemID): """Swap a module from cargo to fitting window""" @@ -420,11 +428,12 @@ class FittingView(d.Display): if not isinstance(mod, Module): return - self.mainFrame.command.Submit(cmd.GuiCargoToLocalModuleCommand( - fitID=self.mainFrame.getActiveFit(), - cargoItemID=cargoItemID, - modPosition=mod.modPosition, - copy=wx.GetMouseState().cmdDown)) + fitID = self.mainFrame.getActiveFit() + fit = Fit.getInstance().getFit(fitID) + if mod in fit.modules: + position = fit.modules.index(mod) + self.mainFrame.command.Submit(cmd.GuiCargoToLocalModuleCommand( + fitID=fitID, cargoItemID=cargoItemID, modPosition=position, copy=wx.GetMouseState().cmdDown)) def swapItems(self, x, y, srcIdx): """Swap two modules in fitting window""" @@ -434,27 +443,27 @@ class FittingView(d.Display): dstRow, _ = self.HitTest((x, y)) if dstRow != -1 and dstRow not in self.blanks: - mod1 = fit.modules[srcIdx] - mod2 = self.mods[dstRow] - + try: + mod1 = fit.modules[srcIdx] + mod2 = self.mods[dstRow] + except IndexError: + return if not isinstance(mod2, Module): return - # can't swap modules to different racks if mod1.slot != mod2.slot: return - - fitID = self.mainFrame.getActiveFit() - if getattr(mod2, "modPosition") is not None: - mstate = wx.GetMouseState() - if mstate.cmdDown and mod2.isEmpty: - self.mainFrame.command.Submit(cmd.GuiCloneLocalModuleCommand( - fitID=fitID, srcPosition=srcIdx, dstPosition=mod2.modPosition)) - elif not mstate.cmdDown: - self.mainFrame.command.Submit(cmd.GuiSwapLocalModulesCommand( - fitID=fitID, position1=srcIdx, position2=mod2.modPosition)) - else: + if mod2 not in fit.modules: pyfalog.error("Missing module position for: {0}", str(getattr(mod2, "ID", "Unknown"))) + return + mod2Position = fit.modules.index(mod2) + mstate = wx.GetMouseState() + if mstate.cmdDown and mod2.isEmpty: + self.mainFrame.command.Submit(cmd.GuiCloneLocalModuleCommand( + fitID=self.activeFitID, srcPosition=srcIdx, dstPosition=mod2Position)) + elif not mstate.cmdDown: + self.mainFrame.command.Submit(cmd.GuiSwapLocalModulesCommand( + fitID=self.activeFitID, position1=srcIdx, position2=mod2Position)) def generateMods(self): """ @@ -546,35 +555,32 @@ class FittingView(d.Display): sel = self.GetFirstSelected() contexts = [] - while sel != -1 and sel not in self.blanks: - mod = self.mods[self.GetItemData(sel)] + while sel != -1: - # Test if this is a mode, which is a special snowflake of a Module - if isinstance(mod, Mode): - srcContext = "fittingMode" - - itemContext = "Tactical Mode" - fullContext = (srcContext, itemContext) - if srcContext not in tuple(fCtxt[0] for fCtxt in contexts): - contexts.append(fullContext) - - selection.append(mod) - - elif not mod.isEmpty: - srcContext = "fittingModule" - itemContext = sMkt.getCategoryByItem(mod.item).name - fullContext = (srcContext, itemContext) - if srcContext not in tuple(fCtxt[0] for fCtxt in contexts): - contexts.append(fullContext) - - if mod.charge is not None: - srcContext = "fittingCharge" - itemContext = sMkt.getCategoryByItem(mod.charge).name + if sel not in self.blanks: + mod = self.mods[self.GetItemData(sel)] + # Test if this is a mode, which is a special snowflake of a Module + if isinstance(mod, Mode): + srcContext = "fittingMode" + itemContext = "Tactical Mode" + fullContext = (srcContext, itemContext) + if srcContext not in tuple(fCtxt[0] for fCtxt in contexts): + contexts.append(fullContext) + selection.append(mod) + elif not mod.isEmpty: + srcContext = "fittingModule" + itemContext = sMkt.getCategoryByItem(mod.item).name fullContext = (srcContext, itemContext) if srcContext not in tuple(fCtxt[0] for fCtxt in contexts): contexts.append(fullContext) - selection.append(mod) + if mod.charge is not None: + srcContext = "fittingCharge" + itemContext = sMkt.getCategoryByItem(mod.charge).name + fullContext = (srcContext, itemContext) + if srcContext not in tuple(fCtxt[0] for fCtxt in contexts): + contexts.append(fullContext) + selection.append(mod) sel = self.GetNextSelected(sel) @@ -607,18 +613,35 @@ class FittingView(d.Display): curr = self.GetNextSelected(curr) if row not in sel: - mods = [self.mods[self.GetItemData(row)]] + try: + mods = [self.mods[self.GetItemData(row)]] + except IndexError: + return else: mods = self.getSelectedMods() - fitID = self.mainFrame.getActiveFit() ctrl = event.cmdDown or event.altDown or event.middleIsDown click = "ctrl" if ctrl is True else "right" if event.GetButton() == 3 else "left" + try: + mainMod = self.mods[self.GetItemData(row)] + except IndexError: + return + + mainPosition = None + positions = [] + fitID = self.mainFrame.getActiveFit() + for position, mod in enumerate(Fit.getInstance().getFit(fitID).modules): + if mod in mods: + positions.append(position) + if mod is mainMod: + mainPosition = position + if mainPosition is None: + return self.mainFrame.command.Submit(cmd.GuiChangeLocalModuleStatesCommand( fitID=fitID, - mainPosition=self.mods[self.GetItemData(row)].modPosition, - positions=[mod.modPosition for mod in mods], + mainPosition=mainPosition, + positions=positions, click=click)) # update state tooltip diff --git a/gui/fitCommands/calc/commandFit/add.py b/gui/fitCommands/calc/commandFit/add.py index 70d9e29aa..a90effaed 100644 --- a/gui/fitCommands/calc/commandFit/add.py +++ b/gui/fitCommands/calc/commandFit/add.py @@ -30,7 +30,9 @@ class CalcAddCommandCommand(wx.Command): if commandFit in fit.commandFits: pyfalog.debug('Command fit had been applied already') return False - + if commandFit.ID in fit.commandFitDict: + pyfalog.debug('Commanding fit is in command dict already') + return False fit.commandFitDict[commandFit.ID] = commandFit # This bit is required, see issue #83 eos.db.saveddata_session.flush() diff --git a/gui/fitCommands/calc/commandFit/remove.py b/gui/fitCommands/calc/commandFit/remove.py index b3500a380..bace3963f 100644 --- a/gui/fitCommands/calc/commandFit/remove.py +++ b/gui/fitCommands/calc/commandFit/remove.py @@ -30,8 +30,10 @@ class CalcRemoveCommandCommand(wx.Command): if commandInfo is None: pyfalog.warning('Fit command info is not available') return False - self.savedState = commandInfo.active + if commandFit.ID not in fit.commandFitDict: + pyfalog.warning('Unable to find commanding fit in command dict') + return False del fit.commandFitDict[commandFit.ID] eos.db.commit() return True diff --git a/gui/fitCommands/calc/module/localAdd.py b/gui/fitCommands/calc/module/localAdd.py index ef21348c7..48ff33b32 100644 --- a/gui/fitCommands/calc/module/localAdd.py +++ b/gui/fitCommands/calc/module/localAdd.py @@ -54,6 +54,9 @@ class CalcAddLocalModuleCommand(wx.Command): eos.db.commit() return False self.savedPosition = fit.modules.index(newMod) + # Need to flush because checkStates sometimes relies on module->fit + # relationship via .owner attribute, which is handled by SQLAlchemy + eos.db.flush() sFit.recalc(fit) self.savedStateCheckChanges = sFit.checkStates(fit, newMod) if self.commit: @@ -67,8 +70,8 @@ class CalcAddLocalModuleCommand(wx.Command): return self.subsystemCmd.Undo() if self.savedPosition is None: return False - from .localRemove import CalcRemoveLocalModuleCommand - cmd = CalcRemoveLocalModuleCommand(fitID=self.fitID, positions=[self.savedPosition], commit=self.commit) + from .localRemove import CalcRemoveLocalModulesCommand + cmd = CalcRemoveLocalModulesCommand(fitID=self.fitID, positions=[self.savedPosition], commit=self.commit) if not cmd.Do(): return False restoreCheckedStates(Fit.getInstance().getFit(self.fitID), self.savedStateCheckChanges) diff --git a/gui/fitCommands/calc/module/localChangeStates.py b/gui/fitCommands/calc/module/localChangeStates.py index 2cf643f42..0f7161632 100644 --- a/gui/fitCommands/calc/module/localChangeStates.py +++ b/gui/fitCommands/calc/module/localChangeStates.py @@ -46,6 +46,9 @@ class CalcChangeLocalModuleStatesCommand(wx.Command): mod.state = proposedState if not changed: return False + # Need to flush because checkStates sometimes relies on module->fit + # relationship via .owner attribute, which is handled by SQLAlchemy + eos.db.flush() sFit.recalc(fit) self.savedStateCheckChanges = sFit.checkStates(fit, mainMod) eos.db.commit() diff --git a/gui/fitCommands/calc/module/localClone.py b/gui/fitCommands/calc/module/localClone.py index d94180666..503a1df41 100644 --- a/gui/fitCommands/calc/module/localClone.py +++ b/gui/fitCommands/calc/module/localClone.py @@ -37,6 +37,9 @@ class CalcCloneLocalModuleCommand(wx.Command): pyfalog.warning('Failed to replace module') eos.db.commit() return False + # Need to flush because checkStates sometimes relies on module->fit + # relationship via .owner attribute, which is handled by SQLAlchemy + eos.db.flush() sFit.recalc(fit) self.savedStateCheckChanges = sFit.checkStates(fit, copyMod) eos.db.commit() @@ -44,8 +47,8 @@ class CalcCloneLocalModuleCommand(wx.Command): def Undo(self): pyfalog.debug('Undoing cloning of local module from position {} to position {} for fit ID {}'.format(self.srcPosition, self.dstPosition, self.fitID)) - from .localRemove import CalcRemoveLocalModuleCommand - cmd = CalcRemoveLocalModuleCommand(fitID=self.fitID, positions=[self.dstPosition]) + from .localRemove import CalcRemoveLocalModulesCommand + cmd = CalcRemoveLocalModulesCommand(fitID=self.fitID, positions=[self.dstPosition]) if not cmd.Do(): return False restoreCheckedStates(Fit.getInstance().getFit(self.fitID), self.savedStateCheckChanges) diff --git a/gui/fitCommands/calc/module/localRemove.py b/gui/fitCommands/calc/module/localRemove.py index 43439bda8..5773c3eaf 100644 --- a/gui/fitCommands/calc/module/localRemove.py +++ b/gui/fitCommands/calc/module/localRemove.py @@ -9,7 +9,7 @@ from service.fit import Fit pyfalog = Logger(__name__) -class CalcRemoveLocalModuleCommand(wx.Command): +class CalcRemoveLocalModulesCommand(wx.Command): def __init__(self, fitID, positions, commit=True): wx.Command.__init__(self, True, 'Remove Module') @@ -30,6 +30,9 @@ class CalcRemoveLocalModuleCommand(wx.Command): self.savedModInfos[position] = ModuleInfo.fromModule(mod) fit.modules.free(position) + # Need to flush because checkStates sometimes relies on module->fit + # relationship via .owner attribute, which is handled by SQLAlchemy + eos.db.flush() sFit.recalc(fit) self.savedStateCheckChanges = sFit.checkStates(fit, None) if self.commit: diff --git a/gui/fitCommands/calc/module/localReplace.py b/gui/fitCommands/calc/module/localReplace.py index 464fa85bc..067a92294 100644 --- a/gui/fitCommands/calc/module/localReplace.py +++ b/gui/fitCommands/calc/module/localReplace.py @@ -24,7 +24,7 @@ class CalcReplaceLocalModuleCommand(wx.Command): self.unloadedCharge = None def Do(self): - pyfalog.debug('Doing replacement of local module at position {} to {} on fit {}'.format(self.newModInfo, self.position, self.fitID)) + pyfalog.debug('Doing replacement of local module at position {} to {} on fit {}'.format(self.position, self.newModInfo, self.fitID)) self.unloadedCharge = False sFit = Fit.getInstance() fit = sFit.getFit(self.fitID) @@ -56,6 +56,9 @@ class CalcReplaceLocalModuleCommand(wx.Command): pyfalog.warning('Failed to replace in list') self.Undo() return False + # Need to flush because checkStates sometimes relies on module->fit + # relationship via .owner attribute, which is handled by SQLAlchemy + eos.db.flush() sFit.recalc(fit) self.savedStateCheckChanges = sFit.checkStates(fit, newMod) if self.commit: @@ -63,13 +66,13 @@ class CalcReplaceLocalModuleCommand(wx.Command): return True def Undo(self): - pyfalog.debug('Undoing replacement of local module at position {} to {} on fit {}'.format(self.newModInfo, self.position, self.fitID)) + pyfalog.debug('Undoing replacement of local module at position {} to {} on fit {}'.format(self.position, self.newModInfo, self.fitID)) sFit = Fit.getInstance() fit = sFit.getFit(self.fitID) # Remove if there was no module if self.oldModInfo is None: - from .localRemove import CalcRemoveLocalModuleCommand - cmd = CalcRemoveLocalModuleCommand(fitID=self.fitID, positions=[self.position], commit=self.commit) + from .localRemove import CalcRemoveLocalModulesCommand + cmd = CalcRemoveLocalModulesCommand(fitID=self.fitID, positions=[self.position], commit=self.commit) if not cmd.Do(): return False sFit.recalc(fit) diff --git a/gui/fitCommands/calc/projectedFit/add.py b/gui/fitCommands/calc/projectedFit/add.py index 6d7375cc7..90b3bf083 100644 --- a/gui/fitCommands/calc/projectedFit/add.py +++ b/gui/fitCommands/calc/projectedFit/add.py @@ -10,10 +10,11 @@ pyfalog = Logger(__name__) class CalcAddProjectedFitCommand(wx.Command): - def __init__(self, fitID, projectedFitID, state=None): + def __init__(self, fitID, projectedFitID, amount=None, state=None): wx.Command.__init__(self, True, 'Add Projected Fit') self.fitID = fitID self.projectedFitID = projectedFitID + self.amount = amount self.state = state def Do(self): @@ -31,18 +32,24 @@ class CalcAddProjectedFitCommand(wx.Command): pyfalog.debug('Projected fit had been applied already') return False + if projectedFit.ID in fit.projectedFitDict: + pyfalog.debug('Projected fit is in projected dict already') + return False fit.projectedFitDict[projectedFit.ID] = projectedFit # This bit is required, see issue #83 eos.db.saveddata_session.flush() eos.db.saveddata_session.refresh(projectedFit) - if self.state is not None: + if self.amount is not None or self.state is not None: projectionInfo = projectedFit.getProjectionInfo(self.fitID) if projectionInfo is None: pyfalog.warning('Fit projection info is not available') self.Undo() return False - projectionInfo.active = self.state + if self.amount is not None: + projectionInfo.amount = self.amount + if self.state is not None: + projectionInfo.active = self.state eos.db.commit() return True diff --git a/gui/fitCommands/calc/projectedFit/remove.py b/gui/fitCommands/calc/projectedFit/remove.py index 71405dd7a..3a342fa07 100644 --- a/gui/fitCommands/calc/projectedFit/remove.py +++ b/gui/fitCommands/calc/projectedFit/remove.py @@ -15,6 +15,7 @@ class CalcRemoveProjectedFitCommand(wx.Command): self.fitID = fitID self.projectedFitID = projectedFitID self.savedState = None + self.savedAmount = None def Do(self): pyfalog.debug('Doing removal of projected fit {} for fit {}'.format(self.projectedFitID, self.fitID)) @@ -32,6 +33,10 @@ class CalcRemoveProjectedFitCommand(wx.Command): return False self.savedState = projectionInfo.active + self.savedAmount = projectionInfo.amount + if projectedFit.ID not in fit.projectedFitDict: + pyfalog.warning('Unable to find projected fit in projected dict') + return False del fit.projectedFitDict[projectedFit.ID] eos.db.commit() return True @@ -39,5 +44,9 @@ class CalcRemoveProjectedFitCommand(wx.Command): def Undo(self): pyfalog.debug('Undoing removal of projected fit {} for fit {}'.format(self.projectedFitID, self.fitID)) from .add import CalcAddProjectedFitCommand - cmd = CalcAddProjectedFitCommand(fitID=self.fitID, projectedFitID=self.projectedFitID, state=self.savedState) + cmd = CalcAddProjectedFitCommand( + fitID=self.fitID, + projectedFitID=self.projectedFitID, + amount=self.savedAmount, + state=self.savedState) return cmd.Do() diff --git a/gui/fitCommands/gui/booster/remove.py b/gui/fitCommands/gui/booster/remove.py index 5d0b28e21..7868addf8 100644 --- a/gui/fitCommands/gui/booster/remove.py +++ b/gui/fitCommands/gui/booster/remove.py @@ -8,6 +8,7 @@ from service.fit import Fit class GuiRemoveBoosterCommand(wx.Command): + def __init__(self, fitID, position): wx.Command.__init__(self, True, 'Remove Booster') self.internalHistory = InternalCommandHistory() diff --git a/gui/fitCommands/gui/booster/toggleState.py b/gui/fitCommands/gui/booster/toggleState.py index 99fe35420..f47dc419b 100644 --- a/gui/fitCommands/gui/booster/toggleState.py +++ b/gui/fitCommands/gui/booster/toggleState.py @@ -8,6 +8,7 @@ from service.fit import Fit class GuiToggleBoosterStateCommand(wx.Command): + def __init__(self, fitID, position): wx.Command.__init__(self, True, 'Toggle Booster State') self.internalHistory = InternalCommandHistory() diff --git a/gui/fitCommands/gui/cargo/remove.py b/gui/fitCommands/gui/cargo/remove.py index 8db09bcb9..6eede4d59 100644 --- a/gui/fitCommands/gui/cargo/remove.py +++ b/gui/fitCommands/gui/cargo/remove.py @@ -17,7 +17,7 @@ class GuiRemoveCargoCommand(wx.Command): self.itemID = itemID def Do(self): - cmd =CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.itemID, amount=math.inf)) + cmd = CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.itemID, amount=math.inf)) success = self.internalHistory.submit(cmd) wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID)) return success diff --git a/gui/fitCommands/gui/localModule/changeCharges.py b/gui/fitCommands/gui/localModule/changeCharges.py index d856e5c1a..fb60ef55f 100644 --- a/gui/fitCommands/gui/localModule/changeCharges.py +++ b/gui/fitCommands/gui/localModule/changeCharges.py @@ -9,11 +9,11 @@ from service.fit import Fit class GuiChangeLocalModuleChargesCommand(wx.Command): - def __init__(self, fitID, modules, chargeItemID): + def __init__(self, fitID, positions, chargeItemID): wx.Command.__init__(self, True, 'Change Local Module Charges') self.internalHistory = InternalCommandHistory() self.fitID = fitID - self.positions = [mod.modPosition for mod in modules] + self.positions = positions self.chargeItemID = chargeItemID def Do(self): diff --git a/gui/fitCommands/gui/localModule/remove.py b/gui/fitCommands/gui/localModule/remove.py index cfc307ba4..58e9ce973 100644 --- a/gui/fitCommands/gui/localModule/remove.py +++ b/gui/fitCommands/gui/localModule/remove.py @@ -2,26 +2,32 @@ import wx import gui.mainFrame from gui import globalEvents as GE -from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModuleCommand +from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModulesCommand from gui.fitCommands.helpers import InternalCommandHistory, ModuleInfo from service.fit import Fit class GuiRemoveLocalModuleCommand(wx.Command): - def __init__(self, fitID, modules): + def __init__(self, fitID, positions): wx.Command.__init__(self, True, 'Remove Local Module') self.internalHistory = InternalCommandHistory() self.fitID = fitID - self.modCache = {mod.modPosition: ModuleInfo.fromModule(mod) for mod in modules if not mod.isEmpty} + self.positions = positions + self.savedTypeIDs = None def Do(self): - cmd = CalcRemoveLocalModuleCommand(fitID=self.fitID, positions=[pos for pos in self.modCache]) + sFit = Fit.getInstance() + fit = sFit.getFit(self.fitID) + self.savedTypeIDs = {m.itemID for m in fit.modules if not m.isEmpty} + cmd = CalcRemoveLocalModulesCommand(fitID=self.fitID, positions=self.positions) success = self.internalHistory.submit(cmd) - Fit.getInstance().recalc(self.fitID) + sFit.recalc(self.fitID) wx.PostEvent( gui.mainFrame.MainFrame.getInstance(), - GE.FitChanged(fitID=self.fitID, action='moddel', typeID={mod.itemID for mod in self.modCache.values()}) if success else GE.FitChanged(fitID=self.fitID)) + GE.FitChanged(fitID=self.fitID, action='moddel', typeID=self.savedTypeIDs) + if success and self.savedTypeIDs else + GE.FitChanged(fitID=self.fitID)) return success def Undo(self): @@ -29,5 +35,7 @@ class GuiRemoveLocalModuleCommand(wx.Command): Fit.getInstance().recalc(self.fitID) wx.PostEvent( gui.mainFrame.MainFrame.getInstance(), - GE.FitChanged(fitID=self.fitID, action='modadd', typeID={mod.itemID for mod in self.modCache.values()}) if success else GE.FitChanged(fitID=self.fitID)) + GE.FitChanged(fitID=self.fitID, action='modadd', typeID=self.savedTypeIDs) + if success and self.savedTypeIDs else + GE.FitChanged(fitID=self.fitID)) return success diff --git a/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py b/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py index a0f0cb153..624c07a6b 100644 --- a/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py +++ b/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py @@ -5,7 +5,7 @@ import gui.mainFrame from gui import globalEvents as GE from gui.fitCommands.calc.cargo.add import CalcAddCargoCommand from gui.fitCommands.calc.cargo.remove import CalcRemoveCargoCommand -from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModuleCommand +from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModulesCommand from gui.fitCommands.calc.module.localReplace import CalcReplaceLocalModuleCommand from gui.fitCommands.helpers import CargoInfo, InternalCommandHistory, ModuleInfo from service.fit import Fit @@ -110,7 +110,7 @@ class GuiLocalModuleToCargoCommand(wx.Command): cargoInfo=CargoInfo(itemID=srcMod.chargeID, amount=srcMod.numCharges), commit=False)) if not self.copy: - commands.append(CalcRemoveLocalModuleCommand( + commands.append(CalcRemoveLocalModulesCommand( fitID=self.fitID, positions=[self.srcModPosition], commit=False)) diff --git a/gui/fitCommands/gui/projectedModule/changeCharges.py b/gui/fitCommands/gui/projectedModule/changeCharges.py index 88983c8d9..754df15d3 100644 --- a/gui/fitCommands/gui/projectedModule/changeCharges.py +++ b/gui/fitCommands/gui/projectedModule/changeCharges.py @@ -9,11 +9,11 @@ from service.fit import Fit class GuiChangeProjectedModuleChargesCommand(wx.Command): - def __init__(self, fitID, modules, chargeItemID): + def __init__(self, fitID, positions, chargeItemID): wx.Command.__init__(self, True, 'Change Projected Module Charges') self.internalHistory = InternalCommandHistory() self.fitID = fitID - self.positions = [mod.modPosition for mod in modules] + self.positions = positions self.chargeItemID = chargeItemID def Do(self): diff --git a/service/fit.py b/service/fit.py index 8d8b3ffbf..7ce5bf351 100644 --- a/service/fit.py +++ b/service/fit.py @@ -437,7 +437,7 @@ class Fit(FitDeprecated): changedProjMods = {} changedProjDrones = {} for pos, mod in enumerate(fit.modules): - if mod != base: + if mod is not base: # fix for #529, where a module may be in incorrect state after CCP changes mechanics of module if not mod.canHaveState(mod.state) or not mod.isValidState(mod.state): changedMods[pos] = mod.state diff --git a/service/port/efs.py b/service/port/efs.py index 3aa22d35b..84c0db833 100755 --- a/service/port/efs.py +++ b/service/port/efs.py @@ -17,7 +17,7 @@ from eos.db import gamedata_session, getCategory, getAttributeInfo, getGroup from eos.gamedata import Attribute, Effect, Group, Item, ItemEffect from eos.utils.spoolSupport import SpoolType, SpoolOptions from gui.fitCommands.calc.module.localAdd import CalcAddLocalModuleCommand -from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModuleCommand +from gui.fitCommands.calc.module.localRemove import CalcRemoveLocalModulesCommand from gui.fitCommands.helpers import ModuleInfo @@ -71,7 +71,7 @@ class EfsPort: fit = eos.db.getFit(fitID) mwdPropSpeed = fit.maxSpeed mwdPosition = list(filter(lambda mod: mod.item and mod.item.ID == propID, fit.modules))[0].position - CalcRemoveLocalModuleCommand(fitID, [mwdPosition]).Do() + CalcRemoveLocalModulesCommand(fitID, [mwdPosition]).Do() sFit.recalc(fit) fit = eos.db.getFit(fitID) return mwdPropSpeed