From 9301bb56fa55e283d833d10f2b6c21cec5dc2c00 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Tue, 16 Apr 2019 12:20:54 +0300 Subject: [PATCH] More changes to cargo to module command, start reworking module to cargo as well --- gui/builtinAdditionPanes/cargoView.py | 23 +-- gui/fitCommands/calc/module/localAdd.py | 3 +- .../calc/module/localChangeStates.py | 3 +- gui/fitCommands/calc/module/localClone.py | 1 + gui/fitCommands/calc/module/localRemove.py | 4 +- gui/fitCommands/calc/module/localReplace.py | 5 + .../localModuleCargo/cargoToLocalModule.py | 74 +++++--- .../localModuleCargo/localModuleToCargo.py | 167 ++++++++++++------ 8 files changed, 182 insertions(+), 98 deletions(-) diff --git a/gui/builtinAdditionPanes/cargoView.py b/gui/builtinAdditionPanes/cargoView.py index 75a27c699..b750b6d68 100644 --- a/gui/builtinAdditionPanes/cargoView.py +++ b/gui/builtinAdditionPanes/cargoView.py @@ -112,26 +112,11 @@ class CargoView(d.Display): dstRow, _ = self.HitTest((x, y)) mstate = wx.GetMouseState() - # Gather module information to get position - module = fit.modules[modIdx] - - if module.item.isAbyssal: - dlg = wx.MessageDialog(self, - "Moving this Abyssal module to the cargo will convert it to the base module. Do you wish to proceed?", - "Confirm", wx.YES_NO | wx.ICON_QUESTION) - result = dlg.ShowModal() == wx.ID_YES - - if not result: - return - - cargoPos = dstRow if dstRow > -1 else None - self.mainFrame.command.Submit(cmd.GuiLocalModuleToCargoCommand( - self.mainFrame.getActiveFit(), - module.modPosition, - cargoPos, - mstate.cmdDown - )) + fitID=self.mainFrame.getActiveFit(), + modPosition=fit.modules[modIdx].modPosition, + cargoItemID=self.cargo[dstRow].itemID if dstRow > -1 else None, + copy=mstate.cmdDown)) def fitChanged(self, event): sFit = Fit.getInstance() diff --git a/gui/fitCommands/calc/module/localAdd.py b/gui/fitCommands/calc/module/localAdd.py index 50f5a0981..a69101952 100644 --- a/gui/fitCommands/calc/module/localAdd.py +++ b/gui/fitCommands/calc/module/localAdd.py @@ -49,10 +49,11 @@ class CalcAddLocalModuleCommand(wx.Command): if self.commit: eos.db.commit() return False + self.savedPosition = newMod.modPosition + sFit.recalc(self.fitID) sFit.checkStates(fit, newMod) if self.commit: eos.db.commit() - self.savedPosition = newMod.modPosition return True def Undo(self): diff --git a/gui/fitCommands/calc/module/localChangeStates.py b/gui/fitCommands/calc/module/localChangeStates.py index 834060d5a..70596e37c 100644 --- a/gui/fitCommands/calc/module/localChangeStates.py +++ b/gui/fitCommands/calc/module/localChangeStates.py @@ -44,8 +44,9 @@ class CalcChangeLocalModuleStatesCommand(wx.Command): mod.state = proposedState if not changed: return False - eos.db.commit() + sFit.recalc(self.fitID) sFit.checkStates(fit, mainMod) + eos.db.commit() return True def Undo(self): diff --git a/gui/fitCommands/calc/module/localClone.py b/gui/fitCommands/calc/module/localClone.py index 5e2eb6bea..0410571d4 100644 --- a/gui/fitCommands/calc/module/localClone.py +++ b/gui/fitCommands/calc/module/localClone.py @@ -36,6 +36,7 @@ class CalcCloneLocalModuleCommand(wx.Command): pyfalog.warning('Failed to replace module') eos.db.commit() return False + sFit.recalc(self.fitID) sFit.checkStates(fit, copyMod) eos.db.commit() return True diff --git a/gui/fitCommands/calc/module/localRemove.py b/gui/fitCommands/calc/module/localRemove.py index 14b9df1c5..45cbec868 100644 --- a/gui/fitCommands/calc/module/localRemove.py +++ b/gui/fitCommands/calc/module/localRemove.py @@ -20,7 +20,8 @@ class CalcRemoveLocalModuleCommand(wx.Command): def Do(self): pyfalog.debug('Doing removal of local modules from positions {} on fit {}'.format(self.positions, self.fitID)) - fit = Fit.getInstance().getFit(self.fitID) + sFit = Fit.getInstance() + fit = sFit.getFit(self.fitID) for position in self.positions: mod = fit.modules[position] @@ -28,6 +29,7 @@ class CalcRemoveLocalModuleCommand(wx.Command): self.savedModInfos[position] = ModuleInfo.fromModule(mod) fit.modules.free(position) + sFit.checkStates(fit, None) if self.commit: eos.db.commit() # If no modules were removed, report that command was not completed diff --git a/gui/fitCommands/calc/module/localReplace.py b/gui/fitCommands/calc/module/localReplace.py index 642cf3013..59dc29c8d 100644 --- a/gui/fitCommands/calc/module/localReplace.py +++ b/gui/fitCommands/calc/module/localReplace.py @@ -20,9 +20,11 @@ class CalcReplaceLocalModuleCommand(wx.Command): self.oldModInfo = None self.unloadInvalidCharges = unloadInvalidCharges self.commit = commit + 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)) + self.unloadedCharge = False sFit = Fit.getInstance() fit = sFit.getFit(self.fitID) oldMod = fit.modules[self.position] @@ -42,6 +44,7 @@ class CalcReplaceLocalModuleCommand(wx.Command): if not newMod.isValidCharge(newMod.charge): if self.unloadInvalidCharges: newMod.charge = None + self.unloadedCharge = True else: pyfalog.warning('Invalid charge') self.Undo() @@ -53,6 +56,7 @@ class CalcReplaceLocalModuleCommand(wx.Command): pyfalog.warning('Failed to replace in list') self.Undo() return False + sFit.recalc(self.fitID) sFit.checkStates(fit, newMod) if self.commit: eos.db.commit() @@ -83,6 +87,7 @@ class CalcReplaceLocalModuleCommand(wx.Command): pyfalog.warning('Failed to replace in list') self.Do() return False + sFit.recalc(self.fitID) sFit.checkStates(fit, oldMod) if self.commit: eos.db.commit() diff --git a/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py b/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py index 33788c113..5d74a3e21 100644 --- a/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py +++ b/gui/fitCommands/gui/localModuleCargo/cargoToLocalModule.py @@ -13,11 +13,8 @@ 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. + Moves cargo to the fitting window. If target is not empty, take whatever we take off and put + into the cargo hold. If we copy, we do the same but do not remove the item from the cargo hold. """ def __init__(self, fitID, cargoItemID, modPosition, copy): @@ -27,8 +24,8 @@ class GuiCargoToLocalModuleCommand(wx.Command): self.srcCargoItemID = cargoItemID self.dstModPosition = modPosition self.copy = copy - self.addedModItemID = None self.removedModItemID = None + self.addedModItemID = None def Do(self): sFit = Fit.getInstance() @@ -37,7 +34,7 @@ class GuiCargoToLocalModuleCommand(wx.Command): if srcCargo is None: return dstMod = fit.modules[self.dstModPosition] - # Moving charge from cargo to fit - just attempt to load charge into destination module + # Moving/copying charge from cargo to fit if srcCargo.item.isCharge and not dstMod.isEmpty: newCargoChargeItemID = dstMod.chargeID newCargoChargeAmount = dstMod.numCharges @@ -62,50 +59,85 @@ class GuiCargoToLocalModuleCommand(wx.Command): chargeMap={dstMod.modPosition: self.srcCargoItemID}, commit=False)) success = self.internalHistory.submitBatch(*commands) + # Moving/copying/replacing module elif srcCargo.item.isModule: dstModItemID = dstMod.itemID + dstModSlot = dstMod.slot if self.srcCargoItemID == dstModItemID: return False + # To keep all old item properties, copy them over from old module newModInfo = ModuleInfo.fromModule(dstMod) newModInfo.itemID = self.srcCargoItemID if dstMod.isEmpty: newCargoModItemID = None - newCargoChargeItemID = None - newCargoChargeAmount = None + dstModChargeItemID = None + dstModChargeAmount = None + # We cannot put mutated items to cargo, so use base item ID elif dstMod.isMutated: newCargoModItemID = dstMod.baseItemID - newCargoChargeItemID = dstMod.chargeID - newCargoChargeAmount = dstMod.numCharges + dstModChargeItemID = dstMod.chargeID + dstModChargeAmount = dstMod.numCharges else: newCargoModItemID = dstMod.itemID - newCargoChargeItemID = dstMod.chargeID - newCargoChargeAmount = dstMod.numCharges + dstModChargeItemID = dstMod.chargeID + dstModChargeAmount = dstMod.numCharges commands = [] + # Keep cargo only in case we were copying if not self.copy: commands.append(CalcRemoveCargoCommand( fitID=self.fitID, cargoInfo=CargoInfo(itemID=self.srcCargoItemID, amount=1), commit=False)) + # Add item to cargo only if we copied/moved to non-empty slot if newCargoModItemID is not None: commands.append(CalcAddCargoCommand( fitID=self.fitID, cargoInfo=CargoInfo(itemID=newCargoModItemID, amount=1), commit=False)) - if newCargoChargeItemID is not None: - commands.append(CalcAddCargoCommand( - fitID=self.fitID, - cargoInfo=CargoInfo(itemID=newCargoChargeItemID, amount=newCargoChargeAmount), - commit=False)) - commands.append(CalcReplaceLocalModuleCommand( + cmdReplace = CalcReplaceLocalModuleCommand( fitID=self.fitID, position=self.dstModPosition, newModInfo=newModInfo, unloadInvalidCharges=True, - commit=False)) + commit=False) + commands.append(cmdReplace) + # Submit batch now because we need to have updated info on fit to keep going success = self.internalHistory.submitBatch(*commands) + newMod = fit.modules[self.dstModPosition] + # Bail if drag happened to slot to which module cannot be dragged, will undo later + if newMod.slot != dstModSlot: + success = False if success: - self.addedModItemID = self.srcCargoItemID + # Add charge to cargo only if we had to unload it + if cmdReplace.unloadedCharge and dstModChargeItemID is not None: + cmdAddCargoCharge = CalcAddCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=dstModChargeItemID, amount=dstModChargeAmount), + commit=False) + success = self.internalHistory.submit(cmdAddCargoCharge) + # If we did not unload charge and it was there, process the difference + elif not cmdReplace.unloadedCharge and dstModChargeItemID is not None: + extraChargeAmount = newMod.numCharges - dstModChargeAmount + if extraChargeAmount > 0: + cmdRemoveCargoExtraCharge = CalcRemoveCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=dstModChargeItemID, amount=extraChargeAmount), + commit=False) + # Do not check if operation was successful or not, we're okay if we have no such + # charges in cargo + self.internalHistory.submit(cmdRemoveCargoExtraCharge) + elif extraChargeAmount < 0: + cmdAddCargoExtraCharge = CalcAddCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=dstModChargeItemID, amount=abs(extraChargeAmount)), + commit=False) + success = self.internalHistory.submit(cmdAddCargoExtraCharge) + if success: + # Store info to properly send events later self.removedModItemID = dstModItemID + self.addedModItemID = self.srcCargoItemID + else: + self.internalHistory.undoAll() else: return False eos.db.commit() diff --git a/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py b/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py index 63d553ae8..d6d6362b4 100644 --- a/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py +++ b/gui/fitCommands/gui/localModuleCargo/localModuleToCargo.py @@ -1,77 +1,134 @@ import wx -from logbook import Logger +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.localRemove import CalcRemoveLocalModuleCommand from gui.fitCommands.calc.module.localReplace import CalcReplaceLocalModuleCommand -from gui.fitCommands.helpers import ModuleInfo +from gui.fitCommands.helpers import CargoInfo, InternalCommandHistory, ModuleInfo from service.fit import Fit -pyfalog = Logger(__name__) - - class GuiLocalModuleToCargoCommand(wx.Command): - def __init__(self, fitID, moduleIdx, cargoIdx, copy=False): - wx.Command.__init__(self, True, "Module to Cargo") + def __init__(self, fitID, modPosition, cargoItemID, copy): + wx.Command.__init__(self, True, 'Local Module to Cargo') + self.internalHistory = InternalCommandHistory() self.fitID = fitID - self.moduleIdx = moduleIdx - self.cargoIdx = cargoIdx + self.srcModPosition = modPosition + self.dstCargoItemID = cargoItemID self.copy = copy - self.internalHistory = wx.CommandProcessor() + self.removedModItemID = None + self.addedModItemID = None def Do(self): - sFit = Fit.getInstance() - fit = sFit.getFit(self.fitID) - module = fit.modules[self.moduleIdx] - result = False - - if self.cargoIdx: # we're swapping with cargo - if self.copy: # if copying, simply add item to cargo - result = self.internalHistory.Submit(CalcAddCargoCommand( - gui.mainFrame.MainFrame.getInstance().getActiveFit(), module.item.ID if not module.item.isAbyssal else module.baseItemID)) - else: # otherwise, try to swap by replacing module with cargo item. If successful, remove old cargo and add new cargo - - cargo = fit.cargo[self.cargoIdx] - self.modReplaceCmd = CalcReplaceLocalModuleCommand( + fit = Fit.getInstance().getFit(self.fitID) + srcMod = fit.modules[self.srcModPosition] + if srcMod.isEmpty: + return False + srcModItemID = srcMod.itemID + if self.dstCargoItemID == srcModItemID: + return False + dstCargo = next((c for c in fit.cargo if c.itemID == self.dstCargoItemID), None) + newCargoModItemID = srcMod.baseItemID if srcMod.isMutated else srcMod.itemID + newCargoChargeItemID = srcMod.chargeID + newCargoChargeAmount = srcMod.numCharges + # Save module info to do swap is cargo item is module and we're not copying + if dstCargo is not None and dstCargo.item.isModule and not self.copy: + newModInfo = ModuleInfo.fromModule(srcMod) + newModInfo.itemID = self.dstCargoItemID + else: + newModInfo = None + if newModInfo is not None: + cmdRemoveCargo = CalcRemoveCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=self.dstCargoItemID, amount=1), + commit=False) + success = self.internalHistory.submit(cmdRemoveCargo) + if not success: + self.internalHistory.undoAll() + self.__finalizeDo() + return success + cmdAddCargoMod = CalcAddCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=newCargoModItemID, amount=1), + commit=False) + success = self.internalHistory.submit(cmdAddCargoMod) + if not success: + self.internalHistory.undoAll() + self.__finalizeDo() + return success + cmdReplaceMod = None + removeCargo = False + if newModInfo is not None: + removeCargo = True + cmdReplaceMod = CalcReplaceLocalModuleCommand( + fitID=self.fitID, + position=self.srcModPosition, + newModInfo=newModInfo, + unloadInvalidCharges=True, + commit=False) + success = self.internalHistory.submit(cmdReplaceMod) + # If replace fails, try just removing instead - we need this to be able to drag high-slot modules + # over low-slot items in cargo, so that module will still be placed in the cargo + if not success: + success = True + cmdReplaceMod = None + removeCargo = False + if removeCargo: + if not self.copy: + cmdRemoveMod = CalcRemoveLocalModuleCommand( fitID=self.fitID, - position=module.modPosition, - newModInfo=ModuleInfo(itemID=cargo.itemID)) + positions=[self.srcModPosition], + commit=False) + success = self.internalHistory.submit(cmdRemoveMod) + if not success: + self.internalHistory.undoAll() + self.__finalizeDo() + return success + # Add charge to cargo only if we had to unload it or we're copying + if newCargoChargeItemID is not None and ((cmdReplaceMod is not None and cmdReplaceMod.unloadedCharge) or self.copy): + cmdAddCargoCharge = CalcAddCargoCommand( + fitID=self.fitID, + cargoInfo=CargoInfo(itemID=newCargoChargeItemID, amount=newCargoChargeAmount), + commit=False) + success = self.internalHistory.submit(cmdAddCargoCharge) + if not success: + self.internalHistory.undoAll() + self.__finalizeDo() + return success + if success: + self.addedModItemID = newModInfo.itemID if newModInfo is not None else None + self.removedModItemID = srcModItemID + self.__finalizeDo() + return success - result = self.internalHistory.Submit(self.modReplaceCmd) - - if not result: - # creating module failed for whatever reason - return False - - if self.modReplaceCmd.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.modReplaceCmd.old_module.itemID) - result = self.internalHistory.Submit(self.addCargoCmd) - - else: # dragging to blank spot, append - result = self.internalHistory.Submit(CalcAddCargoCommand(gui.mainFrame.MainFrame.getInstance().getActiveFit(), - module.item.ID if not module.item.isAbyssal else module.baseItemID)) - - if not self.copy: # if not copying, remove module - self.internalHistory.Submit(CalcRemoveLocalModuleCommand(gui.mainFrame.MainFrame.getInstance().getActiveFit(), [self.moduleIdx])) - - if result: - sFit.recalc(self.fitID) - wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID, action="moddel", typeID=module.item.ID)) - - return result + def __finalizeDo(self): + eos.db.commit() + Fit.getInstance().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) def Undo(self): - for _ in self.internalHistory.Commands: - self.internalHistory.Undo() + success = self.internalHistory.undoAll() + eos.db.commit() Fit.getInstance().recalc(self.fitID) - wx.PostEvent(gui.mainFrame.MainFrame.getInstance(), GE.FitChanged(fitID=self.fitID)) - return True + 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