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

presetservice.py (59311B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\overview\presetservice.py
      2 import logging
      3 from copy import deepcopy
      4 import blue
      5 import yaml
      6 from carbonui import uiconst
      7 import eve.client.script.parklife.stateSetting as stateSetting
      8 import eve.client.script.parklife.states as stateConst
      9 import localization
     10 import overviewPresets.overviewSettingsConst as oConst
     11 import overviewPresets.overviewSharingConst as sharingConst
     12 import utillib
     13 from bannedwords.client import bannedwords
     14 from carbon.common.script.sys.service import Service
     15 from eve.client.script.parklife.bracketConst import SHOW_ALL, SHOW_NONE, SHOW_DEFAULT
     16 from eve.client.script.parklife.overview import overviewSignals
     17 from eve.client.script.parklife.overview.blocker import OverviewBlocker
     18 from eve.client.script.parklife.overview.default.defaultoverviews import DefaultOverviews
     19 from eve.client.script.parklife.overview.default.settings import DefaultOverviewSettings
     20 from eve.client.script.parklife.overview.default.informer import DefaultOverviewUpdateInformer
     21 from eve.client.script.parklife.overview.override import OverviewOverride
     22 from eve.client.script.parklife.state import GetStateColors, FindColorName, GetNPCGroups
     23 from eve.client.script.parklife.tacticalConst import get_group_ids
     24 from eve.client.script.ui.inflight.bracketsAndTargets.bracketNameFormatting import GetAllowedLabelTypes, GetAllowedVariables
     25 from eve.client.script.ui.inflight.overview import overviewConst, overviewColumns
     26 from eve.client.script.ui.inflight.overview.overviewConst import LABEL_TYPE, LABEL_TYPE_LINEBREAK
     27 from eve.client.script.ui.util import utilWindows
     28 from eve.client.script.ui.view.viewStateConst import is_entering_space
     29 from eve.client.script.util.settings import EncodeSetting
     30 from eveexceptions import ExceptionEater, UserError
     31 from localization import GetByLabel
     32 from overviewPresets.overviewPresetUtil import EncodeKeyInDict, DecodeKeyInDict, GetDeterministicListFromDict, IsPresetTheSame, GetDictFromList, ReplaceInnerListsWithDicts, ReorderList, GetOrderedListFromDict
     33 from overviewPresets.overviewSettingsConst import SETTING_BRACKET_PRESET_NAME, SETTING_OVERVIEW_PRESET_NAME, SETTING_TAB_COLOR, SETTING_TAB_NAME, SETTING_BRACKETS_SHOWNONE, SETTING_BRACKETS_SHOWSPECIALS, SETTING_BRACKETS_SHOWALL, PRESET_SETTINGS_ALWAYS_SHOWN_STATES, PRESET_SETTINGS_GROUPS, PRESET_SETTINGS_FILTERED_STATES, MAX_TAB_NUM
     34 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     35 from storylines.client.airnpe import is_air_npe_active
     36 DEFAULT_BROADCAST_TO_TOP = True
     37 log = logging.getLogger(__name__)
     38 
     39 class OverviewPresetSvc(Service):
     40     __guid__ = 'svc.overviewPresetSvc'
     41     __displayName__ = 'Overview Preset Service'
     42     __serviceName__ = 'This service handles overview presets'
     43     __notifyevents__ = ['OnViewStateChanged']
     44     __update_on_reload__ = 1
     45 
     46     def Run(self, *args):
     47         Service.Run(self, *args)
     48         self._Setup()
     49         self.Initialize()
     50 
     51     def _HadOverviewSettings(self):
     52         try:
     53             overviewID = self.defaultOverviewSettings.get_overview()
     54             defaultOverviewID = self.defaultOverviewSettings.get_default_overview()
     55             shipLabels = settings.user.overview.Get(oConst.SETTINGS_SHIP_LABELS, None)
     56             activePreset = settings.user.overview.Get(oConst.SETTING_ACTIVE_PRESET, None)
     57             presets = settings.user.overview.Get(oConst.SETTING_PRESETS, None)
     58             presetsOld = settings.user.overview.Get(oConst.SETTING_OLD_PRESET_BACKUP, None)
     59             tabs = settings.user.overview.Get(oConst.SETTING_TAB_SETTINGS_OLD, None)
     60             tabsNew = settings.user.overview.Get(oConst.SETTING_TAB_SETTINGS, None)
     61             result = any([overviewID,
     62              defaultOverviewID,
     63              shipLabels,
     64              activePreset,
     65              presets,
     66              presetsOld,
     67              tabs,
     68              tabsNew])
     69             with ExceptionEater('Failed to log checks in _HadOverviewSettings'):
     70                 log.info('Default Overview: Checking if player had any settings:\n    Result: {result}, \n    Overview ID: {overviewID}, \n    Default Overview ID: {defaultOverviewID}, \n    Ship Labels: {shipLabels}, \n    Active Preset: {activePreset}, \n    Presets: {presets}, \n    Presets (Backup): {presetsOld}, \n    Tabs: {tabs}, \n    Tabs (New): {tabsNew}, \n'.format(result=result, overviewID=EncodeSetting(overviewID), defaultOverviewID=EncodeSetting(defaultOverviewID), shipLabels=EncodeSetting(shipLabels), activePreset=EncodeSetting(activePreset), presets=EncodeSetting(presets), presetsOld=EncodeSetting(presetsOld), tabs=EncodeSetting(tabs), tabsNew=EncodeSetting(tabsNew)))
     71             return result
     72         except Exception as exc:
     73             log.exception('Failed to check if player had Overview Settings: %s', exc)
     74             return False
     75 
     76     def _Setup(self):
     77         self.isReadOnly = False
     78         self.configNamesAndDefaults = None
     79         self.cachedPresetsFromServer = {}
     80         self.overviewOverride = OverviewOverride()
     81         self._SetupDefaultOverviews()
     82         self.overviewBlocker = OverviewBlocker(initialize_function=self.Initialize, reset_function=self.ResetOverviewSettingsToDefault, set_read_only_function=self.SetReadOnly, default_settings=self.defaultOverviewSettings)
     83 
     84     def _SetupDefaultOverviews(self):
     85         self.isDefaultInitialized = False
     86         self.defaultOverviewSettings = DefaultOverviewSettings()
     87         self.hadOverviewSettings = self._HadOverviewSettings()
     88         self.defaultOverviews = DefaultOverviews(general_settings_loader=self._LoadGeneralSettings if not self.hadOverviewSettings else None)
     89         self.defaultOverviewUpdater = DefaultOverviewUpdateInformer(settings=self.defaultOverviewSettings, defaults=self.defaultOverviews, should_delay=is_air_npe_active)
     90         previousDefaultOverview = self.defaultOverviewSettings.get_default_overview()
     91         newDefaultOverview = self.defaultOverviews.default_overview_id
     92         if previousDefaultOverview != newDefaultOverview:
     93             self.defaultOverviewSettings.set_default_overview(newDefaultOverview)
     94             self.defaultOverviewSettings.set_informed_of_update(False)
     95         if not self.hadOverviewSettings:
     96             self.isDefaultInitialized = True
     97             self.defaultOverviewSettings.set_overview(newDefaultOverview)
     98             self.defaultOverviewSettings.set_informed_of_update(True)
     99             log.info('Default Overview: Setting default as the player has no settings')
    100 
    101     def OnViewStateChanged(self, _fromView, toView):
    102         if self.isDefaultInitialized or not is_entering_space(toView):
    103             return
    104         self.isDefaultInitialized = self.defaultOverviewUpdater.update()
    105 
    106     def ResetDefaultOverviewData(self, defaultOverviewID):
    107         try:
    108             self.defaultOverviews.switch(defaultOverviewID, self.LoadGeneralSettings)
    109             self._ResetSettings(overviewID=defaultOverviewID)
    110             self.defaultPreset = self.defaultOverviews.get_default_preset()
    111         except Exception as exc:
    112             self.LogException('Failed to reset default overview data to {overviewID}: {exc}'.format(overviewID=defaultOverviewID, exc=exc))
    113 
    114         self.defaultOverviewSettings.set_default_overview(self.defaultOverviews.default_overview_id)
    115         self.defaultOverviewSettings.set_informed_of_update(True)
    116 
    117     def _AddMissingPresetsFromOtherDefaultOverviews(self):
    118         namesToLoad = []
    119         oldTabSettings = self.GetSettingsByTabID()
    120         newTabSettings = {}
    121         for tabIdx, tabSettings in oldTabSettings.iteritems():
    122             newTabSettings[tabIdx] = tabSettings
    123             for setupGroupName in (SETTING_OVERVIEW_PRESET_NAME, SETTING_BRACKET_PRESET_NAME):
    124                 if setupGroupName not in tabSettings:
    125                     continue
    126                 presetName = tabSettings[setupGroupName]
    127                 if presetName in self.allPresets:
    128                     continue
    129                 name, data = self.defaultOverviews.get_old_preset(presetName)
    130                 if name and data:
    131                     self.allPresets[name] = data
    132                     newTabSettings[tabIdx][setupGroupName] = name
    133                     namesToLoad.append(name)
    134 
    135         if namesToLoad:
    136             self._PersistPresets()
    137             self.PersistSettingsByTabID(newTabSettings)
    138             sm.ScatterEvent('OnOverviewPresetSaved')
    139 
    140     def Initialize(self):
    141         self.defaultPreset = self.defaultOverviews.get_default_preset()
    142         self.LoadPresetsFromUserSettings()
    143         self._AddMissingPresetsFromOtherDefaultOverviews()
    144         self.activeOverviewPresetName = settings.user.overview.Get(oConst.SETTING_ACTIVE_PRESET, self.defaultPreset)
    145         self.activeBracketPresetName = None
    146         self.AddDefaultPresetsToAllPresets()
    147         self._PersistPresets()
    148 
    149     def IsReadOnly(self):
    150         return self.isReadOnly
    151 
    152     def SetReadOnly(self, isReadOnly):
    153         self.isReadOnly = isReadOnly
    154 
    155     def BlockOverview(self):
    156         self.overviewBlocker.block()
    157 
    158     def UnblockOverview(self):
    159         self.overviewBlocker.unblock()
    160 
    161     def AddDefaultPresetsToAllPresets(self):
    162         for presetName in self.GetDefaultOverviewPresetNames():
    163             self.allPresets[presetName] = self.defaultOverviews.get_preset_data(presetName)
    164 
    165     def LoadPresetsFromUserSettings(self):
    166         try:
    167             self.ConvertOldSettingsToNewSettings()
    168             if settings.user.overview.Get(oConst.SETTING_PRESETS, None) is not None:
    169                 oldPresets = settings.user.overview.Get(oConst.SETTING_PRESETS, {}).copy()
    170                 settings.user.overview.Set(oConst.SETTING_OLD_PRESET_BACKUP, oldPresets.copy())
    171                 for presetKey, presetValue in oldPresets.iteritems():
    172                     presetValue.pop('ewarFilters', None)
    173 
    174                 settings.user.overview.Delete(oConst.SETTING_PRESETS)
    175             else:
    176                 oldPresets = {}
    177         except Exception as e:
    178             log.exception('Error when migrating overview presets, e = %s' % e)
    179             settings.user.overview.Delete(oConst.SETTING_PRESETS)
    180             oldPresets = {}
    181 
    182         self.allPresets = settings.user.overview.Get(oConst.SETTING_PROFILE_PRESETS, oldPresets)
    183         self.unsavedPresets = self._GetUnsavedPresets()
    184         self.ReorderPresets(self.allPresets)
    185         self.ReorderPresets(self.unsavedPresets)
    186 
    187     def _GetUnsavedPresets(self):
    188         default = settings.user.overview.Get(oConst.SETTING_PROFILE_PRESETS_NOT_SAVED, {})
    189         unsavedPresets = settings.user.overview.Get(oConst.SETTING_PROFILE_PRESETS_NOT_SAVED2, default)
    190         return unsavedPresets
    191 
    192     def ConvertOldSettingsToNewSettings(self):
    193         with ExceptionEater('Failed to convert old overview settings to new'):
    194             for oldSettingName, newSettingName in ((stateSetting.SETTING_OLD_BACKGROUND_STATES_CONFIG_NAME, stateSetting.SETTING_BACKGROUND_STATES_CONFIG_NAME),
    195              (stateSetting.SETTING_OLD_FLAG_STATES_CONFIG_NAME, stateSetting.SETTING_FLAG_STATES_CONFIG_NAME),
    196              (stateSetting.SETTING_OLD_FLAG_ORDER_CONFIG_NAME, stateSetting.SETTING_FLAG_ORDER_CONFIG_NAME),
    197              (stateSetting.SETTING_OLD_BACKGROUND_ORDER_CONFIG_NAME, stateSetting.SETTING_BACKGROUND_ORDER_CONFIG_NAME)):
    198                 oldSettings = settings.user.overview.Get(oldSettingName, None)
    199                 if oldSettings and settings.user.overview.Get(newSettingName, stateSetting.SETTING_NOT_PRESENT) == stateSetting.SETTING_NOT_PRESENT:
    200                     backupName = oldSettingName + '_backup'
    201                     oldSettingsCopy = oldSettings[:] if isinstance(oldSettings, list) else None
    202                     settings.user.overview.Set(backupName, oldSettingsCopy)
    203                     if oldSettings and stateConst.flagSamePlayerCorp in oldSettings:
    204                         indexOfCorpState = oldSettings.index(stateConst.flagSamePlayerCorp)
    205                         oldSettings.insert(indexOfCorpState, stateConst.flagSameNpcCorp)
    206                     settings.user.overview.Set(newSettingName, oldSettings)
    207                     settings.user.overview.Delete(oldSettingName)
    208 
    209     def ReorderPresets(self, presetDict):
    210         try:
    211             for presetKey, presetValue in presetDict.iteritems():
    212                 ReorderList(presetValue, (PRESET_SETTINGS_GROUPS, PRESET_SETTINGS_FILTERED_STATES, PRESET_SETTINGS_ALWAYS_SHOWN_STATES))
    213 
    214         except Exception as e:
    215             oldPresets = settings.user.overview.Get(oConst.SETTING_OLD_PRESET_BACKUP, {})
    216             log.exception('Error when reordering presets, e=%s, oldPresets=%s' % (e, oldPresets))
    217             presetDict.clear()
    218 
    219     def GetDefaultOverviewPresetNames(self):
    220         return self.defaultOverviews.get_preset_names()
    221 
    222     def GetCustomPresetNames(self):
    223         defaultPresetNames = self.GetDefaultOverviewPresetNames()
    224         return [ presetName for presetName in self.allPresets if presetName not in defaultPresetNames ]
    225 
    226     def GetDefaultPreset(self):
    227         return self.defaultPreset
    228 
    229     def GetDefaultOverviewDisplayName(self, presetName):
    230         return self.defaultOverviews.get_preset_name(presetName)
    231 
    232     def GetDefaultOverviewDisplayNameWithCategory(self, presetName):
    233         return self.defaultOverviews.get_preset_name_with_category(presetName)
    234 
    235     def GetDefaultOverviewDescription(self, presetName):
    236         return self.defaultOverviews.get_preset_description(presetName)
    237 
    238     def GetDefaultOverviewCategoryID(self, presetName):
    239         return self.defaultOverviews.get_preset_category_id(presetName)
    240 
    241     def GetDefaultOverviewCategoryName(self, presetName):
    242         return self.defaultOverviews.get_preset_category_name(presetName)
    243 
    244     def GetAllPresets(self):
    245         if not self.allPresets:
    246             self.AddDefaultPresetsToAllPresets()
    247         return self.allPresets
    248 
    249     def GetPresetFromKey(self, presetName):
    250         if self.IsUnsavedPreset(presetName):
    251             preset = self.unsavedPresets.get(self._ExtractPresetNameFromTuple(presetName), None)
    252         else:
    253             self.GetAllPresets()
    254             preset = self.allPresets.get(presetName, None)
    255         if not preset:
    256             preset = self.allPresets.get(self.defaultPreset, {})
    257         return preset
    258 
    259     def GetPresetGroupsFromKey(self, presetName):
    260         preset = self.GetPresetFromKey(presetName)
    261         if not preset:
    262             return []
    263         return preset.get(PRESET_SETTINGS_GROUPS, [])
    264 
    265     def GetGroups(self, presetName = None):
    266         if not presetName:
    267             presetName = self.GetActiveOverviewPresetName()
    268         return self.GetPresetGroupsFromKey(presetName)
    269 
    270     def IsGroupIDShown(self, groupID, presetName = None):
    271         if groupID not in get_group_ids():
    272             return False
    273         return groupID in self.GetGroups(presetName)
    274 
    275     def GetBracketGroups(self, presetName = None):
    276         if not presetName:
    277             presetName = self.GetActiveBracketPresetName()
    278         return self.GetPresetGroupsFromKey(presetName)
    279 
    280     def FindPresetForStates(self, isBracket = False, presetName = None):
    281         if not presetName:
    282             if isBracket:
    283                 presetName = self.GetActiveBracketPresetName()
    284             else:
    285                 presetName = self.GetActiveOverviewPresetName()
    286         preset = self.GetPresetFromKey(presetName)
    287         if preset is None:
    288             preset = self.GetPresetFromKey(self.defaultPreset)
    289         return preset
    290 
    291     def GetFilteredStates(self, isBracket = False, presetName = None):
    292         preset = self.FindPresetForStates(isBracket, presetName)
    293         return preset.get(PRESET_SETTINGS_FILTERED_STATES, [])
    294 
    295     def GetAlwaysShownStates(self, isBracket = False, presetName = None):
    296         preset = self.FindPresetForStates(isBracket, presetName)
    297         return preset.get(PRESET_SETTINGS_ALWAYS_SHOWN_STATES, [])
    298 
    299     def GetValidGroups(self, isBracket = False, presetName = None):
    300         if isBracket:
    301             groups = set(self.GetBracketGroups(presetName=presetName))
    302         else:
    303             groups = set(self.GetGroups(presetName=presetName))
    304         availableGroups = get_group_ids()
    305         return groups.intersection(availableGroups)
    306 
    307     def GetFilteredStatesByPresetKey(self, presetName = ''):
    308         preset = self.GetPresetFromKey(presetName)
    309         if not preset:
    310             return []
    311         return preset.get(PRESET_SETTINGS_FILTERED_STATES, [])
    312 
    313     def GetAlwaysShownStatesByPresetKey(self, presetName = ''):
    314         preset = self.GetPresetFromKey(presetName)
    315         if not preset:
    316             return []
    317         return preset.get(PRESET_SETTINGS_ALWAYS_SHOWN_STATES, [])
    318 
    319     def GetOverrideState(self, slimItem):
    320         return self.overviewOverride.get_state_slim_item(slimItem)
    321 
    322     def GetPresetsMenuElevated(self):
    323         m = []
    324         m.append(('Switch to New Default Overview', lambda : self.ResetDefaultOverviewData('jotunn_default')))
    325         m.append(('Switch to Old Default Overview', lambda : self.ResetDefaultOverviewData('old_default')))
    326         m.append(('Reset informing of new Default for next login', self._ResetInformingOfNewDefault))
    327         return m
    328 
    329     def _ResetInformingOfNewDefault(self):
    330         self.defaultOverviewSettings.set_default_overview('')
    331         self.defaultOverviewSettings.set_informed_of_update(False)
    332 
    333     def PersistBracketSettings(self, tabID, showState, showingSpecials):
    334         tabsetting = self.GetTabSettings(tabID)
    335         if tabsetting:
    336             tabsetting[SETTING_BRACKETS_SHOWALL] = showState == SHOW_ALL
    337             tabsetting[SETTING_BRACKETS_SHOWNONE] = showState == SHOW_NONE
    338             tabsetting[SETTING_BRACKETS_SHOWSPECIALS] = showingSpecials
    339 
    340     def GetBracketShowState(self, tabID):
    341         tabSettings = self.GetTabSettings(tabID)
    342         if tabSettings.get(SETTING_BRACKETS_SHOWALL, False):
    343             return SHOW_ALL
    344         elif tabSettings.get(SETTING_BRACKETS_SHOWNONE, False):
    345             return SHOW_NONE
    346         else:
    347             return SHOW_DEFAULT
    348 
    349     def LoadTab(self, tabID):
    350         tabsettings = self.GetSettingsByTabID().get(tabID, {})
    351         presetName = tabsettings.get(SETTING_OVERVIEW_PRESET_NAME, None)
    352         self.LoadPreset(presetName, False, notSavedPreset=self.IsUnsavedPreset(presetName))
    353         bracketPresetName = tabsettings.get(SETTING_BRACKET_PRESET_NAME, None)
    354         showSpecials = tabsettings.get(SETTING_BRACKETS_SHOWSPECIALS, False)
    355         if not self.IsBracketFilterDictatingTab(tabID):
    356             return
    357         self.LoadBracketPreset(bracketPresetName, showSpecials=showSpecials, bracketShowState=self.GetBracketShowState(tabID))
    358 
    359     def IsBracketFilterDictatingTab(self, tabID):
    360         wndInstID = self.GetWindowInstanceID(tabID)
    361         return self.IsBracketFilterDictatingWindow(wndInstID)
    362 
    363     def IsBracketFilterDictatingWindow(self, wndInstID):
    364         return wndInstID == self.GetDefaultWindowInstanceID()
    365 
    366     def LoadPreset(self, presetName, updateTabSettings = True, notSavedPreset = False):
    367         if not notSavedPreset:
    368             presetName = self._GetPresetNameFromNotSaved(presetName)
    369         self.activeOverviewPresetName = presetName
    370         settings.user.overview.Set(oConst.SETTING_ACTIVE_PRESET, presetName)
    371         sm.ScatterEvent('OnOverviewPresetLoaded', presetName, None)
    372 
    373     def _ApplyPresetToCurrentlySelectedTab(self, presetName):
    374         overview = sm.GetService('tactical').GetPanelForUpdate(overviewConst.WINDOW_ID)
    375         if overview is not None and hasattr(overview, 'GetSelectedTabID'):
    376             tabID = overview.GetSelectedTabID()
    377             tabSettings = self.GetSettingsByTabID()
    378             if tabID in tabSettings.keys():
    379                 tabSettings[tabID][oConst.SETTING_OVERVIEW_PRESET_NAME] = presetName
    380             self.UpdateSettingsByTabID(tabSettings)
    381 
    382     def _GetPresetNameFromNotSaved(self, presetName):
    383         presets = self.GetAllPresets()
    384         if self.IsUnsavedPreset(presetName):
    385             log.warning("Loading temp name when I shouldn't be, label = %s" % repr(presetName))
    386             presetName = self._ExtractPresetNameFromTuple(presetName)
    387         defaultPresetNames = self.GetDefaultOverviewPresetNames()
    388         if presetName not in presets and presetName not in defaultPresetNames:
    389             log.info("Trying to load a preset that doesn't exist, load default instead - presetName=%s" % repr(presetName))
    390             presetName = self.defaultPreset
    391         return presetName
    392 
    393     def LoadBracketPreset(self, presetName, showSpecials = None, bracketShowState = None):
    394         if presetName not in self.allPresets and presetName not in (None, oConst.BRACKET_FILTER_SHOWALL):
    395             return
    396         self.activeBracketPresetName = presetName
    397         sm.GetService('bracket').SoftReload(showSpecials, bracketShowState)
    398 
    399     def GetActiveBracketPresetName(self):
    400         isInvalid = not self.activeBracketPresetName or self.activeBracketPresetName not in self.allPresets or self.IsUnsavedPreset(self.activeBracketPresetName) and self._ExtractPresetNameFromTuple(self.activeBracketPresetName) not in self.unsavedPresets
    401         if isInvalid:
    402             self.activeBracketPresetName = oConst.BRACKET_FILTER_SHOWALL
    403         return self.activeBracketPresetName
    404 
    405     def GetActiveOverviewPresetName(self):
    406         presetName = self.activeOverviewPresetName
    407         isInvalid = not presetName or presetName not in self.allPresets and self.IsUnsavedPreset(presetName) and self._ExtractPresetNameFromTuple(presetName) not in self.unsavedPresets
    408         if isInvalid:
    409             self.activeOverviewPresetName = self.defaultPreset
    410         return presetName
    411 
    412     def _ResetActivePresets(self):
    413         self.activeOverviewPresetName = self.defaultPreset
    414         self.activeBracketPresetName = None
    415 
    416     def _ResetPresetsToDefault(self):
    417         self.allPresets = {}
    418         self.AddDefaultPresetsToAllPresets()
    419 
    420     def ResetOverviewSettingsToDefault(self):
    421         overviewID = self.defaultOverviews.default_overview_id
    422         self._ResetSettings(overviewID)
    423 
    424     def ResetOverviewSettingsToDefaultWithPrompt(self):
    425         if prompt_player_fsd_dialog('ResetAllOverviewSettings', {}, uiconst.YESNO) != uiconst.ID_YES:
    426             return
    427         self.StoreCurrentProfileDataInSettings()
    428         self.ResetOverviewSettingsToDefault()
    429         self.defaultOverviewSettings.set_informed_of_update(True)
    430 
    431     def _ResetSettings(self, overviewID = None):
    432         self._ResetPresetsToDefault()
    433         self._ResetActivePresets()
    434         self.unsavedPresets = {}
    435         self._DeleteAllOverviewSettingValues()
    436         stateSvc = sm.StartService('stateSvc')
    437         stateSvc.SetDefaultShipLabel('default')
    438         stateSvc.ResetColors()
    439         self.defaultOverviews.activate_default_overview(self.LoadGeneralSettings)
    440         self.UpdateSettingsByTabID(self._GetDefaultSettingsByTabID(), overviewID)
    441         sm.GetService('bracket').Reload()
    442 
    443     def _DeleteAllOverviewSettingValues(self):
    444         values = settings.user.overview.GetValues()
    445         keys = values.keys()
    446         for key in keys:
    447             if key in oConst.NEVER_DELETE_SETTINGS:
    448                 continue
    449             settings.user.overview.Delete(key)
    450 
    451     def SavePresetAs(self, presetName = None):
    452         if not presetName:
    453             presetName = self.GetActiveOverviewPresetName()
    454         newPresetName = utilWindows.NamePopup(localization.GetByLabel('UI/Common/Buttons/SaveAs'), localization.GetByLabel('UI/Overview/FilterName'), setvalue=self._GetPresetNameForSaveWindow(presetName), maxLength=80)
    455         if newPresetName:
    456             if self.IsDefaultPresetName(newPresetName):
    457                 prompt_player_fsd_dialog('InvalidPresetName')
    458                 return self.SavePresetAs(presetName)
    459             if newPresetName in self.allPresets:
    460                 if prompt_player_fsd_dialog('AlreadyHaveLabel', {}, uiconst.YESNO) != uiconst.ID_YES:
    461                     return self.SavePresetAs(presetName)
    462             self.SavePreset(presetName, newPresetName)
    463 
    464     def IsDefaultPresetName(self, presetName):
    465         presetName = presetName.lower()
    466         for p in self.GetDefaultOverviewPresetNames():
    467             if p.lower() == presetName:
    468                 return True
    469             if self.GetDefaultOverviewDisplayName(p).lower() == presetName:
    470                 return True
    471 
    472         return False
    473 
    474     def SavePreset(self, presetName, newPresetName = None):
    475         if newPresetName is None:
    476             newPresetName = presetName
    477         bannedwords.check_words_allowed(newPresetName)
    478         newPreset = {PRESET_SETTINGS_GROUPS: self.GetGroups(presetName=presetName)[:],
    479          PRESET_SETTINGS_FILTERED_STATES: self.GetFilteredStates(presetName=presetName)[:],
    480          PRESET_SETTINGS_ALWAYS_SHOWN_STATES: self.GetAlwaysShownStates(presetName=presetName)[:]}
    481         self.unsavedPresets.pop(newPresetName, None)
    482         self.unsavedPresets.pop(presetName, None)
    483         self.allPresets[newPresetName] = newPreset
    484         self._PersistPresets()
    485         self.LoadPreset(newPresetName)
    486         if presetName != newPresetName:
    487             overviewSignals.on_preset_saved_as(presetName, newPresetName)
    488         else:
    489             overviewSignals.on_preset_saved(newPresetName)
    490         sm.ScatterEvent('OnOverviewPresetSaved')
    491 
    492     def _GetPresetNameForSaveWindow(self, presetName):
    493         return self._GetPresetDisplayName(presetName)
    494 
    495     def RevertUnsaved(self, presetName):
    496         if not self.IsUnsavedPreset(presetName):
    497             return
    498         preset = self.unsavedPresets.pop(presetName, None)
    499         if preset:
    500             overviewSignals.on_preset_restored(presetName)
    501 
    502     def DeletePreset(self, presetName):
    503         if presetName in self.allPresets:
    504             self.allPresets.pop(presetName)
    505         if presetName in self.unsavedPresets:
    506             self.unsavedPresets.pop(presetName)
    507         if presetName == self.activeOverviewPresetName:
    508             self.LoadPreset(self.defaultPreset)
    509         sm.ScatterEvent('OnOverviewPresetSaved')
    510         overviewSignals.on_preset_deleted(presetName)
    511 
    512     def GetMotifiedSetting(self, value, add, current):
    513         if add:
    514             if type(value) == list:
    515                 for each in value:
    516                     if each not in current:
    517                         current.append(each)
    518 
    519             elif value not in current:
    520                 current.append(value)
    521         elif type(value) == list:
    522             for each in value:
    523                 while each in current:
    524                     current.remove(each)
    525 
    526         else:
    527             while value in current:
    528                 current.remove(value)
    529 
    530         current.sort()
    531         return current
    532 
    533     def SetNPCGroups(self):
    534         sendGroupIDs = []
    535         userSettings = self.GetGroups()
    536         for cat, groupdict in GetNPCGroups().iteritems():
    537             for groupname, groupids in groupdict.iteritems():
    538                 for groupid in groupids:
    539                     if groupid in userSettings:
    540                         sendGroupIDs += groupids
    541                         break
    542 
    543         if sendGroupIDs:
    544             changeList = [('groups', sendGroupIDs, 1)]
    545             self.ChangeSettings(changeList=changeList)
    546 
    547     def AddGroupIDToPreset(self, groupID, presetName = None):
    548         self.ChangeSettings([(PRESET_SETTINGS_GROUPS, groupID, 1)], presetName)
    549 
    550     def RemoveGroupIDFromPreset(self, groupID, presetName = None):
    551         self.ChangeSettings([(PRESET_SETTINGS_GROUPS, groupID, 0)], presetName)
    552 
    553     def ChangeSettings(self, changeList, presetName = None):
    554         if not presetName:
    555             presetName = self.GetActiveOverviewPresetName()
    556         activePreset = self.GetPresetFromKey(presetName).copy()
    557         changeCounter = 0
    558         for eachChange in changeList:
    559             settingID, value, add = eachChange
    560             current = None
    561             if settingID == PRESET_SETTINGS_FILTERED_STATES:
    562                 current = self.GetFilteredStatesByPresetKey(presetName)[:]
    563             elif settingID == PRESET_SETTINGS_ALWAYS_SHOWN_STATES:
    564                 current = self.GetAlwaysShownStatesByPresetKey(presetName)[:]
    565             elif settingID == PRESET_SETTINGS_GROUPS:
    566                 current = self.GetPresetGroupsFromKey(presetName)[:]
    567             if current is None:
    568                 continue
    569             changeCounter += 1
    570             current = self.GetMotifiedSetting(value, add, current)
    571             activePreset[settingID] = current
    572 
    573         if changeCounter == 0:
    574             return
    575         if self.IsUnsavedPreset(presetName):
    576             basePresetName = self._ExtractPresetNameFromTuple(presetName)
    577             unsavedName = presetName
    578         else:
    579             basePresetName = presetName
    580             unsavedName = self.GetUnsavedPresetName(presetName)
    581         basePreset = self.allPresets.get(basePresetName, {})
    582         if IsPresetTheSame(basePreset, activePreset):
    583             self.RestoreSavedPreset(basePresetName, unsavedName)
    584         else:
    585             self.unsavedPresets[basePresetName] = activePreset
    586             self._PersistPresets()
    587             self.LoadPreset(unsavedName, notSavedPreset=True)
    588         overviewSignals.on_preset_saved(presetName)
    589 
    590     def RestoreSavedPreset(self, basePresetName, unsavedName):
    591         self.ChangeTabSettingsToUseBasePreset(unsavedName, basePresetName)
    592         self.unsavedPresets.pop(basePresetName, None)
    593         self._PersistPresets()
    594         self.LoadPreset(basePresetName, notSavedPreset=True)
    595         overviewSignals.on_preset_restored(basePresetName)
    596 
    597     def ChangeTabSettingsToUseBasePreset(self, tempPresetName, basePresetName):
    598         tabSettings = self.GetSettingsByTabID()
    599         for _, tSetting in tabSettings.iteritems():
    600             if tSetting.get(SETTING_OVERVIEW_PRESET_NAME) == tempPresetName:
    601                 tSetting[SETTING_OVERVIEW_PRESET_NAME] = basePresetName
    602             if tSetting.get(SETTING_BRACKET_PRESET_NAME) == tempPresetName:
    603                 tSetting[SETTING_BRACKET_PRESET_NAME] = basePresetName
    604 
    605         self.PersistSettingsByTabID(tabSettings)
    606 
    607     def GetSettingForGroups(self, presetName = None):
    608         if presetName is None:
    609             presetName = self.GetActiveOverviewPresetName()
    610         preset = self.GetPresetFromKey(presetName)
    611         try:
    612             return preset[PRESET_SETTINGS_GROUPS][:]
    613         except KeyError:
    614             return set()
    615 
    616     def SavePresetGroupFilters(self, groupList, presetName = None):
    617         if not presetName:
    618             presetName = self.GetActiveOverviewPresetName()
    619         preset = self.GetPresetFromKey(presetName).copy()
    620         preset[PRESET_SETTINGS_GROUPS] = groupList
    621         if self.IsUnsavedPreset(presetName):
    622             newTempPresetName = self._ExtractPresetNameFromTuple(presetName)
    623             unsavedName = presetName
    624         else:
    625             newTempPresetName = presetName
    626             unsavedName = self.GetUnsavedPresetName(presetName)
    627         self.unsavedPresets[newTempPresetName] = preset
    628         self.LoadPreset(unsavedName, notSavedPreset=True)
    629         self._PersistPresets()
    630         overviewSignals.on_preset_saved(presetName)
    631 
    632     def GetUnsavedPresetName(self, presetName):
    633         return presetName
    634 
    635     def IsUnsavedPreset(self, presetName):
    636         return presetName in self.unsavedPresets
    637 
    638     def IsTuplePresetName(self, presetName):
    639         return isinstance(presetName, (list, tuple))
    640 
    641     def GetPresetDisplayName(self, presetName, showCategory = True):
    642         if presetName == oConst.BRACKET_FILTER_SHOWALL:
    643             return GetByLabel('UI/Overview/ShowAllBrackets')
    644         else:
    645             display_name = self._GetPresetDisplayName(presetName, showCategory)
    646             if self.IsUnsavedPreset(presetName):
    647                 return GetByLabel('UI/Overview/PresetNotSaved', presetName=display_name)
    648             return display_name
    649 
    650     def _GetPresetDisplayName(self, presetName, showCategory = True):
    651         if presetName in self.defaultOverviews.get_all_presets():
    652             if showCategory:
    653                 return self.GetDefaultOverviewDisplayNameWithCategory(presetName)
    654             else:
    655                 return self.GetDefaultOverviewDisplayName(presetName)
    656         else:
    657             return presetName
    658 
    659     def _ExtractPresetNameFromTuple(self, presetName):
    660         if self.IsTuplePresetName(presetName):
    661             return presetName[1]
    662         else:
    663             return presetName
    664 
    665     def _PersistPresets(self):
    666         settings.user.overview.Set(oConst.SETTING_PROFILE_PRESETS, self.allPresets)
    667         settings.user.overview.Set(oConst.SETTING_PROFILE_PRESETS_NOT_SAVED, self.unsavedPresets)
    668 
    669     def GetStringForOverviewPreset(self, data):
    670         dataString = yaml.safe_dump(data)
    671         return dataString
    672 
    673     def GetOverviewDataForSave(self, presetsToUse = None):
    674         data = self.GetGeneralSettings()
    675         presetsInUseDict = self.GetPresetsInUse(presetsToUse=presetsToUse)
    676         presetsInUseList = presetsInUseDict.values()
    677         presetsInUseList.sort()
    678         data[sharingConst.OVERVIEW_SHARING_PRESETS] = presetsInUseList
    679         data[sharingConst.OVERVIEW_SHARING_TAB_SETUP] = self.GetTabSettingsForSaving()
    680         return data
    681 
    682     def GetGeneralSettings(self):
    683         data = {}
    684         settingsAndDefaults = self.GetSettingsNamesAndDefaults()
    685         userSettingsTuples = []
    686         for configName, defaultSetting in settingsAndDefaults.iteritems():
    687             myValue = bool(settings.user.overview.Get(configName, defaultSetting))
    688             if myValue == defaultSetting:
    689                 continue
    690             userSettingsTuples.append((configName, myValue))
    691 
    692         userSettingsTuples.sort()
    693         data[sharingConst.OVERVIEW_SHARING_USERSETTINGS] = userSettingsTuples
    694         stateSvc = sm.GetService('stateSvc')
    695         flagOrder = stateSvc.GetStateOrder('Flag')
    696         backgroundOrder = stateSvc.GetStateOrder('Background')
    697         data[sharingConst.OVERVIEW_SHARING_FLAG_ORDER] = flagOrder
    698         data[sharingConst.OVERVIEW_SHARING_BACKGROUND_ORDER] = backgroundOrder
    699         flagStates = stateSvc.GetStateStates('flag')[:]
    700         backgroundStates = stateSvc.GetStateStates('background')[:]
    701         flagStates.sort()
    702         backgroundStates.sort()
    703         data[sharingConst.OVERVIEW_SHARING_FLAG_STATES] = flagStates
    704         data[sharingConst.OVERVIEW_SHARING_BG_STATES] = backgroundStates
    705         columnOrder = overviewColumns.GetColumnOrder()
    706         columnsIDs = overviewColumns.GetColumns()[:]
    707         columnsIDs.sort()
    708         data[sharingConst.OVERVIEW_SHARING_COLUMN_ORDER] = columnOrder
    709         data[sharingConst.OVERVIEW_SHARING_OVERVIEW_COLUMNS] = columnsIDs
    710         colorDict = sm.GetService('stateSvc').GetFixedColorSettings()
    711         newColorDict = self.GetColorsToSave(colorDict)
    712         colorDictAsList = GetDeterministicListFromDict(newColorDict)
    713         data[sharingConst.OVERVIEW_SHARING_STATE_COLORS_LIST] = colorDictAsList
    714         stateBlinks = sm.GetService('stateSvc').defaultBlinkStates.copy()
    715         stateBlinks.update(settings.user.overview.Get(oConst.SETTING_STATE_BLINKS, {}))
    716         stateBlinks = EncodeKeyInDict(stateBlinks)
    717         stateBlinksList = GetDeterministicListFromDict(stateBlinks)
    718         data[sharingConst.OVERVIEW_SHARING_STATE_BLINKS] = stateBlinksList
    719         shipLabels = sm.GetService('stateSvc').GetShipLabels()
    720         shipLabelsList = []
    721         shipLabelOrder = []
    722         allowedLabelTypes = GetAllowedLabelTypes()
    723         allowedVariables = GetAllowedVariables()
    724         for eachConfig in shipLabels:
    725             configType = eachConfig[LABEL_TYPE]
    726             if configType not in allowedLabelTypes:
    727                 continue
    728             eachConfigCopy = eachConfig.copy()
    729             for k in eachConfigCopy.keys():
    730                 if k not in allowedVariables:
    731                     eachConfigCopy.pop(k, None)
    732 
    733             shipLabelOrder.append(configType)
    734             orderedConfig = GetDeterministicListFromDict(eachConfig)
    735             shipLabelsList.append((configType, orderedConfig))
    736 
    737         shipLabelsList.sort()
    738         data[sharingConst.OVERVIEW_SHARING_SHIP_LABELS] = shipLabelsList
    739         data[sharingConst.OVERVIEW_SHARING_SHIP_LABEL_ORDER] = shipLabelOrder
    740         return data
    741 
    742     def GetPresetsInUse(self, presetsToUse = None):
    743         allPresets = self.GetAllPresets()
    744         allTabSettings = self.GetSettingsByTabID()
    745         defaultPresetNames = self.GetDefaultOverviewPresetNames()
    746         return self.GetPresetsInUseFromTabSettings(allTabSettings, allPresets, defaultPresetNames, presetsToUse=presetsToUse)
    747 
    748     def GetPresetsInUseFromTabSettings(self, allTabSettings, allPresets, exludePresets = [], presetsToUse = None):
    749         presetsInUse = {}
    750 
    751         def ShouldAddPreset(presetName):
    752             if presetName not in allPresets:
    753                 return False
    754             if presetName in presetsInUse:
    755                 return False
    756             if presetName in exludePresets:
    757                 return False
    758             return True
    759 
    760         def AddPreset(presetName):
    761             presetAsList = GetDeterministicListFromDict(allPresets[presetName])
    762             presetsInUse[presetName] = (presetName, presetAsList)
    763 
    764         if presetsToUse:
    765             for presetName in presetsToUse:
    766                 if ShouldAddPreset(presetName):
    767                     AddPreset(presetName)
    768 
    769         else:
    770             for tabIdx, tabSettings in allTabSettings.iteritems():
    771                 if tabIdx >= MAX_TAB_NUM:
    772                     break
    773                 for setupGroupName in (SETTING_OVERVIEW_PRESET_NAME, SETTING_BRACKET_PRESET_NAME):
    774                     presetName = tabSettings[setupGroupName]
    775                     if self.IsUnsavedPreset(presetName):
    776                         presetName = self._ExtractPresetNameFromTuple(presetName)
    777                     if ShouldAddPreset(presetName):
    778                         AddPreset(presetName)
    779 
    780         return presetsInUse
    781 
    782     def GetSettingsNamesAndDefaults(self):
    783         if self.configNamesAndDefaults is None:
    784             self.configNamesAndDefaults = {oConst.SETTING_NAME_APPLY_STRUCTURE: True,
    785              oConst.SETTING_NAME_APPLY_OTHER_OBJ: False,
    786              oConst.SETTING_NAME_SMALL_TAGS: False,
    787              oConst.SETTING_NAME_SMALL_TEXT: False,
    788              oConst.SETTING_HIDE_CORP_TICKER: False,
    789              oConst.SETTING_BROADCAST_TO_TOP: DEFAULT_BROADCAST_TO_TOP,
    790              oConst.SETTING_BIGGEST_DMG_DEALER: True,
    791              oConst.SETTING_MODULE_HAIRLINES: True,
    792              oConst.SETTING_TARGET_CROSSHAIR: True,
    793              oConst.SETTING_TARGET_RANGE: True,
    794              'showCategoryInTargetRange_6': True,
    795              'showCategoryInTargetRange_11': True,
    796              'showCategoryInTargetRange_18': True}
    797         return self.configNamesAndDefaults
    798 
    799     def GetSettingValueOrDefaultFromName(self, settingName, fallbackDefaultValue):
    800         defaultValue = self.GetDefaultSettingValueFromName(settingName, fallbackDefaultValue)
    801         return settings.user.overview.Get(settingName, defaultValue)
    802 
    803     def GetDefaultSettingValueFromName(self, settingName, fallbackDefaultValue):
    804         defaultNameAndSettings = self.GetSettingsNamesAndDefaults()
    805         return defaultNameAndSettings.get(settingName, fallbackDefaultValue)
    806 
    807     def LoadSharedOverviewProfile(self, presetKey, overviewName):
    808         if prompt_player_fsd_dialog('LoadOverviewProfile', {}, uiconst.YESNO, default=uiconst.ID_NO) != uiconst.ID_YES:
    809             return
    810         yamlString = self.cachedPresetsFromServer.get(presetKey, None)
    811         if yamlString is None:
    812             yamlString = sm.RemoteSvc('overviewPresetMgr').GetStoredPreset(presetKey)
    813         if yamlString is None:
    814             raise UserError('OverviewProfileLoadingError')
    815         self.StoreCurrentProfileDataInSettings()
    816         dataList = yaml.safe_load(yamlString)
    817         data = GetDictFromList(dataList)
    818         self.LoadOverviewProfileFromDict(data, overviewName, presetKey, saveInHistory=True)
    819 
    820     def RestoreAutoSavedOverviewProfile(self):
    821         restoreData = settings.user.overview.Get(oConst.SETTING_RESTORE_DATA, {})
    822         if not restoreData:
    823             return
    824         data = restoreData['data']
    825         overviewName = restoreData['name']
    826         self.LoadOverviewProfileFromDict(data, overviewName)
    827         settings.user.overview.Set(oConst.SETTING_RESTORE_DATA, {})
    828 
    829     def LoadOverviewProfileFromDict(self, data, overviewName, presetKey = None, saveInHistory = False):
    830         self.LoadGeneralSettings(data)
    831         presetDict = GetDictFromList(data[sharingConst.OVERVIEW_SHARING_PRESETS])
    832         tabPresets = ReplaceInnerListsWithDicts(presetDict)
    833         self.UpdateAllPresets(tabPresets)
    834         tabSetup = self.GetTabSetupToLoad(data)
    835         self.PersistSettingsByTabID(tabSetup)
    836         settings.user.ui.Set('overviewProfileName', overviewName)
    837         if presetKey and saveInHistory:
    838             self.SaveOverviewLinkInSettings(overviewName, presetKey)
    839         self.UpdateSettingsByTabID(tabSetup)
    840         self._CheckResetTabIDsByWindowInstanceIDs()
    841         sm.ScatterEvent('OnReloadingOverviewProfile')
    842 
    843     def _CheckResetTabIDsByWindowInstanceIDs(self):
    844         if not self._IsTabsByWndInstIDDataValid(self.GetTabIDsByWindowInstanceID()):
    845             self.PersistTabIDsByWindowInstanceID(self._GetDefaultTabIDsByWindowInstanceID())
    846             sm.ScatterEvent('OnOverviewTabsChanged')
    847 
    848     def StoreCurrentProfileDataInSettings(self):
    849         oldProfileData = self.GetOverviewDataForSave()
    850         oldOverviewName = self.GetOverviewName()
    851         now = blue.os.GetWallclockTime()
    852         oldProfileInfo = {'data': oldProfileData,
    853          'name': oldOverviewName,
    854          'timestamp': now}
    855         settings.user.overview.Set(oConst.SETTING_RESTORE_DATA, oldProfileInfo)
    856 
    857     def SaveOverviewLinkInSettings(self, overviewName, presetKey):
    858         timestamp = blue.os.GetWallclockTime()
    859         presetHistoryKeys = settings.user.overview.Get(oConst.SETTING_HISTORY_KEYS, {})
    860         if presetKey in presetHistoryKeys:
    861             entry = presetHistoryKeys[presetKey]
    862             entry['overviewName'] = overviewName
    863             entry['timestamp'] = timestamp
    864         else:
    865             entry = {'overviewName': overviewName,
    866              'presetKey': presetKey,
    867              'timestamp': timestamp}
    868             presetHistoryKeys[presetKey] = entry
    869         settings.user.overview.Set(oConst.SETTING_HISTORY_KEYS, presetHistoryKeys)
    870 
    871     def _LoadGeneralSettings(self, data):
    872         configNamesAndDefaultsCopy = self.GetSettingsNamesAndDefaults().copy()
    873         userSettings = data.get('userSettings', [])
    874         for configName, settingValue in userSettings:
    875             if configName not in configNamesAndDefaultsCopy:
    876                 continue
    877             settings.user.overview.Set(configName, settingValue)
    878             configNamesAndDefaultsCopy.pop(configName)
    879 
    880         for configName, defaultValue in configNamesAndDefaultsCopy.iteritems():
    881             settings.user.overview.Set(configName, defaultValue)
    882 
    883         flagOrder = data.get(sharingConst.OVERVIEW_SHARING_FLAG_ORDER, [])
    884         backgroundOrder = data.get(sharingConst.OVERVIEW_SHARING_BACKGROUND_ORDER, [])
    885         settings.user.overview.Set(stateSetting.SETTING_FLAG_ORDER_CONFIG_NAME, flagOrder)
    886         settings.user.overview.Set(stateSetting.SETTING_BACKGROUND_ORDER_CONFIG_NAME, backgroundOrder)
    887         flagStates = data.get(sharingConst.OVERVIEW_SHARING_FLAG_STATES, [])
    888         flagStates.sort()
    889         backgroundStates = data.get(sharingConst.OVERVIEW_SHARING_BG_STATES, [])
    890         backgroundStates.sort()
    891         settings.user.overview.Set(stateSetting.SETTING_FLAG_STATES_CONFIG_NAME, flagStates)
    892         settings.user.overview.Set(stateSetting.SETTING_BACKGROUND_STATES_CONFIG_NAME, backgroundStates)
    893         columnOrder = data.get(sharingConst.OVERVIEW_SHARING_COLUMN_ORDER, overviewConst.ALL_COLUMNS)
    894         overviewColumns = data.get(sharingConst.OVERVIEW_SHARING_OVERVIEW_COLUMNS, overviewConst.DEFAULT_COLUMNS[:])
    895         overviewColumns.sort()
    896         settings.user.overview.Set(oConst.SETTING_COLUMN_ORDER, columnOrder)
    897         settings.user.overview.Set(oConst.SETTING_COLUMNS, overviewColumns)
    898         colorNameDictAsList = data.get(sharingConst.OVERVIEW_SHARING_STATE_COLORS_LIST, [])
    899         try:
    900             colorNameDict = GetDictFromList(colorNameDictAsList)
    901             newColorDict = self.GetColorValuesFromName(colorNameDict)
    902             settings.user.overview.Set(oConst.SETTING_STATE_COLORS, newColorDict)
    903         except Exception as exc:
    904             log.warning('Omit loading Overview data for colors: %s. \nData: %s' % (exc, colorNameDictAsList))
    905 
    906         stateBlinksAsList = data.get(sharingConst.OVERVIEW_SHARING_STATE_BLINKS, [])
    907         try:
    908             stateBlinks = GetDictFromList(stateBlinksAsList)
    909             stateBlinks = DecodeKeyInDict(stateBlinks)
    910             settings.user.overview.Set(oConst.SETTING_STATE_BLINKS, stateBlinks)
    911         except Exception as exc:
    912             log.warning('Omit loading Overview data for state blinks: %s. \nData: %s' % (exc, stateBlinksAsList))
    913 
    914         shipLabelsAsList = data.get(sharingConst.OVERVIEW_SHARING_SHIP_LABELS, [])
    915         try:
    916             shipLabels = GetDictFromList(shipLabelsAsList)
    917             shipLabels = ReplaceInnerListsWithDicts(shipLabels)
    918             shipLabelOrder = data.get(sharingConst.OVERVIEW_SHARING_SHIP_LABEL_ORDER, [])
    919             orderedShipLabelsList = GetOrderedListFromDict(shipLabels, shipLabelOrder, allowedDuplicates=(LABEL_TYPE_LINEBREAK,))
    920             settings.user.overview.Set(oConst.SETTINGS_SHIP_LABELS, orderedShipLabelsList)
    921         except Exception as exc:
    922             log.warning('Omit loading Overview data for ship labels: %s. \nData: %s' % (exc, shipLabelsAsList))
    923 
    924     def LoadGeneralSettings(self, data):
    925         self._LoadGeneralSettings(data)
    926         sm.GetService('stateSvc').InitColors(reset=True)
    927         sm.GetService('stateSvc').shipLabels = None
    928 
    929     def GetTabSetupToLoad(self, data):
    930         tabSetup = GetDictFromList(data.get(sharingConst.OVERVIEW_SHARING_TAB_SETUP, []))
    931         tabSetup = ReplaceInnerListsWithDicts(tabSetup)
    932         return tabSetup
    933 
    934     def UpdateAllPresets(self, profileUpdateDict):
    935         self.allPresets.update(profileUpdateDict)
    936         self._PersistPresets()
    937 
    938     def GetColorsToSave(self, colorDict):
    939         newColorDict = {}
    940         for key, colorValue in colorDict.iteritems():
    941             colorName = FindColorName(colorValue)
    942             if colorName:
    943                 newColorDict[key] = colorName
    944 
    945         newColorDict = EncodeKeyInDict(newColorDict)
    946         return newColorDict
    947 
    948     def GetColorValuesFromName(self, colorDict):
    949         newColorDict = {}
    950         for key, colorName in colorDict.iteritems():
    951             colorInfo = GetStateColors().get(colorName, None)
    952             if colorInfo:
    953                 newColorDict[key] = colorInfo[0]
    954 
    955         newColorDict = DecodeKeyInDict(newColorDict)
    956         return newColorDict
    957 
    958     def GetTabSettingsForSaving(self):
    959         tabSettings = self.GetSettingsByTabID()
    960         tabSettingsAsList = []
    961         for idx, tSettingValue in tabSettings.items():
    962             for setupGroupName in (SETTING_OVERVIEW_PRESET_NAME, SETTING_BRACKET_PRESET_NAME):
    963                 if self.IsUnsavedPreset(tSettingValue.get(setupGroupName, None)):
    964                     tSettingValue[setupGroupName] = self._ExtractPresetNameFromTuple(tSettingValue[setupGroupName])
    965 
    966             tSettingList = GetDeterministicListFromDict(tSettingValue)
    967             tabSettingsAsList.append((idx, tSettingList))
    968 
    969         tabSettingsAsList.sort()
    970         tabSettingsAsList = tabSettingsAsList[:MAX_TAB_NUM]
    971         return tabSettingsAsList
    972 
    973     def GetWindowInstanceIDs(self):
    974         return range(len(self.GetTabIDsByWindowInstanceID()))
    975 
    976     def GetDefaultWindowInstanceID(self):
    977         return self.GetWindowInstanceIDs()[0]
    978 
    979     def GetWindowIDs(self):
    980         return [ self.GetWindowID(wndInstID) for wndInstID in self.GetWindowInstanceIDs() ]
    981 
    982     def GetWindowID(self, windowInstanceID):
    983         windowID = overviewConst.WINDOW_ID
    984         if windowInstanceID > 0:
    985             windowID += '_%s' % windowInstanceID
    986         return windowID
    987 
    988     def GetTabIDsByWindowInstanceID(self):
    989         return settings.user.overview.Get(oConst.SETTING_TABS_BY_WINDOW_INSTANCE_ID, self._GetDefaultTabIDsByWindowInstanceID())
    990 
    991     def _IsTabsByWndInstIDDataValid(self, tabIDsByWndInstID):
    992         settingsByTabID = self.GetSettingsByTabID()
    993         if sum([ len(tabIDs) for tabIDs in tabIDsByWndInstID ]) != len(settingsByTabID):
    994             log.warning("Number of tabs don't match, so resetting to default. tabIdsByWndInstID=%s, settingsByTabID=%s" % (tabIDsByWndInstID, settingsByTabID))
    995             return False
    996         return True
    997 
    998     def GetWindowInstanceID(self, tabID):
    999         for wndInstID, tabIDs in enumerate(self.GetTabIDsByWindowInstanceID()):
   1000             if tabID in tabIDs:
   1001                 return wndInstID
   1002 
   1003     def _GetDefaultTabIDsByWindowInstanceID(self):
   1004         return [self.GetSettingsByTabID().keys()]
   1005 
   1006     def GetTabIDs(self, windowInstanceID):
   1007         tabIDsByWndInstID = self.GetTabIDsByWindowInstanceID()
   1008         if windowInstanceID >= len(tabIDsByWndInstID):
   1009             return None
   1010         tabIDs = tabIDsByWndInstID[windowInstanceID]
   1011         return sorted(tabIDs)
   1012 
   1013     def PersistTabIDsByWindowInstanceID(self, tabIDsByWndInstID):
   1014         if not self._IsTabsByWndInstIDDataValid(tabIDsByWndInstID):
   1015             tabIDsByWndInstID = self._GetDefaultTabIDsByWindowInstanceID()
   1016         return settings.user.overview.Set(oConst.SETTING_TABS_BY_WINDOW_INSTANCE_ID, tabIDsByWndInstID)
   1017 
   1018     def GetSettingsByTabID(self):
   1019         settingsByTabID = settings.user.overview.Get(oConst.SETTING_TAB_SETTINGS, None)
   1020         if settingsByTabID is None:
   1021             settingsByTabID = settings.user.overview.Get(oConst.SETTING_TAB_SETTINGS_OLD, self._GetDefaultSettingsByTabID())
   1022             self._ConvertOldFormatSettingsByTabID(settingsByTabID)
   1023             self.PersistSettingsByTabID(settingsByTabID)
   1024         return settingsByTabID
   1025 
   1026     def _ConvertOldFormatSettingsByTabID(self, settingsByTabID):
   1027         for tabID, _settings in settingsByTabID.iteritems():
   1028             if SETTING_OVERVIEW_PRESET_NAME in _settings:
   1029                 presetName = _settings[SETTING_OVERVIEW_PRESET_NAME]
   1030                 if self.IsTuplePresetName(presetName):
   1031                     _settings[SETTING_OVERVIEW_PRESET_NAME] = self._ExtractPresetNameFromTuple(presetName)
   1032             if SETTING_BRACKET_PRESET_NAME in _settings:
   1033                 bracketPresetName = _settings[SETTING_BRACKET_PRESET_NAME]
   1034                 if self.IsTuplePresetName(bracketPresetName):
   1035                     _settings[SETTING_BRACKET_PRESET_NAME] = self._ExtractPresetNameFromTuple(bracketPresetName)
   1036 
   1037     def GetTabSettings(self, tabID):
   1038         return self.GetSettingsByTabID().get(tabID, None)
   1039 
   1040     def GetTabName(self, tabID):
   1041         return self.GetTabSettings(tabID)[oConst.SETTING_TAB_NAME]
   1042 
   1043     def PersistSettingsByTabID(self, settingsByTabID):
   1044         if not settingsByTabID:
   1045             log.exception('Attempting to persist empty settingsByTabID')
   1046             return
   1047         self._ConvertOldFormatSettingsByTabID(settingsByTabID)
   1048         settings.user.overview.Set(oConst.SETTING_TAB_SETTINGS, settingsByTabID)
   1049 
   1050     def GetOverviewName(self):
   1051         currentText = settings.user.ui.Get('overviewProfileName', None)
   1052         if not currentText:
   1053             currentText = localization.GetByLabel('UI/Overview/DefaultOverviewName', charID=session.charid)
   1054         return currentText
   1055 
   1056     def GetShareData(self, text, presetsToUse = None):
   1057         data = self.GetOverviewDataForSave(presetsToUse=presetsToUse)
   1058         overviewPreset = utillib.KeyVal(__guid__='fakeentry.OverviewProfile', data=data, label=text)
   1059         return [overviewPreset]
   1060 
   1061     def UpdateSettingsByTabID(self, settingsByTabID, overviewID = None):
   1062         if settingsByTabID is None:
   1063             settingsByTabID = self.GetSettingsByTabID() or self._GetDefaultSettingsByTabID()
   1064         self.PersistSettingsByTabID(deepcopy(settingsByTabID))
   1065         self.defaultOverviewSettings.set_overview(overviewID)
   1066         sm.ScatterEvent('OnOverviewPresetsChanged')
   1067 
   1068     def ImportOverviewSettings(self, settingsByTabID):
   1069         self.UpdateSettingsByTabID(settingsByTabID)
   1070         self._AddMissingPresetsFromOtherDefaultOverviews()
   1071 
   1072     def _GetDefaultSettingsByTabID(self):
   1073         settingsByTabID = {}
   1074         defaultTabs = self.defaultOverviews.get_tabs()
   1075         for tabID, tab in defaultTabs.iteritems():
   1076             settingsByTabID[tabID] = {SETTING_OVERVIEW_PRESET_NAME: tab.overview_preset,
   1077              SETTING_BRACKET_PRESET_NAME: tab.bracket_preset,
   1078              SETTING_TAB_NAME: tab.name,
   1079              SETTING_TAB_COLOR: tab.color}
   1080 
   1081         return settingsByTabID
   1082 
   1083     def GetSettingValueBroadcastToTop(self):
   1084         return self.GetSettingValueOrDefaultFromName(oConst.SETTING_BROADCAST_TO_TOP, DEFAULT_BROADCAST_TO_TOP)
   1085 
   1086     def AddTab(self, name, overviewPreset = None, bracketPreset = None, windowInstanceID = None, color = None):
   1087         bannedwords.check_words_allowed(name)
   1088         settingsByTabID = self.GetSettingsByTabID()
   1089         if len(settingsByTabID) >= MAX_TAB_NUM:
   1090             prompt_player_fsd_dialog('TooManyTabs', {'numTabs': MAX_TAB_NUM})
   1091             return
   1092         tabID = self._AppendTab(name, settingsByTabID, overviewPreset, bracketPreset, color)
   1093         self.UpdateSettingsByTabID(settingsByTabID)
   1094         self._AssignTabToWindow(tabID, windowInstanceID)
   1095         sm.ScatterEvent('OnOverviewTabsChanged')
   1096 
   1097     def UpdateTab(self, tabID, name, presetName, bracketPresetName, color):
   1098         settingsByTabID = self.GetSettingsByTabID()
   1099         if tabID not in settingsByTabID:
   1100             log.exception('Trying to edit missing tab (tabID=%s' % tabID)
   1101             return
   1102         settings = settingsByTabID[tabID]
   1103         if name is not None:
   1104             settings[SETTING_TAB_NAME] = name
   1105         if presetName is not None:
   1106             settings[SETTING_OVERVIEW_PRESET_NAME] = presetName
   1107         if bracketPresetName is not None:
   1108             settings[SETTING_BRACKET_PRESET_NAME] = bracketPresetName
   1109         settings[SETTING_TAB_COLOR] = color
   1110         self.PersistSettingsByTabID(settingsByTabID)
   1111         sm.ScatterEvent('OnOverviewTabsChanged')
   1112 
   1113     def GetTabPreset(self, tabID):
   1114         tabSettings = self.GetTabSettings(tabID)
   1115         if tabSettings:
   1116             return tabSettings[SETTING_OVERVIEW_PRESET_NAME]
   1117 
   1118     def SetTabPreset(self, tabID, presetName):
   1119         self._SetTabSetting(tabID, SETTING_OVERVIEW_PRESET_NAME, presetName)
   1120 
   1121     def GetTabBracketPreset(self, tabID):
   1122         tabSettings = self.GetTabSettings(tabID)
   1123         if tabSettings:
   1124             return tabSettings[SETTING_BRACKET_PRESET_NAME] or oConst.BRACKET_FILTER_SHOWALL
   1125 
   1126     def SetTabBracketPreset(self, tabID, presetName):
   1127         self._SetTabSetting(tabID, SETTING_BRACKET_PRESET_NAME, presetName)
   1128 
   1129     def GetTabVisibleColumnIDs(self, tabID):
   1130         tabSettings = self.GetTabSettings(tabID)
   1131         if tabSettings:
   1132             defaultColumnIDs = settings.user.overview.Get(oConst.SETTING_COLUMNS, overviewConst.DEFAULT_COLUMNS)
   1133             return tabSettings.get(oConst.SETTING_TAB_VISIBLE_COLUMN_IDS, defaultColumnIDs)[:]
   1134 
   1135     def SetTabVisibleColumnIDs(self, tabID, columnIDs):
   1136         self._SetTabSetting(tabID, oConst.SETTING_TAB_VISIBLE_COLUMN_IDS, columnIDs)
   1137         overviewSignals.on_tab_columns_changed(tabID)
   1138 
   1139     def ResetTabVisibleColumnIDs(self, tabID):
   1140         self.SetTabVisibleColumnIDs(tabID, overviewConst.DEFAULT_COLUMNS[:])
   1141 
   1142     def GetTabColumnOrder(self, tabID):
   1143         tabSettings = self.GetTabSettings(tabID)
   1144         if tabSettings:
   1145             return tabSettings.get(oConst.SETTING_TAB_COLUMN_ORDER, overviewConst.ALL_COLUMNS[:])
   1146 
   1147     def SetTabColumnOrder(self, tabID, columnIDs):
   1148         self._SetTabSetting(tabID, oConst.SETTING_TAB_COLUMN_ORDER, columnIDs)
   1149         overviewSignals.on_tab_columns_changed(tabID)
   1150 
   1151     def ResetTabColumnOrder(self, tabID):
   1152         self.SetTabColumnOrder(tabID, overviewConst.ALL_COLUMNS[:])
   1153 
   1154     def ToggleTabColumnVisibility(self, tabID, columnID):
   1155         columnIDs = self.GetTabVisibleColumnIDs(tabID)
   1156         if columnID in columnIDs:
   1157             columnIDs.remove(columnID)
   1158         else:
   1159             columnIDs.append(columnID)
   1160         self.SetTabVisibleColumnIDs(tabID, columnIDs)
   1161 
   1162     def SetTabName(self, tabID, tabName):
   1163         self._SetTabSetting(tabID, SETTING_TAB_NAME, tabName)
   1164 
   1165     def _SetTabSetting(self, tabID, settingID, value):
   1166         settingsByTabID = self.GetSettingsByTabID()
   1167         if tabID not in settingsByTabID:
   1168             log.exception('Trying to edit missing tab (tabID=%s' % tabID)
   1169             return
   1170         settingsByTabID[tabID][settingID] = value
   1171         self.PersistSettingsByTabID(settingsByTabID)
   1172         sm.ScatterEvent('OnOverviewTabsChanged')
   1173 
   1174     def _AppendTab(self, name, settingsByTabID, overviewPreset = None, bracketPreset = None, color = None):
   1175         if len(settingsByTabID) == 0:
   1176             tabID = 0
   1177         else:
   1178             tabID = max(settingsByTabID.keys()) + 1
   1179         settingsByTabID[tabID] = {SETTING_TAB_NAME: name,
   1180          SETTING_OVERVIEW_PRESET_NAME: overviewPreset or self.defaultPreset,
   1181          SETTING_BRACKET_PRESET_NAME: bracketPreset,
   1182          SETTING_TAB_COLOR: color}
   1183         return tabID
   1184 
   1185     def DeleteTab(self, tabID):
   1186         oldSettings = self.GetSettingsByTabID()
   1187         if tabID not in oldSettings:
   1188             return
   1189         settingsByTabID = {}
   1190         _tabID = 0
   1191         for key, dictItem in oldSettings.iteritems():
   1192             if key == tabID:
   1193                 continue
   1194             settingsByTabID[_tabID] = dictItem
   1195             _tabID += 1
   1196 
   1197         self.UpdateSettingsByTabID(settingsByTabID)
   1198         self._RemoveTabFromWindow(tabID)
   1199         sm.ScatterEvent('OnOverviewTabsChanged')
   1200 
   1201     def _RemoveTabFromWindow(self, tabID):
   1202         tabIDsByWndInstID = self.GetTabIDsByWindowInstanceID()
   1203         self._RemoveTabID(tabID, tabIDsByWndInstID)
   1204         self._RemoveEmptyTabIDs(tabIDsByWndInstID)
   1205         self._UpdateTabIDsAfterTabRemoval(tabID, tabIDsByWndInstID)
   1206         self.PersistTabIDsByWindowInstanceID(tabIDsByWndInstID)
   1207 
   1208     def _UpdateTabIDsAfterTabRemoval(self, tabID, tabIDsByWndInstID):
   1209         for tabIDs in tabIDsByWndInstID:
   1210             for i, _tabID in enumerate(tabIDs):
   1211                 if _tabID > tabID:
   1212                     tabIDs[i] -= 1
   1213 
   1214     def _RemoveTabID(self, tabID, tabIDsByWndInstID):
   1215         for tabIDs in tabIDsByWndInstID:
   1216             if tabID in tabIDs:
   1217                 tabIDs.remove(tabID)
   1218 
   1219     def _RemoveEmptyTabIDs(self, tabIDsByWndInstID):
   1220         if [] in tabIDsByWndInstID:
   1221             tabIDsByWndInstID.remove([])
   1222 
   1223     def MoveTab(self, tabID, windowInstanceID = None):
   1224         self._AssignTabToWindow(tabID, windowInstanceID)
   1225         sm.ScatterEvent('OnOverviewTabsChanged')
   1226 
   1227     def _AssignTabToWindow(self, tabID, windowInstanceID = None):
   1228         tabIDsByWndInstID = self.GetTabIDsByWindowInstanceID()
   1229         self._RemoveTabID(tabID, tabIDsByWndInstID)
   1230         if windowInstanceID is None:
   1231             tabIDsByWndInstID.append([tabID])
   1232         else:
   1233             tabIDsByWndInstID[windowInstanceID].append(tabID)
   1234         self._RemoveEmptyTabIDs(tabIDsByWndInstID)
   1235         self.PersistTabIDsByWindowInstanceID(tabIDsByWndInstID)