diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py index 16f6a3bf9..f1f947296 100644 --- a/eos/db/saveddata/queries.py +++ b/eos/db/saveddata/queries.py @@ -30,6 +30,7 @@ from eos.saveddata.targetResists import TargetResists from eos.saveddata.character import Character from eos.saveddata.implantSet import ImplantSet from eos.saveddata.fit import Fit +from eos.saveddata.module import Module from eos.saveddata.miscData import MiscData from eos.saveddata.override import Override @@ -241,22 +242,17 @@ def getFitsWithShip(shipID, ownerID=None, where=None, eager=None): return fits -def getBoosterFits(ownerID=None, where=None, eager=None): +def getFitsWithModules(typeIDs, eager=None): """ - Get all the fits that are flagged as a boosting ship - If no user is passed, do this for all users. + Get all the fits that have typeIDs fitted to them """ - if ownerID is not None and not isinstance(ownerID, int): - raise TypeError("OwnerID must be integer") - filter = Fit.booster == 1 - if ownerID is not None: - filter = and_(filter, Fit.ownerID == ownerID) + if not hasattr(typeIDs, "__iter__"): + typeIDs = (typeIDs,) - filter = processWhere(filter, where) eager = processEager(eager) with sd_lock: - fits = removeInvalid(saveddata_session.query(Fit).options(*eager).filter(filter).all()) + fits = removeInvalid(saveddata_session.query(Fit).join(Module).options(*eager).filter(Module.itemID.in_(typeIDs)).all()) return fits diff --git a/gui/builtinContextMenus/commandFits.py b/gui/builtinContextMenus/commandFits.py new file mode 100644 index 000000000..9640a83ef --- /dev/null +++ b/gui/builtinContextMenus/commandFits.py @@ -0,0 +1,96 @@ +# noinspection PyPackageRequirements +import wx + +from service.fit import Fit +from service.market import Market +import gui.mainFrame +import gui.globalEvents as GE +from gui.contextMenu import ContextMenu +from service.settings import ContextMenuSettings + + +class CommandFits(ContextMenu): + # Get list of items that define a command fit + sMkt = Market.getInstance() + grp = sMkt.getGroup(1770) # Command burst group + commandTypeIDs = [item.ID for item in grp.items] + commandFits = [] + menu = None + + @classmethod + def populateFits(cls, evt): + if evt is None or (getattr(evt, 'action', None) in ("modadd", "moddel") and getattr(evt, 'typeID', None) in cls.commandTypeIDs): + # we are adding or removing an item that defines a command fit. Need to refresh fit list + sFit = Fit.getInstance() + cls.commandFits = sFit.getFitsWithModules(cls.commandTypeIDs) + + def __init__(self): + self.mainFrame = gui.mainFrame.MainFrame.getInstance() + self.settings = ContextMenuSettings.getInstance() + + def display(self, srcContext, selection): + if self.mainFrame.getActiveFit() is None or len(self.__class__.commandFits) == 0 or srcContext != "commandView": + return False + + return True + + def getText(self, itmContext, selection): + return "Command Fits" + + def addFit(self, menu, fit, includeShip=False): + label = fit.name if not includeShip else "({}) {}".format(fit.ship.item.name, fit.name) + id = ContextMenu.nextID() + self.fitMenuItemIds[id] = fit + menuItem = wx.MenuItem(menu, id, label) + menu.Bind(wx.EVT_MENU, self.handleSelection, menuItem) + return menuItem + + def getSubMenu(self, context, selection, rootMenu, i, pitem): + msw = True if "wxMSW" in wx.PlatformInfo else False + self.context = context + self.fitMenuItemIds = {} + + sub = wx.Menu() + + if len(self.__class__.commandFits) < 15: + for fit in sorted(self.__class__.commandFits, key=lambda x: x.name): + print fit + menuItem = self.addFit(rootMenu if msw else sub, fit, True) + sub.AppendItem(menuItem) + else: + typeDict = {} + + for fit in self.__class__.commandFits: + shipName = fit.ship.item.name + if shipName not in typeDict: + typeDict[shipName] = [] + typeDict[shipName].append(fit) + + for ship in sorted(typeDict.keys()): + shipItem = wx.MenuItem(sub, ContextMenu.nextID(), ship) + grandSub = wx.Menu() + shipItem.SetSubMenu(grandSub) + + for fit in sorted(typeDict[ship], key=lambda x: x.name): + fitItem = self.addFit(rootMenu if msw else grandSub, fit, False) + grandSub.AppendItem(fitItem) + + sub.AppendItem(shipItem) + + return sub + + def handleSelection(self, event): + fit = self.fitMenuItemIds[event.Id] + if fit is False or fit not in self.__class__.commandFits: + event.Skip() + return + + sFit = Fit.getInstance() + fitID = self.mainFrame.getActiveFit() + + sFit.addCommandFit(fitID, fit) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + + +CommandFits.populateFits(None) +CommandFits.register() diff --git a/gui/builtinStatsViews/targetingMiscViewMinimal.py b/gui/builtinStatsViews/targetingMiscViewMinimal.py index 4dffc9e40..df0d9f70a 100644 --- a/gui/builtinStatsViews/targetingMiscViewMinimal.py +++ b/gui/builtinStatsViews/targetingMiscViewMinimal.py @@ -242,7 +242,6 @@ class TargetingMiscViewMinimal(StatsView): # forces update of probe size, since this stat is used by both sig radius and sensor str if labelName == "labelFullSigRadius": - print "labelName" if fit: label.SetToolTip(wx.ToolTip("Probe Size: %.3f" % (fit.probeSize or 0))) else: diff --git a/gui/builtinViews/fittingView.py b/gui/builtinViews/fittingView.py index 496cf4fb8..01eb3ff66 100644 --- a/gui/builtinViews/fittingView.py +++ b/gui/builtinViews/fittingView.py @@ -334,7 +334,7 @@ class FittingView(d.Display): populate = sFit.appendModule(fitID, itemID) if populate is not None: self.slotsChanged() - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID)) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=fitID, action="modadd", typeID=itemID)) event.Skip() @@ -355,7 +355,7 @@ class FittingView(d.Display): if populate is not None: self.slotsChanged() - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID)) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.activeFitID, action="moddel", typeID=module.item.ID)) def addModule(self, x, y, srcIdx): """Add a module from the market browser""" @@ -368,7 +368,8 @@ class FittingView(d.Display): if moduleChanged is None: # the new module doesn't fit in specified slot, try to simply append it wx.PostEvent(self.mainFrame, gui.marketBrowser.ItemSelected(itemID=srcIdx)) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) + + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="modadd", typeID=srcIdx)) def swapCargo(self, x, y, srcIdx): """Swap a module from cargo to fitting window""" @@ -379,10 +380,13 @@ class FittingView(d.Display): module = self.mods[dstRow] sFit = Fit.getInstance() + fit = sFit.getFit(self.activeFitID) + typeID = fit.cargo[srcIdx].item.ID + sFit.moveCargoToModule(self.mainFrame.getActiveFit(), module.modPosition, srcIdx, mstate.CmdDown() and module.isEmpty) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="modadd", typeID=typeID)) def swapItems(self, x, y, srcIdx): """Swap two modules in fitting window""" diff --git a/gui/cargoView.py b/gui/cargoView.py index d997afa79..cd560c1c2 100644 --- a/gui/cargoView.py +++ b/gui/cargoView.py @@ -125,7 +125,7 @@ class CargoView(d.Display): if not mstate.CmdDown(): # if not copying, remove module sFit.removeModule(self.mainFrame.getActiveFit(), module.position) - wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit())) + wx.PostEvent(self.mainFrame, GE.FitChanged(fitID=self.mainFrame.getActiveFit(), action="moddel", typeID=module.item.ID)) def fitChanged(self, event): sFit = Fit.getInstance() diff --git a/gui/commandView.py b/gui/commandView.py index 38dec46c9..d295c7939 100644 --- a/gui/commandView.py +++ b/gui/commandView.py @@ -25,6 +25,7 @@ import gui.globalEvents as GE import gui.droneView from gui.builtinViewColumns.state import State from gui.contextMenu import ContextMenu +from gui.builtinContextMenus.commandFits import CommandFits from service.fit import Fit from eos.saveddata.drone import Drone as es_Drone @@ -63,6 +64,7 @@ class CommandView(d.Display): self.lastFitId = None + self.mainFrame.Bind(GE.FIT_CHANGED, CommandFits.populateFits) self.mainFrame.Bind(GE.FIT_CHANGED, self.fitChanged) self.Bind(wx.EVT_LEFT_DOWN, self.click) self.Bind(wx.EVT_RIGHT_DOWN, self.click) @@ -194,13 +196,13 @@ class CommandView(d.Display): fitSrcContext = "commandFit" fitItemContext = item.name context = ((fitSrcContext, fitItemContext),) - context += ("command",), + context += ("commandView",), menu = ContextMenu.getMenu((item,), *context) elif sel == -1: fitID = self.mainFrame.getActiveFit() if fitID is None: return - context = (("command",),) + context = (("commandView",),) menu = ContextMenu.getMenu([], *context) if menu is not None: self.PopupMenu(menu) diff --git a/gui/contextMenu.py b/gui/contextMenu.py index a35c73282..adfeeb324 100644 --- a/gui/contextMenu.py +++ b/gui/contextMenu.py @@ -205,4 +205,5 @@ from gui.builtinContextMenus import ( # noqa: E402,F401 metaSwap, implantSets, fighterAbilities, + commandFits, ) diff --git a/service/fit.py b/service/fit.py index cbcbd7e4c..36170f1f8 100644 --- a/service/fit.py +++ b/service/fit.py @@ -97,15 +97,10 @@ class Fit(object): return names @staticmethod - def getBoosterFits(): + def getFitsWithModules(typeIDs): """ Lists fits flagged as booster """ - pyfalog.debug("Fetching all fits flagged as a booster.") - fits = eos.db.getBoosterFits() - names = [] - for fit in fits: - names.append((fit.ID, fit.name, fit.shipID)) - - return names + fits = eos.db.getFitsWithModules(typeIDs) + return fits @staticmethod def countAllFits():