From 64bba0cfdbc5e115e776c0d7ea7033843affae7e Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Tue, 16 Apr 2019 01:41:19 +0300 Subject: [PATCH] Rework cargo to module command --- eos/saveddata/module.py | 6 + gui/builtinAdditionPanes/cargoView.py | 7 +- gui/builtinViews/fittingView.py | 20 +-- gui/fitCommands/__init__.py | 4 +- gui/fitCommands/calc/cargo/add.py | 11 +- gui/fitCommands/calc/cargo/remove.py | 12 +- gui/fitCommands/calc/module/changeCharges.py | 16 ++- gui/fitCommands/calc/module/localReplace.py | 2 +- gui/fitCommands/gui/guiCargoToModule.py | 80 ------------ .../gui/localModuleCargo/__init__.py | 0 .../localModuleCargo/cargoToLocalModule.py | 119 ++++++++++++++++++ .../localModuleToCargo.py} | 5 +- gui/fitCommands/helpers.py | 8 +- 13 files changed, 174 insertions(+), 116 deletions(-) delete mode 100644 gui/fitCommands/gui/guiCargoToModule.py create mode 100644 gui/fitCommands/gui/localModuleCargo/__init__.py create mode 100644 gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py rename gui/fitCommands/gui/{guiModuleToCargo.py => localModuleCargo/localModuleToCargo.py} (98%) diff --git a/eos/saveddata/module.py b/eos/saveddata/module.py index 28ee586ec..a659c5a5f 100644 --- a/eos/saveddata/module.py +++ b/eos/saveddata/module.py @@ -593,6 +593,12 @@ class Module(HandledItem, HandledCharge, ItemAttrShortcut, ChargeAttrShortcut): else: return True + def getMaxState(self, proposedState=None): + states = sorted((s for s in FittingModuleState if proposedState is None or s <= proposedState), reverse=True) + for state in states: + if self.isValidState(state): + return state + def canHaveState(self, state=None, projectedOnto=None): """ Check with other modules if there are restrictions that might not allow this module to be activated diff --git a/gui/builtinAdditionPanes/cargoView.py b/gui/builtinAdditionPanes/cargoView.py index f2a3c9903..75a27c699 100644 --- a/gui/builtinAdditionPanes/cargoView.py +++ b/gui/builtinAdditionPanes/cargoView.py @@ -87,7 +87,7 @@ class CargoView(d.Display): if row != -1: data = wx.TextDataObject() - dataStr = "cargo:" + str(row) + dataStr = "cargo:{}".format(self.cargo[row].itemID) data.SetText(dataStr) dropSource = wx.DropSource(self) @@ -126,7 +126,7 @@ class CargoView(d.Display): cargoPos = dstRow if dstRow > -1 else None - self.mainFrame.command.Submit(cmd.GuiModuleToCargoCommand( + self.mainFrame.command.Submit(cmd.GuiLocalModuleToCargoCommand( self.mainFrame.getActiveFit(), module.modPosition, cargoPos, @@ -177,10 +177,7 @@ class CargoView(d.Display): def spawnMenu(self, event): sel = self.GetFirstSelected() if sel != -1: - sFit = Fit.getInstance() - fit = sFit.getFit(self.mainFrame.getActiveFit()) cargo = self.cargo[sel] - sMkt = Market.getInstance() sourceContext = "cargoItem" itemContext = sMkt.getCategoryByItem(cargo.item).name diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index 882065ede..8be470456 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -357,11 +357,11 @@ class FittingView(d.Display): itemID = event.itemID fitID = self.activeFitID if fitID is not None: - item = Market.getInstance().getItem(event.itemID, eager='group.category') + item = Market.getInstance().getItem(itemID, eager='group.category') if item is None or not (item.isModule or item.isSubsystem): event.Skip() return - if Fit.getInstance().isAmmo(itemID): + if item.isCharge: # If we've selected ammo, then apply to the selected module(s) modules = [] sel = self.GetFirstSelected() @@ -410,22 +410,22 @@ class FittingView(d.Display): self.mainFrame.command.Submit(cmd.GuiAddLocalModuleCommand(fitID, itemID, self.mods[dstRow].modPosition)) - def swapCargo(self, x, y, srcIdx): + def swapCargo(self, x, y, cargoItemID): """Swap a module from cargo to fitting window""" mstate = wx.GetMouseState() dstRow, _ = self.HitTest((x, y)) if dstRow != -1 and dstRow not in self.blanks: - module = self.mods[dstRow] + mod = self.mods[dstRow] - if not isinstance(module, Module): + if not isinstance(mod, Module): return - self.mainFrame.command.Submit(cmd.GuiCargoToModuleCommand( - self.mainFrame.getActiveFit(), - module.modPosition, - srcIdx, - mstate.CmdDown() and module.isEmpty)) + self.mainFrame.command.Submit(cmd.GuiCargoToLocalModuleCommand( + fitID=self.mainFrame.getActiveFit(), + cargoItemID=cargoItemID, + modPosition=mod.modPosition, + copy=mstate.CmdDown())) def swapItems(self, x, y, srcIdx): """Swap two modules in fitting window""" diff --git a/gui/fitCommands/__init__.py b/gui/fitCommands/__init__.py index 4ff2aaf2d..ad7d92a12 100644 --- a/gui/fitCommands/__init__.py +++ b/gui/fitCommands/__init__.py @@ -11,8 +11,6 @@ from .gui.commandFit.add import GuiAddCommandFitCommand from .gui.commandFit.remove import GuiRemoveCommandFitCommand from .gui.commandFit.toggleState import GuiToggleCommandFitStateCommand from .gui.fitRename import GuiRenameFitCommand -from .gui.guiCargoToModule import GuiCargoToModuleCommand -from .gui.guiModuleToCargo import GuiModuleToCargoCommand from .gui.implant.add import GuiAddImplantCommand from .gui.implant.changeLocation import GuiChangeImplantLocationCommand from .gui.implant.changeMeta import GuiChangeImplantMetaCommand @@ -43,6 +41,8 @@ from .gui.localModule.mutatedImport import GuiImportLocalMutatedModuleCommand from .gui.localModule.mutatedRevert import GuiRevertMutatedLocalModuleCommand from .gui.localModule.remove import GuiRemoveLocalModuleCommand from .gui.localModule.swap import GuiSwapLocalModulesCommand +from .gui.localModuleCargo.cargoToLocalModule import GuiCargoToLocalModuleCommand +from .gui.localModuleCargo.localModuleToCargo import GuiLocalModuleToCargoCommand from .gui.projectedDrone.add import GuiAddProjectedDroneCommand from .gui.projectedDrone.changeAmount import GuiChangeProjectedDroneAmountCommand from .gui.projectedDrone.changeMeta import GuiChangeProjectedDroneMetaCommand diff --git a/gui/fitCommands/calc/cargo/add.py b/gui/fitCommands/calc/cargo/add.py index 03e2e9b07..f36014e2b 100644 --- a/gui/fitCommands/calc/cargo/add.py +++ b/gui/fitCommands/calc/cargo/add.py @@ -11,10 +11,11 @@ pyfalog = Logger(__name__) class CalcAddCargoCommand(wx.Command): - def __init__(self, fitID, cargoInfo): + def __init__(self, fitID, cargoInfo, commit=True): wx.Command.__init__(self, True, 'Add Cargo') self.fitID = fitID self.cargoInfo = cargoInfo + self.commit = commit def Do(self): pyfalog.debug('Doing addition of cargo {} to fit {}'.format(self.cargoInfo, self.fitID)) @@ -28,13 +29,15 @@ class CalcAddCargoCommand(wx.Command): fit.cargo.append(cargo) except HandledListActionError: pyfalog.warning('Failed to append to list') - eos.db.commit() + if self.commit: + eos.db.commit() return False - eos.db.commit() + if self.commit: + eos.db.commit() return True def Undo(self): pyfalog.debug('Undoing addition of cargo {} to fit {}'.format(self.cargoInfo, self.fitID)) from .remove import CalcRemoveCargoCommand - cmd = CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=self.cargoInfo) + cmd = CalcRemoveCargoCommand(fitID=self.fitID, cargoInfo=self.cargoInfo, commit=self.commit) return cmd.Do() diff --git a/gui/fitCommands/calc/cargo/remove.py b/gui/fitCommands/calc/cargo/remove.py index 4bc5a677a..b27bf1194 100644 --- a/gui/fitCommands/calc/cargo/remove.py +++ b/gui/fitCommands/calc/cargo/remove.py @@ -1,4 +1,5 @@ import wx + from logbook import Logger import eos.db @@ -11,10 +12,11 @@ pyfalog = Logger(__name__) class CalcRemoveCargoCommand(wx.Command): - def __init__(self, fitID, cargoInfo): + def __init__(self, fitID, cargoInfo, commit=True): wx.Command.__init__(self, True, 'Remove Cargo') self.fitID = fitID self.cargoInfo = cargoInfo + self.commit = commit self.savedRemovedAmount = None def Do(self): @@ -27,11 +29,15 @@ class CalcRemoveCargoCommand(wx.Command): cargo.amount -= self.savedRemovedAmount if cargo.amount <= 0: fit.cargo.remove(cargo) - eos.db.commit() + if self.commit: + eos.db.commit() return True def Undo(self): pyfalog.debug('Undoing removal of cargo {} to fit {}'.format(self.cargoInfo, self.fitID)) from .add import CalcAddCargoCommand - cmd = CalcAddCargoCommand(fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.cargoInfo.itemID, amount=self.savedRemovedAmount)) + cmd = CalcAddCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=self.cargoInfo.itemID, amount=self.savedRemovedAmount), + commit=self.commit) return cmd.Do() diff --git a/gui/fitCommands/calc/module/changeCharges.py b/gui/fitCommands/calc/module/changeCharges.py index 98c7bbfea..09b9bb973 100644 --- a/gui/fitCommands/calc/module/changeCharges.py +++ b/gui/fitCommands/calc/module/changeCharges.py @@ -11,11 +11,12 @@ pyfalog = Logger(__name__) class CalcChangeModuleChargesCommand(wx.Command): - def __init__(self, fitID, projected, chargeMap): + def __init__(self, fitID, projected, chargeMap, commit=True): wx.Command.__init__(self, True, 'Change Module Charges') self.fitID = fitID self.projected = projected self.chargeMap = chargeMap + self.commit = commit self.savedChargeMap = None def Do(self): @@ -43,12 +44,17 @@ class CalcChangeModuleChargesCommand(wx.Command): self.savedChargeMap[position] = mod.chargeID changes = True mod.charge = chargeItem - if changes: + if not changes: + return False + if self.commit: eos.db.commit() - return True - return False + return True def Undo(self): pyfalog.debug('Undoing change of module charges according to map {} on fit {}'.format(self.chargeMap, self.fitID)) - cmd = CalcChangeModuleChargesCommand(fitID=self.fitID, projected=self.projected, chargeMap=self.savedChargeMap) + cmd = CalcChangeModuleChargesCommand( + fitID=self.fitID, + projected=self.projected, + chargeMap=self.savedChargeMap, + commit=self.commit) return cmd.Do() diff --git a/gui/fitCommands/calc/module/localReplace.py b/gui/fitCommands/calc/module/localReplace.py index 4fcc7d43f..642cf3013 100644 --- a/gui/fitCommands/calc/module/localReplace.py +++ b/gui/fitCommands/calc/module/localReplace.py @@ -63,7 +63,7 @@ class CalcReplaceLocalModuleCommand(wx.Command): # Remove if there was no module if self.oldModInfo is None: from .localRemove import CalcRemoveLocalModuleCommand - cmd = CalcRemoveLocalModuleCommand(fitID=self.fitID, positions=[self.position]) + cmd = CalcRemoveLocalModuleCommand(fitID=self.fitID, positions=[self.position], commit=self.commit) return cmd.Do() # Replace if there was sFit = Fit.getInstance() diff --git a/gui/fitCommands/gui/guiCargoToModule.py b/gui/fitCommands/gui/guiCargoToModule.py deleted file mode 100644 index e2f96d33d..000000000 --- a/gui/fitCommands/gui/guiCargoToModule.py +++ /dev/null @@ -1,80 +0,0 @@ -import wx -from service.fit import Fit - -import gui.mainFrame -from gui import globalEvents as GE -from gui.fitCommands.calc.module.changeCharges import CalcChangeModuleChargesCommand -from gui.fitCommands.calc.module.localReplace import CalcReplaceLocalModuleCommand -from gui.fitCommands.calc.cargo.remove import CalcRemoveCargoCommand -from gui.fitCommands.helpers import ModuleInfo -from gui.fitCommands.calc.cargo.add import CalcAddCargoCommand -from logbook import Logger -pyfalog = Logger(__name__) - - -class GuiCargoToModuleCommand(wx.Command): - """ - Moves cargo to fitting window. Can either do a copy, move, or swap with current module - If we try to copy/move into a spot with a non-empty module, we swap instead. - To avoid redundancy in converting Cargo item, this function does the - sanity checks as opposed to the GUI View. This is different than how the - normal .swapModules() does things, which is mostly a blind swap. - """ - - def __init__(self, fitID, moduleIdx, cargoIdx, copy=False): - wx.Command.__init__(self, True, "Cargo to Module") - self.fitID = fitID - self.moduleIdx = moduleIdx - self.cargoIdx = cargoIdx - self.copy = copy - self.internalHistory = wx.CommandProcessor() - - def Do(self): - sFit = Fit.getInstance() - fit = sFit.getFit(self.fitID) - module = fit.modules[self.moduleIdx] - cargo = fit.cargo[self.cargoIdx] - result = False - - # We're trying to move a charge from cargo to a slot. Use SetCharge command (don't respect move vs copy) - # todo: replace with item.ischarge, broken for now - if sFit.isAmmo(cargo.itemID): - result = self.internalHistory.Submit(CalcChangeModuleChargesCommand(self.fitID, False, {module.modPosition: cargo.itemID})) - else: - - pyfalog.debug("Moving cargo item to module for fit ID: {0}", self.fitID) - - self.addCmd = CalcReplaceLocalModuleCommand( - fitID=self.fitID, - position=module.modPosition, - newModInfo=ModuleInfo(itemID=cargo.itemID)) - - result = self.internalHistory.Submit(self.addCmd) - - if not result: - # creating module failed for whatever reason - return False - - if self.addCmd.old_module is not None: - # we're swapping with an existing module, so remove cargo and add module - self.removeCmd = CalcRemoveCargoCommand(self.fitID, cargo.itemID) - result = self.internalHistory.Submit(self.removeCmd) - - self.addCargoCmd = CalcAddCargoCommand(self.fitID, self.addCmd.old_module.itemID) - result = self.internalHistory.Submit(self.addCargoCmd) - elif not self.copy: - # move, not copying, so remove cargo - self.removeCmd = CalcRemoveCargoCommand(self.fitID, cargo.itemID) - result = self.internalHistory.Submit(self.removeCmd) - - if result: - sFit.recalc(self.fitID) - wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID)) - return result - - def Undo(self): - for _ in self.internalHistory.Commands: - self.internalHistory.Undo() - Fit.getInstance().recalc(self.fitID) - wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID)) - return True diff --git a/gui/fitCommands/gui/localModuleCargo/__init__.py b/gui/fitCommands/gui/localModuleCargo/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py b/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py new file mode 100644 index 000000000..14670c626 --- /dev/null +++ b/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py @@ -0,0 +1,119 @@ +import wx + +import eos.db +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.changeCharges import CalcChangeModuleChargesCommand +from gui.fitCommands.calc.module.localReplace import CalcReplaceLocalModuleCommand +from gui.fitCommands.helpers import CargoInfo, InternalCommandHistory, ModuleInfo +from service.fit import Fit + + +class GuiCargoToLocalModuleCommand(wx.Command): + """ + Moves cargo to fitting window. Can either do a copy, move, or swap with current module + If we try to copy/move into a spot with a non-empty module, we swap instead. + To avoid redundancy in converting Cargo item, this function does the + sanity checks as opposed to the GUI View. This is different than how the + normal .swapModules() does things, which is mostly a blind swap. + """ + + def __init__(self, fitID, cargoItemID, modPosition, copy): + wx.Command.__init__(self, True, 'Cargo to Local Module') + self.internalHistory = InternalCommandHistory() + self.fitID = fitID + self.srcCargoItemID = cargoItemID + self.dstModPosition = modPosition + self.copy = copy + self.addedModItemID = None + self.removedModItemID = None + + def Do(self): + sFit = Fit.getInstance() + fit = sFit.getFit(self.fitID) + srcCargo = next((c for c in fit.cargo if c.itemID == self.srcCargoItemID), None) + if srcCargo is None: + return + dstMod = fit.modules[self.dstModPosition] + # Moving charge from cargo to fit - just attempt to load charge into destination module + if srcCargo.item.isCharge and not dstMod.isEmpty: + cmd = CalcChangeModuleChargesCommand( + fitID=self.fitID, + projected=False, + chargeMap={dstMod.modPosition: self.srcCargoItemID}, + commit=False) + success = self.internalHistory.submit(cmd) + # Copying item to empty slot + elif srcCargo.item.isModule and self.copy and dstMod.isEmpty: + cmd = CalcReplaceLocalModuleCommand( + fitID=self.fitID, + position=self.dstModPosition, + newModInfo=ModuleInfo(itemID=self.srcCargoItemID), + commit=False) + success = self.internalHistory.submit(cmd) + if success: + self.addedModItemID = self.srcCargoItemID + # Swapping with target module, or moving there if there's no module + elif srcCargo.item.isModule and not self.copy: + dstModItemID = dstMod.itemID + if self.srcCargoItemID == dstModItemID: + return False + newModInfo = ModuleInfo.fromModule(dstMod) + newModInfo.itemID = self.srcCargoItemID + if dstMod.isEmpty: + newCargoItemID = None + elif dstMod.isMutated: + newCargoItemID = dstMod.baseItemID + else: + newCargoItemID = dstMod.itemID + commands = [] + commands.append(CalcRemoveCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=self.srcCargoItemID, amount=1), + commit=False)) + if newCargoItemID is not None: + commands.append(CalcAddCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=newCargoItemID, amount=1), + commit=False)) + commands.append(CalcReplaceLocalModuleCommand( + fitID=self.fitID, + position=self.dstModPosition, + newModInfo=newModInfo, + unloadInvalidCharges=True, + commit=False)) + success = self.internalHistory.submitBatch(*commands) + if success: + self.addedModItemID = self.srcCargoItemID + self.removedModItemID = dstModItemID + else: + return False + eos.db.commit() + sFit.recalc(self.fitID) + events = [] + if self.removedModItemID is not None: + events.append(GE.FitChanged(fitID=self.fitID, action='moddel', typeID=self.removedModItemID)) + if self.addedModItemID is not None: + events.append(GE.FitChanged(fitID=self.fitID, action='modadd', typeID=self.addedModItemID)) + if not events: + events.append(GE.FitChanged(fitID=self.fitID)) + for event in events: + wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), event) + return success + + def Undo(self): + success = self.internalHistory.undoAll() + eos.db.commit() + Fit.getInstance().recalc(self.fitID) + events = [] + if self.addedModItemID is not None: + events.append(GE.FitChanged(fitID=self.fitID, action='moddel', typeID=self.addedModItemID)) + if self.removedModItemID is not None: + events.append(GE.FitChanged(fitID=self.fitID, action='modadd', typeID=self.removedModItemID)) + if not events: + events.append(GE.FitChanged(fitID=self.fitID)) + for event in events: + wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), event) + return success diff --git a/gui/fitCommands/gui/guiModuleToCargo.py b/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py similarity index 98% rename from gui/fitCommands/gui/guiModuleToCargo.py rename to gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py index 6ecb02966..63d553ae8 100644 --- a/gui/fitCommands/gui/guiModuleToCargo.py +++ b/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py @@ -3,17 +3,18 @@ from logbook import Logger 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.localReplace import CalcReplaceLocalModuleCommand from gui.fitCommands.helpers import ModuleInfo from service.fit import Fit -from gui.fitCommands.calc.cargo.add import CalcAddCargoCommand + pyfalog = Logger(__name__) -class GuiModuleToCargoCommand(wx.Command): +class GuiLocalModuleToCargoCommand(wx.Command): def __init__(self, fitID, moduleIdx, cargoIdx, copy=False): wx.Command.__init__(self, True, "Module to Cargo") diff --git a/gui/fitCommands/helpers.py b/gui/fitCommands/helpers.py index 55e397f6e..2db87a09c 100644 --- a/gui/fitCommands/helpers.py +++ b/gui/fitCommands/helpers.py @@ -107,10 +107,10 @@ class ModuleInfo: mod.spoolAmount = self.spoolAmount if self.state is not None: - if not mod.isValidState(self.state): - pyfalog.warning('Cannot set state {}'.format(self.state)) - return None - mod.state = self.state + if mod.isValidState(self.state): + mod.state = self.state + else: + mod.state = mod.getMaxState(self.state) elif fallbackState is not None: if mod.isValidState(fallbackState): mod.state = fallbackState