contractsDetailsWnd.py (53515B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\neocom\contracts\contractsDetailsWnd.py 2 from collections import defaultdict 3 import eveformat 4 import dogma.data as dogma_data 5 import evetypes 6 import log 7 import utillib 8 from brennivin.itertoolsext import Bundle 9 from carbon.common.script.util.format import FmtAmt, FmtDate 10 from carbonui import const as uiconst 11 from carbonui.primitives.container import Container 12 from carbonui.primitives.line import Line 13 from eve.client.script.ui.control import eveEdit, eveIcon, eveLabel, eveScroll 14 from carbonui.button.group import ButtonGroup, ButtonSizeMode 15 from eve.client.script.ui.control.entries.item import Item 16 from eve.client.script.ui.control.entries.util import GetFromClass 17 from carbonui.control.window import Window 18 from eve.client.script.ui.control.infoIcon import InfoIcon 19 from eve.client.script.ui.control.itemIcon import ItemIcon 20 from eve.client.script.ui.control.themeColored import SpriteThemeColored 21 from eve.client.script.ui.shared.neocom.contracts.contractDraggableIcon import ContractDraggableIcon 22 from eve.client.script.util.contractutils import GetContractIcon, ConFmtDate, FmtISKWithDescription, COL_GET, COL_PAY, CategoryName, GetCorpseName 23 from eve.common.lib import appConst as const 24 from eve.common.script.sys import eveCfg, idCheckers 25 from eve.common.script.sys.idCheckers import IsNPC 26 from eve.common.script.util import contractscommon 27 from eve.common.script.sys.eveCfg import GetShipFlagLocationName 28 import blue 29 import localization 30 from eve.common.script.util.contractscommon import IsPlayerAllowedToRejectContract 31 from eve.common.script.util.eveFormat import FmtISK 32 from eveexceptions import UserError 33 from eveformat.client import solar_system_security_status 34 from eveservices.menu import GetMenuService 35 from localization import GetByLabel 36 from menu import MenuLabel 37 from player_messaging.client.ui_message import prompt_player_fsd_dialog 38 BCancel = 0 39 BAccept = 1 40 BReject = 2 41 BComplete = 3 42 BDelete = 4 43 BSucceed = 5 44 BFail = 6 45 BGetItems = 7 46 BGetMoney = 8 47 BAcceptForCorp = 9 48 BPlaceBid = 10 49 HISTORY_LENGTH = 10 50 51 class ContractDetailsWindow(Window): 52 __guid__ = 'form.ContractDetailsWindow' 53 default_windowID = 'contractdetails' 54 55 def ApplyAttributes(self, attributes): 56 Window.ApplyAttributes(self, attributes) 57 contractID = attributes.contractID 58 self.contract = None 59 self.buttons = [] 60 self.isContractMgr = False 61 self.contractID = contractID 62 self.sr.main.clipChildren = True 63 self.sr.main.padRight = const.defaultPadding 64 self.scope = uiconst.SCOPE_INGAME 65 self.SetCaption(GetByLabel('UI/Common/Contract') % {'name': '-'}) 66 self.LoadTabs() 67 self.icon = GetContractIcon(const.conTypeNothing) 68 self.SetMinSize([520, 200]) 69 self.MakeUnstackable() 70 self.MakeUncollapseable() 71 self.history = settings.user.ui.Get('contracts_history', []) 72 self.state = uiconst.UI_HIDDEN 73 self.pathfinder = sm.GetService('clientPathfinderService') 74 self.Init() 75 76 def Init(self): 77 self.corpseNameLabel = None 78 self.sr.main.Flush() 79 topParent = Container(name='topParent', parent=self.GetMainArea(), align=uiconst.TOTOP, height=52, clipChildren=True) 80 SpriteThemeColored(name='mainicon', parent=topParent, state=uiconst.UI_DISABLED, pos=(0, -5, 64, 64), texturePath=self.iconNum, colorType=uiconst.COLORTYPE_UIHILIGHTGLOW) 81 self.buttons = [] 82 contract = sm.GetService('contracts').GetContract(self.contractID, force=True) 83 if not contract: 84 self.HistoryRemove(self.contractID) 85 self.Close() 86 raise UserError('ConContractNotFound') 87 self.contract = contract 88 c = contract.contract 89 self.contractID = c.contractID 90 self.isContractMgr = isContractMgr = session.corprole & const.corpRoleContractManager == const.corpRoleContractManager 91 canRejectContract = IsPlayerAllowedToRejectContract(c, session.charid, session.corpid, session.allianceid, session.corprole) 92 isAssignedToMePersonally = c.assigneeID == session.charid 93 isAcceptedByMe = c.acceptorID == session.charid or c.acceptorID == session.corpid and isContractMgr 94 isAcceptedByMyCorp = c.acceptorID == session.corpid 95 isIssuedByMe = c.issuerID == session.charid or c.issuerCorpID == session.corpid and c.forCorp and isContractMgr 96 isIssuedByMePersonally = c.issuerID == session.charid 97 isExpired = c.dateExpired < blue.os.GetWallclockTime() 98 isOverdue = c.dateAccepted + const.DAY * c.numDays < blue.os.GetWallclockTime() 99 title = GetByLabel('UI/Contracts/ContractsService/ContractTitleAndType', contractTitle=contractscommon.GetContractTitle(c, contract.items), contractType=contractscommon.GetContractTypeText(c.type)) 100 self.icon = GetContractIcon(c.type) 101 icon = ContractDraggableIcon(name='theicon', align=uiconst.TOPLEFT, parent=self, height=64, width=64, left=0, top=11) 102 icon.Startup(c, title) 103 icon.state = uiconst.UI_NORMAL 104 Container(name='push', parent=self.sr.main, align=uiconst.TOLEFT, width=6) 105 Container(name='push', parent=self.sr.main, align=uiconst.TORIGHT, width=6) 106 titleParent = Container(name='titleparent', parent=topParent, align=uiconst.TOPLEFT, top=12, left=70, width=430) 107 l = eveLabel.EveLabelLarge(text=title, parent=titleParent, width=400, state=uiconst.UI_DISABLED) 108 titleParent.height = l.textheight + 2 * const.defaultPadding 109 self.HistoryAdd(self.contractID, c.startSolarSystemID, title) 110 text = GetBasicInfoText(c) 111 tabs = [115, 480] 112 basicInfoParent = Container(name='infocontainer', parent=self.sr.main, align=uiconst.TOTOP, padRight=const.defaultPadding) 113 basicInfo = eveLabel.EveLabelMedium(text=text, parent=basicInfoParent, top=const.defaultPadding, idx=0, tabs=tabs, state=uiconst.UI_NORMAL, left=6) 114 basicInfoParent.height = basicInfo.textheight + 5 115 Line(parent=basicInfoParent, align=uiconst.TOTOP) 116 isResizable = False 117 if c.status == const.conStatusInProgress: 118 if isAcceptedByMe: 119 if c.type != 4: 120 self.AddButton(BComplete) 121 self.AddButton(BFail) 122 elif isIssuedByMe and isOverdue: 123 self.AddButton(BFail) 124 elif isAcceptedByMyCorp and c.type == const.conTypeCourier: 125 self.AddButton(BComplete) 126 if c.type == const.conTypeAuction: 127 text = '' 128 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/StartingBid'), FmtISKWithDescription(c.price)) 129 bo = [GetByLabel('UI/Contracts/ContractEntry/NoneParen'), FmtISKWithDescription(c.collateral)][c.collateral > 0] 130 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/BuyoutPrice'), bo) 131 b = GetByLabel('UI/Contracts/ContractEntry/NoBids') 132 if len(contract.bids) > 0: 133 b = GetByLabel('UI/Contracts/ContractsWindow/BidsSoFar', numISK=FmtISKWithDescription(contract.bids[0].amount), numBids=len(contract.bids)) 134 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/CurrentBid'), b) 135 timeleft = GetByLabel('UI/Contracts/ContractsWindow/Finished') 136 if c.status == const.conStatusOutstanding: 137 diff = c.dateExpired - blue.os.GetWallclockTime() 138 if c.dateExpired - blue.os.GetWallclockTime() > 0: 139 timeleft = ConFmtDate(diff, True) 140 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/TimeLeft'), timeleft) 141 isExpired = c.dateExpired < blue.os.GetWallclockTime() 142 isCancelled = c.status == const.conStatusCancelled 143 highBidder = None 144 if len(contract.bids) > 0: 145 highBidder = contract.bids[0].bidderID 146 if not isCancelled: 147 if session.charid == highBidder: 148 if isExpired: 149 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YouWon') 150 else: 151 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YouAreHighBidder') 152 boldStr = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=strToBold) 153 rowInfo = '<color=%s>%s</color>' % (COL_GET, boldStr) 154 text += AddBasicInfoRow('', rowInfo) 155 elif session.corpid == highBidder: 156 if isExpired: 157 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YourCorpWon') 158 else: 159 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YourCorpHighBidder') 160 boldStr = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=strToBold) 161 rowInfo = '<color=%s>%s</color>' % (COL_GET, boldStr) 162 text += AddBasicInfoRow('', rowInfo) 163 else: 164 for i in range(len(contract.bids)): 165 b = contract.bids[i] 166 if i != 0: 167 if b.bidderID == session.charid: 168 if isExpired: 169 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YouLost') 170 else: 171 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YouHaveBeenOutBid') 172 boldStr = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=strToBold) 173 rowInfo = '<color=%s>%s</color>' % (COL_PAY, boldStr) 174 text += AddBasicInfoRow('', rowInfo) 175 elif b.bidderID == session.corpid: 176 if isExpired: 177 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YourCorpLost') 178 else: 179 strToBold = GetByLabel('UI/Contracts/ContractsWindow/YourCorpWasOutBid') 180 boldStr = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=strToBold) 181 rowInfo = '<color=%s>%s</color>' % (COL_PAY, boldStr) 182 text += AddBasicInfoRow('', rowInfo) 183 break 184 185 if isExpired and len(contract.bids) > 0: 186 winner = cfg.eveowners.Get(contract.bids[0].bidderID) 187 showInfoLink = GetByLabel('UI/Contracts/ContractsWindow/ShowInfoLinkWithMore', showInfoName=winner.ownerName, info=('showinfo', winner.typeID, winner.ownerID), more=GetByLabel('UI/Contracts/ContractsWindow/WonThisAuction')) 188 text += AddBasicInfoRow('', showInfoLink) 189 infoParent = Container(name='infocontainer', parent=self.sr.main, align=uiconst.TOTOP, width=const.defaultPadding) 190 info = eveLabel.EveLabelMedium(text=text, parent=infoParent, top=const.defaultPadding, idx=0, tabs=tabs, state=uiconst.UI_NORMAL, left=6) 191 infoParent.height = info.textheight + 2 * const.defaultPadding 192 Line(parent=infoParent, align=uiconst.TOTOP) 193 Line(parent=infoParent, align=uiconst.TOBOTTOM) 194 isResizable = self.InsertItemList(contract, '<color=%s>%s</color>' % (COL_GET, [GetByLabel('UI/Contracts/ContractsWindow/YouWillGet'), GetByLabel('UI/Contracts/ContractsWindow/BuyerWillGet')][session.charid == c.issuerID]), True, 3) 195 if len(contract.bids) > 0 and isExpired and not isCancelled: 196 if c.status != const.conStatusFinishedIssuer and c.status != const.conStatusFinished and isIssuedByMe: 197 self.AddButton(BGetMoney) 198 if c.status != const.conStatusFinishedContractor and c.status != const.conStatusFinished and (contract.bids[0].bidderID == session.charid or contract.bids[0].bidderID == session.corpid and isContractMgr): 199 self.AddButton(BGetItems) 200 if isIssuedByMe and not isCancelled: 201 if (c.status == const.conStatusOutstanding or c.status == const.conStatusRejected) and len(contract.bids) == 0: 202 self.AddButton(BDelete) 203 if not isIssuedByMePersonally and c.status == const.conStatusOutstanding: 204 if not isExpired: 205 self.AddButton(BPlaceBid) 206 if canRejectContract and not highBidder: 207 self.AddButton(BReject) 208 elif c.type == const.conTypeItemExchange: 209 text = '' 210 if c.price > 0: 211 if session.charid == c.issuerID: 212 rowLabel = GetByLabel('UI/Contracts/ContractsWindow/BuyerWillPay') 213 else: 214 rowLabel = GetByLabel('UI/Contracts/ContractsWindow/YouWillPay') 215 boldIsk = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=FmtISKWithDescription(c.price)) 216 rowInfo = '<color=%s>%s</color>' % (COL_PAY, boldIsk) 217 text += AddBasicInfoRow(rowLabel, rowInfo) 218 if c.reward > 0 or c.price == 0: 219 if session.charid == c.issuerID: 220 rowLabel = GetByLabel('UI/Contracts/ContractsWindow/BuyerWillGet') 221 else: 222 rowLabel = GetByLabel('UI/Contracts/ContractsWindow/YouWillGet') 223 boldIsk = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=FmtISKWithDescription(c.reward)) 224 rowInfo = '<color=%s>%s</color>' % (COL_GET, boldIsk) 225 text += AddBasicInfoRow(rowLabel, rowInfo) 226 infoParent = Container(name='infocontainer', parent=self.sr.main, align=uiconst.TOTOP, width=const.defaultPadding) 227 info = eveLabel.EveLabelLarge(text=text, parent=infoParent, top=const.defaultPadding, idx=0, tabs=tabs, state=uiconst.UI_NORMAL, left=6) 228 infoParent.height = info.textheight + 2 * const.defaultPadding 229 Line(parent=infoParent, align=uiconst.TOTOP) 230 Line(parent=infoParent, align=uiconst.TOBOTTOM) 231 fixedSize = False 232 for i in contract.items: 233 if not i.inCrate: 234 fixedSize = True 235 236 isResizable = self.InsertItemList(contract, '<color=%s>%s</color>' % (COL_GET, [GetByLabel('UI/Contracts/ContractsWindow/YouWillGet'), GetByLabel('UI/Contracts/ContractsWindow/BuyerWillGet')][session.charid == c.issuerID]), True, 2, fixedSize=fixedSize) 237 if self.InsertItemList(contract, '<color=%s>%s</color>' % (COL_PAY, [GetByLabel('UI/Contracts/ContractsWindow/YouWillPay'), GetByLabel('UI/Contracts/ContractsWindow/BuyerWillPay')][session.charid == c.issuerID]), False, 2, hint=GetByLabel('UI/Contracts/ContractEntry/NoRequiredItems'), forceList=True): 238 isResizable = True 239 if isIssuedByMe: 240 if c.status == const.conStatusOutstanding or c.status == const.conStatusRejected: 241 self.AddButton(BDelete) 242 if c.status == const.conStatusOutstanding and (not isIssuedByMePersonally or isAssignedToMePersonally): 243 if not isExpired: 244 self.AddButton(BAccept) 245 if isContractMgr: 246 self.AddButton(BAcceptForCorp) 247 if canRejectContract: 248 self.AddButton(BReject) 249 elif c.type == const.conTypeCourier: 250 text = '' 251 if c.status == const.conStatusInProgress: 252 de = c.dateExpired 253 if c.status == const.conStatusInProgress: 254 de = c.dateAccepted + const.DAY * c.numDays 255 diff = de - blue.os.GetWallclockTime() 256 if diff > 0: 257 timeleft = GetByLabel('UI/Contracts/ContractsService/TimeLeftWithoutCaption', timeLeft=ConFmtDate(diff, False), expireTime=FmtDate(de, 'ss')) 258 else: 259 overdueLabel = GetByLabel('UI/Contracts/ContractsService/Overdue', time=FmtDate(-diff, 'ss')) 260 timeleft = '<color=red>%s</color>' % overdueLabel 261 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/TimeLeft'), timeleft) 262 elif c.status == const.conStatusOutstanding: 263 rowInfoText = GetByLabel('UI/Contracts/ContractsService/QuantityDays', numDays=c.numDays) 264 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/CompleteIn'), rowInfoText) 265 volumeLabel = GetByLabel('UI/Contracts/ContractsWindow/NumericVolume', volume=eveformat.number(c.volume)) 266 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsSearch/columnVolume'), volumeLabel) 267 numJumps = self.pathfinder.GetAutopilotJumpCount(c.endSolarSystemID, c.startSolarSystemID) 268 perjump = '' 269 if numJumps: 270 jumpCost = int(c.reward / numJumps) 271 perjump = GetByLabel('UI/Contracts/ContractsService/ISKPerJump', costPerJump=FmtISKWithDescription(jumpCost, justDesc=True)) 272 if c.reward > 0: 273 boldIsk = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=FmtISKWithDescription(c.reward)) 274 b = '<color=%s>%s</color>' % (COL_GET, boldIsk) 275 else: 276 b = GetByLabel('UI/Contracts/ContractEntry/NoneParen') 277 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/Reward'), b) 278 if c.reward > 0: 279 text += AddBasicInfoRow('', perjump) 280 if c.volume: 281 volumeCost = FmtISK(float(c.reward) / c.volume, showFractionsAlways=1) 282 perM3 = GetByLabel('UI/Contracts/ContractsService/ISKPerM3', costPerM3=volumeCost) 283 text += AddBasicInfoRow('', perM3) 284 if c.collateral > 0: 285 boldIsk = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=FmtISKWithDescription(c.collateral)) 286 b = '<color=%s>%s</color>' % (COL_PAY, boldIsk) 287 else: 288 b = GetByLabel('UI/Contracts/ContractEntry/NoneParen') 289 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/Collateral'), b) 290 mr = sm.GetService('contracts').GetRouteSecurityWarning(c.startSolarSystemID, c.endSolarSystemID) 291 if mr: 292 mr = '<t>%s' % mr 293 if idCheckers.IsStation(c.endStationID): 294 endStationTypeID = sm.GetService('ui').GetStationStaticInfo(c.endStationID).stationTypeID 295 else: 296 endStationTypeID = sm.GetService('structureDirectory').GetStructureInfo(c.endStationID).typeID 297 dot = solar_system_security_status(c.endSolarSystemID) 298 loc = GetByLabel('UI/Contracts/ContractsWindow/StationLinkWithDot', dot=dot, station=c.endStationID, info=('showinfo', endStationTypeID, c.endStationID)) 299 if not idCheckers.IsStation(c.endStationID): 300 loc += '<br><t><color=0xffbb0000>%s</color>' % GetByLabel('UI/Contracts/ContractEntry/MightBeInaccessible') 301 jumpsToEndSolarSystem = self.pathfinder.GetAutopilotJumpCount(session.solarsystemid2, c.endSolarSystemID) 302 if jumpsToEndSolarSystem <= contractscommon.NUMJUMPS_UNREACHABLE: 303 routeLabel = GetByLabel('UI/Contracts/ContractsService/RouteInfo', numJumps=jumpsToEndSolarSystem) 304 loc += '<br><t>%s' % routeLabel 305 if c.startSolarSystemID != session.solarsystemid2: 306 if numJumps <= contractscommon.NUMJUMPS_UNREACHABLE: 307 routeLabel = GetByLabel('UI/Contracts/ContractsService/ShowRouteFromStart', numJumps=numJumps) 308 loc += '<br><t>%s' % routeLabel 309 if mr: 310 loc += '<br>%s' % mr 311 text += AddBasicInfoRow(GetByLabel('UI/Common/Destination'), loc) 312 infoParent = Container(name='infocontainer', parent=self.sr.main, align=uiconst.TOTOP, width=const.defaultPadding) 313 info = eveLabel.EveLabelMedium(text=text, parent=infoParent, top=const.defaultPadding, idx=0, tabs=tabs, state=uiconst.UI_NORMAL, left=const.defaultPadding) 314 infoParent.height = info.textheight 315 Line(parent=infoParent, align=uiconst.TOTOP) 316 if isIssuedByMe: 317 if c.status == const.conStatusOutstanding or c.status == const.conStatusRejected: 318 self.AddButton(BDelete) 319 if c.status == const.conStatusOutstanding and (not isIssuedByMePersonally or isAssignedToMePersonally): 320 if not isExpired: 321 self.AddButton(BAccept) 322 if isContractMgr: 323 self.AddButton(BAcceptForCorp) 324 if canRejectContract: 325 self.AddButton(BReject) 326 elif c.type == const.conTypeLoan: 327 text = '' 328 if c.status == const.conStatusInProgress: 329 timeleft = '<font color=red>%s</font>' % GetByLabel('UI/Contracts/ContractsWindow/Expired') 330 de = c.dateExpired 331 if c.status == const.conStatusInProgress: 332 de = c.dateAccepted + const.DAY * c.numDays 333 overdueLabel = GetByLabel('UI/Contracts/ContractsService/Overdue', time=FmtDate(-(de - blue.os.GetWallclockTime()), 'ss')) 334 timeleft = '<color=red>%s</color>' % overdueLabel 335 diff = de - blue.os.GetWallclockTime() 336 if diff > 0: 337 timeleft = GetByLabel('UI/Contracts/ContractsService/TimeLeftWithoutCaption', timeLeft=ConFmtDate(diff, False), expireTime=FmtDate(de, 'ss')) 338 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/TimeLeft'), timeleft) 339 elif c.status == const.conStatusOutstanding or c.status == const.conStatusRejected: 340 self.AddButton(BDelete) 341 if c.price > 0: 342 boldISK = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=FmtISKWithDescription(c.price)) 343 rowInfo = '<color=%s>%s</color>' % (COL_PAY, boldISK) 344 else: 345 rowInfo = GetByLabel('UI/Contracts/ContractEntry/NoneParen') 346 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsSearch/columnPrice'), rowInfo) 347 if c.collateral > 0: 348 boldISK = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=FmtISKWithDescription(c.collateral)) 349 rowInfo = '<color=%s>%s</color>' % (COL_PAY, boldISK) 350 else: 351 rowInfo = GetByLabel('UI/Contracts/ContractEntry/NoneParen') 352 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/Collateral'), rowInfo) 353 if c.reward > 0: 354 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractEntry/ISKBorrowed'), '<color=%s>%s</color>' % (COL_GET, FmtISKWithDescription(c.reward))) 355 infoParent = Container(name='infocontainer', parent=self.sr.main, align=uiconst.TOTOP, width=const.defaultPadding) 356 info = eveLabel.EveLabelMedium(text=text, parent=infoParent, top=const.defaultPadding, idx=0, tabs=tabs, state=uiconst.UI_NORMAL) 357 infoParent.height = info.textheight 358 Line(parent=infoParent, align=uiconst.TOTOP) 359 Line(parent=infoParent, align=uiconst.TOBOTTOM) 360 isResizable = self.InsertItemList(contract, GetByLabel('UI/Contracts/ContractsWindow/BorrowedItems'), True, 3, fixedSize=True) 361 if isIssuedByMe: 362 if c.status == const.conStatusRejected: 363 self.AddButton(BDelete) 364 if c.status == const.conStatusInProgress: 365 nocollateral = '' 366 if not c.collateral: 367 isk = c.reward or 0 368 nocollateral = GetByLabel('UI/Contracts/ContractsService/NoCollateralISK', reward=isk) 369 else: 370 nocollateral = GetByLabel('UI/Contracts/ContractsService/NoCollateral') 371 contractTypeLabel = GetByLabel('UI/Contracts/ContractsService/ContractTypeNotSupported') 372 notSupportedLabel = GetByLabel('UI/Contracts/ContractsService/LoanContractNotSupported') 373 failLabel = GetByLabel('UI/Contracts/ContractsService/ClickFail') 374 apologizeLabel = GetByLabel('UI/Contracts/ContractsService/WeApologize') 375 html = '<font color=0xffff4444><h4>%s</h4></font>%s<br>%s<br><br>%s<br><br>%s' % (contractTypeLabel, 376 notSupportedLabel, 377 failLabel, 378 nocollateral, 379 apologizeLabel) 380 descParent = Container(name='desc', parent=self.sr.main, align=uiconst.TOTOP, left=const.defaultPadding, top=const.defaultPadding, height=180) 381 desc = eveEdit.Edit(parent=descParent, readonly=1, hideBackground=1) 382 desc.SetValue('<html><body>%s</body></html>' % html) 383 else: 384 raise RuntimeError('Invalid contract type!') 385 self.AddButton(BCancel) 386 childrenList = self.sr.main.children 387 height = sum([ x.height for x in childrenList if x.state != uiconst.UI_HIDDEN and x.align in (uiconst.TOBOTTOM, uiconst.TOTOP) ]) + 110 388 w, h = self.minsize 389 add = {False: 0, 390 True: 160}[isResizable] 391 self.SetMinSize([w, height + add]) 392 self.buttonWnd = ButtonGroup(btns=self.buttons, parent=self.sr.main, button_size_mode=ButtonSizeMode.DYNAMIC, idx=0) 393 self.state = uiconst.UI_NORMAL 394 self.sr.captionpush = Container(name='captionpush', parent=self.sr.main, align=uiconst.TOBOTTOM, height=12, left=0, top=-16) 395 historyicon = eveIcon.MenuIcon(size=24, ignoreSize=True, align=uiconst.CENTERLEFT) 396 historyicon.GetMenu = lambda : self.GetHistoryMenu() 397 historyicon.hint = GetByLabel('UI/Common/History') 398 self.sr.captionpush = Container(name='captionpush', parent=self.sr.main, align=uiconst.TOBOTTOM, height=12, left=0, top=-16) 399 self.sr.captionpush.children.insert(1000, historyicon) 400 return self 401 402 def GetHistoryMenu(self): 403 m = [] 404 if self.contract.contract.issuerID == session.charid: 405 if self.contract.contract.forCorp: 406 if not IsNPC(session.corpid): 407 lastCopiedCorpFlag = settings.char.ui.Get('contracts_lastCopiedDiv', const.flagCorpSAG1) 408 if lastCopiedCorpFlag not in (const.flagCorpDeliveries,) + const.flagCorpSAGs: 409 lastCopiedCorpFlag = const.flagCorpSAG1 410 divName = self.GetDivisionName(lastCopiedCorpFlag) 411 text = GetByLabel('UI/Contracts/ContractsWindow/CopyContractDivisionName', divisionName=divName) 412 m.append((text, sm.GetService('contracts').OpenCreateContract, (None, self.contract, lastCopiedCorpFlag))) 413 m += [(MenuLabel('UI/Contracts/ContractsWindow/CopyContractFromDivision'), ('isDynamic', self._GetCorpDivisions, ()))] 414 else: 415 m.append((MenuLabel('UI/Contracts/ContractsWindow/CopyContract'), sm.GetService('contracts').OpenCreateContract, (None, self.contract))) 416 typeID = None 417 if self.contract.items and len(self.contract.items) == 1: 418 typeID = self.contract.items[0].itemTypeID 419 m += [(MenuLabel('UI/Contracts/ContractEntry/FindRelated'), ('isDynamic', sm.GetService('contracts').GetRelatedMenu, (self.contract.contract, typeID)))] 420 m += [None] 421 m += [(MenuLabel('UI/Contracts/ContractsWindow/PreviouslyViewedContracts'), ('isDynamic', self._GetLatestContractsForHistory, ()))] 422 return m 423 424 def GetDivisionName(self, corpFlag): 425 if corpFlag == const.flagCorpDeliveries: 426 return GetByLabel('UI/Contracts/ContractsWindow/Deliveries') 427 division = const.corpDivisionsByFlag[corpFlag] 428 divName = sm.GetService('corp').GetDivisionNames()[division + 1] 429 return divName 430 431 def _GetCorpDivisions(self): 432 m = [] 433 for eachFlagID in const.flagCorpSAGs: 434 text = self.GetDivisionName(eachFlagID) 435 m.append((text, self._OpenCreateContractForCorp, (self.contract, eachFlagID))) 436 437 if session.corprole & (const.corpRoleAccountant | const.corpRoleJuniorAccountant | const.corpRoleTrader): 438 m.append((GetByLabel('UI/Contracts/ContractsWindow/Deliveries'), self._OpenCreateContractForCorp, (self.contract, const.flagCorpDeliveries))) 439 return m 440 441 def _OpenCreateContractForCorp(self, contract, corpFlagID): 442 settings.char.ui.Set('contracts_lastCopiedDiv', corpFlagID) 443 sm.GetService('contracts').OpenCreateContract(None, contract, corpFlagID) 444 445 def _GetLatestContractsForHistory(self): 446 m = [] 447 for i in range(len(self.history)): 448 h = self.history[-(i + 1)] 449 m.append((h.title, self.SelectHistory, (h.contractID, h.solarSystemID))) 450 451 return m 452 453 def SelectHistory(self, contractID, solarSystemID): 454 sm.GetService('contracts').ShowContract(contractID) 455 456 def AddButton(self, which): 457 caption = function = None 458 if which == BCancel: 459 caption = GetByLabel('UI/Common/Close') 460 function = self.Cancel 461 elif which == BAccept: 462 caption = GetByLabel('UI/Contracts/ContractsWindow/Accept') 463 function = self.Accept 464 elif which == BAcceptForCorp: 465 caption = GetByLabel('UI/Contracts/ContractsWindow/AcceptForCorp') 466 function = self.AcceptForCorp 467 elif which == BReject: 468 caption = GetByLabel('UI/Contracts/ContractsWindow/Reject') 469 function = self.Reject 470 elif which == BComplete: 471 caption = GetByLabel('UI/Contracts/ContractsWindow/Complete') 472 function = self.Complete 473 elif which == BDelete: 474 caption = GetByLabel('UI/Contracts/ContractsWindow/Delete') 475 function = self.Delete 476 elif which == BSucceed: 477 caption = GetByLabel('UI/Contracts/ContractsWindow/Succeed') 478 function = self.Succeed 479 elif which == BFail: 480 caption = GetByLabel('UI/Contracts/ContractsWindow/Fail') 481 function = self.Fail 482 elif which == BGetItems: 483 caption = GetByLabel('UI/Contracts/ContractEntry/GetItems') 484 function = self.GetItems 485 elif which == BGetMoney: 486 caption = GetByLabel('UI/Contracts/ContractEntry/GetMoney') 487 function = self.GetMoney 488 elif which == BPlaceBid: 489 caption = GetByLabel('UI/Contracts/ContractEntry/PlaceBid') 490 function = self.PlaceBid 491 button = (caption, 492 function, 493 (), 494 84) 495 self.buttons.append(button) 496 497 def Cancel(self): 498 self.Close() 499 500 def TryHideLoad(self): 501 try: 502 self.HideLoad() 503 except: 504 pass 505 506 def Accept(self): 507 try: 508 self.ShowLoad() 509 if sm.GetService('contracts').AcceptContract(self.contractID, False): 510 if not self or self.destroyed: 511 return 512 self.Init() 513 finally: 514 self.TryHideLoad() 515 516 def AcceptForCorp(self): 517 try: 518 self.ShowLoad() 519 if sm.GetService('contracts').AcceptContract(self.contractID, True): 520 self.Init() 521 finally: 522 self.TryHideLoad() 523 524 def Reject(self): 525 try: 526 self.ShowLoad() 527 if sm.GetService('contracts').RejectContract(self.contractID): 528 self.Init() 529 finally: 530 self.TryHideLoad() 531 532 def Complete(self): 533 try: 534 self.ShowLoad() 535 if sm.GetService('contracts').CompleteContract(self.contractID): 536 self.Init() 537 finally: 538 self.TryHideLoad() 539 540 def Delete(self): 541 try: 542 self.ShowLoad() 543 if sm.GetService('contracts').DeleteContract(self.contractID): 544 self.Close() 545 finally: 546 try: 547 self.TryHideLoad() 548 except: 549 pass 550 551 def Succeed(self): 552 try: 553 self.ShowLoad() 554 if sm.GetService('contracts').CompleteContract(self.contractID): 555 self.Init() 556 finally: 557 self.TryHideLoad() 558 559 def Fail(self): 560 try: 561 self.ShowLoad() 562 if sm.GetService('contracts').FailContract(self.contractID): 563 self.Init() 564 finally: 565 self.TryHideLoad() 566 567 def GetItems(self): 568 try: 569 self.ShowLoad() 570 sm.GetService('contracts').FinishAuction(self.contractID, False) 571 self.Init() 572 finally: 573 self.TryHideLoad() 574 575 def GetMoney(self): 576 try: 577 self.ShowLoad() 578 sm.GetService('contracts').FinishAuction(self.contractID, True) 579 self.Init() 580 finally: 581 self.TryHideLoad() 582 583 def PlaceBid(self): 584 try: 585 self.ShowLoad() 586 if sm.GetService('contracts').PlaceBid(self.contractID): 587 if not self.destroyed: 588 self.Init() 589 finally: 590 self.TryHideLoad() 591 592 def InsertItemList(self, contract, title, inCrate, numRows, hint = None, fixedSize = False, forceList = False): 593 shouldHideBlueprintInfo = contract.contract.status in [const.conStatusFinished, const.conStatusFinishedContractor] 594 items = [ e for e in contract.items if e.inCrate == inCrate ] 595 if len(items) == 0: 596 if len(contract.items) > 1: 597 return True 598 else: 599 return False 600 else: 601 titleParent = Container(name='title', parent=self.sr.main, align=uiconst.TOTOP, width=const.defaultPadding) 602 boldTitle = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=title) 603 title = eveLabel.EveLabelLarge(text=boldTitle, parent=titleParent, top=6, idx=0, state=uiconst.UI_NORMAL, left=6) 604 titleParent.height = title.textheight + 6 605 if len(items) == 1 and not forceList: 606 item = items[0] 607 typeID = item.itemTypeID 608 itemID = item.itemID 609 groupName = evetypes.GetGroupName(item.itemTypeID) 610 isCorpse = evetypes.GetGroupID(item.itemTypeID) == const.groupBiomass 611 categoryID = evetypes.GetCategoryID(item.itemTypeID) 612 categoryName = CategoryName(categoryID) 613 details = '' 614 if categoryID == const.categoryBlueprint: 615 if item.copy == 1: 616 if shouldHideBlueprintInfo: 617 details = GetByLabel('UI/Contracts/ContractsService/BlueprintCopy') 618 else: 619 details = GetByLabel('UI/VirtualGoodsStore/BlueprintCopy', runs=item.licensedProductionRunsRemaining or 0, materialLevel=item.materialLevel or 0, productivityLevel=item.productivityLevel or 0) 620 elif shouldHideBlueprintInfo: 621 details = GetByLabel('UI/Contracts/ContractsService/BlueprintOriginal') 622 else: 623 details = GetByLabel('UI/VirtualGoodsStore/OriginalBlueprint', materialLevel=item.materialLevel or 0, productivityLevel=item.productivityLevel or 0) 624 descParent = Container(name='desc', parent=self.sr.main, align=uiconst.TOTOP, left=const.defaultPadding, top=const.defaultPadding, height=80) 625 leftParent = Container(name='leftParent', parent=descParent, align=uiconst.TOLEFT, width=72) 626 infoParent = Container(name='infoParent', parent=descParent, align=uiconst.TOALL, padding=(8, 627 2, 628 const.defaultPadding, 629 0)) 630 if getattr(item, 'copy', False): 631 isCopy = True 632 else: 633 isCopy = False 634 icon = ItemIcon(parent=leftParent, typeID=typeID, itemID=itemID, isCopy=isCopy, width=64, height=64, align=uiconst.TOPRIGHT) 635 if eveCfg.IsPreviewable(typeID): 636 setattr(icon, 'typeID', typeID) 637 icon.cursor = uiconst.UICURSOR_MAGNIFIER 638 icon.OnClick = (self.OnPreviewClick, icon) 639 captionText = GetByLabel('UI/Contracts/ContractsService/NameXQuantity', typeID=item.itemTypeID, quantity=FmtAmt(max(1, item.quantity))) 640 self.info_caption = eveLabel.EveCaptionSmall(parent=infoParent, text=captionText, padRight=16) 641 top = self.info_caption.textheight 642 self.corpseNameLabel = None 643 if isCorpse: 644 corpseName = GetCorpseName(itemID) 645 if corpseName: 646 self.corpseNameLabel = eveLabel.EveLabelMedium(parent=infoParent, top=top, text=corpseName) 647 top += self.corpseNameLabel.textheight 648 self.infolink = InfoIcon(itemID=itemID, typeID=typeID, left=0, top=const.defaultPadding, parent=infoParent, idx=0) 649 self.infolink.left = self.info_caption.textwidth + 8 650 categoryAndGroupText = GetByLabel('UI/Contracts/ContractEntry/CategoryAndGroup', categoryName=categoryName, groupName=groupName) 651 self.categoryAndGroup = eveLabel.EveLabelMedium(parent=infoParent, top=top, text=categoryAndGroupText) 652 top += self.categoryAndGroup.textheight 653 if GetItemDamageText(item): 654 damageAndTextilsText = '<color=red>%s</color> %s' % (GetItemDamageText(item), details) 655 else: 656 damageAndTextilsText = details 657 self.damageAndTextils = eveLabel.EveLabelMedium(parent=infoParent, top=top, text=damageAndTextilsText) 658 return False 659 if fixedSize: 660 self.sr.scroll = eveScroll.Scroll(parent=self.sr.main, align=uiconst.TOTOP, padding=(const.defaultPadding, 661 const.defaultPadding, 662 const.defaultPadding, 663 const.defaultPadding), height=100) 664 else: 665 self.sr.scroll = eveScroll.Scroll(parent=self.sr.main, padding=(const.defaultPadding, 666 const.defaultPadding, 667 const.defaultPadding, 668 const.defaultPadding)) 669 self.sr.scroll.sr.id = 'contractDetailScroll' 670 self.sr.data = {'items': []} 671 parents = [] 672 children = [] 673 for item in items: 674 if not item.parentID: 675 parents.append(item) 676 else: 677 children.append(item) 678 679 items = [] 680 for parent in parents: 681 items.append(parent) 682 for child in children: 683 if child.parentID == parent.itemID: 684 items.append(child) 685 686 for child in children: 687 for item in items: 688 if child.itemID == item.itemID: 689 break 690 else: 691 items.append(child) 692 693 scrolllist = [] 694 itemsByParentID = defaultdict(set) 695 for eachItem in items: 696 itemsByParentID[eachItem.parentID].add(eachItem) 697 698 for item in items: 699 if item.inCrate != inCrate: 700 continue 701 typeName = evetypes.GetName(item.itemTypeID) 702 groupName = evetypes.GetGroupName(item.itemTypeID) 703 categoryName = evetypes.GetCategoryName(item.itemTypeID) 704 categoryID = evetypes.GetCategoryID(item.itemTypeID) 705 details = '' 706 isBlueprint = False 707 isCopy = False 708 if categoryID == const.categoryBlueprint: 709 isBlueprint = True 710 if item.copy == 1: 711 isCopy = True 712 if shouldHideBlueprintInfo: 713 details = GetByLabel('UI/Contracts/ContractsService/BlueprintCopy') 714 else: 715 details = GetByLabel('UI/VirtualGoodsStore/BlueprintCopy', runs=item.licensedProductionRunsRemaining or 0, materialLevel=item.materialLevel or 0, productivityLevel=item.productivityLevel or 0) 716 elif shouldHideBlueprintInfo: 717 details = GetByLabel('UI/Contracts/ContractsService/BlueprintOriginal') 718 else: 719 details = GetByLabel('UI/VirtualGoodsStore/OriginalBlueprint', materialLevel=item.materialLevel or 0, productivityLevel=item.productivityLevel or 0) 720 elif item.flagID: 721 details = GetShipFlagLocationName(item.flagID) 722 chld = '' 723 sublevel = 0 724 if item.parentID > 0: 725 chld = ' ' 726 sublevel = 1 727 mrdmg = GetItemDamageText(item) 728 quantity = max(1, item.quantity) if item.quantity is not None else None 729 quantityLabel = localization.formatters.FormatNumeric(quantity, useGrouping=True) 730 if forceList: 731 label = '%s%s<t>%s<t>%s' % (chld, 732 typeName, 733 quantityLabel, 734 groupName) 735 hdr = [GetByLabel('UI/Contracts/ContractsWindow/Name'), GetByLabel('UI/Inventory/ItemQuantityShort'), GetByLabel('UI/Common/Type')] 736 else: 737 label = '%s%s<t>%s<t>%s<t>%s<t>%s%s' % (chld, 738 typeName, 739 quantityLabel, 740 groupName, 741 categoryName, 742 details, 743 mrdmg) 744 hdr = [GetByLabel('UI/Contracts/ContractsWindow/Name'), 745 GetByLabel('UI/Inventory/ItemQuantityShort'), 746 GetByLabel('UI/Common/Type'), 747 GetByLabel('UI/Common/Category'), 748 GetByLabel('UI/Common/Details')] 749 scrolllist.append(GetFromClass(Item, {'itemID': item.itemID, 750 'typeID': item.itemTypeID, 751 'label': label, 752 'getIcon': 1, 753 'isBlueprint': isBlueprint, 754 'isCopy': isCopy, 755 'GetMenu': GetContractItemMenu, 756 'sublevel': sublevel, 757 'childrenItems': itemsByParentID.get(item.itemID, set()), 758 'sort_%s' % GetByLabel('UI/Inventory/ItemQuantityShort'): quantity, 759 'LoadTooltipPanelFunc': self.LoadItemTooltipPanel})) 760 761 self.sr.scroll.Load(None, scrolllist, headers=hdr) 762 if len(scrolllist) >= 1: 763 hint = None 764 elif hint is None: 765 hint = GetByLabel('UI/Contracts/ContractsWindow/NoItemsFound') 766 self.sr.scroll.ShowHint(hint) 767 return not fixedSize 768 769 def LoadItemTooltipPanel(self, tooltipPanel, itemID, typeID): 770 if evetypes.GetGroupID(typeID) == const.groupBiomass: 771 corpseName = GetCorpseName(itemID) 772 if corpseName: 773 tooltipPanel.LoadGeneric1ColumnTemplate() 774 tooltipPanel.AddTextBodyLabel(text=corpseName) 775 776 def OnPreviewClick(self, wnd, *args): 777 sm.GetService('preview').PreviewType(getattr(wnd, 'typeID')) 778 779 def UpdateTexts(self): 780 if hasattr(self, 'info_caption'): 781 self.infolink.left = self.info_caption.textwidth + 8 782 top = self.info_caption.textheight 783 if self.corpseNameLabel: 784 top += self.corpseNameLabel.textheight 785 self.categoryAndGroup.top = top 786 top += self.categoryAndGroup.textheight 787 self.damageAndTextils.top = top 788 789 def _OnResize(self, *args): 790 self.UpdateTexts() 791 792 def LoadTabs(self): 793 pass 794 795 def Load(self, key): 796 pass 797 798 def Confirm(self, *etc): 799 pass 800 801 def GetError(self, checkNumber = 1): 802 return '' 803 804 def Error(self, error): 805 if error: 806 prompt_player_fsd_dialog('CustomInfo', {'info': error}) 807 808 def HistoryAdd(self, id, solarSystemID, title): 809 self.HistoryRemove(id) 810 kv = utillib.KeyVal() 811 kv.contractID = id 812 kv.solarSystemID = solarSystemID 813 kv.title = title 814 self.history.append(kv) 815 if len(self.history) > HISTORY_LENGTH: 816 del self.history[0] 817 settings.user.ui.Set('contracts_history', self.history) 818 819 def HistoryRemove(self, id): 820 for i in range(len(self.history)): 821 if self.history[i].contractID == id: 822 del self.history[i] 823 return 824 825 826 def AddBasicInfoRow(key, val): 827 boldKey = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=key) 828 return '%(key)s<t>%(val)s<br>' % {'key': boldKey, 829 'val': val} 830 831 832 def GetBasicInfoText(c): 833 isContractMgr = session.corprole & const.corpRoleContractManager == const.corpRoleContractManager 834 text = '' 835 desc = c.title 836 if desc == '': 837 desc = GetByLabel('UI/Contracts/ContractEntry/NoneParen') 838 else: 839 desc = GetByLabel('UI/Contracts/ContractsWindow/ContractDescription', description=desc) 840 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/InfoByIssuer'), '<color=0xff999999>%s</color>' % desc) 841 text += AddBasicInfoRow(GetByLabel('UI/Common/Type'), contractscommon.GetContractTypeText(c.type)) 842 if c.forCorp: 843 issuerID = c.issuerCorpID 844 else: 845 issuerID = c.issuerID 846 try: 847 issuer = cfg.eveowners.Get(issuerID) 848 issuerTypeID = issuer.typeID 849 issuerName = issuer.ownerName 850 except: 851 issuerTypeID = cfg.eveowners.Get(session.charid).typeID 852 issuerName = GetByLabel('UI/Contracts/ContractsWindow/UnknownSystem') 853 log.LogException() 854 855 issuedByURL = GetByLabel('UI/Contracts/ContractsWindow/ShowInfoLink', showInfoName=issuerName, info=('showinfo', issuerTypeID, issuerID)) 856 issuedByLabel = GetByLabel('UI/Contracts/ContractsWindow/IssuedBy') 857 text += AddBasicInfoRow(issuedByLabel, issuedByURL) 858 isPrivate = not not c.availability 859 if isPrivate: 860 assignee = cfg.eveowners.Get(c.assigneeID) 861 a = GetByLabel('UI/Contracts/ContractsWindow/PrivateWithLink', showInfoName=assignee.name, info=('showinfo', assignee.typeID, c.assigneeID)) 862 else: 863 if c.startRegionID == session.regionid: 864 reg = GetByLabel('UI/Contracts/ContractsWindow/CurrentRegion') 865 else: 866 reg = GetByLabel('UI/Contracts/ContractEntry/OtherRegion') 867 a = GetByLabel('UI/Contracts/ContractsService/RegionInfo', regionHeader=GetByLabel('UI/Common/LocationTypes/Region'), region=c.startRegionID, currentOrOther=reg) 868 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/Availability'), a) 869 if c.acceptorID > 0 and (c.status != const.conStatusInProgress or c.issuerID == session.charid or c.issuerCorpID == session.corpid and c.forCorp or c.acceptorID == session.charid or c.acceptorID == session.corpid): 870 acceptor = cfg.eveowners.Get(c.acceptorID) 871 more = '' 872 if c.acceptorID == session.corpid and isContractMgr and c.acceptorWalletKey is not None: 873 more = GetByLabel('UI/Contracts/ContractsService/WalletDivisionAccountName', accountName=sm.GetService('corp').GetCorpAccountName(c.acceptorWalletKey)) 874 acceptorURL = GetByLabel('UI/Contracts/ContractsWindow/ShowInfoLinkWithMore', showInfoName=acceptor.ownerName, info=('showinfo', acceptor.typeID, c.acceptorID), more=more) 875 contractorLabel = GetByLabel('UI/Contracts/ContractsWindow/Contractor') 876 text += AddBasicInfoRow(contractorLabel, acceptorURL) 877 st = contractscommon.GetContractStatusText(c.status, c.type) 878 if c.status == const.conStatusFailed: 879 textToBold = '<color=red>%s</color>' % st 880 st = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=textToBold) 881 boldStatus = GetByLabel('UI/Contracts/ContractsService/BoldGenericLabel', labelText=GetByLabel('UI/Contracts/ContractsWindow/Status')) 882 text += '%(statusKey)s<t>%(status)s<br>' % {'statusKey': boldStatus, 883 'status': st} 884 if c.startStationID == 0: 885 loc = GetByLabel('UI/Contracts/ContractEntry/NoneParen') 886 else: 887 if idCheckers.IsStation(c.startStationID): 888 startStationTypeID = sm.GetService('ui').GetStationStaticInfo(c.startStationID).stationTypeID 889 else: 890 startStationTypeID = sm.GetService('structureDirectory').GetStructureInfo(c.startStationID).typeID 891 dot = solar_system_security_status(c.startSolarSystemID) 892 loc = GetByLabel('UI/Contracts/ContractsWindow/StationLinkWithDot', dot=dot, station=c.startStationID, info=('showinfo', startStationTypeID, c.startStationID)) 893 if c.startStationID == session.stationid: 894 loc += '<br><t>%s' % GetByLabel('UI/Generic/CurrentStation') 895 elif c.startSolarSystemID == session.solarsystemid: 896 loc += '<br><t>%s' % GetByLabel('UI/Generic/CurrentSystem') 897 if not idCheckers.IsStation(c.startStationID): 898 loc += ' - <color=0xffbb0000>%s</color>' % GetByLabel('UI/Contracts/ContractEntry/MightBeInaccessible') 899 else: 900 if not idCheckers.IsStation(c.startStationID): 901 loc += '<br><t><color=0xffbb0000>%s</color>' % GetByLabel('UI/Contracts/ContractEntry/MightBeInaccessible') 902 jumpsToStartSystem = sm.GetService('clientPathfinderService').GetAutopilotJumpCount(session.solarsystemid2, c.startSolarSystemID) 903 mr = sm.GetService('contracts').GetRouteSecurityWarning(session.solarsystemid2, c.startSolarSystemID) 904 if jumpsToStartSystem <= contractscommon.NUMJUMPS_UNREACHABLE: 905 loc += '<br><t>' 906 loc += GetByLabel('UI/Common/NumJumpsAway', numJumps=int(jumpsToStartSystem)) 907 if mr: 908 loc += '<br><t>%s' % mr 909 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/Location'), loc) 910 if c.type != const.conTypeAuction or c.status != const.conStatusOutstanding or session.charid == c.issuerID: 911 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/DateIssued'), FmtDate(c.dateIssued, 'ss')) 912 if c.status == const.conStatusInProgress: 913 cb = c.dateAccepted + const.DAY * c.numDays 914 if cb < blue.os.GetWallclockTime() + const.HOUR: 915 if cb - blue.os.GetWallclockTime() < 0: 916 timeLeftLabel = GetByLabel('UI/Contracts/ContractEntry/Overdue') 917 else: 918 timeLeftLabel = GetByLabel('UI/Contracts/ContractsService/TimeLeftWithoutLabelVerbose', time=FmtDate(cb, 'ls'), timeLeft=FmtDate(cb - blue.os.GetWallclockTime(), 'ls')) 919 cb = '<color=red>%s</color>' % timeLeftLabel 920 else: 921 cb = FmtDate(cb, 'ls') 922 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/CompleteBefore'), cb) 923 elif c.status != const.conStatusOutstanding: 924 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/DateCompleted'), FmtDate(c.dateCompleted, 'ls')) 925 elif c.type != const.conTypeAuction: 926 expirationDateLabel = GetByLabel('UI/Contracts/ContractsService/ExpirationDate', expiredOn=FmtDate(c.dateExpired, 'ls'), timeSinceExpired=ConFmtDate(c.dateExpired - blue.os.GetWallclockTime(), False)) 927 text += AddBasicInfoRow(GetByLabel('UI/Contracts/ContractsWindow/ExpirationDate'), expirationDateLabel) 928 return text 929 930 931 def GetItemDamageText(item): 932 dmg = 0 933 if item.damage: 934 for attribute in dogma_data.get_type_attributes(item.itemTypeID): 935 if attribute.attributeID == const.attributeHp and attribute.value: 936 dmg = item.damage / attribute.value 937 dmg = int(dmg * 100) 938 break 939 940 txt = '' 941 if dmg > 0: 942 txt = ' <color=0xffff4444>%s</color>' % GetByLabel('UI/Contracts/ContractsService/PercentDamaged', percent=dmg) 943 return txt 944 945 946 def GetContractItemMenu(entry, *args): 947 node = entry.sr.node 948 typeID = entry.typeID 949 itemID = entry.itemID 950 m = [] 951 if evetypes.GetCategoryID(typeID) == const.categoryShip: 952 m += [(MenuLabel('UI/Fitting/FittingWindow/SimulateShipFitting'), SimulateShipFromContract, (typeID, node.childrenItems))] 953 m += GetMenuService().GetMenuFromItemIDTypeID(itemID, entry.typeID, includeMarketDetails=True) 954 return m 955 956 957 def SimulateShipFromContract(shipTypeID, fittedItems): 958 fittedItems = {Bundle(typeID=x.itemTypeID, itemID=x.itemID, flagID=x.flagID, categoryID=evetypes.GetCategoryID(x.itemTypeID), groupID=evetypes.GetGroupID(x.itemTypeID), stacksize=x.quantity) for x in fittedItems} 959 fitData, _ = sm.GetService('fittingSvc').GetFittingDictFromItems(fittedItems, putModuleAmmoInCargo=False) 960 fitting = utillib.KeyVal(shipTypeID=shipTypeID, fitData=fitData) 961 sm.GetService('ghostFittingSvc').SimulateFitting(fitting)