NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

treeData.py (27598B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\inventory\treeData.py
      2 from carbon.common.lib import telemetry
      3 from carbon.common.script.util.format import FmtDist
      4 from eve.client.script.environment import invControllers as invCtrl
      5 from eve.client.script.ui.control.treeData import TreeData
      6 from eve.client.script.ui.plex.textures import PLEX_32_GRADIENT_YELLOW
      7 from eve.client.script.ui.shared.inventory.invCommon import CONTAINERGROUPS, SortData
      8 import evetypes
      9 from eve.common.script.sys import eveCfg
     10 from eveexceptions import UserError
     11 from inventorycommon.const import INVENTORY_ID_PLEX_VAULT
     12 from inventorycommon.util import IsModularShip
     13 import localization
     14 from eve.client.script.ui.util import uix
     15 from eve.common.lib import appConst as const
     16 from carbonui.uicore import uicore
     17 from eveservices.menu import GetMenuService
     18 from eve.common.script.sys.idCheckers import IsDockableStructure, IsAutoMoonMiner
     19 from locks import SingletonCall
     20 from caching.memoize import Memoize
     21 import eve.client.script.ui.shared.inventory.invConst as invDef
     22 from eve.client.script.ui.shared.inventory.invConst import ContainerType
     23 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     24 NO_DISTANCE_SHOWN = ['POSCorpHangar',
     25  'POSStrontiumBay',
     26  'POSFuelBay',
     27  'POSStructureChargesStorage',
     28  'POSStructureChargeCrystal',
     29  'StructureCorpHangar',
     30  INVENTORY_ID_PLEX_VAULT]
     31 
     32 class TreeDataInv(TreeData):
     33 
     34     def __init__(self, invType, parent = None, children = None, label = None, isRemovable = False, cmdName = None, iconName = None, **kw):
     35         TreeData.__init__(self, parent=parent, children=children, label=label, isRemovable=isRemovable, **kw)
     36         self.invType = invType
     37         self.cmdName = cmdName
     38         self.iconName = iconName
     39         self.uiName = invType
     40         self.invController = invDef.GetInventoryControllerClass(invType)(**kw)
     41 
     42     @property
     43     def clsName(self):
     44         return self.invType
     45 
     46     @telemetry.ZONE_METHOD
     47     def GetLabel(self):
     48         if self._label:
     49             return self._label
     50         else:
     51             return self.invController.GetName()
     52 
     53     @telemetry.ZONE_METHOD
     54     def GetLabelWithDistance(self):
     55         label = self.GetLabel()
     56         if self.clsName in NO_DISTANCE_SHOWN or self.invController.itemID == eveCfg.GetActiveShip():
     57             return label
     58         if session.solarsystemid:
     59             ball = sm.GetService('michelle').GetBall(self.invController.itemID)
     60             if ball:
     61                 dist = FmtDist(ball.surfaceDist, 1)
     62                 return '%s <color=#66FFFFFF>%s</color>' % (label, dist)
     63         return label
     64 
     65     def GetIcon(self):
     66         if self.iconName:
     67             return self.iconName
     68         return self.invController.GetIconName()
     69 
     70     def GetMenu(self):
     71         m = self.invController.GetMenu()
     72         if self.invController.IsInRange():
     73             m += [(localization.GetByLabel('UI/Inventory/OpenInNewWindow'), self.OpenNewWindow, ())]
     74         return m
     75 
     76     def GetHint(self):
     77         if self.cmdName:
     78             shortcut = uicore.cmd.GetShortcutStringByFuncName(self.cmdName)
     79             if shortcut:
     80                 return localization.GetByLabel('UI/Inventory/ShortcutBrackets', shortcut=shortcut)
     81 
     82     def GetID(self):
     83         return self.invController.GetInvID()
     84 
     85     def GetItemID(self):
     86         return self.invController.itemID
     87 
     88     def GetInvCont(self, **kw):
     89         kw.update(self._kw)
     90         return invDef.GetInventoryContainerClass(self.invType)(**kw)
     91 
     92     def HasInvCont(self):
     93         return True
     94 
     95     def OpenNewWindow(self, openDragging = False):
     96         from eve.client.script.ui.shared.inventory.invWindow import Inventory
     97         invID = self.GetID()
     98         windowID = invID[0]
     99         if len(invID) == 3:
    100             windowID = '%s_%s' % (invID[0], invID[2])
    101             windowInstanceID = '%s_%s' % (invID[1], invID[2])
    102         else:
    103             windowInstanceID = invID[1]
    104         return Inventory.OpenOrShow(invID=invID, usePrimary=False, toggle=True, openDragging=openDragging, windowID=windowID, windowInstanceID=windowInstanceID, **self._kw)
    105 
    106     def IsForceCollapsed(self):
    107         return not self.invController.IsPrimed()
    108 
    109     def IsDraggable(self):
    110         return self.invController.IsInRange()
    111 
    112     def CheckCanQuery(self):
    113         if self.clsName == 'StationContainer':
    114             return self.GetParent().CheckCanTake()
    115         return self.invController.CheckCanQuery()
    116 
    117     def CheckCanTake(self):
    118         return self.invController.CheckCanTake()
    119 
    120     def IsValidDefaultSelection(self):
    121         return True
    122 
    123 
    124 class TreeDataPlasticWrap(TreeDataInv):
    125 
    126     def GetChildren(self):
    127         data = GetContainerDataFromItems(self.invController.GetItems(), parent=self)
    128         if not data:
    129             data = [TreeData(parent=self, label=localization.GetByLabel('UI/Inventory/NoNestedContainers'), id='none_%s' % self.invController.itemID)]
    130         return data
    131 
    132     def HasChildren(self):
    133         return True
    134 
    135 
    136 def GetSharedBayHint(invController):
    137     if invController.itemID != eveCfg.GetActiveShip():
    138         hint = cfg.evelocations.Get(invController.itemID).name
    139         ownerID = invController.GetOwnerID()
    140         if ownerID:
    141             hint += '<br>%s' % cfg.eveowners.Get(ownerID).name
    142         return hint
    143 
    144 
    145 class TreeDataFleetHangar(TreeDataInv):
    146 
    147     def GetChildren(self):
    148         return GetContainerDataFromItems(self.invController.GetItems(), parent=self)
    149 
    150     def HasChildren(self):
    151         try:
    152             for item in self.invController.GetItems():
    153                 if item.groupID in CONTAINERGROUPS:
    154                     return True
    155 
    156         except UserError as e:
    157             if e.msg in ('CantViewShipContainer', 'CantViewShipContainerSpace'):
    158                 prompt_player_fsd_dialog(e.msg, e.dict)
    159             else:
    160                 raise
    161 
    162         return False
    163 
    164     def GetHint(self):
    165         return GetSharedBayHint(self.invController)
    166 
    167 
    168 class TreeDataShipMaintenanceBay(TreeDataInv):
    169 
    170     def GetHint(self):
    171         return GetSharedBayHint(self.invController)
    172 
    173 
    174 class TreeDataCelestialParent(TreeDataInv):
    175 
    176     def HasInvCont(self, **kw):
    177         return False
    178 
    179     def IsForceCollapsed(self):
    180         return False
    181 
    182 
    183 class TreeDataInvFolder(TreeData):
    184 
    185     def OpenNewWindow(self, openDragging = False):
    186         from eve.client.script.ui.shared.inventory.invWindow import Inventory
    187         return Inventory.OpenOrShow(invID=self.GetID(), usePrimary=False, toggle=True, openDragging=openDragging, iconNum=self.GetIcon(), **self._kw)
    188 
    189     def GetMenu(self):
    190         return [(localization.GetByLabel('UI/Inventory/OpenInNewWindow'), self.OpenNewWindow, ())]
    191 
    192     def HasChildren(self):
    193         return True
    194 
    195     @telemetry.ZONE_METHOD
    196     def GetLabelWithDistance(self):
    197         return self.GetLabel()
    198 
    199     def IsDraggable(self):
    200         return True
    201 
    202 
    203 class TreeDataPOSCorp(TreeDataInvFolder):
    204 
    205     def __init__(self, slimItem, **kw):
    206         TreeData.__init__(self, **kw)
    207         self.slimItem = slimItem
    208         self.invController = invCtrl.POSCorpHangar(self.slimItem.itemID)
    209 
    210     @telemetry.ZONE_METHOD
    211     def GetLabel(self):
    212         return uix.GetSlimItemName(self.slimItem)
    213 
    214     @telemetry.ZONE_METHOD
    215     def GetLabelWithDistance(self):
    216         label = self.GetLabel()
    217         bp = sm.GetService('michelle').GetBallpark()
    218         ball = bp.GetBall(self.invController.itemID)
    219         if not ball:
    220             return label
    221         dist = FmtDist(ball.surfaceDist, 1)
    222         return '%s <color=#66FFFFFF>%s</color>' % (label, dist)
    223 
    224     def GetIcon(self):
    225         return 'res:/ui/Texture/WindowIcons/corporation.png'
    226 
    227     def GetItemID(self):
    228         return self.slimItem.itemID
    229 
    230     def GetID(self):
    231         return ('POSCorpHangars', self.slimItem.itemID)
    232 
    233     def GetMenu(self):
    234         m = TreeDataInvFolder.GetMenu(self)
    235         m += GetMenuService().GetMenuFromItemIDTypeID(self.slimItem.itemID, self.slimItem.typeID)
    236         return m
    237 
    238     def GetChildren(self):
    239         data = []
    240         itemID = self.slimItem.itemID
    241         for flagID in const.flagCorpSAGs:
    242             divisionID = const.corpDivisionsByFlag[flagID]
    243             data.append(TreeDataInv(parent=self, invType=ContainerType.POS_CORP_HANGAR, itemID=itemID, divisionID=divisionID))
    244 
    245         return data
    246 
    247     def IsDraggable(self):
    248         return self.invController.IsInRange()
    249 
    250 
    251 class TreeDataShip(TreeDataInv):
    252 
    253     def __init__(self, invType, typeID, **kw):
    254         TreeDataInv.__init__(self, invType, **kw)
    255         self.uiName = 'ShipHangar'
    256         self.typeID = typeID
    257 
    258     @telemetry.ZONE_METHOD
    259     def GetLabel(self):
    260         shipName = TreeDataInv.GetLabel(self)
    261         return localization.GetByLabel('UI/Inventory/ShipNameAndType', shipName=shipName, typeName=evetypes.GetName(self.typeID))
    262 
    263     def GetHint(self):
    264         hint = TreeDataInv.GetHint(self)
    265         typeName = evetypes.GetName(self.typeID)
    266         if hint:
    267             return typeName + hint
    268         else:
    269             return typeName
    270 
    271     def HasChildren(self):
    272         return True
    273 
    274     def IsForceCollapsed(self):
    275         if self.invController.itemID == eveCfg.GetActiveShip():
    276             return False
    277         return TreeDataInv.IsForceCollapsed(self)
    278 
    279     def GetIcon(self):
    280         return self.invController.GetIconName(highliteIfActive=True)
    281 
    282     def GetChildren(self):
    283         shipData = []
    284         itemID = self.invController.itemID
    285         typeID = self.typeID
    286         if itemID == eveCfg.GetActiveShip():
    287             cmdName = 'OpenDroneBayOfActiveShip'
    288         else:
    289             cmdName = None
    290         godmaType = sm.GetService('godma').GetType(typeID)
    291         if godmaType.droneCapacity or IsModularShip(typeID):
    292             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_DRONE_BAY, itemID=itemID, cmdName=cmdName))
    293         if godmaType.fighterCapacity:
    294             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_FIGHTER_BAY, itemID=itemID, cmdName=cmdName))
    295         godmaSM = sm.GetService('godma').GetStateManager()
    296         if bool(godmaSM.GetType(typeID).hasShipMaintenanceBay):
    297             shipData.append(TreeDataShipMaintenanceBay(parent=self, invType=ContainerType.SHIP_MAINTENANCE_BAY, itemID=itemID))
    298         if bool(godmaSM.GetType(typeID).frigateEscapeBayCapacity):
    299             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_FRIGATE_ESCAPE_BAY, itemID=itemID))
    300         if bool(godmaSM.GetType(typeID).hasFleetHangars):
    301             shipData.append(TreeDataFleetHangar(parent=self, invType=ContainerType.SHIP_FLEET_HANGAR, itemID=itemID))
    302         if bool(godmaSM.GetType(typeID).specialFuelBayCapacity):
    303             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_FUEL_BAY, itemID=itemID))
    304         if bool(godmaSM.GetType(typeID).generalMiningHoldCapacity):
    305             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_GENERAL_MINING_HOLD, itemID=itemID))
    306         if bool(godmaSM.GetType(typeID).specialAsteroidHoldCapacity):
    307             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_ASTEROID_HOLD, itemID=itemID))
    308         if bool(godmaSM.GetType(typeID).specialIceHoldCapacity):
    309             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_ICE_HOLD, itemID=itemID))
    310         if bool(godmaSM.GetType(typeID).specialGasHoldCapacity):
    311             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_GAS_HOLD, itemID=itemID))
    312         if bool(godmaSM.GetType(typeID).specialMineralHoldCapacity):
    313             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_MINERAL_HOLD, itemID=itemID))
    314         if bool(godmaSM.GetType(typeID).specialSalvageHoldCapacity):
    315             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_SALVAGE_HOLD, itemID=itemID))
    316         if bool(godmaSM.GetType(typeID).specialShipHoldCapacity):
    317             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_SHIP_HOLD, itemID=itemID))
    318         if bool(godmaSM.GetType(typeID).specialSmallShipHoldCapacity):
    319             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_SMALL_SHIP_HOLD, itemID=itemID))
    320         if bool(godmaSM.GetType(typeID).specialMediumShipHoldCapacity):
    321             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_MEDIUM_SHIP_HOLD, itemID=itemID))
    322         if bool(godmaSM.GetType(typeID).specialLargeShipHoldCapacity):
    323             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_LARGE_SHIP_HOLD, itemID=itemID))
    324         if bool(godmaSM.GetType(typeID).specialIndustrialShipHoldCapacity):
    325             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_INDUSTRIAL_SHIP_HOLD, itemID=itemID))
    326         if bool(godmaSM.GetType(typeID).specialAmmoHoldCapacity):
    327             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_AMMO_HOLD, itemID=itemID))
    328         if bool(godmaSM.GetType(typeID).specialCommandCenterHoldCapacity):
    329             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_COMMAND_CENTER_HOLD, itemID=itemID))
    330         if bool(godmaSM.GetType(typeID).specialPlanetaryCommoditiesHoldCapacity):
    331             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_PLANETARY_COMMODITIES_HOLD, itemID=itemID))
    332         if bool(godmaSM.GetType(typeID).specialQuafeHoldCapacity):
    333             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_QUAFE_HOLD, itemID=itemID))
    334         if bool(godmaSM.GetType(typeID).specialCorpseHoldCapacity):
    335             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_CORPSE_HOLD, itemID=itemID))
    336         if bool(godmaSM.GetType(typeID).specialBoosterHoldCapacity):
    337             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_BOOSTER_HOLD, itemID=itemID))
    338         if bool(godmaSM.GetType(typeID).specialSubsystemHoldCapacity):
    339             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_SUBSYSTEM_HOLD, itemID=itemID))
    340         if bool(godmaSM.GetType(typeID).specialMobileDepotHoldCapacity):
    341             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_MOBILE_DEPOT_HOLD, itemID=itemID))
    342         if bool(godmaSM.GetType(typeID).specialColonyResourcesHoldCapacity):
    343             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_COLONY_RESOURCES_HOLD, itemID=itemID))
    344         if bool(godmaSM.GetType(typeID).specialExpeditionHoldCapacity):
    345             shipData.append(TreeDataInv(parent=self, invType=ContainerType.SHIP_EXPEDITION_HOLD, itemID=itemID))
    346         invController = invCtrl.ShipCargo(itemID=itemID)
    347         shipData += GetContainerDataFromItems(invController.GetItems(), parent=self)
    348         if not shipData:
    349             shipData.append(TreeData(parent=self, label=localization.GetByLabel('UI/Inventory/NoAdditionalBays'), id='none_%s' % itemID))
    350         return shipData
    351 
    352 
    353 class TreeDataStructure(TreeDataInvFolder):
    354 
    355     def __init__(self, *args, **kwargs):
    356         invType = kwargs.pop('invType')
    357         self.invController = invDef.GetInventoryControllerClass(invType)(**kwargs)
    358         self.itemID = kwargs.pop('itemID')
    359         self.typeID = kwargs.pop('typeID')
    360         TreeDataInvFolder.__init__(self, *args, **kwargs)
    361 
    362     def HasInvCont(self):
    363         return False
    364 
    365     def HasChildren(self):
    366         return True
    367 
    368     def GetLabel(self):
    369         return self.invController.GetName()
    370 
    371     @Memoize(1 / 60.0)
    372     @SingletonCall
    373     def GetChildren(self):
    374         children = []
    375         isDockableStructure = IsDockableStructure(self.typeID)
    376         if isDockableStructure:
    377             children.append(TreeDataInv(parent=self, invType=ContainerType.STRUCTURE_AMMO_BAY, itemID=self.invController.itemID))
    378             godmaType = sm.GetService('godma').GetType(self.typeID)
    379             if godmaType.fighterCapacity:
    380                 children.append(TreeDataInv(parent=self, invType=ContainerType.STRUCTURE_FIGHTER_BAY, itemID=self.invController.itemID))
    381         children.append(TreeDataInv(parent=self, invType=ContainerType.STRUCTURE_FUEL_BAY, itemID=self.invController.itemID))
    382         if isDockableStructure:
    383             children.append(TreeDataInv(parent=self, invType=ContainerType.STRUCTURE_DEED_BAY, itemID=self.invController.itemID))
    384         if IsAutoMoonMiner(self.typeID):
    385             children.append(TreeDataInv(parent=self, invType=ContainerType.STRUCTURE_MOON_MATERIAL_BAY, itemID=self.invController.itemID))
    386         if isDockableStructure:
    387             children += GetContainerDataFromItems(self.invController.GetItems(), parent=self)
    388         return children
    389 
    390     def GetIcon(self):
    391         return self.invController.GetIconName()
    392 
    393     def GetID(self):
    394         return ('Structure', self.itemID)
    395 
    396 
    397 class TreeDataStationCorp(TreeDataInvFolder):
    398 
    399     def __init__(self, forceCollapsed = True, forceCollapsedMembers = True, *args):
    400         self.itemID = sm.GetService('officeManager').GetCorpOfficeAtLocation().officeID
    401         self.forceCollapsedMembers = forceCollapsedMembers
    402         self.forceCollapsed = forceCollapsed
    403         TreeDataInvFolder.__init__(self, *args)
    404 
    405     def GetChildren(self):
    406         if self._children:
    407             return self._children
    408         corpData = []
    409         for flagID in sorted(const.corpDivisionsByFlag.keys()):
    410             divID = const.corpDivisionsByFlag[flagID]
    411             invController = invCtrl.StationCorpHangar(self.itemID, divID)
    412             divData = []
    413             for item in invController.GetItems():
    414                 if item.groupID in CONTAINERGROUPS and item.singleton:
    415                     divData.append(TreeDataInv(invType=ContainerType.STATION_CONTAINER, itemID=item.itemID, typeID=item.typeID))
    416 
    417             cfg.evelocations.Prime([ d.invController.itemID for d in divData ])
    418             SortData(divData)
    419             corpData.append(TreeDataInv(parent=self, invType=ContainerType.STATION_CORP_HANGAR, itemID=self.itemID, divisionID=divID, children=divData))
    420 
    421         securityOfficerRoles = session.corprole & const.corpRoleSecurityOfficer == const.corpRoleSecurityOfficer
    422         if securityOfficerRoles:
    423             memberData = sm.GetService('corpui').GetMemberHangarsData().keys()
    424             cfg.eveowners.Prime([ member[1] for member in memberData ])
    425             corpData.append(TreeDataCorpMembers(parent=self, memberData=memberData, groupChildren=True, forceCollapsed=self.forceCollapsedMembers))
    426         self._children = corpData
    427         return corpData
    428 
    429     def HasChildren(self):
    430         return True
    431 
    432     def IsForceCollapsed(self):
    433         if self._children or not self.forceCollapsed:
    434             return False
    435         invController = invCtrl.StationCorpHangar(self.itemID, 0)
    436         return not invController.IsPrimed()
    437 
    438     def GetIcon(self):
    439         return 'res:/ui/Texture/WindowIcons/corpHangar.png'
    440 
    441     @telemetry.ZONE_METHOD
    442     def GetLabel(self):
    443         return localization.GetByLabel('UI/Inventory/CorporationHangars')
    444 
    445     def GetID(self):
    446         return ('StationCorpHangars', self.itemID)
    447 
    448 
    449 class TreeDataShipHangar(TreeDataInv):
    450 
    451     def HasChildren(self):
    452         return True
    453 
    454     def GetChildren(self):
    455         children = []
    456         activeShipID = eveCfg.GetActiveShip()
    457         singletonShips = [ ship for ship in self.invController.GetItems() if ship.singleton == 1 and ship.itemID != activeShipID ]
    458         cfg.evelocations.Prime([ ship.itemID for ship in singletonShips ])
    459         for ship in singletonShips:
    460             children.append(TreeDataShip(parent=self, invType=ContainerType.SHIP_CARGO, itemID=ship.itemID, typeID=ship.typeID))
    461 
    462         SortData(children)
    463         return children
    464 
    465     def GetLabelWithDistance(self):
    466         return self.GetLabel()
    467 
    468 
    469 class TreeDataItemHangar(TreeDataInv):
    470 
    471     def __init__(self, invType, **kw):
    472         super(TreeDataItemHangar, self).__init__(invType, **kw)
    473         self.uiName = 'ItemHangar'
    474 
    475     def HasChildren(self):
    476         for item in self.invController.GetItems():
    477             if item.groupID in CONTAINERGROUPS:
    478                 return True
    479 
    480         return False
    481 
    482     def GetChildren(self):
    483         return GetContainerDataFromItems(self.invController.GetItems(), parent=self)
    484 
    485     def GetLabelWithDistance(self):
    486         return self.GetLabel()
    487 
    488 
    489 class TreeDataStructureCorp(TreeDataInvFolder):
    490 
    491     def __init__(self, *args, **kwargs):
    492         self.itemID = kwargs.pop('itemID')
    493         TreeDataInvFolder.__init__(self, *args, **kwargs)
    494 
    495     def GetChildren(self):
    496         if not self._children:
    497             children = []
    498             for flagID in const.flagCorpSAGs:
    499                 divisionID = const.corpDivisionsByFlag[flagID]
    500                 controller = invCtrl.StructureCorpHangar(self.itemID, divisionID)
    501                 data = GetContainerDataFromItems(controller.GetItems(), parent=self)
    502                 children.append(TreeDataInv(parent=self, invType=ContainerType.STRUCTURE_CORP_HANGAR, itemID=self.itemID, divisionID=divisionID, children=data))
    503 
    504             self._children = children
    505         return self._children
    506 
    507     def HasChildren(self):
    508         return True
    509 
    510     def IsForceCollapsed(self):
    511         return False
    512 
    513     def GetIcon(self):
    514         return 'res:/ui/Texture/WindowIcons/corpHangar.png'
    515 
    516     def GetLabel(self):
    517         return localization.GetByLabel('UI/Inventory/CorporationHangars')
    518 
    519     def GetID(self):
    520         return ('StructureCorpHangars', self.itemID)
    521 
    522 
    523 class TreeDataCorpAssetSafety(TreeDataStructureCorp):
    524 
    525     def __init__(self, *args, **kwargs):
    526         self.name = kwargs.pop('name')
    527         TreeDataStructureCorp.__init__(self, *args, **kwargs)
    528 
    529     def GetChildren(self):
    530         if not self._children:
    531             children = []
    532             controller = invCtrl.AssetSafetyCorpContainer(self.itemID, None)
    533             items = controller.GetItems()
    534             divisions = {const.corpAssetSafetyFlags[item.flagID] for item in items}
    535             for division in sorted(list(divisions)):
    536                 filteredItems = [ item for item in items if const.corpAssetSafetyFlags[item.flagID] == division ]
    537                 data = GetContainerDataFromItems(filteredItems, parent=self)
    538                 children.append(TreeDataInv(parent=self, invType=ContainerType.ASSET_SAFETY_CORP_CONTAINER, itemID=self.itemID, divisionID=division, children=data))
    539 
    540             self._children = children
    541         return self._children
    542 
    543     def HasInvCont(self):
    544         return True
    545 
    546     def IsForceCollapsed(self):
    547         return False
    548 
    549     def GetLabel(self):
    550         return self.name
    551 
    552 
    553 class TreeDataAssetSafety(TreeDataInv):
    554 
    555     def __init__(self, *args, **kw):
    556         kw.setdefault('invType', ContainerType.ASSET_SAFETY_DELIVERIES)
    557         TreeDataInv.__init__(self, *args, **kw)
    558 
    559     def GetLabel(self):
    560         return localization.GetByLabel('UI/Inventory/AssetSafety/AssetSafetyDeliveries')
    561 
    562     def HasChildren(self):
    563         return True
    564 
    565     def HasInvCont(self):
    566         return True
    567 
    568     def IsForceCollapsed(self):
    569         return False
    570 
    571     def GetChildren(self):
    572         items = self.invController.GetItems()
    573         if not items:
    574             self._children = []
    575             return []
    576         if self._children:
    577             return self._children
    578         data = []
    579         names = sm.GetService('assetSafety').GetWrapNames([ item.itemID for item in items ])
    580         for item in items:
    581             itemID = item.itemID
    582             if item.typeID != const.typeAssetSafetyWrap:
    583                 raise RuntimeError('There is something in the asset safety that is not a assetSafetyWrap', itemID, item.typeID)
    584             if item.ownerID == session.corpid:
    585                 data.append(TreeDataCorpAssetSafety(parent=self, itemID=itemID, name=names[itemID]))
    586             else:
    587                 data.append(TreeDataInv(parent=self, invType=ContainerType.ASSET_SAFETY_CONTAINER, itemID=itemID, typeID=item.typeID, name=names[itemID]))
    588 
    589         cfg.evelocations.Prime([ item.itemID for item in items ])
    590         SortData(data)
    591         self._children = data
    592         return data
    593 
    594     def GetLabelWithDistance(self):
    595         return self.GetLabel()
    596 
    597 
    598 class TreeDataCorpMembers(TreeDataInvFolder):
    599 
    600     def __init__(self, memberData, groupChildren = False, label = None, forceCollapsed = True, *args, **kw):
    601         if label is None:
    602             label = localization.GetByLabel('UI/Inventory/MemberHangars')
    603         self.memberData = memberData
    604         self.groupChildren = groupChildren
    605         self.memberData.sort(key=lambda x: cfg.eveowners.Get(x[0]).name.lower())
    606         self.forceCollapsed = forceCollapsed
    607         TreeData.__init__(self, label=label, *args, **kw)
    608 
    609     def GetID(self):
    610         return ('StationCorpMembers', self.GetLabel())
    611 
    612     def GetChildren(self):
    613         if self._children:
    614             return self._children
    615         data = []
    616         maxNumPerLevel = 50
    617         numMembers = len(self.memberData)
    618         if not self.groupChildren or numMembers <= maxNumPerLevel:
    619             for itemID, ownerID in self.memberData:
    620                 if itemID == session.charid:
    621                     continue
    622                 if itemID == ownerID:
    623                     data.append(TreeDataInv(parent=self, invType=ContainerType.STATION_CORP_MEMBER, itemID=itemID, ownerID=ownerID))
    624 
    625         else:
    626             currLetter = None
    627             levelData = []
    628             for itemID, ownerID in self.memberData:
    629                 letter = cfg.eveowners.Get(ownerID).name[0].upper()
    630                 if letter != currLetter:
    631                     if levelData:
    632                         data.append(TreeDataCorpMembers(label=currLetter, memberData=levelData))
    633                     currLetter = letter
    634                     levelData = []
    635                 levelData.append((itemID, ownerID))
    636 
    637             if levelData:
    638                 data.append(TreeDataCorpMembers(label=currLetter, memberData=levelData))
    639         if not data:
    640             data.append(TreeData(label=localization.GetByLabel('UI/Inventory/NoCorpHangars')))
    641         self.forceCollapsed = False
    642         self._children = data
    643         return data
    644 
    645     def IsForceCollapsed(self):
    646         return self.forceCollapsed
    647 
    648     def GetIcon(self):
    649         return 'res:/ui/Texture/WindowIcons/corporationmembers.png'
    650 
    651 
    652 class TreeDataPlexVault(TreeDataInv):
    653 
    654     def __init__(self, **kwargs):
    655         kwargs['invType'] = ContainerType.PLEX_VAULT
    656         super(TreeDataPlexVault, self).__init__(**kwargs)
    657 
    658     def GetLabel(self):
    659         return localization.GetByLabel('UI/PlexVault/PlexVault')
    660 
    661     def GetIcon(self):
    662         return PLEX_32_GRADIENT_YELLOW
    663 
    664     def IsValidDefaultSelection(self):
    665         return False
    666 
    667 
    668 def GetContainerDataFromItems(items, parent = None):
    669     data = []
    670     for item in items:
    671         if item.typeID == const.typePlasticWrap and item.singleton:
    672             data.append(TreeDataPlasticWrap(parent=parent, invType=ContainerType.STATION_CONTAINER, itemID=item.itemID, typeID=item.typeID))
    673         elif item.groupID in CONTAINERGROUPS and item.singleton:
    674             data.append(TreeDataInv(parent=parent, invType=ContainerType.STATION_CONTAINER, itemID=item.itemID, typeID=item.typeID))
    675         elif item.typeID == const.typeAssetSafetyWrap:
    676             data.append(TreeDataInv(parent=parent, invType=ContainerType.ASSET_SAFETY_CONTAINER, itemID=item.itemID, typeID=item.typeID))
    677 
    678     cfg.evelocations.Prime([ d.invController.itemID for d in data ])
    679     SortData(data)
    680     return data
    681 
    682 
    683 def GetTreeDataClassByInvName(invName):
    684     if invName == 'ShipFleetHangar':
    685         return TreeDataFleetHangar
    686     elif invName == 'ShipMaintenanceBay':
    687         return TreeDataShipMaintenanceBay
    688     else:
    689         return TreeDataInv