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

structureEntryMyCorp.py (30813B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\structure\structureBrowser\entries\structureEntryMyCorp.py
      2 from collections import defaultdict
      3 import evetypes
      4 import gametime
      5 from carbon.common.lib.const import SEC
      6 from carbon.common.script.util.linkUtil import GetShowInfoLink
      7 from carbonui.primitives.container import Container
      8 import structures
      9 from carbon.common.script.util.commonutils import StripTags
     10 from carbon.common.script.util.format import FmtDate, FmtAmt
     11 from carbonui.primitives.sprite import Sprite
     12 from carbonui.util.sortUtil import SortListOfTuples
     13 from eve.client.script.ui.control.baseListEntry import BaseListEntryCustomColumns
     14 from eve.client.script.ui.control.eveEditPlainText import EditPlainText
     15 from carbonui.control.window import Window
     16 from eve.client.script.ui.control.gaugeCircular import GaugeCircular
     17 from eve.client.script.ui.structure.structureIcon import StructureIcon
     18 from eve.client.script.ui.control.eveLabel import Label, EveLabelSmall, EveLabelMedium
     19 from carbonui.fontconst import EVE_MEDIUM_FONTSIZE
     20 from eve.client.script.ui.station import stationServiceConst
     21 from eve.client.script.ui.station.stationServiceConst import UPWELL_STANDARD_SERVICES, serviceDataByNameID
     22 from eve.client.script.ui.structure import ChangeSignalConnect
     23 from eve.client.script.ui.structure.structureBrowser.browserUIConst import ALL_SERVICES
     24 from eve.client.script.ui.structure.structureBrowser.controllers.reinforceTimersBundle import GetDayAndHourText, ReinforcementBundle
     25 from eve.client.script.ui.structure.structureBrowser.controllers.structureEntryController import StructureEntryController
     26 from eve.client.script.ui.structure.structureBrowser.entries.structureEntry import StructureServiceIconMyCorp
     27 from eve.client.script.ui.structure.structureBrowser.structureState import StructureStateIcon
     28 from eve.common.script.sys.idCheckers import IsDockableStructure
     29 from eve.common.script.util.structuresCommon import MAX_STRUCTURE_BIO_LENGTH
     30 from eveservices.scheduling import GetSchedulingService
     31 import inventorycommon.const as invConst
     32 from globalConfig.getFunctions import IsContentComplianceControlSystemActive
     33 from localization import GetByLabel
     34 import carbonui.const as uiconst
     35 from localization.formatters import FormatTimeIntervalShortWritten
     36 from structures.types import IsFlexStructure, GetUnanchoringDuration
     37 from utillib import KeyVal
     38 import blue
     39 from carbonui.uicore import uicore
     40 from eveservices.menu import GetMenuService
     41 from menu import MenuLabel
     42 HEIGHT = 48
     43 ICONSIZE = 20
     44 LABEL_PARAMS = (EVE_MEDIUM_FONTSIZE, 0, 0)
     45 STATE_ICON_SIZE = 30
     46 UPKEEP_TEXTURE_PATH = 'res:/UI/Texture/classes/StructureBrowser/bolt.png'
     47 
     48 class StructureEntryMyCorp(BaseListEntryCustomColumns):
     49     default_name = 'StructureEntryMyCorp'
     50     isDragObject = True
     51 
     52     def ApplyAttributes(self, attributes):
     53         BaseListEntryCustomColumns.ApplyAttributes(self, attributes)
     54         self.controller = self.node.controller
     55         self.slimProfileController = self.node.slimProfileController
     56         self.ChangeSignalConnection(connect=True)
     57         self.BuildUI()
     58 
     59     def BuildUI(self):
     60         self.AddProfileNameColumn()
     61         self.stateColumn = self.AddColumnContainer()
     62         self.jumpColumnLabel = self.AddColumnText()
     63         self.securityColumnLabel = self.AddColumnText()
     64         self.nameColumn = self.AddColumnContainer()
     65         self.servicesColumn = self.AddColumnContainer()
     66         self.fuelColumnLabel = self.AddColumnText()
     67         self.reinforcementTimeColumn = self.AddColumnContainer()
     68         self.AddExtraColumns()
     69         self.LoadUI()
     70 
     71     def LoadUI(self):
     72         self.PopulateProfileNameColumn()
     73         self.PopulateStateColumn()
     74         self.PopulateJumpColumn()
     75         self.PopulateSecurityColumn()
     76         self.PopulateNameColumn()
     77         self.PopulateServicesColumn()
     78         self.PopulateReinforcementTimeColumn()
     79         self.PopulateFuelColumn()
     80         self.PopulateExtraColumns()
     81         if self.controller.IsUnanchoring():
     82             self.opacity = 0.4
     83 
     84     def ChangeSignalConnection(self, connect = True):
     85         signalAndCallback = [(self.controller.on_structure_state_changed, self.OnStructureStateChanged)]
     86         ChangeSignalConnect(signalAndCallback, connect)
     87 
     88     def AddProfileNameColumn(self):
     89         pass
     90 
     91     def AddExtraColumns(self):
     92         structureServicesChecked = self.node.structureServicesChecked
     93         if structureServicesChecked == ALL_SERVICES:
     94             return
     95         for serviceName in structureServicesChecked:
     96             serviceData = serviceDataByNameID.get(serviceName)
     97             if serviceData and serviceData.serviceID == structures.SERVICE_JUMP_BRIDGE:
     98                 columnLabel = self.AddColumnText()
     99                 variableName = StructureEntryMyCorp.GetColumnVariableName(serviceName)
    100                 setattr(self, variableName, columnLabel)
    101                 break
    102 
    103     def PopulateProfileNameColumn(self):
    104         pass
    105 
    106     def PopulateStateColumn(self):
    107         self.stateColumn.Flush()
    108         self.upkeepLowPowerSprite = Sprite(parent=self.stateColumn, align=uiconst.TOPRIGHT, texturePath=UPKEEP_TEXTURE_PATH, state=uiconst.UI_NORMAL, pos=(4, 6, 9, 9))
    109         self.upkeepLowPowerSprite.SetRGBA(1, 1, 0, 0.8)
    110         self.upkeepLowPowerSprite.hint = GetByLabel('UI/Structures/LowPowerStructureModeHint')
    111         self.upkeepLowPowerSprite.display = False
    112         self.upkeepLowPowerSprite.DelegateEvents(self)
    113         self.upkeepAbandonedSprite = Sprite(parent=self.stateColumn, align=uiconst.TOPRIGHT, texturePath=UPKEEP_TEXTURE_PATH, state=uiconst.UI_NORMAL, pos=(4, 6, 9, 9))
    114         self.upkeepAbandonedSprite.SetRGBA(1, 0, 0, 0.8)
    115         self.upkeepAbandonedSprite.hint = GetByLabel('UI/Structures/AbandonedStructureModeHint')
    116         self.upkeepAbandonedSprite.display = False
    117         self.upkeepAbandonedSprite.DelegateEvents(self)
    118         self.structureStateIcon = StructureStateIcon(parent=self.stateColumn)
    119         self.structureStateIcon.DelegateEvents(self)
    120         self.SetStructureState()
    121 
    122     def SetStructureState(self):
    123         if self.structureStateIcon:
    124             self.upkeepLowPowerSprite.display = self.controller.IsLowPower()
    125             self.upkeepAbandonedSprite.display = self.controller.IsAbandoned()
    126             structureState = self.controller.GetState()
    127             timerEnd = self.controller.GetTimerEnd()
    128             self.structureStateIcon.SetStructureState(structureState, timerEnd=timerEnd)
    129 
    130     def PopulateNameColumn(self):
    131         self.nameColumn.Flush()
    132         name = self.controller.GetName()
    133         if self.controller.IsLowPower():
    134             name += '<br><color=0xcfffff00>%s</color>' % GetByLabel('UI/Structures/UpkeepModeLowPower')
    135         elif self.controller.IsAbandoned():
    136             name += '<br><color=0xcfff0000>%s</color>' % GetByLabel('UI/Structures/UpkeepModeAbandoned')
    137         size = HEIGHT - 4
    138         itemIcon = StructureIcon(parent=self.nameColumn, align=uiconst.CENTERLEFT, typeID=self.controller.GetTypeID(), structureID=self.controller.GetItemID(), pos=(0,
    139          0,
    140          size,
    141          size), state=uiconst.UI_PICKCHILDREN, name='structureIcon_%s' % name.replace('<br>', '_'), wars=self.controller.GetWars())
    142         label = EveLabelMedium(parent=self.nameColumn, text=name, align=uiconst.CENTERLEFT, left=HEIGHT, state=uiconst.UI_NORMAL, lineSpacing=-0.2)
    143         label.GetMenu = None
    144         label.DelegateEventsNotImplemented(self)
    145         if self.controller.IsUnanchoring():
    146             timeUntilUnanchor = self._GetTimeUntilUnanchor()
    147             totalUnanchoringTime = GetUnanchoringDuration(self.controller.GetTypeID())
    148             gaugeCircular = GaugeCircular(name='gaugeCircular', parent=itemIcon, align=uiconst.CENTER, radius=16, lineWidth=4, value=1.0 - timeUntilUnanchor / float(totalUnanchoringTime * SEC), showMarker=False, idx=0, state=uiconst.UI_NORMAL, opacity=2.0)
    149             itemIcon.state = uiconst.UI_PICKCHILDREN
    150             gaugeCircular.gauge.state = uiconst.UI_DISABLED
    151             gaugeCircular.LoadTooltipPanel = self._LoadUnanchoringTooltipPanel
    152 
    153     def _LoadUnanchoringTooltipPanel(self, tooltipPanel, *args):
    154         tooltipPanel.LoadGeneric1ColumnTemplate()
    155         tooltipPanel.AddLabelMedium(text=GetByLabel('UI/Structures/Browser/StructureUnanchoring'))
    156         diff = self._GetTimeUntilUnanchor()
    157         fmtDiff = FormatTimeIntervalShortWritten(diff)
    158         tooltipPanel.AddLabelMedium(text=fmtDiff)
    159 
    160     def _GetTimeUntilUnanchor(self):
    161         unanchorTime = self.controller.GetUnanchorTime()
    162         now = gametime.GetWallclockTime()
    163         return max(0, unanchorTime - now)
    164 
    165     def PopulateServicesColumn(self):
    166         self.servicesColumn.Flush()
    167         availableServices, onlineStates = self.controller.GetServicesAndOnlineStatus()
    168         serviceData = stationServiceConst.serviceData
    169         basicServicesList = sorted([ '-%s' % x.label for x in UPWELL_STANDARD_SERVICES.itervalues() ])
    170         basicServicesList = ['%s:' % GetByLabel('UI/Structures/UpwellStandardServices')] + basicServicesList
    171         basicServicesHint = '<br>'.join(basicServicesList)
    172         s = StructureServiceIconMyCorp(name='upwellStandardServices', parent=self.servicesColumn, texturePath='res:/UI/Texture/WindowIcons/basicServices.png', pos=(0,
    173          0,
    174          ICONSIZE,
    175          ICONSIZE), hintHeader=basicServicesHint, opacity=0.1 if IsFlexStructure(self.controller.GetTypeID()) else 1.0, controller=self.controller, serviceID=-1, isOffline=False)
    176         s.DelegateEvents(self)
    177         left = ICONSIZE
    178         for i, data in enumerate(serviceData):
    179             if data.name in UPWELL_STANDARD_SERVICES:
    180                 continue
    181             isAvailable = self.IsThisServiceAvailable(data, availableServices)
    182             opacity = 1.0 if isAvailable else 0.1
    183             isOffline = onlineStates.get(data.serviceID, False) == structures.SERVICE_STATE_OFFLINE
    184             s = StructureServiceIconMyCorp(name=data.name, parent=self.servicesColumn, texturePath=data.iconID, pos=(left,
    185              0,
    186              ICONSIZE,
    187              ICONSIZE), hintHeader=data.label, opacity=opacity, serviceName=data.name, controller=self.controller, serviceID=data.serviceID, isOffline=isOffline)
    188             s.DelegateEvents(self)
    189             left += ICONSIZE
    190 
    191     def IsThisServiceAvailable(self, data, availableServices):
    192         if data in availableServices:
    193             return True
    194         if self.controller.GetTypeID() in structures.STRUCTURES_WITHOUT_ONLINE_SERVICES:
    195             return False
    196         return data.serviceID == stationServiceConst.serviceIDAlwaysPresent or data.serviceID in structures.ONLINE_SERVICES
    197 
    198     def PopulateJumpColumn(self):
    199         text = self.controller.GetNumJumpsText()
    200         self.jumpColumnLabel.text = text
    201         self.jumpColumnLabel.align = uiconst.CENTER
    202         self.jumpColumnLabel.left = 0
    203 
    204     def PopulateSecurityColumn(self):
    205         text = self.controller.GetSecurityWithColor()
    206         self.securityColumnLabel.text = text
    207         self.securityColumnLabel.align = uiconst.CENTER
    208         self.securityColumnLabel.left = 0
    209 
    210     def PopulateFuelColumn(self):
    211         fuelExpires = self.controller.GetFuelExpiry()
    212         if fuelExpires:
    213             text = FmtDate(fuelExpires - blue.os.GetWallclockTime(), 'ns')
    214         else:
    215             text = ''
    216         self.fuelColumnLabel.text = text
    217 
    218     def PopulateReinforcementTimeColumn(self):
    219         self.reinforcementTimeColumn.Flush()
    220         day, hour = self.controller.GetReinforcementTime()
    221         self.reinforcementTimeColumn.hint = ''
    222         dayText, hourText = GetDayAndHourText(day, hour)
    223         textList = [hourText]
    224         text = '<br>'.join(textList)
    225         label = Label(parent=self.reinforcementTimeColumn, text=text, align=uiconst.CENTERLEFT, left=6, state=uiconst.UI_DISABLED)
    226         nextDay, nextHour = self.controller.GetNextReinforcementTime()
    227         if None not in (nextDay, nextHour):
    228             texturePath = 'res:/UI/Texture/classes/StructureBrowser/notSameSchedule.png'
    229             hint = GetByLabel('UI/Structures/Browser/NotSameScheduleHint')
    230             diffSprite = Sprite(name='changeReinforceTime', parent=self.reinforcementTimeColumn, align=uiconst.CENTERRIGHT, pos=(2, 2, 16, 16), iconSize=16, texturePath=texturePath, opacity=0.75, hint=hint)
    231             diffSprite.DelegateEvents(self)
    232             self.reinforcementTimeColumn.state = uiconst.UI_NORMAL
    233             self.reinforcementTimeColumn.DelegateEvents(self)
    234             self.reinforcementTimeColumn.LoadTooltipPanel = self.ChangedReinforcementTimes
    235 
    236     def PopulateExtraColumns(self):
    237         structureServicesChecked = self.node.structureServicesChecked
    238         if structureServicesChecked == ALL_SERVICES:
    239             return
    240         for serviceName in structureServicesChecked:
    241             serviceData = serviceDataByNameID.get(serviceName)
    242             if serviceData and serviceData.serviceID == structures.SERVICE_JUMP_BRIDGE:
    243                 self._PopulateLiquidOzoneColumn(serviceName)
    244                 break
    245 
    246     def _PopulateLiquidOzoneColumn(self, serviceName):
    247         variableName = StructureEntryMyCorp.GetColumnVariableName(serviceName)
    248         columnLabel = getattr(self, variableName, None)
    249         if columnLabel:
    250             liquidOzone = self.controller.GetLiquidOzoneQty()
    251             if liquidOzone:
    252                 text = FmtAmt(liquidOzone)
    253             else:
    254                 text = ''
    255             columnLabel.align = uiconst.CENTERRIGHT
    256             columnLabel.text = text
    257 
    258     def ChangedReinforcementTimes(self, tooltipPanel, *args):
    259         tooltipPanel.LoadGeneric2ColumnTemplate()
    260         day, hour = self.controller.GetReinforcementTime()
    261         dayText, hourText = GetDayAndHourText(day, hour)
    262         tooltipPanel.AddLabelMedium(text=GetByLabel('UI/StructureBrowser/CurrentReinforcementTimes'), colSpan=tooltipPanel.columns, bold=True)
    263         if dayText:
    264             tooltipPanel.AddLabelMedium(text=GetByLabel('UI/StructureBrowser/ReinforcementWeekday'))
    265             tooltipPanel.AddLabelMedium(text=dayText)
    266             tooltipPanel.FillRow()
    267         tooltipPanel.AddLabelMedium(text=GetByLabel('UI/StructureBrowser/ReinforcementTime'))
    268         tooltipPanel.AddLabelMedium(text=hourText)
    269         tooltipPanel.FillRow()
    270         tooltipPanel.AddSpacer(height=10, colSpan=tooltipPanel.columns)
    271         nextDay, nextHour = self.controller.GetNextReinforcementTime()
    272         nextDayText, nextHourText = GetDayAndHourText(nextDay, nextHour)
    273         tooltipPanel.AddLabelMedium(text=GetByLabel('UI/StructureBrowser/PendingReinforcementTimes'), colSpan=tooltipPanel.columns, bold=True)
    274         if nextDayText:
    275             tooltipPanel.AddLabelMedium(text=GetByLabel('UI/StructureBrowser/ReinforcementWeekday'))
    276             tooltipPanel.AddLabelMedium(text=nextDayText)
    277             tooltipPanel.FillRow()
    278         tooltipPanel.AddLabelMedium(text=GetByLabel('UI/StructureBrowser/ReinforcementTime'))
    279         tooltipPanel.AddLabelMedium(text=nextHourText)
    280         tooltipPanel.FillRow()
    281         tooltipPanel.AddSpacer(height=10, colSpan=tooltipPanel.columns)
    282         nextApply = self.controller.GetGetNextApplyReinforcementTime()
    283         if nextApply < gametime.GetWallclockTime():
    284             text = GetByLabel('UI/StructureBrowser/ChangesArePending')
    285             tooltipPanel.AddLabelMedium(text=text, colSpan=tooltipPanel.columns)
    286         else:
    287             text = GetByLabel('UI/StructureBrowser/TakesEffect')
    288             date = FmtDate(nextApply)
    289             tooltipPanel.AddLabelMedium(text=text, colSpan=tooltipPanel.columns)
    290             tooltipPanel.AddLabelMedium(text=date, colSpan=tooltipPanel.columns)
    291 
    292     def GetDragData(self):
    293         nodesSelected = self.sr.node.scroll.GetSelectedNodes(self.sr.node)
    294         data = []
    295         for eachNode in nodesSelected:
    296             k = KeyVal(__guid__='xtriui.ListSurroundingsBtn', itemID=eachNode.controller.GetItemID(), typeID=eachNode.controller.GetTypeID(), label=StripTags(eachNode.controller.GetCleanName().replace('<br>', '-')), isMyCorpStructureEntry=True)
    297             data.append(k)
    298 
    299         return data
    300 
    301     def GetMenu(self):
    302         selectedNodes = self.sr.node.scroll.GetSelectedNodes(self.sr.node)
    303         numSelectedNodes = len(selectedNodes)
    304         itemID = self.controller.GetItemID()
    305         typeID = self.controller.GetTypeID()
    306         m = []
    307         if numSelectedNodes == 1:
    308             if self.controller.CanUnanchor():
    309                 m.append([MenuLabel('UI/StructureBrowser/Decommission'), sm.GetService('structureDeployment').Unanchor, [itemID, typeID]])
    310             elif self.controller.CanCancelUnanchor():
    311                 m.append([MenuLabel('UI/StructureBrowser/CancelDecommission'), sm.GetService('structureDeployment').CancelUnanchor, [itemID, typeID]])
    312             if session.corprole & const.corpRoleStationManager and not IsContentComplianceControlSystemActive(sm.GetService('machoNet')):
    313                 m.append([MenuLabel('UI/StructureBrowser/SetStructureDescription'), self.SetDescription, []])
    314             if itemID == session.shipid and self.IsSchedulingAvailableOption(typeID, itemID):
    315                 m.append([GetByLabel('UI/Moonmining/OpenSchedulingWnd'), self.OpenSchedulingWindow, [itemID]])
    316         m += self._GetReinforcementTimeOptions(selectedNodes)
    317         if numSelectedNodes > 1:
    318             setProfileMenu = MenuLabel('UI/StructureBrowser/SetProfileMany', {'numSelected': numSelectedNodes})
    319         else:
    320             setProfileMenu = MenuLabel('UI/StructureBrowser/SetProfile')
    321             m += GetMenuService().GetMenuFromItemIDTypeID(itemID=itemID, typeID=typeID)
    322         m += [[setProfileMenu, ('isDynamic', self._GetProfilesMenu, (selectedNodes,))]]
    323         return m
    324 
    325     def IsSchedulingAvailableOption(self, structureTypeID, structureID):
    326         if evetypes.GetGroupID(structureTypeID) != invConst.groupStructureDrillingPlatform:
    327             return False
    328         return bool(sm.GetService('structureSettings').CharacterHasService(structureID, structures.SERVICE_MOONMINING))
    329 
    330     def OpenSchedulingWindow(self, itemID, *args):
    331         GetSchedulingService().OpenSchedulingWndForStructure(itemID)
    332 
    333     def _GetReinforcementTimeOptions(self, selectedNodes):
    334         nonDockableStructureControllers = [ x.controller for x in selectedNodes if not IsDockableStructure(x.controller.GetTypeID()) ]
    335         dockableStructureControllers = [ x.controller for x in selectedNodes if IsDockableStructure(x.controller.GetTypeID()) ]
    336         addPostfix = bool(nonDockableStructureControllers and nonDockableStructureControllers)
    337         singleLabelPath = 'UI/StructureBrowser/SetReinforcementTime'
    338         controllerGroups = [(dockableStructureControllers, 'UI/StructureBrowser/SetReinforcementTimeDockable' if addPostfix else singleLabelPath), (nonDockableStructureControllers, 'UI/StructureBrowser/SetReinforcementTimeNonDockable' if addPostfix else singleLabelPath)]
    339         m = []
    340         for selectedControllers, menuLabelPath in controllerGroups:
    341             if not selectedControllers:
    342                 continue
    343             day, hour = GetMostFrequentReinforcementTime(selectedControllers)
    344             nDay, nHour, nextApplies, changedStructures = GetNextReinforcementTimes(selectedControllers)
    345             doAllStructuresHavePendingChanges = len(selectedControllers) == len(changedStructures)
    346             hour = hour if hour is not None else structures.DEFAULT_REINFORCE_HOUR
    347             day = day if day is not None else structures.DEFAULT_REINFORCE_WEEKDAY
    348             reinforceTimers = ReinforcementBundle(reinforceWeekday=day, reinforceHour=hour, nextReinforceWeekday=nDay, nextReinforceHour=nHour, nextReinforceApply=nextApplies)
    349             menuLabel = MenuLabel(menuLabelPath)
    350             infoOnStructures = [ (x.GetItemID(), x.GetSolarSystemID(), x.GetTypeID()) for x in selectedControllers ]
    351             funcArgs = (infoOnStructures,
    352              reinforceTimers,
    353              changedStructures,
    354              doAllStructuresHavePendingChanges)
    355             m += [(menuLabel, self.SetReinforcementTime, funcArgs)]
    356 
    357         return m
    358 
    359     def _GetProfilesMenu(self, selectedNodes):
    360         selectedStructureIDs = [ x.controller.GetItemID() for x in selectedNodes ]
    361         allStructureProfileController = sm.GetService('structureControllers').GetAllStructuresProfileController()
    362         allCorpProfiles = allStructureProfileController.GetProfiles()
    363 
    364         def UpdateProfileIDForStructures(profileID):
    365             allStructureProfileController.UpdateProfileIDForStructures(profileID, selectedStructureIDs)
    366 
    367         m = []
    368         for profileID, profileController in allCorpProfiles.iteritems():
    369             name = profileController.GetProfileName()
    370             m.append((name.lower(), (name, UpdateProfileIDForStructures, (profileID,))))
    371 
    372         m = SortListOfTuples(m)
    373         return m
    374 
    375     def SetDescription(self, *args):
    376         itemID = self.controller.GetItemID()
    377         structureName = GetShowInfoLink(self.controller.GetTypeID(), cfg.evelocations.Get(itemID).name, itemID)
    378         desc = sm.RemoteSvc('structureDirectory').GetStructureDescription(itemID)
    379         wnd = SetStrucureDescriptionWnd.Open(windowID='setStructureDescription_%s' % itemID, structureID=itemID, currentName=structureName, currentDesc=desc)
    380 
    381     def SetReinforcementTime(self, infoOnStructures, reinforceTimers, changedStructures, doAllStructuresHavePendingChanges):
    382         from eve.client.script.ui.structure.structureBrowser.reinforcementTimeWnd import ReinforcementTimeWnd
    383         wnd = ReinforcementTimeWnd.GetIfOpen()
    384         if wnd and not wnd.destroyed:
    385             wnd.LoadInfo(infoOnStructures, reinforceTimers, changedStructures, doAllStructuresHavePendingChanges)
    386             wnd.Maximize()
    387         else:
    388             ReinforcementTimeWnd.Open(infoOnStructures=infoOnStructures, reinforceTimers=reinforceTimers, changedStructures=changedStructures, doAllStructuresHavePendingChanges=doAllStructuresHavePendingChanges)
    389 
    390     def OnStructureStateChanged(self, structureID):
    391         self.LoadUI()
    392 
    393     def Close(self):
    394         self.ChangeSignalConnection(connect=False)
    395         BaseListEntryCustomColumns.Close(self)
    396 
    397     @staticmethod
    398     def GetColumnSortValues(controller, slimProfileController, structureServicesChecked):
    399         ret = ((controller.GetState(), controller.IsLowPower()),
    400          controller.GetNumJumps(),
    401          controller.GetSecurity(),
    402          '%s %s ' % (controller.GetSystemName(), StripTags(controller.GetName()).lower()),
    403          len(controller.GetServices()),
    404          controller.GetFuelExpiry(),
    405          controller.GetReinforcementTime())
    406         if structureServicesChecked != ALL_SERVICES:
    407             for serviceName in structureServicesChecked:
    408                 serviceData = serviceDataByNameID.get(serviceName)
    409                 if serviceData and serviceData.serviceID == structures.SERVICE_JUMP_BRIDGE:
    410                     ret = ret + (controller.GetLiquidOzoneQty(),)
    411                     break
    412 
    413         return ret
    414 
    415     @staticmethod
    416     def GetSortValue(node, by, sortDirection, idx):
    417         return (node.columnSortValues[idx],) + tuple(node.columnSortValues)
    418 
    419     @staticmethod
    420     def GetHeaders(structureServicesChecked):
    421         extraHeaders = StructureEntryMyCorp.GetExtraHeaders(structureServicesChecked)
    422         return [GetByLabel('UI/Structures/Browser/HeaderState'),
    423          GetByLabel('UI/Common/Jumps'),
    424          GetByLabel('UI/Common/Security'),
    425          GetByLabel('UI/Common/Name'),
    426          GetByLabel('UI/Structures/Browser/HeaderServices'),
    427          GetByLabel('UI/Structures/Browser/HeaderFuel'),
    428          GetByLabel('UI/Structures/Browser/HeaderReinforcementTime')] + extraHeaders
    429 
    430     @staticmethod
    431     def GetExtraHeaders(structureServicesChecked):
    432         extraHeaders = []
    433         if structureServicesChecked == ALL_SERVICES:
    434             return []
    435         for serviceName in structureServicesChecked:
    436             serviceData = serviceDataByNameID.get(serviceName)
    437             if serviceData and serviceData.serviceID == structures.SERVICE_JUMP_BRIDGE:
    438                 extraHeaders += StructureEntryMyCorp._GetLiquidOzoneHeader()
    439                 break
    440 
    441         return extraHeaders
    442 
    443     @staticmethod
    444     def _GetLiquidOzoneHeader():
    445         header = evetypes.GetName(invConst.typeLiquidOzone)
    446         return [header]
    447 
    448     @staticmethod
    449     def GetDynamicHeight(node, width):
    450         return HEIGHT
    451 
    452     @staticmethod
    453     def GetFixedColumns():
    454         numServices = len({x for x in stationServiceConst.serviceData if x.name not in UPWELL_STANDARD_SERVICES})
    455         numServices += 1
    456         return {GetByLabel('UI/Structures/Browser/HeaderServices'): ICONSIZE * numServices + 2}
    457 
    458     @staticmethod
    459     def GetColWidths(node, idx = None):
    460         controller = node.controller
    461         widths = []
    462         getAllWidths = idx is None
    463         if getAllWidths or idx == 0:
    464             widths.append(STATE_ICON_SIZE + 10)
    465         if getAllWidths or idx == 1:
    466             jumpText = unicode(controller.GetNumJumpsText())
    467             widths.append(uicore.font.MeasureTabstops([(jumpText,) + LABEL_PARAMS])[0])
    468         if getAllWidths or idx == 2:
    469             securityText = unicode(controller.GetSecurity())
    470             widths.append(uicore.font.MeasureTabstops([(securityText,) + LABEL_PARAMS])[0])
    471         if getAllWidths or idx == 3:
    472             nameToUse = max(StripTags(controller.GetName(), ignoredTags=('br',)).split('<br>'), key=len)
    473             widths.append(uicore.font.MeasureTabstops([(nameToUse,) + LABEL_PARAMS])[0] + HEIGHT - 4)
    474         return widths
    475 
    476     @staticmethod
    477     def GetColumnVariableName(serviceName):
    478         return 'column_%s' % serviceName
    479 
    480 
    481 class StructureEntryMyCorpAllProfiles(StructureEntryMyCorp):
    482 
    483     def AddProfileNameColumn(self):
    484         self.profileNameColumnLabel = self.AddColumnText()
    485 
    486     def PopulateProfileNameColumn(self):
    487         profileName = self._GetProfileName(self.slimProfileController)
    488         self.profileNameColumnLabel.text = profileName
    489 
    490     @staticmethod
    491     def _GetProfileName(slimProfileController):
    492         if slimProfileController:
    493             profileName = slimProfileController.GetProfileName()
    494         else:
    495             profileName = ''
    496         return profileName
    497 
    498     @staticmethod
    499     def GetColumnSortValues(controller, slimProfileController, structureServicesChecked):
    500         baseSortValues = StructureEntryMyCorp.GetColumnSortValues(controller, slimProfileController, structureServicesChecked)
    501         return (StructureEntryMyCorpAllProfiles._GetProfileName(slimProfileController).lower(),) + baseSortValues
    502 
    503     @staticmethod
    504     def GetHeaders(structureServicesChecked):
    505         baseHeaders = StructureEntryMyCorp.GetHeaders(structureServicesChecked)
    506         return [GetByLabel('UI/Structures/Browser/HeaderProfileName')] + baseHeaders
    507 
    508     @staticmethod
    509     def GetColWidths(node, idx = None):
    510         widths = []
    511         getAllWidths = idx is None
    512         if getAllWidths or idx == 0:
    513             profileName = StructureEntryMyCorpAllProfiles._GetProfileName(node.slimProfileController)
    514             widths.append(uicore.font.MeasureTabstops([(profileName,) + LABEL_PARAMS])[0])
    515         if getAllWidths:
    516             widths += StructureEntryMyCorp.GetColWidths(node, idx)
    517         elif idx > 0:
    518             widths += StructureEntryMyCorp.GetColWidths(node, idx - 1)
    519         return widths
    520 
    521 
    522 class SetStrucureDescriptionWnd(Window):
    523     __guid__ = 'SetStrucureDescriptionWnd'
    524     default_width = 400
    525     default_height = 350
    526     default_minSize = (300, 200)
    527     default_windowID = 'setStructureDescription'
    528     default_maxLength = MAX_STRUCTURE_BIO_LENGTH
    529     default_captionLabelPath = 'UI/StructureBrowser/SetStructureDescription'
    530 
    531     def ApplyAttributes(self, attributes):
    532         Window.ApplyAttributes(self, attributes)
    533         self.structureID = attributes.structureID
    534         self.currentDesc = attributes.get('currentDesc', '')
    535         currentName = attributes.get('currentName', '')
    536         self.DefineButtons(uiconst.OKCANCEL, okFunc=self.Confirm, cancelFunc=self.Cancel)
    537         self.maxLength = attributes.get('maxLength', self.default_maxLength)
    538         self.ConstructLayout()
    539         self.SetText(currentName, self.currentDesc)
    540 
    541     def SetText(self, structureName, desc):
    542         self.structureNameLabel.text = structureName
    543         self.descField.SetValue(desc)
    544 
    545     def ConstructLayout(self):
    546         cont = Container(parent=self.sr.main, align=uiconst.TOALL, pos=(const.defaultPadding,
    547          0,
    548          const.defaultPadding,
    549          0))
    550         self.structureNameLabel = EveLabelMedium(name='structureName', parent=cont, text='', align=uiconst.TOTOP, top=6, padLeft=4, state=uiconst.UI_NORMAL)
    551         EveLabelSmall(name='titleHeader', parent=cont, text=GetByLabel('UI/InfoWindow/TabNames/Description'), align=uiconst.TOTOP, top=6, padLeft=4)
    552         self.descField = EditPlainText(parent=cont, padding=(4, 2, 4, 4), maxLength=self.maxLength, showattributepanel=True)
    553 
    554     def Confirm(self, *args):
    555         newDesc = self.descField.GetValue()
    556         newDesc.strip()
    557         if newDesc != self.currentDesc:
    558             sm.RemoteSvc('structureDirectory').SetStructureDescription(self.structureID, newDesc)
    559         self.Close()
    560 
    561     def Cancel(self, *args):
    562         self.CloseByUser()
    563 
    564 
    565 def GetMostFrequentReinforcementTime(controllers):
    566     controllersByReinforcementTime = defaultdict(int)
    567     for eachController in controllers:
    568         reinforcementTime = eachController.GetReinforcementTime()
    569         if reinforcementTime != (None, None):
    570             controllersByReinforcementTime[reinforcementTime] += 1
    571 
    572     day = hour = None
    573     if controllersByReinforcementTime:
    574         day, hour = max(controllersByReinforcementTime.iterkeys(), key=lambda k: controllersByReinforcementTime[k])
    575     return (day, hour)
    576 
    577 
    578 def GetNextReinforcementTimes(controllers):
    579     controllersByNewReinforcementTime = defaultdict(set)
    580     for eachController in controllers:
    581         nextReinforcementTime = eachController.GetNextReinforcementTime()
    582         if nextReinforcementTime != (None, None):
    583             nextApply = eachController.GetGetNextApplyReinforcementTime()
    584             key = nextReinforcementTime + (nextApply,)
    585             controllersByNewReinforcementTime[key].add((eachController.GetItemID(), eachController.GetTypeID()))
    586 
    587     day = hour = applyDate = None
    588     if not controllersByNewReinforcementTime:
    589         return (day,
    590          hour,
    591          applyDate,
    592          set())
    593     if len(controllersByNewReinforcementTime) == 1:
    594         day, hour, applyDate = controllersByNewReinforcementTime.keys()[0]
    595     structuresWithChangedReinforcementTimes = set.union(*controllersByNewReinforcementTime.values())
    596     return (day,
    597      hour,
    598      applyDate,
    599      structuresWithChangedReinforcementTimes)