Esempio n. 1
0
class NotificationUIService(CoreService):
    __guid__ = 'svc.notificationUIService'
    __notifyevents__ = [
        'OnNewNotificationReceived', 'OnSetDevice',
        'OnLocalNotificationSettingChanged'
    ]
    __startupdependencies__ = [
        'settings', 'mailSvc', 'notificationSvc', 'logger'
    ]

    def Run(self, memstream=None):
        self.notificationCenter = None
        self.notificationCache = None
        self.pendingNotificationCache = []
        self.cacheFillThread = None
        self.unreadCounter = 0
        self.notificationSettings = NotificationSettingHandler()
        self.notificationGenerator = NotificationGenerator()
        self.isEnabled = self.notificationSettings.GetNotificationWidgetEnabled(
        )
        self.shouldShowOnEnable = False
        self.__developerMode = False
        self.adapterRegistry = [
            ContactNotificationAdapter(),
            CCPNotificationAdapter(),
            ShutdownNotificationAdapter(),
            OreMinedNotificationAdapter(sm.GetService('logger')),
            BountyNotificationAdapter(sm.GetService('logger'))
        ]
        for adapter in self.adapterRegistry:
            sm.RegisterNotify(adapter)

        self.lastSeenMessageTime = self.notificationSettings.GetLastSeenTime()
        self.lastHistoryTimeCleanTime = self.notificationSettings.GetLastHistoryTimeCleanTime(
        )
        self.lastSeenNotificationId = self.notificationSettings.GetLastSeenNotificationId(
        )
        self.lastClearedNotificationId = self.notificationSettings.GetLastClearedNotificationId(
        )

    def OnLocalNotificationSettingChanged(self):
        self.UpdateEnabledStatus()

    def Stop(self, memStream=None):
        CoreService.Stop(self, memStream)
        for adapter in self.adapterRegistry:
            sm.UnregisterNotify(adapter)

    def PlaySound(self, eventName):
        if self.notificationSettings.GetNotificationSoundEnabled():
            sm.GetService('audio').SendUIEvent(eventName)

    def ToggleDeveloperMode(self):
        print 'TogglingDeveloperMode'
        self.__developerMode = not self.__developerMode
        print 'DeveloperMode is ' + str(self.__developerMode)

    def IsDeveloperMode(self):
        return self.__developerMode

    def IsEnabled(self):
        return self.isEnabled

    def OnNewNotificationReceived(self, notification):
        if self.isEnabled:
            self._InsertNotification(notification)
            self._DisplayNotificationIfPossible(notification)

    def SpawnFakeNotifications(self):
        self.notificationGenerator.Start()

    def ResetUnreadCounter(self):
        if self.notificationCache and len(self.notificationCache) > 0:
            self._SetLastReadTime(self.notificationCache[0].created)
        self.unreadCounter = 0
        self._UpdateCounter()

    def _UpdateCounter(self):
        if self.notificationCenter:
            self.notificationCenter.SetBadgeValue(self.unreadCounter)
            if self.unreadCounter == 0:
                self.notificationCenter.hideBadge()
            else:
                self.notificationCenter.showBadge()

    def _IncrementCounter(self):
        self.unreadCounter = self.unreadCounter + 1
        self._UpdateCounter()

    def _SetLastReadTime(self, lastReadTimeStamp):
        self.lastSeenMessageTime = lastReadTimeStamp
        self.notificationSettings.SetLastSeenTime(self.lastSeenMessageTime)

    def _ShouldIncrementCounterForNotification(self, notification):
        notificationSetting = self.notificationSettings.LoadSettings()
        specificSetting = notificationSetting.get(notification.typeID)
        if specificSetting and specificSetting.showAtAll:
            return True
        return False

    def _IncrementCounterIfIShould(self, notification):
        if self._ShouldIncrementCounterForNotification(notification):
            self._IncrementCounter()

    def _InsertNotification(self, notification):
        self._IncrementCounterIfIShould(notification)
        if self.notificationCache is None:
            self.pendingNotificationCache.append(notification)
        else:
            self.notificationCache.insert(0, notification)

    def _DisplayNotificationIfPossible(self, notification):
        if self.notificationCenter:
            self.notificationCenter.DisplaySingleNotification(notification)

    def ClearHistory(self):
        self.lastHistoryTimeCleanTime = self.lastSeenMessageTime
        self.lastClearedNotificationId = self.lastSeenNotificationId
        self.notificationSettings.SetLastHistoryCleanTime(
            self.lastHistoryTimeCleanTime)
        self.notificationSettings.SetLastClearedNotificationId(
            self.lastClearedNotificationId)
        self.ClearCache()

    def UnClearHistory(self):
        self.lastHistoryTimeCleanTime = 0
        self.lastClearedNotificationId = 0
        self.lastSeenNotificationId = 0
        self.notificationSettings.SetLastHistoryCleanTime(
            self.lastHistoryTimeCleanTime)
        self.notificationSettings.SetLastClearedNotificationId(
            self.lastClearedNotificationId)
        self.SaveLastSeenNotificationId()
        self.ClearCache()

    def SaveLastSeenNotificationId(self):
        self.notificationSettings.SetLastSeenNotificationId(
            self.lastSeenNotificationId)

    def OnSetDevice(self):
        pass

    def _IsCacheInitialized(self):
        return self.notificationCache is not None

    def _CheckAndFillCache(self):
        if self.notificationCache is None:
            self.notificationCache = self._NotificationProvider(sortThem=False)
            self.notificationCache.extend(self.pendingNotificationCache)
            self.pendingNotificationCache = []
            self._SortNotifications(self.notificationCache)
            counter = 0
            for notification in self.notificationCache:
                if notification.created > self.lastSeenMessageTime and self._ShouldIncrementCounterForNotification(
                        notification):
                    counter += 1
                self.lastSeenNotificationId = max(notification.notificationID,
                                                  self.lastSeenNotificationId)

            self.SaveLastSeenNotificationId()
            self.unreadCounter = counter
            self._UpdateCounter()
            self._NotifyInitialized()

    def _NotifyInitialized(self):
        if self.notificationCenter:
            self.notificationCenter.SetCacheIsInitialized(True)

    def _NotifyUnInitialized(self):
        if self.notificationCenter:
            self.notificationCenter.SetCacheIsInitialized(False)

    def UpdateEnabledStatus(self):
        if self.notificationSettings.GetNotificationWidgetEnabled():
            self.SetEnabled(True)
        else:
            self.SetEnabled(False)

    def SetEnabled(self, value):
        if value is self.isEnabled:
            return
        if self.shouldShowOnEnable and value is True:
            self.isEnabled = True
            self.Show()
        else:
            self.TearDown()
            self.isEnabled = value

    def _StartCheckAndFillCacheThread(self):
        import uthread
        uthread.new(self._CheckAndFillCache)

    def Show(self):
        self.shouldShowOnEnable = True
        if self.isEnabled:
            self._ConstructNotificationCenter()
            self._StartCheckAndFillCacheThread()
        else:
            self.UpdateEnabledStatus()

    def ToggleEnabledFlag(self):
        if self.isEnabled:
            self.Hide()
            self.isEnabled = False
        else:
            self.isEnabled = True
            self.Show()

    def Hide(self):
        self.shouldShowOnEnable = False
        self.TearDown()

    def TearDown(self):
        if self.isEnabled:
            self._TearDownNotificationCenter()
        self.ClearCache(refillCache=False)

    def _TearDownNotificationCenter(self):
        if self.notificationCenter:
            self.notificationCenter.deconstruct()
            self.notificationCenter = None

    def _OnNotificationCenterReconstructed(self):
        self._UpdateCounter()

    def _ConstructNotificationCenter(self):
        if self.isEnabled:
            self._TearDownNotificationCenter()
            self.notificationCenter = NotificationCenter(
                onReconstructCallBack=self._OnNotificationCenterReconstructed,
                developerMode=self.IsDeveloperMode(),
                audioCallback=self.PlaySound)
            self.notificationCenter.Construct(
                notificationProviderFunction=self._PersonalCachedProvider)
            self.notificationCenter.SetCacheIsInitialized(
                self._IsCacheInitialized())
            self._UpdateCounter()

    def _PersonalCachedProvider(self):
        if self.notificationCache is None:
            self._CheckAndFillCache()
        else:
            self.ResetUnreadCounter()
        return self.notificationCache

    def _SortNotifications(self, notificationList):
        notificationList.sort(key=lambda notification: notification.created,
                              reverse=True)

    def _NotificationProvider(self, sortThem=True):
        from notifications.client.development.skillHistoryProvider import SkillHistoryProvider
        skillNotifications = SkillHistoryProvider(
            onlyShowAfterDate=self.lastHistoryTimeCleanTime).provide()
        achievementNotifications = self.GetAchievementNotifications()
        restOfNotifications = sm.GetService(
            'notificationSvc').GetAllFormattedNotifications(
                fromID=self.lastClearedNotificationId)
        sortedList = skillNotifications + restOfNotifications + achievementNotifications
        if sortThem:
            self._SortNotifications(sortedList)
        return sortedList

    def GetAchievementNotifications(self):
        if not sm.GetService('experimentClientSvc').OpportunitiesEnabled():
            return []
        from notifications.client.development.achievementHistoryProvider import AchievementHistoryProvider
        notifications = AchievementHistoryProvider(
            onlyShowAfterDate=self.lastHistoryTimeCleanTime).provide()
        achievementNotifications = sm.GetService(
            'notificationSvc').FormatNotifications(notifications)
        return achievementNotifications

    def ClearCache(self, refillCache=True):
        self.notificationCache = None
        sm.GetService('notificationSvc').ClearAllNotificationsCache()
        self._NotifyUnInitialized()
        if refillCache:
            self._CheckAndFillCache()
class NotificationSettingsMainContainer(Container):
    default_clipChildren = True

    def ApplyAttributes(self, attributes):
        Container.ApplyAttributes(self, attributes=attributes)
        self.isDeveloperMode = attributes.get('developerMode', True)
        self.basePadLeft = 5
        self.dev_simpleHistoryDisplayEnabled = False
        self.dev_historySettingsEnabled = True
        self.dev_exportNotificationHistoryEnabled = False
        self.dev_clearNotificationHistoryEnabled = False
        self.dev_soundSettingsEnabled = True
        parentwidth = attributes.get('parentwidth')
        self.lastVerticalBarEnabledStatus = False
        self.entryCache = {}
        self.leftContainer = NotificationSettingList(name='LeftContainer', align=uiconst.TOLEFT, width=parentwidth / 2, padding=4, parent=self, developerMode=self.isDeveloperMode)
        self.rightContainer = Container(name='RightContainer', align=uiconst.TOALL, padding=(0, 4, 4, 4), parent=self)
        BumpedUnderlay(name='leftUnderlay', bgParent=self.leftContainer)
        BumpedUnderlay(name='rightUnderlay', bgParent=self.rightContainer)
        self.notificationSettingHandler = NotificationSettingHandler()
        self.notificationSettingData = self.notificationSettingHandler.LoadSettings()
        self._SetupRightSide()
        self.leftContainer.PopulateScroll()

    def ReloadSettings(self):
        self.leftContainer.ReloadScroll()

    def _SetupRightSide(self):
        self._SetupPopupArea()
        if self.dev_historySettingsEnabled:
            self._SetupHistoryArea()
        self._SetupUIArea()

    def _SetupPopupArea(self):
        self.popupSettingsContainer = ContainerAutoSize(name='PopupSettings', align=uiconst.TOTOP, parent=self.rightContainer, padding=(self.basePadLeft,
         5,
         10,
         0))
        EveLabelMediumBold(name='PopupHeader', align=uiconst.TOTOP, parent=self.popupSettingsContainer, text=localization.GetByLabel('Notifications/NotificationSettings/PopupsHeader'))
        self._MakeSeperationLine(self.popupSettingsContainer)
        Checkbox(name='UsepopupNotifications', text=localization.GetByLabel('Notifications/NotificationSettings/UsePopupNotifications'), parent=self.popupSettingsContainer, align=uiconst.TOTOP, checked=self.notificationSettingHandler.GetPopupsEnabled(), callback=self.OnShowPopupNotificationToggle)
        if self.dev_soundSettingsEnabled:
            Checkbox(name='Play sound checkbox', text=localization.GetByLabel('Notifications/NotificationSettings/PlaySound'), parent=self.popupSettingsContainer, align=uiconst.TOTOP, checked=self.notificationSettingHandler.GetNotificationSoundEnabled(), callback=self.OnPlaySoundToggle)
        self.MakeSliderTextRow(label=localization.GetByLabel('Notifications/NotificationSettings/FadeDelay'), minValue=0, maxValue=10.0, startValue=self.notificationSettingHandler.GetFadeTime(), stepping=0.5, endSliderFunc=self.OnFadeDelaySet)
        self.MakeSliderTextRow(label=localization.GetByLabel('Notifications/NotificationSettings/StackSize'), minValue=1, maxValue=10, startValue=self.notificationSettingHandler.GetStackSize(), stepping=1, endSliderFunc=self.OnStackSizeSet)

    def OnFadeDelaySet(self, slider):
        self.notificationSettingHandler.SaveFadeTime(slider.GetValue())
        sm.ScatterEvent('OnNotificationFadeTimeChanged', slider.GetValue())

    def OnStackSizeSet(self, slider):
        self.notificationSettingHandler.SaveStackSize(slider.GetValue())
        sm.ScatterEvent('OnNotificationStackSizeChanged', slider.GetValue())

    def _MakeSeperationLine(self, parent):
        Line(name='topLine', parent=parent, align=uiconst.TOTOP, weight=1, padBottom=2, opacity=0.3)

    def OnShowPopupNotificationToggle(self, checkbox):
        self.notificationSettingHandler.TogglePopupsEnabled()

    def OnPlaySoundToggle(self, *args):
        self.notificationSettingHandler.ToggleSoundEnabled()

    def _SetupHistoryArea(self):
        self.historySettingsContainer = ContainerAutoSize(name='HistorySettings', align=uiconst.TOTOP, parent=self.rightContainer, alignMode=uiconst.TOTOP, padding=(self.basePadLeft,
         0,
         0,
         0))
        EveLabelMediumBold(name='History', align=uiconst.TOTOP, parent=self.historySettingsContainer, text=localization.GetByLabel('Notifications/NotificationSettings/HistoryHeader'))
        self._MakeSeperationLine(self.historySettingsContainer)
        Button(name='Restore Notification History Button', align=uiconst.TOTOP, label=localization.GetByLabel('Notifications/NotificationSettings/RestoreNotificationHistory'), func=self.OnExportHistoryClick, pos=(0, 0, 100, 20), parent=self.historySettingsContainer, padding=(5, 5, 50, 5))
        Button(name='clearNotificationHistoryBtn', align=uiconst.TOTOP, label=localization.GetByLabel('Notifications/NotificationSettings/ClearNotificationHistory'), func=self.OnClearHistoryClick, pos=(0, 0, 100, 20), parent=self.historySettingsContainer, padding=(5, 0, 50, 5))

    def _SetupUIArea(self):
        self.UISettingsContainer = ContainerAutoSize(name='HistorySettings', align=uiconst.TOTOP, parent=self.rightContainer, alignMode=uiconst.TOTOP, padLeft=self.basePadLeft)
        EveLabelMediumBold(name='UI', align=uiconst.TOTOP, parent=self.UISettingsContainer, text=localization.GetByLabel('Notifications/NotificationSettings/UISettingHeader'))
        self._MakeSeperationLine(self.UISettingsContainer)
        if self.dev_simpleHistoryDisplayEnabled:
            Checkbox(name='simple history view', text=localization.GetByLabel('Notifications/NotificationSettings/SimpleHistoryDisplay'), parent=self.UISettingsContainer, align=uiconst.TOTOP, checked=True)
        hComboRowContainer = Container(name='ComboBoxRow', parent=self.UISettingsContainer, align=uiconst.TOTOP, alignMode=uiconst.TOTOP, height=40, padRight=10)
        from eve.client.script.ui.control.eveCombo import Combo
        Combo(name='H-ExpandCombo', parent=hComboRowContainer, labelleft=120, label=localization.GetByLabel('Notifications/NotificationSettings/DefaultHExpand'), hint=localization.GetByLabel('Notifications/NotificationSettings/DefaultHExpandToolTip'), options=self.GetHorizontalComboOptions(), align=uiconst.TOTOP, width=self.rightContainer.width, callback=self.OnHorizontalComboSelect, select=self.notificationSettingHandler.GetHorizontalExpandAlignment())
        Combo(name='V-ExpandCombo', parent=hComboRowContainer, labelleft=120, label=localization.GetByLabel('Notifications/NotificationSettings/DefaultVExpand'), hint=localization.GetByLabel('Notifications/NotificationSettings/DefaultVExpandToolTip'), align=uiconst.TOTOP, options=self.GetVerticalComboOptions(), width=self.rightContainer.width, callback=self.OnVerticalComboSelect, select=self.notificationSettingHandler.GetVerticalExpandAlignment())

    def OnVerticalComboSelect(self, box, key, value):
        self.notificationSettingHandler.SetVerticalExpandAlignment(value)

    def OnHorizontalComboSelect(self, box, key, value):
        self.notificationSettingHandler.SetHorizontalExpandAlignment(value)

    def GetHorizontalComboOptions(self):
        return ((localization.GetByLabel('Notifications/NotificationSettings/ExpandDirectionLeft'), ExpandAlignmentConst.EXPAND_ALIGNMENT_HORIZONTAL_LEFT), (localization.GetByLabel('Notifications/NotificationSettings/ExpandDirectionRight'), ExpandAlignmentConst.EXPAND_ALIGNMENT_HORIZONTAL_RIGHT))

    def GetVerticalComboOptions(self):
        return ((localization.GetByLabel('Notifications/NotificationSettings/ExpandDirectionUp'), ExpandAlignmentConst.EXPAND_ALIGNMENT_VERTICAL_UP), (localization.GetByLabel('Notifications/NotificationSettings/ExpandDirectionDown'), ExpandAlignmentConst.EXPAND_ALIGNMENT_VERTICAL_DOWN))

    def OnExportHistoryClick(self, *args):
        sm.GetService('notificationUIService').UnClearHistory()

    def OnClearHistoryClick(self, *args):
        sm.GetService('notificationUIService').ClearHistory()

    def MakeSliderTextRow(self, label, minValue, maxValue, startValue, stepping, setValueFunc = None, endSliderFunc = None):
        sliderWidth = 100
        sliderValueWidth = 30
        sliderLabelWidth = 120
        rowPadding = (5, 2, 10, 2)
        size = EveLabelSmall.MeasureTextSize(label, width=sliderLabelWidth)
        rowHeight = size[1]
        rowContainer = Container(name='TextRowContainer', parent=self.rightContainer, align=uiconst.TOTOP, alignMode=uiconst.TOTOP, height=rowHeight, padding=rowPadding)
        EveLabelSmall(name='sliderlabel', align=uiconst.TOLEFT, parent=rowContainer, text=label, width=sliderLabelWidth)
        increments = []
        currentValue = minValue
        while currentValue <= maxValue:
            increments.append(currentValue)
            currentValue = currentValue + stepping

        valueLabel = EveLabelSmall(name='sliderValuelabel', left=sliderWidth, align=uiconst.CENTERRIGHT, text=str(startValue), width=sliderValueWidth)

        def UpdateLabel(slider):
            valueLabel.text = str(slider.GetValue())

        Slider(name='niceSlider', align=uiconst.CENTERRIGHT, parent=rowContainer, minValue=minValue, maxValue=maxValue, width=sliderWidth, showLabel=False, startVal=startValue, isEvenIncrementsSlider=True, increments=increments, onsetvaluefunc=UpdateLabel, endsliderfunc=endSliderFunc)
        rowContainer.children.append(valueLabel)
        return rowContainer