From 543089bcd9e5d58e6b5ded043a3cddb214fd0db3 Mon Sep 17 00:00:00 2001 From: DarkPhoenix Date: Mon, 6 Apr 2020 22:20:28 +0300 Subject: [PATCH] Add context menu support for predefined implant sets --- db_update.py | 2 + eos/db/gamedata/queries.py | 9 -- gui/builtinAdditionPanes/implantView.py | 4 +- gui/builtinContextMenus/implantSetApply.py | 95 +++++++++++++++---- .../targetProfile/adder.py | 6 +- gui/characterEditor.py | 4 +- service/precalcImplantSet.py | 62 ++++++++++++ 7 files changed, 146 insertions(+), 36 deletions(-) create mode 100644 service/precalcImplantSet.py diff --git a/db_update.py b/db_update.py index 0c517324f..e6a4d83e1 100644 --- a/db_update.py +++ b/db_update.py @@ -484,6 +484,8 @@ def update_db(): break data = [] for (gradeName, setName), implants in implantSets.items(): + if len(implants) < 2: + continue implants = ','.join('{}'.format(tid) for tid in sorted(implants)) row = {'setName': setName, 'gradeName': gradeName, 'implants': implants} data.append(row) diff --git a/eos/db/gamedata/queries.py b/eos/db/gamedata/queries.py index cfad61d3d..9b3865844 100644 --- a/eos/db/gamedata/queries.py +++ b/eos/db/gamedata/queries.py @@ -426,15 +426,6 @@ def getDynamicItem(itemID, eager=None): return result -@cachedQuery(1, "lookfor") -def getImplantSet(lookfor): - if isinstance(lookfor, int): - implantSet = gamedata_session.query(ImplantSet).get(lookfor) - else: - raise TypeError("Need integer as argument") - return implantSet - - @cachedQuery(1, "lookfor") def getAllImplantSets(): implantSets = gamedata_session.query(ImplantSet).all() diff --git a/gui/builtinAdditionPanes/implantView.py b/gui/builtinAdditionPanes/implantView.py index 30768247a..967d1aaef 100644 --- a/gui/builtinAdditionPanes/implantView.py +++ b/gui/builtinAdditionPanes/implantView.py @@ -316,7 +316,7 @@ class ImplantDisplay(d.Display): implants.append(implant) return implants - def addImplantSet(self, impSet): + def addImplants(self, implants): self.mainFrame.command.Submit(cmd.GuiAddImplantSetCommand( fitID=self.mainFrame.getActiveFit(), - itemIDs=[i.itemID for i in impSet.implants])) + itemIDs=[i.itemID for i in implants])) diff --git a/gui/builtinContextMenus/implantSetApply.py b/gui/builtinContextMenus/implantSetApply.py index 5cc15b18a..477aaa200 100644 --- a/gui/builtinContextMenus/implantSetApply.py +++ b/gui/builtinContextMenus/implantSetApply.py @@ -2,17 +2,19 @@ import wx from gui.contextMenu import ContextMenuUnconditional -from service.implantSet import ImplantSets as s_ImplantSets +from service.market import Market +from service.implantSet import ImplantSets as UserImplantSets +from service.precalcImplantSet import PrecalcedImplantSets class ImplantSetApply(ContextMenuUnconditional): def display(self, callingWindow, srcContext): - sIS = s_ImplantSets.getInstance() - implantSets = sIS.getImplantSetList() + self.userImplantSets = UserImplantSets.getInstance().getImplantSetList() + self.structedImplantSets = PrecalcedImplantSets.getStructuredSets() - if len(implantSets) == 0: + if len(self.userImplantSets) == 0 and len(self.structedImplantSets) == 0: return False return srcContext in ("implantItemMisc", "implantEditor") @@ -20,34 +22,87 @@ class ImplantSetApply(ContextMenuUnconditional): def getText(self, callingWindow, context): return "Apply Implant Set" - def getSubMenu(self, callingWindow, context, rootMenu, i, pitem): - m = wx.Menu() - bindmenu = rootMenu if "wxMSW" in wx.PlatformInfo else m + def _addSeparator(self, m, text): + id_ = ContextMenuUnconditional.nextID() + m.Append(id_, '─ %s ─' % text) + m.Enable(id_, False) - sIS = s_ImplantSets.getInstance() - implantSets = sIS.getImplantSetList() + def _addSet(self, parentMenu, profile, name): + id = ContextMenuUnconditional.nextID() + self.eventSetMap[id] = profile + menuItem = wx.MenuItem(parentMenu, id, name) + parentMenu.Bind(wx.EVT_MENU, self.handleSelection, menuItem) + return menuItem + + def _addCategory(self, parentMenu, name): + id = ContextMenuUnconditional.nextID() + menuItem = wx.MenuItem(parentMenu, id, name) + parentMenu.Bind(wx.EVT_MENU, self.handleSelection, menuItem) + return menuItem + + def _gradeSorter(self, item): + order = ['low-grade', 'mid-grade', 'high-grade'] + try: + pos = order.index(item.lower()) + except IndexError: + pos = len(order) + return pos, item + + def getSubMenu(self, callingWindow, context, rootMenu, i, pitem): + msw = "wxMSW" in wx.PlatformInfo + menu_lvl1 = wx.Menu() self.context = context self.callingWindow = callingWindow - self.idmap = {} + self.eventSetMap = {} - for set in sorted(implantSets, key=lambda i: i.name): - id = ContextMenuUnconditional.nextID() - mitem = wx.MenuItem(rootMenu, id, set.name) - bindmenu.Bind(wx.EVT_MENU, self.handleSelection, mitem) - self.idmap[id] = set - m.Append(mitem) + # Auto-generated sets + for setName in sorted(self.structedImplantSets): + setData = self.structedImplantSets[setName] + if len(setData) == 1: + for implantIDs in setData.values(): + menuitem_lvl1 = self._addSet(rootMenu, implantIDs, setName) + menu_lvl1.Append(menuitem_lvl1) + else: + menuitem_lvl1 = self._addCategory(rootMenu, setName) + menu_lvl2 = wx.Menu() + for gradeName in sorted(setData, key=self._gradeSorter): + implantIDs = setData[gradeName] + menuitem_lvl2 = self._addSet(rootMenu if msw else menu_lvl1, implantIDs, gradeName) + menu_lvl2.Append(menuitem_lvl2) + menu_lvl2.Bind(wx.EVT_MENU, self.handleSelection) + menuitem_lvl1.SetSubMenu(menu_lvl2) + menu_lvl1.Append(menuitem_lvl1) - return m + # Separator + if self.userImplantSets and self.structedImplantSets: + menu_lvl1.AppendSeparator() + + # Saved sets + if self.userImplantSets: + menuitem_lvl1 = self._addCategory(rootMenu, 'Saved Sets') + menu_lvl2 = wx.Menu() + for implantSet in sorted(self.userImplantSets, key=lambda i: i.name): + menuitem_lvl2 = self._addSet(rootMenu if msw else menu_lvl1, implantSet, implantSet.name) + menu_lvl2.Append(menuitem_lvl2) + menu_lvl2.Bind(wx.EVT_MENU, self.handleSelection) + menuitem_lvl1.SetSubMenu(menu_lvl2) + menu_lvl1.Append(menuitem_lvl1) + + menu_lvl1.Bind(wx.EVT_MENU, self.handleSelection) + return menu_lvl1 def handleSelection(self, event): - impSet = self.idmap.get(event.Id, None) + impSet = self.eventSetMap.get(event.Id, None) if impSet is None: event.Skip() return - - self.callingWindow.addImplantSet(impSet) + if isinstance(impSet, str): + implants = PrecalcedImplantSets.stringToImplants(impSet) + else: + implants = impSet.implants + self.callingWindow.addImplants(implants) ImplantSetApply.register() diff --git a/gui/builtinContextMenus/targetProfile/adder.py b/gui/builtinContextMenus/targetProfile/adder.py index 4292a8f98..9bb185736 100644 --- a/gui/builtinContextMenus/targetProfile/adder.py +++ b/gui/builtinContextMenus/targetProfile/adder.py @@ -26,7 +26,7 @@ class TargetProfileAdder(ContextMenuUnconditional): return 'Add Target Profile' def handleProfileAdd(self, event): - profile = self.profileEventMap.get(event.Id, False) + profile = self.eventProfileMap.get(event.Id, False) if profile is False: event.Skip() return @@ -34,7 +34,7 @@ class TargetProfileAdder(ContextMenuUnconditional): def _addProfile(self, parentMenu, profile, name): id = ContextMenuUnconditional.nextID() - self.profileEventMap[id] = profile + self.eventProfileMap[id] = profile menuItem = wx.MenuItem(parentMenu, id, name) parentMenu.Bind(wx.EVT_MENU, self.handleProfileAdd, menuItem) return menuItem @@ -51,7 +51,7 @@ class TargetProfileAdder(ContextMenuUnconditional): profiles = list(chain(sTR.getBuiltinTargetProfileList(), sTR.getUserTargetProfileList())) profiles.sort(key=lambda p: smartSort(p.fullName)) - self.profileEventMap = {} + self.eventProfileMap = {} items = (OrderedDict(), OrderedDict()) for profile in profiles: container = items diff --git a/gui/characterEditor.py b/gui/characterEditor.py index ddff34bdb..44701081b 100644 --- a/gui/characterEditor.py +++ b/gui/characterEditor.py @@ -729,12 +729,12 @@ class ImplantEditorView(BaseImplantEditorView): sChar.removeImplant(char.ID, implant) - def addImplantSet(self, impSet): + def addImplants(self, implants): charEditor = self.Parent.Parent char = charEditor.entityEditor.getActiveEntity() sChar = Character.getInstance() - for implant in impSet.implants: + for implant in implants: sChar.addImplant(char.ID, implant.item.ID) wx.PostEvent(charEditor, GE.CharChanged()) diff --git a/service/precalcImplantSet.py b/service/precalcImplantSet.py new file mode 100644 index 000000000..9f90bc51b --- /dev/null +++ b/service/precalcImplantSet.py @@ -0,0 +1,62 @@ +# ============================================================================= +# Copyright (C) 2010 Diego Duclos +# +# This file is part of pyfa. +# +# pyfa is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# pyfa is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with pyfa. If not, see . +# ============================================================================= + + +import eos.db +from eos.db.saveddata.implant import Implant + +from service.market import Market + + +class PrecalcedImplantSets: + instance = None + + @classmethod + def getInstance(cls): + if cls.instance is None: + cls.instance = PrecalcedImplantSets() + return cls.instance + + @staticmethod + def getImplantSets(): + return eos.db.getAllImplantSets() + + @staticmethod + def getStructuredSets(): + structured = {} + for implantSet in PrecalcedImplantSets.getImplantSets(): + structured.setdefault(implantSet.setName, {})[implantSet.gradeName] = implantSet.implants + return structured + + @staticmethod + def stringToImplants(string): + sMkt = Market.getInstance() + implants = [] + for typeID in (int(tid) for tid in string.split(',')): + item = sMkt.getItem(typeID) + if item is None: + continue + try: + implant = Implant(item) + except ValueError: + continue + implants.append(implant) + return implants + +