class SecurityStatusPanel(Container): default_name = 'SecurityStatusPanel' __notifyevents__ = [] def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) sm.RegisterNotify(self) self.scroll = Scroll(parent=self, padding=(0, 4, 0, 4)) self.scroll.sr.id = 'charsheet_securitystatus' def LoadPanel(self, *args): crimewatchSvc = sm.GetService('crimewatchSvc') data = crimewatchSvc.GetSecurityStatusTransactions() self.scroll.Clear() scrolllist = [] for transaction in data: if transaction.eventTypeID == logConst.eventSecStatusGmModification: subject = GetByLabel('UI/Generic/FormatStandingTransactions/subjectSetBySlashCmd') body = GetByLabel('UI/Generic/FormatStandingTransactions/messageResetBySlashCmd') elif transaction.eventTypeID == logConst.eventSecStatusGmRollback: subject = GetByLabel('UI/Generic/FormatStandingTransactions/subjectSetBySlashCmd') body = GetByLabel('UI/Generic/FormatStandingTransactions/messageResetBySlashCmd') elif transaction.eventTypeID == logConst.eventSecStatusIllegalAggression: cfg.eveowners.Prime([transaction.otherOwnerID]) cfg.evelocations.Prime([transaction.locationID]) subject = GetByLabel('UI/Generic/FormatStandingTransactions/subjectCombatAgression') body = GetByLabel('UI/Generic/FormatStandingTransactions/messageCombatAgression', locationID=transaction.locationID, ownerName=cfg.eveowners.Get(transaction.otherOwnerID).name, typeID=transaction.otherTypeID) elif transaction.eventTypeID == logConst.eventSecStatusKillPirateNpc: subject = GetByLabel('UI/Generic/FormatStandingTransactions/subjectLawEnforcmentGain') body = GetByLabel('UI/Generic/FormatStandingTransactions/messageLawEnforcmentGain', name=cfg.eveowners.Get(transaction.otherOwnerID).name) elif transaction.eventTypeID == logConst.eventSecStatusHandInTags: subject = GetByLabel('UI/Generic/FormatStandingTransactions/subjectHandInTags') body = GetByLabel('UI/Generic/FormatStandingTransactions/messageHandInTags') if transaction.modification is not None: modification = GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SecurityStatusScroll/Persentage', value=transaction.modification * 100.0, decimalPlaces=4) else: modification = '' text = '%s<t>%s<t><right>%s</right><t>%s' % (FmtDate(transaction.eventDate, 'ls'), modification, localization.formatters.FormatNumeric(transaction.newValue, decimalPlaces=2), subject) hint = '%s<br>%s' % (localization.formatters.FormatNumeric(transaction.newValue, decimalPlaces=4), subject) scrolllist.append(entries.Get('StandingTransaction', {'sort_%s' % GetByLabel('UI/Common/Date'): transaction.eventDate, 'sort_%s' % GetByLabel('UI/Common/Change'): transaction.modification, 'line': 1, 'text': text, 'hint': hint, 'details': body, 'isNPC': True})) headers = [GetByLabel('UI/Common/Date'), GetByLabel('UI/Common/Change'), GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SecurityStatus'), GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SecurityStatusScroll/Subject')] noChangesHint = GetByLabel('UI/CharacterSheet/CharacterSheetWindow/SecurityStatusScroll/NoSecurityStatusChanges') self.scroll.Load(contentList=scrolllist, headers=headers, noContentHint=noChangesHint)
class SkinsPanel(Container): __notifyevents__ = ['OnSkinLicenseActivated'] def ApplyAttributes(self, attributes): super(SkinsPanel, self).ApplyAttributes(attributes) sm.RegisterNotify(self) self.Layout() def Layout(self): menuBar = ContainerAutoSize(parent=self, align=uiconst.TOTOP, padBottom=4) UtilMenu(parent=menuBar, align=uiconst.CENTERLEFT, menuAlign=uiconst.BOTTOMLEFT, GetUtilMenu=self.GetSettingsMenu, texturePath='res:/UI/Texture/SettingsCogwheel.png', width=16, height=16, iconSize=18) self.filter = QuickFilterEdit(parent=menuBar, align=uiconst.CENTERLEFT, left=18, width=150) self.filter.ReloadFunction = self.LoadPanel self.scroll = Scroll(parent=self, align=uiconst.TOALL) @property def filterText(self): return self.filter.GetValue().strip().lower() def LoadPanel(self, *args): self.scroll.Clear() skinsByMaterialID = self._GetFilteredSkinsByMaterialID() entries = [] for materialID, skins in skinsByMaterialID.iteritems(): entry = self._CreateMaterialGroupEntry(materialID, skins) if entry is not None: entries.append(entry) self.scroll.Load(contentList=sorted(entries, key=lambda e: e.label), noContentHint=localization.GetByLabel( 'UI/SkillQueue/NoResultsForFilters')) def _GetFilteredSkinsByMaterialID(self): skinSvc = sm.GetService('skinSvc') licensedSkinsByID = {s.skinID: s for s in skinSvc.GetLicensedSkins()} skins = [] for staticSkin in skinSvc.static.GetAllSkins(): licensedSkin = licensedSkinsByID.get(staticSkin.skinID, None) skins.append(self._CreateSkinObject(staticSkin, licensedSkin)) show = GetSetting(SETTING_SHOW_SKINS) if show == SHOW_ACTIVE_SKINS: skins = filter(lambda s: s.licensed, skins) elif show == SHOW_INACTIVE_SKINS: skins = filter(lambda s: not s.licensed, skins) return bucket(skins, keyprojection=lambda s: s.materialID) def _CreateSkinObject(self, staticSkin, licensedSkin=None): material = sm.GetService('skinSvc').static.GetMaterialByID( staticSkin.skinMaterialID) licensed = licensedSkin is not None expires = licensedSkin.expires if licensedSkin else None return Skin(material, skin=staticSkin, licensed=licensed, expires=expires) def _CreateMaterialGroupEntry(self, materialID, skins): skinsByShipID = self._GroupAndFilterByShip(skins) if not skinsByShipID: return None material = sm.GetService('skinSvc').GetStaticMaterialByID(materialID) owned = count((ship for ship, skins in skinsByShipID.iteritems() if any((s.licensed for s in skins)))) label = localization.GetByLabel( 'UI/CharacterSheet/CharacterSheetWindow/SkinsGroupWithCount', groupName=material.name, skinsOwned=owned, skinsTotal=len(skinsByShipID)) data = { 'label': label, 'id': ('SkinMaterials', material.materialID), 'showicon': material.iconTexturePath, 'groupItems': skinsByShipID, 'GetSubContent': self._GetSkinsSubContent, 'showlen': False, 'BlockOpenWindow': True, 'state': 'locked' } return listentry.Get('Group', data=data) def _GroupAndFilterByShip(self, skins): skinsByShipID = defaultdict(list) for skin in skins: for shipTypeID in skin.types: if self._IsFilterMatch(shipTypeID, skin): skinsByShipID[shipTypeID].append(skin) return skinsByShipID def _IsFilterMatch(self, shipTypeID, skin): if len(self.filterText) == 0: return True shipName = evetypes.GetName(shipTypeID).lower() skinName = skin.name.lower() return self.filterText in shipName or self.filterText in skinName def _GetSkinsSubContent(self, nodedata, *args): skinsByShipID = nodedata.groupItems nodes = [] for shipTypeID, skins in skinsByShipID.iteritems(): skin = self._PickRepresentingSkin(skins) data = { 'typeID': shipTypeID, 'itemID': None, 'label': evetypes.GetName(shipTypeID), 'getIcon': True, 'sublevel': 1, 'skin': skin } entry = listentry.Get(decoClass=ShipSkinEntry, data=data) nodes.append(entry) nodes = sorted(nodes, key=lambda x: x.label) return nodes def _PickRepresentingSkin(self, skins): licensedSkins = filter(lambda s: s.licensed, skins) if not licensedSkins: return skins[0] else: permanentSkins = filter(lambda s: s.expires is None, licensedSkins) if permanentSkins: return permanentSkins[0] limitedSkins = filter(lambda s: s.expires, licensedSkins) limitedSkins = sorted(limitedSkins, key=lambda s: s.expires, reverse=True) return limitedSkins[0] def GetSettingsMenu(self, menuParent): menuParent.AddRadioButton( text=localization.GetByLabel( 'UI/CharacterSheet/CharacterSheetWindow/Skins/ShowAllSkins'), checked=GetSetting(SETTING_SHOW_SKINS) == SHOW_ALL_SKINS, callback=partial(self.SetSettingAndReload, SETTING_SHOW_SKINS, SHOW_ALL_SKINS)) menuParent.AddRadioButton(text=localization.GetByLabel( 'UI/CharacterSheet/CharacterSheetWindow/Skins/ShowActiveSkins'), checked=GetSetting(SETTING_SHOW_SKINS) == SHOW_ACTIVE_SKINS, callback=partial(self.SetSettingAndReload, SETTING_SHOW_SKINS, SHOW_ACTIVE_SKINS)) menuParent.AddRadioButton(text=localization.GetByLabel( 'UI/CharacterSheet/CharacterSheetWindow/Skins/ShowInactiveSkins'), checked=GetSetting(SETTING_SHOW_SKINS) == SHOW_INACTIVE_SKINS, callback=partial(self.SetSettingAndReload, SETTING_SHOW_SKINS, SHOW_INACTIVE_SKINS)) def SetSettingAndReload(self, key, value): SetSetting(key, value) self.LoadPanel() def OnSkinLicenseActivated(self, skinID): if self.display: self.LoadPanel()
class BrowserJobs(Container): default_name = 'BrowserJobs' __notifyevents__ = [ 'OnIndustryJob', 'OnFacilityReload', 'OnSessionChanged' ] def ApplyAttributes(self, attributes): Container.ApplyAttributes(self, attributes) sm.RegisterNotify(self) self.callback = attributes.callback self.isInitialized = False def _OnClose(self, *args): sm.UnregisterNotify(self) def OnTabSelect(self): if self.isInitialized: self.UpdateOwnerCombo() self.UpdateInstallerCombo() self.UpdateScroll() return self.isInitialized = True self.topPanel = Container(name='topPanel', parent=self, align=uiconst.TOTOP, height=20, padding=(0, 6, 0, 6)) self.bottomButtons = ButtonGroup(parent=self) self.deliverSelectedBtn = self.bottomButtons.AddButton( localization.GetByLabel('UI/Industry/DeliverSelectedJobs'), self.DeliverSelectedJobs) self.deliverAllBtn = self.bottomButtons.AddButton( localization.GetByLabel('UI/Industry/DeliverAllJobs'), self.DeliverAllJobs) self.scroll = Scroll(parent=self, id='JobBrowser') self.scroll.OnSelectionChange = self.OnScrollSelectionChange self.scroll.Confirm = self.OnScrollReturn self.viewModeButtons = ViewModeButtons( parent=self.topPanel, align=uiconst.TORIGHT, controller=self, settingsID='IndustryBlueprintBrowserViewMode') self.ownerCombo = Combo(name='ownerCombo', parent=self.topPanel, align=uiconst.TOLEFT, callback=self.OnOwnerCombo, width=120, padRight=4) self.statusCombo = Combo(name='statusCombo', parent=self.topPanel, align=uiconst.TOLEFT, prefsKey='IndustryJobStatus', callback=self.OnStatusCombo, width=120, padRight=4) self.activityCombo = Combo(name='activityCombo', parent=self.topPanel, align=uiconst.TOLEFT, prefsKey='IndustryBlueprintActivity', callback=self.OnActivityCombo, options=self.GetActivityOptions(), width=120, padRight=4) self.installerCombo = Combo(name='installerCombo', parent=self.topPanel, align=uiconst.TOLEFT, callback=self.OnInstallerCombo, options=self.GetInstallerOptions(), width=140, padRight=4) self.filterEdit = QuickFilterEdit( name='searchField', parent=self.topPanel, hinttext=localization.GetByLabel('UI/Inventory/Filter'), maxLength=64, align=uiconst.TORIGHT, OnClearFilter=self.OnFilterEditCleared, padRight=4) self.filterEdit.ReloadFunction = self.OnFilterEdit self.UpdateStatusCombo() self.UpdateOwnerCombo() self.UpdateInstallerCombo() self.UpdateScroll() uthread.new(self._UpdateJobCountersThread) def OnTabDeselect(self): if self.isInitialized: self.scroll.Clear() def OnScrollSelectionChange(self, entries): if entries: self.callback(entries[0].jobData) self.UpdateDeliverButtons() def OnScrollReturn(self, *args): self.DeliverJobs(self.scroll.GetSelected()) def OnFilterEdit(self): self.UpdateScroll() def OnFilterEditCleared(self): self.UpdateScroll() def OnViewModeChanged(self, viewMode): self.UpdateScroll() def OnIndustryJob(self, jobID, ownerID, blueprintID, installerID, status, successfulRuns): """ Server telling us that a job changed it's state """ if self.destroyed or self.IsHidden(): return if self.isInitialized and self.display: self.UpdateJobEntry(jobID, status, successfulRuns) self.UpdateDeliverButtons() def OnFacilityReload(self, facilityID): """ Server telling us a facility was modified. If this applies to any jobs currently displayed then we should reload the scroll. """ if self.destroyed or self.IsHidden(): return if self.isInitialized and self.display: for node in self.scroll.GetNodes(): if facilityID is None or node.jobData.facilityID == facilityID: self.UpdateScroll() return def OnSessionChanged(self, isRemote, session, change): """ If we change solarsystem then reload the jobs tab. """ if 'solarsystemid2' in change or 'stationid2' in change: self.UpdateScroll() if 'corpid' in change: self.UpdateOwnerCombo() self.UpdateScroll() def UpdateJobEntry(self, jobID, status, successfulRuns): """ Update the state of an individual job entry """ for node in self.scroll.GetNodes(): if node.jobData.jobID == jobID and node.panel: node.panel.OnStatusChanged(status, successfulRuns) break else: self.UpdateScroll() def IsSomeJobReady(self): for node in self.scroll.GetNodes(): if node.jobData.status == industry.STATUS_READY: return True return False def IsSomeReadyJobSelected(self): for node in self.scroll.GetSelected(): if node.jobData.status == industry.STATUS_READY: return True return False def UpdateDeliverButtons(self): self.deliverAllBtn.display = self.IsSomeJobReady() self.bottomButtons.display = self.deliverAllBtn.display self.deliverSelectedBtn.display = self.IsSomeReadyJobSelected() self.bottomButtons.ResetLayout() def UpdateScroll(self): if not self.isInitialized: return statusFilter = self.statusCombo.selectedValue jobs = self.GetJobData(statusFilter == STATUS_COMPLETED) scrollList = self.GetScrollList(jobs) self.scroll.sr.defaultColumnWidth = JobEntry.GetDefaultColumnWidth() isPersonalJob = self.ownerCombo.GetValue() == OWNER_ME self.scroll.LoadContent( contentList=scrollList, headers=JobEntry.GetHeaders(isPersonalJob=isPersonalJob), noContentHint=localization.GetByLabel('UI/Industry/NoJobsFound')) self.UpdateDeliverButtons() def GetJobData(self, includeCompleted): if self.IsCorpSelected(): jobs = sm.GetService('industrySvc').GetCorporationJobs( includeCompleted) else: jobs = sm.GetService('industrySvc').GetCharacterJobs( includeCompleted) return jobs def GetScrollList(self, jobs): scrollList = [] for jobData in jobs: if self.IsFilteredOut(jobData): continue node = Bunch(jobData=jobData, decoClass=JobEntry, sortValues=JobEntry.GetColumnSortValues( jobData, jobData.distance), viewMode=self.viewModeButtons.GetViewMode(), jumps=max(0, jobData.distance)) scrollList.append(node) return scrollList def IsFilteredOut(self, jobData): statusFilter = self.statusCombo.selectedValue if statusFilter == STATUS_INCOMPLETE and jobData.completed or statusFilter == STATUS_READY and not jobData.status == industry.STATUS_READY or statusFilter == STATUS_INSTALLED and not jobData.status == industry.STATUS_INSTALLED or statusFilter == STATUS_COMPLETED and not jobData.completed or statusFilter == STATUS_PAUSED and not jobData.status == industry.STATUS_PAUSED: return True if self.IsCorpSelected(): installerType = self.installerCombo.GetValue() if installerType == INSTALLER_ME and jobData.installerID != session.charid: return True if installerType == INSTALLER_CORPMATE and jobData.installerID == session.charid: return True filterText = self.filterEdit.GetValue().strip().lower() if filterText: text = jobData.blueprint.GetName() + jobData.GetFacilityName( ) + jobData.GetInstallerName() if text.lower().find(filterText) == -1: return True activityValue = self.activityCombo.GetValue() if activityValue and activityValue != jobData.activityID: return True return False def OnStatusCombo(self, combo, key, value): settings.user.ui.Set('IndustryJobBrowserStatus', value) self.UpdateScroll() def UpdateStatusCombo(self): options = ((localization.GetByLabel('UI/Industry/StatusAllActiveJobs'), STATUS_INCOMPLETE), (localization.GetByLabel('UI/Industry/StatusInProgress'), STATUS_INSTALLED, None, STATUS_ICONS[STATUS_INSTALLED]), (localization.GetByLabel('UI/Industry/StatusReady'), STATUS_READY, None, STATUS_ICONS[STATUS_READY]), (localization.GetByLabel('UI/Industry/StatusHalted'), STATUS_PAUSED, None, STATUS_ICONS[STATUS_PAUSED]), (localization.GetByLabel('UI/Industry/StatusHistory'), STATUS_COMPLETED, None, STATUS_ICONS[STATUS_COMPLETED])) select = settings.user.ui.Get('IndustryJobBrowserStatus', STATUS_INCOMPLETE) self.statusCombo.LoadOptions(options, select=select) def OnActivityCombo(self, *args): self.UpdateScroll() def GetActivityOptions(self): ret = [ (localization.GetByLabel(ACTIVITY_NAMES[activityID]), activityID, None, industryUIConst.ACTIVITY_ICONS_SMALL[activityID]) for activityID in industry.ACTIVITIES ] ret.insert(0, (localization.GetByLabel('UI/Industry/AllActivities'), 0)) return ret def GetInstallerOptions(self): return ((localization.GetByLabel('UI/Industry/InstalledByAnyone'), INSTALLER_ANY), (localization.GetByLabel('UI/Industry/InstalledByMe'), INSTALLER_ME, None, 'res:/UI/Texture/classes/Industry/iconPersonal.png'), (localization.GetByLabel('UI/Industry/InstalledByCorpmates'), INSTALLER_CORPMATE, None, 'res:/UI/Texture/classes/Industry/iconCorp.png')) def OnInstallerCombo(self, combo, key, value): settings.user.ui.Set('IndustryJobsBrowserInstaller', value) self.UpdateScroll() def UpdateInstallerCombo(self): self.installerCombo.display = self.IsCorpSelected() value = settings.user.ui.Get('IndustryJobsBrowserInstaller', INSTALLER_ANY) self.installerCombo.SelectItemByValue(value) def OnOwnerCombo(self, combo, key, value): settings.user.ui.Set('IndustryBlueprintBrowserOwner', value) self.UpdateInstallerCombo() self.UpdateScroll() def IsCorpSelected(self): return self.ownerCombo.GetValue() == OWNER_CORP def UpdateOwnerCombo(self): options = [(localization.GetByLabel('UI/Industry/OwnedByMe'), OWNER_ME) ] if sm.GetService('blueprintSvc').CanSeeCorpBlueprints(): options.append((localization.GetByLabel('UI/Industry/OwnedByCorp'), OWNER_CORP, None, 'res:/UI/Texture/classes/Industry/iconCorp.png')) select = settings.user.ui.Get('IndustryBlueprintBrowserOwner', OWNER_ME) self.ownerCombo.LoadOptions(options, select=select) def _UpdateJobCountersThread(self): msecs = 0 while not self.destroyed: animate = False msecs += INTERVAL_UPDATE if msecs >= INTERVAL_FLASH: msecs = 0 animate = True nodes = self.scroll.GetVisibleNodes() for i, node in enumerate(nodes): if node.panel: node.panel.UpdateValues(animate, i) blue.synchro.SleepWallclock(INTERVAL_UPDATE) def DeliverAllJobs(self, *args): self.DeliverJobs(self.scroll.GetNodes()) def DeliverSelectedJobs(self, *args): self.DeliverJobs(self.scroll.GetSelected()) def DeliverJobs(self, nodes): jobIDs = [ node.jobData.jobID for node in nodes if node.jobData.status == industry.STATUS_READY ] sm.GetService('industrySvc').CompleteJobs(jobIDs) sm.GetService('audio').SendUIEvent('ind_jobDelivered')
class PythonObjectClassDetails(Window): default_caption = 'Python Object Class Details' default_windowID = 'pythonobjectclassdetails' default_minSize = (500, 400) def ApplyAttributes(self, attributes): self._ready = False Window.ApplyAttributes(self, attributes) self.collectTimestamp = None self.itemClass = attributes.itemClass self.classDetailsContainer = Container(parent=self.sr.topParent, align=uiconst.TOTOP, height=32, padding=16) self.scroll = Scroll(parent=self.sr.main, id='pythonobjectclassdetailscroll', align=uiconst.TOALL) self.ShowObjectDetail() self._ready = True def Close(self, setClosed=False, *args, **kwds): self.scroll = None self.classDetailsContainer = None gc.collect() Window.Close(self, setClosed, *args, **kwds) def Refresh(self): self.scroll.Clear() self.classDetailsContainer.Flush() self.ShowObjectDetail() def SwitchItemClass(self, itemClass): if not self._ready: return self.itemClass = itemClass self._ready = False self.Refresh() self._ready = True def ShowObjectDetail(self): objectDetails = self.GetObjectDetails() classLabel = EveLabelMedium(name='classLabel', parent=self.classDetailsContainer, text='module.class: %s' % self.itemClass, align=uiconst.TOPLEFT) timeStamp = EveLabelMedium(name='timestamp', parent=self.classDetailsContainer, text='Collected at %s' % FmtDate(self.collectTimestamp), align=uiconst.BOTTOMLEFT) oCount = len(objectDetails) objectCount = EveLabelMedium(name='oCount', parent=self.classDetailsContainer, text='%s Object%s' % (oCount, ['', 's'][oCount > 1]), align=uiconst.BOTTOMRIGHT) self.PopulateScroll(objectDetails) def PopulateScroll(self, objectData): contentList = [] for object in objectData: objectName = self.GetObjectName(object) data = { 'GetSubContent': self.GetReferees, 'label': objectName, 'id': objectName, 'instanceData': object, 'sublevel': 0, 'showlen': 0 } contentList.append(listentry.Get('Group', data)) self.scroll.Load(contentList=contentList) def GetReferees(self, data, *args): refList = [] object = data.instanceData referrers = gc.get_referrers(object) myref = stackless.getcurrent().frame known = [ gc.garbage, stackless.getcurrent().frame, object, data, self.scroll ] for ref in referrers: if ref not in known: try: objectName = self.GetObjectName(ref) listEntry = ScrollEntryNode(decoClass=SE_GenericCore, id=id, name=objectName, label=objectName, sublevel=1) refList.append(listEntry) except Exception as e: log.LogError( 'Failed naming reference! Need to do something about this error' ) return refList def GetObjectDetails(self): self.collectTimestamp = startTime = blue.os.GetWallclockTimeNow() activeObjects = gc.get_objects() objectDetails = [] for activeObject in activeObjects: typeOrClass = type(activeObject) if not isinstance(activeObject, weakref.ProxyType): try: typeOrClass = activeObject.__class__ except AttributeError: sys.exc_clear() objectName = '%s.%s' % (typeOrClass.__module__, typeOrClass.__name__) if objectName == self.itemClass: objectDetails.append(activeObject) endTime = blue.os.GetWallclockTimeNow() log.LogInfo('Finished fetching object details in %s Ms' % blue.os.TimeDiffInMs(startTime, endTime)) return objectDetails def GetObjectName(self, object): Swing = MultipleReplacer({ '&': '&', '<': '<', '>': '>', '\n': '<br>', ' ': ' ' }) objectName = '%s at 0x%.8x: %s' % (object.__class__, id(object), repr(object)) objectName = '%s - Ref Count = %s' % (objectName, sys.getrefcount(object) - 4) objectName = Swing(objectName) return objectName