Example #1
0
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)
Example #2
0
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()
Example #3
0
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')
Example #4
0
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({
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '\n': '<br>',
            '    ': '&nbsp;&nbsp;&nbsp;'
        })
        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