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

addressbookService.py (56474B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\neocom\addressBook\addressbookService.py
      2 import sys
      3 import collections
      4 import evetypes
      5 import localization
      6 import log
      7 import telemetry
      8 import uthread
      9 import uthread2
     10 import utillib
     11 from caching.memoize import Memoize
     12 from carbon.common.script.sys.service import Service
     13 from carbon.common.script.util.timerstuff import AutoTimer
     14 from carbonui import uiconst
     15 from carbonui.uicore import uicore
     16 from carbonui.util.bunch import Bunch
     17 from carbonui.util.various_unsorted import SortListOfTuples
     18 from eve.client.script.ui.control.allUserEntries import AllUserEntries
     19 from eve.client.script.ui.control.entries.util import GetFromClass
     20 from eve.client.script.ui.shared.addressBookWindow import AddressBookWindow
     21 from eve.client.script.ui.shared.neocom.addressBook.contactManagementMultiEditWindow import ContactManagementMultiEditWnd
     22 from eve.client.script.ui.shared.neocom.addressBook.contactManagementWindow import ContactManagementWnd
     23 from eve.client.script.ui.shared.neocom.addressBook.contactNotificationEntry import ContactNotificationEntry
     24 from eve.client.script.ui.shared.neocom.addressBook.contactsConst import TAB_CONTACTS, TAB_CORPCONTACTS, TAB_ALLIANCECONTACTS
     25 from eve.client.script.ui.shared.neocom.addressBook.corpAllianceContactManagementWindow import CorpAllianceContactManagementWnd
     26 from eve.client.script.ui.shared.userentry import User
     27 from eve.client.script.ui.util import uix, utilWindows
     28 from eve.client.script.ui.shared.bookmarks.bookmarkContainerWindow import BookmarkContainerWindow
     29 from eve.client.script.ui.shared.bookmarks.bookmarkLocationWindow import BookmarkLocationWindow
     30 from eve.client.script.util import eveMisc
     31 from eve.common.script.sys import idCheckers
     32 from eve.common.script.sys.eveCfg import InShipInSpace
     33 from eveexceptions import UserError
     34 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     35 
     36 class AddressBookSvc(Service):
     37     __exportedcalls__ = {'AddToPersonal': [],
     38      'AddToPersonalMulti': [],
     39      'DeleteEntryMulti': [],
     40      'GetSolConReg': [],
     41      'BookmarkCurrentLocation': [],
     42      'BookmarkLocationPopup': [],
     43      'DeleteBookmarks': [],
     44      'RefreshWindow': [],
     45      'IsInAddressBook': [],
     46      'GetAddressBook': [],
     47      'IsBlocked': [],
     48      'GetRelationship': [],
     49      'GetContactsByMinRelationship': [],
     50      'AssignLabelFromWnd': [],
     51      'RemoveLabelFromWnd': []}
     52     __guid__ = 'svc.addressbook'
     53     __update_on_reload__ = 0
     54     __notifyevents__ = ['ProcessSessionChange',
     55      'OnDestinationSet',
     56      'OnCharacterSessionChanged',
     57      'OnSessionReset',
     58      'OnContactNoLongerContact',
     59      'OnOrganizationContactsUpdated',
     60      'OnPersonalContactsUpdated',
     61      'OnContactSlashCommand',
     62      'OnRefreshBookmarks',
     63      'OnAgentAdded',
     64      'OnPersonalContactsAdded',
     65      'OnPersonalContactsDeleted']
     66     __servicename__ = 'addressbook'
     67     __displayname__ = 'AddressBook Client Service'
     68     __dependencies__ = ['bookmarkSvc']
     69     __startupdependencies__ = ['settings']
     70 
     71     def __init__(self):
     72         Service.__init__(self)
     73         self.agents = None
     74         self.blocked = None
     75         self.labels = None
     76         self.corporateLabels = None
     77         self.allianceLabels = None
     78         self.contactType = None
     79         self.contacts = None
     80         self.corporateContacts = None
     81         self.allianceContacts = None
     82 
     83     def Run(self, memStream = None):
     84         self.LogInfo('Starting AddressBook')
     85         self.Reset()
     86         if session.charid:
     87             self.GetContacts()
     88 
     89     def CloseWindow(self):
     90         AddressBookWindow.CloseIfOpen()
     91 
     92     def OnCharacterSessionChanged(self, _oldCharacterID, _newCharacterID):
     93         if session.charid:
     94             self.GetContacts()
     95             self.RefreshWindow()
     96 
     97     def OnSessionReset(self):
     98         wnd = self.GetWnd()
     99         if wnd is not None:
    100             wnd.CloseIfOpen()
    101         self.Reset()
    102 
    103     def OnDropData(self, dragObj, nodes):
    104         wnd = self.GetWnd()
    105         if wnd is None or wnd.destroyed or not wnd.inited:
    106             return
    107         wnd.OnDropData(dragObj, nodes)
    108 
    109     def ProcessSessionChange(self, isremote, session, change):
    110         if session.charid is None:
    111             self.CloseWindow()
    112             self.Reset()
    113         elif 'solarsystemid' in change:
    114             self.RefreshWindow()
    115 
    116     def OnContactSlashCommand(self, contactID, level):
    117         if level is None:
    118             try:
    119                 self.contacts.pop(contactID)
    120             except:
    121                 sys.exc_clear()
    122 
    123         elif contactID not in self.contacts:
    124             contact = utillib.KeyVal()
    125             contact.contactID = contactID
    126             contact.relationshipID = level
    127             contact.labelMask = 0
    128             contact.inWatchlist = 0
    129             self.contacts[contactID] = contact
    130         else:
    131             self.contacts[contactID].relationshipID = level
    132         sm.ScatterEvent('OnContactChange', [contactID], 'contact')
    133 
    134     def OnPersonalContactsUpdated(self, contactIDs, standing, inWatchlist):
    135         if self.contacts is None:
    136             self.GetContacts()
    137         onlineContactsToUpdate = []
    138         for contactID in contactIDs:
    139             if standing is None and inWatchlist is None:
    140                 contact = self.contacts.pop(contactID, None)
    141             else:
    142                 try:
    143                     contact = self.contacts[contactID]
    144                     contact.relationshipID = standing if standing is not None else contact.relationshipID
    145                     contact.inWatchlist = inWatchlist if inWatchlist is not None else contact.inWatchlist
    146                 except KeyError as e:
    147                     sys.exc_clear()
    148                     contact = utillib.KeyVal()
    149                     contact.contactID = contactID
    150                     contact.relationshipID = standing
    151                     contact.inWatchlist = inWatchlist
    152                     contact.labelMask = 0
    153 
    154                 self.contacts[contactID] = contact
    155             if inWatchlist is not None or contact and contact.inWatchlist:
    156                 onlineContactsToUpdate.append(contactID)
    157 
    158         sm.ScatterEvent('OnContactChange', contactIDs, 'contact')
    159         for contactID in onlineContactsToUpdate:
    160             if idCheckers.IsCharacter(contactID) and not idCheckers.IsNPC(contactID):
    161                 isOnline = sm.GetService('onlineStatus').GetOnlineStatus(contactID)
    162                 sm.ScatterEvent('OnClientContactChange', contactID, isOnline)
    163 
    164     def OnOrganizationContactsUpdated(self, ownerID, updates):
    165         if self.contacts is None:
    166             self.GetContacts()
    167         if ownerID == session.corpid:
    168             contacts = self.corporateContacts
    169             event = 'OnSetCorpStanding'
    170         elif ownerID == session.allianceid:
    171             contacts = self.allianceContacts
    172             event = 'OnSetAllianceStanding'
    173         else:
    174             self.LogError('Invalid ownerID in contact update notification', ownerID, updates)
    175             return
    176         for update in updates:
    177             contactID, level, labelMask = update
    178             if level is None and labelMask is None:
    179                 try:
    180                     contacts.pop(contactID)
    181                 except:
    182                     sys.exc_clear()
    183 
    184             elif contactID not in contacts:
    185                 labelMask = labelMask or 0
    186                 contact = utillib.KeyVal()
    187                 contact.contactID = contactID
    188                 contact.relationshipID = level
    189                 contact.inWatchlist = 0
    190                 contact.labelMask = labelMask
    191                 contacts[contactID] = contact
    192             elif labelMask is None:
    193                 contacts[contactID].relationshipID = level
    194             else:
    195                 contacts[contactID].labelMask = labelMask
    196 
    197         sm.ScatterEvent(event)
    198 
    199     def GetContacts(self):
    200         uthread.Lock(self, 'contacts')
    201         try:
    202             bms = self.bookmarkSvc.GetBookmarks()
    203             if self.contacts is not None and self.blocked is not None and self.corporateContacts is not None and self.allianceContacts is not None and self.agents is not None and bms is not None:
    204                 return utillib.KeyVal(contacts=self.contacts, blocked=self.blocked, corpContacts=self.corporateContacts, allianceContacts=self.allianceContacts)
    205             self.contacts = {}
    206             self.blocked = {}
    207             self.corporateContacts = {}
    208             self.allianceContacts = {}
    209             self.agents = []
    210             if session.allianceid:
    211                 addressbook, self.corporateContacts, self.allianceContacts, statuses = uthread.parallel([(sm.RemoteSvc('charMgr').GetContactList, ()),
    212                  (sm.GetService('corp').GetContactList, ()),
    213                  (sm.GetService('alliance').GetContactList, ()),
    214                  (sm.GetService('onlineStatus').Prime, ())])
    215             else:
    216                 addressbook, self.corporateContacts, statuses = uthread.parallel([(sm.RemoteSvc('charMgr').GetContactList, ()), (sm.GetService('corp').GetContactList, ()), (sm.GetService('onlineStatus').Prime, ())])
    217             for each in addressbook.addresses:
    218                 if idCheckers.IsNPC(each.contactID) and idCheckers.IsCharacter(each.contactID):
    219                     if sm.GetService('agents').IsAgent(each.contactID):
    220                         self.agents.append(each.contactID)
    221                 else:
    222                     contact = utillib.KeyVal()
    223                     contact.contactID = each.contactID
    224                     contact.inWatchlist = each.inWatchlist
    225                     contact.relationshipID = each.relationshipID
    226                     contact.labelMask = each.labelMask
    227                     self.contacts[each.contactID] = contact
    228 
    229             for each in addressbook.blocked:
    230                 if each.senderID != 0:
    231                     blocked = utillib.KeyVal()
    232                     blocked.contactID = each.senderID
    233                     self.blocked[each.senderID] = blocked
    234 
    235             cfg.eveowners.Prime(self.blocked.keys())
    236             cfg.eveowners.Prime(self.contacts.keys())
    237             cfg.eveowners.Prime(self.corporateContacts)
    238             cfg.eveowners.Prime(self.allianceContacts)
    239             cfg.eveowners.Prime(self.agents)
    240             sm.ScatterEvent('OnStateSetupChange', 'contactsLoaded')
    241             return utillib.KeyVal(contacts=self.contacts, blocked=self.blocked, corpContacts=self.corporateContacts, allianceContacts=self.allianceContacts)
    242         finally:
    243             uthread.UnLock(self, 'contacts')
    244 
    245     def GetRelationship(self, charID, corporationID, allianceID = None):
    246         relationships = utillib.KeyVal()
    247         relationships.persToPers = const.contactNeutralStanding
    248         relationships.persToCorp = const.contactNeutralStanding
    249         relationships.persToAlliance = const.contactNeutralStanding
    250         relationships.corpToPers = const.contactNeutralStanding
    251         relationships.corpToCorp = const.contactNeutralStanding
    252         relationships.corpToAlliance = const.contactNeutralStanding
    253         relationships.allianceToPers = const.contactNeutralStanding
    254         relationships.allianceToCorp = const.contactNeutralStanding
    255         relationships.allianceToAlliance = const.contactNeutralStanding
    256         relationships.hasRelationship = False
    257         if charID in self.contacts:
    258             relationships.persToPers = self.contacts[charID].relationshipID
    259             relationships.hasRelationship = True
    260         if corporationID in self.contacts:
    261             relationships.persToCorp = self.contacts[corporationID].relationshipID
    262             relationships.hasRelationship = True
    263         if allianceID is not None and allianceID in self.contacts:
    264             relationships.persToAlliance = self.contacts[allianceID].relationshipID
    265             relationships.hasRelationship = True
    266         if charID in self.corporateContacts:
    267             relationships.corpToPers = self.corporateContacts[charID].relationshipID
    268             relationships.hasRelationship = True
    269         if corporationID in self.corporateContacts:
    270             relationships.corpToCorp = self.corporateContacts[corporationID].relationshipID
    271             relationships.hasRelationship = True
    272         if allianceID in self.corporateContacts:
    273             relationships.corpToAlliance = self.corporateContacts[allianceID].relationshipID
    274             relationships.hasRelationship = True
    275         if charID in self.allianceContacts:
    276             relationships.allianceToPers = self.allianceContacts[charID].relationshipID
    277             relationships.hasRelationship = True
    278         if corporationID in self.allianceContacts:
    279             relationships.allianceToCorp = self.allianceContacts[corporationID].relationshipID
    280             relationships.hasRelationship = True
    281         if allianceID is not None and allianceID in self.allianceContacts:
    282             relationships.allianceToAlliance = self.allianceContacts[allianceID].relationshipID
    283             relationships.hasRelationship = True
    284         return relationships
    285 
    286     def GetContactsByMinRelationship(self, relationshipID):
    287         contacts = set()
    288         for contactID, contact in self.contacts.iteritems():
    289             if contact.relationshipID >= relationshipID:
    290                 contacts.add(contactID)
    291 
    292         for contactID, contact in self.corporateContacts.iteritems():
    293             if contact.relationshipID >= relationshipID:
    294                 contacts.add(contactID)
    295 
    296         for contactID, contact in self.allianceContacts.iteritems():
    297             if contact.relationshipID >= relationshipID:
    298                 contacts.add(contactID)
    299 
    300         return contacts
    301 
    302     def GetContactsAboveAndBelowRelationship(self, standingValue):
    303         atOrAboveStanding = set()
    304         belowStanding = set()
    305         for contactDict in [self.contacts, self.corporateContacts, self.allianceContacts]:
    306             for contactID, contact in contactDict.iteritems():
    307                 if contact.relationshipID >= standingValue:
    308                     atOrAboveStanding.add(contactID)
    309                 else:
    310                     belowStanding.add(contactID)
    311 
    312         belowStanding = belowStanding - atOrAboveStanding
    313         return (atOrAboveStanding, belowStanding)
    314 
    315     def OnDestinationSet(self, destinationID):
    316         self.RefreshLocationFolderWindows()
    317 
    318     def OnContactNoLongerContact(self, charID):
    319         if charID in self.contacts:
    320             del self.contacts[charID]
    321             self.RefreshWindow()
    322 
    323     def OnRefreshBookmarks(self):
    324         self.RefreshLocationFolderWindows()
    325 
    326     def GetAgents(self, *args):
    327         return self.agents
    328 
    329     @Memoize
    330     def GetSolarSystemDetails(self, itemID):
    331         solarSystem = cfg.mapSystemCache.Get(itemID)
    332         return (cfg.evelocations.Get(itemID).name, solarSystem.constellationID, solarSystem.regionID)
    333 
    334     @Memoize
    335     def GetConstellationDetails(self, itemID):
    336         constellation = cfg.mapConstellationCache.Get(itemID)
    337         return (cfg.evelocations.Get(itemID).name, constellation.regionID)
    338 
    339     @Memoize
    340     def GetLocationName(self, itemID):
    341         return cfg.evelocations.Get(itemID).name
    342 
    343     @telemetry.ZONE_METHOD
    344     def GetSolConReg(self, bookmark):
    345         solname = '-'
    346         conname = '-'
    347         regname = '-'
    348         try:
    349             if idCheckers.IsSolarSystem(bookmark.locationID):
    350                 solname, con, reg = self.GetSolarSystemDetails(bookmark.locationID)
    351                 conname = self.GetLocationName(con)
    352                 regname = self.GetLocationName(reg)
    353             elif idCheckers.IsConstellation(bookmark.locationID):
    354                 solname, con, reg = self.GetSolarSystemDetails(bookmark.itemID)
    355                 conname = self.GetLocationName(con)
    356                 regname = self.GetLocationName(reg)
    357             elif idCheckers.IsRegion(bookmark.locationID):
    358                 conname, reg = self.GetConstellationDetails(bookmark.itemID)
    359                 regname = self.GetLocationName(reg)
    360             elif bookmark.typeID == const.typeRegion:
    361                 regname = self.GetLocationName(bookmark.itemID)
    362         finally:
    363             return (solname, conname, regname)
    364 
    365     def BookmarkCurrentLocation(self, *args):
    366         if not (session.stationid or session.shipid):
    367             prompt_player_fsd_dialog('HavetobeatstationOrinShip')
    368             return
    369         if session.stationid:
    370             stationinfo = sm.GetService('ui').GetStationStaticInfo(session.stationid)
    371             self.BookmarkLocationPopup(session.stationid, stationinfo.stationTypeID, session.solarsystemid2)
    372         elif session.structureid:
    373             structureInfo = sm.GetService('structureDirectory').GetStructureInfo(session.structureid)
    374             self.BookmarkLocationPopup(session.structureid, structureInfo.typeID, session.solarsystemid)
    375         elif session.solarsystemid and session.shipid:
    376             bp = sm.GetService('michelle').GetBallpark()
    377             if bp is None:
    378                 return
    379             slimItem = bp.GetInvItem(session.shipid)
    380             if slimItem is None:
    381                 return
    382             self.BookmarkLocationPopup(session.shipid, slimItem.typeID, session.solarsystemid)
    383 
    384     def CheckLocationID(self, locationID):
    385         bms = sm.GetService('bookmarkSvc').GetBookmarks()
    386         for bookmark in bms.itervalues():
    387             if bookmark.itemID == locationID:
    388                 return bookmark
    389 
    390     def BookmarkLocationPopup(self, locationid, typeID, parentID, note = None, scannerInfo = None, locationName = None):
    391         if locationName is None:
    392             locationName = self.GetDefaultLocationName(locationid, scannerInfo)
    393         existingBookmark = self.CheckLocationID(locationid)
    394         if existingBookmark and locationid not in (session.shipid, session.solarsystemid):
    395             folderName = sm.GetService('bookmarkSvc').GetFolderInfo(existingBookmark.folderID).folderName
    396             if prompt_player_fsd_dialog('AskBookmarkExistingLocation', {'locationName': evetypes.GetName(typeID),
    397              'folderName': folderName,
    398              'caption': existingBookmark.memo}, uiconst.YESNO, uiconst.ID_YES) != uiconst.ID_YES:
    399                 return
    400         folders, subfolders = sm.GetService('bookmarkSvc').GetFilteredFoldersAndSubfolders()
    401         if len(folders) == 0:
    402             if prompt_player_fsd_dialog('CreateBookmarkFolderAsNoneValid', {}, uiconst.YESNO, uiconst.ID_YES) == uiconst.ID_YES:
    403                 wnd = BookmarkContainerWindow.Open()
    404                 wnd.Maximize()
    405             return
    406         wnd = BookmarkLocationWindow.Open(locationID=locationid, windowID='bookmarkLocationWindow', windowInstanceID='bookmarkLocationWindow_%s' % locationid, typeID=typeID, parentID=parentID, scannerInfo=scannerInfo, locationName=locationName, note=note, folders=folders, subfolders=subfolders)
    407         uthread.new(uicore.registry.SetFocus, wnd.labelEdit)
    408 
    409     def GetDefaultLocationName(self, locationID, scannerInfo):
    410         if locationID in (session.solarsystemid, session.shipid) and InShipInSpace():
    411             if scannerInfo is not None:
    412                 locationName = scannerInfo.name
    413             else:
    414                 locationName = localization.GetByLabel('UI/PeopleAndPlaces/SpotInSolarSystem', solarSystemName=cfg.evelocations.Get(session.solarsystemid2).name)
    415         else:
    416             mapSvc = sm.GetService('map')
    417             locationName = cfg.evelocations.Get(locationID).name
    418             locationObj = mapSvc.GetItem(locationID)
    419             if locationObj:
    420                 locationName = localization.GetByLabel('UI/PeopleAndPlaces/NewBookmarkLocationLabel', loc=locationID, group=evetypes.GetName(locationObj.typeID))
    421             bp = sm.GetService('michelle').GetBallpark()
    422             if bp:
    423                 slimItem = uix.GetBallparkRecord(locationID)
    424                 if slimItem is not None:
    425                     if locationName is None or len(locationName) <= 1:
    426                         locationName = evetypes.GetGroupName(slimItem.typeID)
    427                     else:
    428                         locationName = localization.GetByLabel('UI/PeopleAndPlaces/NewBookmarkLocationLabel', loc=locationID, group=evetypes.GetGroupName(slimItem.typeID))
    429         return locationName
    430 
    431     def BookmarkLocation(self, itemID, name, comment, typeID, locationID = None, folderID = None):
    432         self.bookmarkSvc.BookmarkLocation(itemID, name, comment, typeID, locationID=locationID, folderID=folderID)
    433 
    434     def GetBookmark(self, bookmarkID):
    435         return sm.GetService('bookmarkSvc').GetBookmark(bookmarkID)
    436 
    437     def DeleteBookmarks(self, ids, refreshWindow = True, alreadyDeleted = 0):
    438         numBookmarks = len(ids)
    439         if numBookmarks == 1:
    440             bookmark = self.bookmarkSvc.GetBookmark(ids[0])
    441             hint, comment = self.bookmarkSvc.UnzipMemo(bookmark.memo)
    442             if prompt_player_fsd_dialog('RemoveLocation', {'locationName': hint}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    443                 return
    444         elif prompt_player_fsd_dialog('RemoveMultipleLocation', {'numLocations': numBookmarks}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    445             return
    446         wnd = self.GetWnd()
    447         if wnd is not None and not wnd.destroyed:
    448             wnd.ShowLoad()
    449         try:
    450             self.bookmarkSvc.DeleteBookmarks(ids)
    451         finally:
    452             if wnd is not None and not wnd.destroyed:
    453                 wnd.HideLoad()
    454 
    455         if refreshWindow:
    456             self.RefreshWindow()
    457             self.RefreshLocationFolderWindows()
    458 
    459     def EditBookmark(self, bm):
    460         if not hasattr(bm, 'note'):
    461             return
    462         oldlabel, oldnote = self.bookmarkSvc.UnzipMemo(bm.memo)
    463         oldnote = bm.note
    464         folders, subfolders = sm.GetService('bookmarkSvc').GetFilteredFoldersAndSubfolders(forcedFolderID=bm.folderID)
    465         windowInstanceID = 'bookmarkLocationWindow_bookmarkID_%s' % getattr(bm, 'bookmarkID', None)
    466         return BookmarkLocationWindow.Open(bookmark=bm, locationName=oldlabel, windowInstanceID=windowInstanceID, note=oldnote, folders=folders, subfolders=subfolders)
    467 
    468     def Reset(self):
    469         self.destinationSetOnce = 0
    470         self.deleted = []
    471         self.contacts = None
    472         self.blocked = None
    473         self.labels = None
    474         self.corporateLabels = None
    475         self.allianceLabels = None
    476         self.corporateContacts = None
    477         self.allianceContacts = None
    478         self.agents = None
    479 
    480     @telemetry.ZONE_METHOD
    481     def RefreshWindow(self):
    482         self.refreshTimer = AutoTimer(250, self._RefreshWindow)
    483 
    484     def _RefreshWindow(self):
    485         wnd = AddressBookWindow.GetIfOpen()
    486         if wnd is not None and not wnd.destroyed and wnd.inited:
    487             wnd.tabGroup.ReloadVisible()
    488         self.refreshTimer = None
    489 
    490     @uthread2.debounce(wait=0.25, max_wait=3.0)
    491     def RefreshLocationFolderWindows(self):
    492         windows = uicore.registry.GetWindows()
    493         for w in windows:
    494             if "('myPlaces'" in w.name:
    495                 w.LoadContent()
    496 
    497     def DropInAgents(self, dragObj, nodes):
    498         self.DropInPersonal(nodes, None)
    499 
    500     def DropInPersonalContact(self, dragObj, nodes):
    501         self.DropInPersonal(nodes, 'contact')
    502 
    503     def DropInPersonal(self, nodes, contactType):
    504         for what in nodes:
    505             if getattr(what, '__guid__', None) not in AllUserEntries():
    506                 return
    507             if sm.GetService('agents').IsAgent(what.itemID) and contactType != None:
    508                 prompt_player_fsd_dialog('CannotAddContactType')
    509                 continue
    510             elif not sm.GetService('agents').IsAgent(what.itemID) and contactType == None:
    511                 prompt_player_fsd_dialog('CannotAddContactType2')
    512                 continue
    513             else:
    514                 self.AddToAddressBook(what.itemID, contactType)
    515 
    516     def DropInBlocked(self, nodes):
    517         for what in nodes:
    518             if getattr(what, '__guid__', None) not in AllUserEntries():
    519                 return
    520             if not idCheckers.IsOwner(what.itemID) and not idCheckers.IsAlliance(what.itemID):
    521                 self.LogWarn('Skipping block item', what.itemID, 'as this item is not a character!')
    522                 continue
    523             self.BlockOwner(what.itemID)
    524 
    525     def DropInBuddyGroup(self, listID_groupID, nodes, *args):
    526         ids = []
    527         for node in nodes:
    528             if node.Get('__guid__', None) in ('listentry.User', 'listentry.Sender') and node.itemID != session.charid:
    529                 self.AddToPersonal(node.itemID, None, refresh=node == nodes[-1])
    530             currentListGroupID = node.Get('listGroupID', None)
    531             ids.append((node.itemID, currentListGroupID, listID_groupID))
    532 
    533         for itemID, currentListGroupID, listID_groupID in ids:
    534             if currentListGroupID and itemID:
    535                 uicore.registry.RemoveFromListGroup(currentListGroupID, itemID)
    536             uicore.registry.AddToListGroup(listID_groupID, itemID)
    537 
    538         uicore.registry.ReloadGroupWindow(listID_groupID)
    539         self.RefreshWindow()
    540 
    541     def GetWnd(self, new = 0):
    542         if new:
    543             return AddressBookWindow.ToggleOpenClose()
    544         else:
    545             return AddressBookWindow.GetIfOpen()
    546 
    547     def OnAgentAdded(self, entityID):
    548         if entityID in self.agents:
    549             return
    550         self.agents.append(entityID)
    551         self.RefreshWindow()
    552 
    553     def OnPersonalContactsAdded(self, contacts, relationshipID, watchlist, labelMask):
    554         contactIDs = []
    555         contactType = 'contact'
    556         for contact in contacts:
    557             contactID = contact.contactID
    558             contactIDs.append(contactID)
    559             if idCheckers.IsNPCCharacter(contactID):
    560                 self.agents.append(contactID)
    561                 continue
    562             self.contacts[contactID] = utillib.KeyVal(contactID=contactID, relationshipID=relationshipID, inWatchlist=watchlist, labelMask=labelMask)
    563             if watchlist and contact.isOnline:
    564                 sm.ScatterEvent('OnContactAddedToWatchlist', contactID, contact.isOnline)
    565 
    566         if labelMask is not None:
    567             self.AssignLabelFromWnd(contactIDs, labelMask)
    568         sm.ScatterEvent('OnContactChange', contactIDs, contactType)
    569 
    570     def OnPersonalContactsDeleted(self, contacts):
    571         contactType = 'contact'
    572         scatterList = []
    573         for contact in contacts:
    574             contactID = contact.contactID
    575             if contactID in self.agents:
    576                 del self.agents[contactID]
    577             if contactID in self.contacts:
    578                 del self.contacts[contactID]
    579             scatterList.append(contactID)
    580 
    581         sm.ScatterEvent('OnContactChange', contacts, contactType)
    582 
    583     def AddToPersonalMulti(self, charIDs, contactType = None, edit = 0):
    584         if type(charIDs) != list:
    585             charIDs = [charIDs]
    586         for charID in charIDs:
    587             self.AddToPersonal(charID, contactType=contactType, refresh=charID == charIDs[-1], edit=edit)
    588 
    589     def AddToPersonal(self, charID, contactType, refresh = 1, edit = 0):
    590         if charID == const.ownerSystem:
    591             prompt_player_fsd_dialog('CantbookmarkEveSystem')
    592             return
    593         if contactType is None:
    594             if charID not in self.agents:
    595                 try:
    596                     character = cfg.eveowners.Get(charID)
    597                 except:
    598                     log.LogWarn('User trying to bookmark character which is not in the owners table', charID)
    599                     sys.exc_clear()
    600                     return
    601 
    602                 self.AddToAddressBook(charID, contactType, edit)
    603         else:
    604             self.AddToAddressBook(charID, contactType, edit)
    605 
    606     def BlockOwner(self, ownerID):
    607         if ownerID == session.charid:
    608             prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/CannotBlockSelf')})
    609             return
    610         if idCheckers.IsNPC(ownerID):
    611             if idCheckers.IsCharacter(ownerID):
    612                 prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/CannotBlockAgents')})
    613             elif idCheckers.IsCorporation(ownerID) or idCheckers.IsAlliance(ownerID):
    614                 prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/CannotBlockNPCCorps')})
    615             return
    616         if ownerID in self.blocked:
    617             prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/AlreadyHaveBlocked', userName=cfg.eveowners.Get(ownerID).name)})
    618             return
    619         sm.RemoteSvc('charMgr').BlockOwners([ownerID])
    620         blocked = utillib.KeyVal()
    621         blocked.contactID = ownerID
    622         self.blocked[ownerID] = blocked
    623         sm.ScatterEvent('OnBlockContacts', [ownerID])
    624         self.RefreshWindow()
    625 
    626     def UnblockOwner(self, ownerIDs):
    627         blocked = []
    628         for ownerID in ownerIDs:
    629             if ownerID in self.blocked:
    630                 blocked.append(ownerID)
    631                 self.blocked.pop(ownerID)
    632 
    633         if len(blocked):
    634             sm.RemoteSvc('charMgr').UnblockOwners(blocked)
    635             sm.ScatterEvent('OnUnblockContacts', blocked)
    636         self.RefreshWindow()
    637 
    638     def IsBlocked(self, ownerID):
    639         return ownerID in self.blocked
    640 
    641     def EditContacts(self, contactIDs, contactType):
    642         wnd = ContactManagementMultiEditWnd.Open(windowID='contactmanagement', entityIDs=contactIDs, contactType=contactType)
    643         if wnd.ShowModal() == 1:
    644             results = wnd.result
    645             relationshipID = results
    646             if contactType == 'contact':
    647                 sm.RemoteSvc('charMgr').EditContactsRelationshipID(contactIDs, relationshipID)
    648                 for contactID in contactIDs:
    649                     self.contacts[contactID].relationshipID = relationshipID
    650 
    651             elif contactType == 'corpcontact':
    652                 sm.GetService('corp').EditContactsRelationshipID(contactIDs, relationshipID)
    653                 for contactID in contactIDs:
    654                     self.corporateContacts[contactID].relationshipID = relationshipID
    655 
    656             elif contactType == 'alliancecontact':
    657                 sm.GetService('alliance').EditContactsRelationshipID(contactIDs, relationshipID)
    658                 for contactID in contactIDs:
    659                     self.allianceContacts[contactID].relationshipID = relationshipID
    660 
    661             sm.ScatterEvent('OnContactChange', [contactIDs], contactType)
    662 
    663     def AddToAddressBook(self, contactID, contactType, edit = 0, labelID = None):
    664         if contactID == session.charid and contactType == 'contact':
    665             prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/CannotAddSelf')})
    666             return
    667         if idCheckers.IsNPC(contactID) and not sm.GetService('agents').IsAgent(contactID) and idCheckers.IsCharacter(contactID):
    668             prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/IsNotAnAgent', agentName=cfg.eveowners.Get(contactID).name)})
    669             return
    670         if contactType is None and contactID in self.agents:
    671             prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/AlreadyAContact', contactName=cfg.eveowners.Get(contactID).name)})
    672             return
    673         if contactType == 'contact':
    674             if contactID in self.contacts and not edit:
    675                 prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/AlreadyAContact', contactName=cfg.eveowners.Get(contactID).name)})
    676                 return
    677         if contactType == 'corpcontact':
    678             if contactID in self.corporateContacts and not edit:
    679                 prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/AlreadyACorpContact', contactName=cfg.eveowners.Get(contactID).name)})
    680                 return
    681         if contactType == 'alliancecontact':
    682             if contactID in self.allianceContacts and not edit:
    683                 prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/PeopleAndPlaces/AlreadyAnAllianceContact', contactName=cfg.eveowners.Get(contactID).name)})
    684                 return
    685         inWatchlist = False
    686         relationshipID = None
    687         labelMask = 0
    688         message = None
    689         if idCheckers.IsNPC(contactID) and sm.GetService('agents').IsAgent(contactID):
    690             sm.RemoteSvc('charMgr').AddContact(contactID)
    691             self.agents.append(contactID)
    692             self.RefreshWindow()
    693         else:
    694             isContact = self.IsInAddressBook(contactID, contactType)
    695             if contactType == 'contact':
    696                 windowType = ContactManagementWnd
    697                 entityID = contactID
    698                 relationshipID = relationshipID
    699                 wasInWatchlist = inWatchlist
    700                 isContact = isContact
    701             else:
    702                 windowType = CorpAllianceContactManagementWnd
    703                 entityID = contactID
    704                 relationshipID = relationshipID
    705                 wasInWatchlist = None
    706                 isContact = isContact
    707             if isContact:
    708                 if contactType == 'contact':
    709                     contact = self.contacts.get(contactID)
    710                     relationshipID = contact.relationshipID
    711                     inWatchlist = wasInWatchlist = contact.inWatchlist
    712                     labelMask = contact.labelMask
    713                     startupParams = (contactID,
    714                      relationshipID,
    715                      inWatchlist,
    716                      isContact)
    717                 elif contactType == 'corpcontact':
    718                     contact = self.corporateContacts.get(contactID)
    719                     relationshipID = contact.relationshipID
    720                     labelMask = contact.labelMask
    721                     startupParams = (contactID, relationshipID, isContact)
    722                 elif contactType == 'alliancecontact':
    723                     contact = self.allianceContacts.get(contactID)
    724                     relationshipID = contact.relationshipID
    725                     labelMask = contact.labelMask
    726                     startupParams = (contactID, relationshipID, isContact)
    727             wnd = windowType.Open(windowID='contactmanagement_%s' % entityID, entityID=entityID, level=relationshipID, watchlist=wasInWatchlist, isContact=isContact, contactType=contactType, labelID=labelID)
    728             if wnd.ShowModal() == 1:
    729                 results = wnd.result
    730                 if contactType == 'contact':
    731                     relationshipID = results[0]
    732                     inWatchlist = results[1]
    733                     sendNotification = results[2]
    734                     message = results[3]
    735                     contactLabel = results[4]
    736                 else:
    737                     relationshipID = results[0]
    738                     contactLabel = results[1]
    739                 contact = utillib.KeyVal()
    740                 contact.contactID = contactID
    741                 contact.relationshipID = relationshipID
    742                 contact.inWatchlist = inWatchlist
    743                 contact.labelMask = labelMask
    744                 if contactType == 'contact':
    745                     if isContact and edit:
    746                         func = 'EditContact'
    747                     else:
    748                         func = 'AddContact'
    749                     eveMisc.CSPAChargedAction('CSPAContactNotifyCheck', sm.RemoteSvc('charMgr'), func, contactID, relationshipID, inWatchlist, sendNotification, message)
    750                     self.contacts[contactID] = contact
    751                     if contactLabel is not None:
    752                         self.AssignLabelFromWnd([contactID], contactLabel)
    753                 elif contactType == 'corpcontact':
    754                     if isContact and edit:
    755                         sm.GetService('corp').EditCorporateContact(contactID, relationshipID=relationshipID)
    756                     else:
    757                         sm.GetService('corp').AddCorporateContact(contactID, relationshipID=relationshipID)
    758                     self.corporateContacts[contactID] = contact
    759                     if contactLabel is not None:
    760                         self.AssignLabelFromWnd([contactID], contactLabel)
    761                 elif contactType == 'alliancecontact':
    762                     if isContact and edit:
    763                         sm.GetService('alliance').EditAllianceContact(contactID, relationshipID=relationshipID)
    764                     else:
    765                         sm.GetService('alliance').AddAllianceContact(contactID, relationshipID=relationshipID)
    766                     self.allianceContacts[contactID] = contact
    767                     if contactLabel is not None:
    768                         self.AssignLabelFromWnd([contactID], contactLabel)
    769                 sm.ScatterEvent('OnContactChange', [contactID], contactType)
    770                 if idCheckers.IsCharacter(contactID) and not idCheckers.IsNPC(contactID) and contact.inWatchlist and contactType == 'contact':
    771                     isOnline = sm.GetService('onlineStatus').GetOnlineStatus(contactID)
    772                     if not wasInWatchlist:
    773                         sm.ScatterEvent('OnContactAddedToWatchlist', contactID, isOnline)
    774                     sm.ScatterEvent('OnClientContactChange', contactID, isOnline)
    775 
    776     def RemoveFromAddressBook(self, contactIDs, contactType):
    777         if contactType is None:
    778             if idCheckers.IsNPC(contactIDs) and sm.GetService('agents').IsAgent(contactIDs):
    779                 sm.RemoteSvc('charMgr').DeleteContacts([contactIDs])
    780                 self.agents.remove(contactIDs)
    781                 self.RefreshWindow()
    782                 return
    783         charnameList = ''
    784         for contactID in contactIDs:
    785             charName = cfg.eveowners.Get(contactID).name
    786             if len(contactIDs) > 1:
    787                 if charnameList == '':
    788                     charnameList = '%s' % charName
    789                 else:
    790                     charnameList = '%s, %s' % (charnameList, charName)
    791             else:
    792                 charnameList = cfg.eveowners.Get(contactID).name
    793 
    794         if len(contactIDs) > 1:
    795             msg = 'RemoveManyFromContacts'
    796         else:
    797             msg = 'RemoveOneFromContacts'
    798         if contactType == 'contact':
    799             if prompt_player_fsd_dialog(msg, {'names': charnameList}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    800                 return
    801             sm.RemoteSvc('charMgr').DeleteContacts(contactIDs)
    802         elif contactType == 'corpcontact':
    803             if prompt_player_fsd_dialog(msg, {'names': charnameList}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    804                 return
    805             sm.GetService('corp').RemoveCorporateContacts(contactIDs)
    806         elif contactType == 'alliancecontact':
    807             if prompt_player_fsd_dialog(msg, {'names': charnameList}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    808                 return
    809             sm.GetService('alliance').RemoveAllianceContacts(contactIDs)
    810         scatterList = []
    811         for contactID in contactIDs:
    812             scatterList.append(contactID)
    813             if contactType == 'contact':
    814                 if contactID in self.contacts:
    815                     self.contacts.pop(contactID)
    816                     if idCheckers.IsCharacter(contactID):
    817                         sm.GetService('onlineStatus').ClearOnlineStatus(contactID)
    818             elif contactType == 'corpcontact':
    819                 if contactID in self.corporateContacts:
    820                     self.corporateContacts.pop(contactID)
    821             elif contactType == 'alliancecontact':
    822                 if contactID in self.allianceContacts:
    823                     self.allianceContacts.pop(contactID)
    824 
    825         if len(scatterList):
    826             sm.ScatterEvent('OnContactChange', scatterList, contactType)
    827 
    828     def DeleteEntryMulti(self, charIDs, contactType = None):
    829         buddygroups = uicore.registry.GetListGroups('buddygroups')
    830         agentgroups = uicore.registry.GetListGroups('agentgroups')
    831         if not hasattr(charIDs, '__iter__'):
    832             charIDs = [charIDs]
    833         if contactType is None:
    834             if prompt_player_fsd_dialog('RemoveAgents', {}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES:
    835                 return
    836             for charID in charIDs:
    837                 for listgroup in [agentgroups]:
    838                     for group in listgroup.itervalues():
    839                         if not group:
    840                             continue
    841                         if charID in group['groupItems']:
    842                             group['groupItems'].remove(charID)
    843 
    844                 self.RemoveFromAddressBook(charID, contactType)
    845 
    846         else:
    847             self.RemoveFromAddressBook(charIDs, contactType)
    848 
    849     def GetStandingsLevel(self, contactID, contactType):
    850         if self.IsInAddressBook(contactID, contactType):
    851             if contactType == 'alliancecontact':
    852                 contact = self.allianceContacts.get(contactID, None)
    853                 if contact is not None:
    854                     return contact.relationshipID
    855             if contactType == 'corpcontact':
    856                 contact = self.corporateContacts.get(contactID, None)
    857                 if contact is not None:
    858                     return contact.relationshipID
    859             if contactType == 'contact':
    860                 contact = self.contacts.get(contactID, None)
    861                 if contact is not None:
    862                     return contact.relationshipID
    863 
    864     def IsInAddressBook(self, contactID, contactType = None):
    865         if self.contacts is None or self.allianceContacts is None or self.corporateContacts is None:
    866             self.GetContacts()
    867         if contactType == 'alliancecontact':
    868             return contactID in self.allianceContacts
    869         if contactType == 'corpcontact':
    870             return contactID in self.corporateContacts
    871         if contactType == 'contact':
    872             return contactID in self.contacts or contactID in self.agents
    873         if contactType is None:
    874             return contactID in self.allianceContacts or contactID in self.corporateContacts or contactID in self.contacts or contactID in self.agents
    875 
    876     def GetAddressBook(self):
    877         return self.contacts.keys()
    878 
    879     def IsInWatchlist(self, ownerID):
    880         contacts = []
    881         if self.contacts is None:
    882             self.GetContacts()
    883         contact = self.contacts.get(ownerID, None)
    884         if contact is not None:
    885             return contact.inWatchlist
    886         return False
    887 
    888     def GetContactEntry(self, data, contact, onlineOnly = False, dblClick = None, contactType = None, contactLevel = None, labelMask = None, menuFunction = None, extraInfo = None, listentryType = User):
    889         entryTuple = None
    890         charinfo = cfg.eveowners.Get(contact.contactID)
    891         if onlineOnly:
    892             if self.IsInWatchlist(contact.contactID):
    893                 os = sm.GetService('onlineStatus').GetOnlineStatus(contact.contactID)
    894                 if os:
    895                     entry = self.GetEntryLine(data, contact, dblClick, contactType, contactLevel, labelMask, listentryType=listentryType)
    896                     entryTuple = (charinfo.name.lower(), entry)
    897         else:
    898             entry = self.GetEntryLine(data, contact, dblClick, contactType, contactLevel, labelMask, menuFunction, extraInfo, listentryType)
    899             entryTuple = (charinfo.name.lower(), entry)
    900         return entryTuple
    901 
    902     def GetEntryLine(self, data, contact, dblClick = None, contactType = None, contactLevel = None, labelMask = None, menuFunction = None, extraInfo = None, listentryType = User):
    903         if data is None:
    904             data = Bunch()
    905         if data.Get('groupID', None) == const.contactBlocked:
    906             inWatchlist = False
    907         else:
    908             inWatchlist = getattr(contact, 'inWatchlist', False)
    909         entry = GetFromClass(listentryType, {'listGroupID': data.Get('id', None),
    910          'charID': contact.contactID,
    911          'itemID': contact.contactID,
    912          'showOnline': inWatchlist,
    913          'info': cfg.eveowners.Get(contact.contactID),
    914          'OnDblClick': dblClick,
    915          'contactType': contactType,
    916          'contactLevel': contactLevel,
    917          'labelMask': labelMask,
    918          'MenuFunction': menuFunction,
    919          'extraInfo': extraInfo})
    920         return entry
    921 
    922     def GetNotifications(self, notification):
    923         label = ''
    924         senderName = ''
    925         if notification.senderID is not None:
    926             senderName = cfg.eveowners.Get(notification.senderID).ownerName
    927         bodyParts = notification.body.split('<br>')
    928         bodyParts = filter(lambda x: bool(x), bodyParts)
    929         entry = GetFromClass(ContactNotificationEntry, {'label': bodyParts[0] if len(bodyParts) > 0 else '',
    930          'label2': bodyParts[1] if len(bodyParts) > 1 else '',
    931          'hint': notification.body.replace('<br><br>', '<br>'),
    932          'id': notification.notificationID,
    933          'typeID': notification.typeID,
    934          'senderID': notification.senderID,
    935          'data': utillib.KeyVal(read=notification.processed),
    936          'info': notification,
    937          'ignoreRightClick': 1,
    938          'Draggable_blockDrag': 1})
    939         return (notification.created, entry)
    940 
    941     def RenameContactLabelFromUI(self, labelID):
    942         ret = utilWindows.NamePopup(localization.GetByLabel('UI/PeopleAndPlaces/LabelsLabelName'), localization.GetByLabel('UI/PeopleAndPlaces/LabelsTypeNewLabelName'), maxLength=const.mailMaxLabelSize, validator=self.CheckLabelName)
    943         if ret is None:
    944             return
    945         name = ret
    946         name = name.strip()
    947         if name:
    948             self.EditContactLabel(labelID, name=name)
    949 
    950     def EditContactLabel(self, labelID, name = None, color = None):
    951         if name is None and color is None or name == '':
    952             raise UserError('MailLabelMustProvideName')
    953         self.GetSvc().EditLabel(labelID, name, color)
    954         labels = self.GetContactLabels(self.contactType)
    955         if name is not None:
    956             if labelID in labels:
    957                 labels[labelID].name = name
    958         if color is not None:
    959             if labelID in labels:
    960                 labels[labelID].color = color
    961         sm.ScatterEvent('OnMyLabelsChanged', self.contactType, None)
    962 
    963     def CreateContactLabel(self, name, color = None):
    964         labelID = self.GetSvc().CreateLabel(name, color)
    965         labels = self.GetContactLabels(self.contactType)
    966         labels[labelID] = utillib.KeyVal(labelID=labelID, name=name, color=color)
    967         sm.ScatterEvent('OnMyLabelsChanged', self.contactType, labelID)
    968         return labelID
    969 
    970     def GetContactLabels(self, contactType, updateVarible = True):
    971         uthread.Lock(self, 'labels')
    972         try:
    973             if updateVarible:
    974                 self.contactType = contactType
    975             if contactType == 'contact':
    976                 if self.labels is None:
    977                     self.labels = self._GetSvcForContactType(contactType).GetLabels()
    978                 return self.labels
    979             if contactType == 'corpcontact':
    980                 if self.corporateLabels is None:
    981                     self.corporateLabels = self._GetSvcForContactType(contactType).GetLabels()
    982                 return self.corporateLabels
    983             if contactType == 'alliancecontact':
    984                 if self.allianceLabels is None:
    985                     self.allianceLabels = self._GetSvcForContactType(contactType).GetLabels()
    986                 return self.allianceLabels
    987             raise RuntimeError('contact type missing')
    988         finally:
    989             uthread.UnLock(self, 'labels')
    990 
    991     def GetSvc(self):
    992         contactType = self.contactType
    993         return self._GetSvcForContactType(contactType)
    994 
    995     def _GetSvcForContactType(self, contactType):
    996         svc = ''
    997         if contactType == 'contact':
    998             svc = sm.RemoteSvc('charMgr')
    999         elif contactType == 'corpcontact':
   1000             svc = sm.GetService('corp')
   1001         elif contactType == 'alliancecontact':
   1002             svc = sm.GetService('alliance')
   1003         return svc
   1004 
   1005     def CheckLabelName(self, labelName, *args):
   1006         name = labelName.strip()
   1007         myLabelNames = [ label.name for label in self.GetContactLabels(self.contactType).values() ]
   1008         if name in myLabelNames:
   1009             return localization.GetByLabel('UI/PeopleAndPlaces/LabelsLabelNameTaken')
   1010 
   1011     def DeleteContactLabelFromUI(self, labelID, labelName):
   1012         if prompt_player_fsd_dialog('DeleteMailLabel', {'labelName': labelName}, uiconst.YESNO) == uiconst.ID_YES:
   1013             self.DeleteContactLabel(labelID)
   1014 
   1015     def DeleteContactLabel(self, labelID):
   1016         self.GetSvc().DeleteLabel(labelID)
   1017         if self.contactType == 'contact':
   1018             contacts = self.contacts
   1019             self.labels = None
   1020         elif self.contactType == 'corpcontact':
   1021             contacts = self.corporateContacts
   1022             self.corporateLabels = None
   1023         elif self.contactType == 'alliancecontact':
   1024             contacts = self.allianceContacts
   1025             self.allianceLabels = None
   1026         else:
   1027             raise RuntimeError('contact type missing')
   1028         labels = self.GetContactLabels(self.contactType)
   1029         for contactID, contact in contacts.iteritems():
   1030             contacts[contactID].labelMask = contact.labelMask & const.maxLong - labelID
   1031 
   1032         sm.ScatterEvent('OnMyLabelsChanged', self.contactType, None)
   1033 
   1034     def AssignLabelFromMenu(self, selIDs, labelID, labelName):
   1035         self.AssignLabelFromWnd(selIDs, labelID, labelName)
   1036 
   1037     def AssignLabelFromWnd(self, selIDs, labelID, labelName = '', displayNotify = 1):
   1038         self.GetSvc().AssignLabels(selIDs, labelID)
   1039         if self.contactType == 'contact':
   1040             contacts = self.contacts
   1041         elif self.contactType == 'corpcontact':
   1042             contacts = self.corporateContacts
   1043         elif self.contactType == 'alliancecontact':
   1044             contacts = self.allianceContacts
   1045         else:
   1046             raise RuntimeError('contact type missing')
   1047         for contactID in selIDs:
   1048             if self.IsInAddressBook(contactID, self.contactType):
   1049                 contacts[contactID].labelMask = contacts[contactID].labelMask | labelID
   1050                 sm.ScatterEvent('OnEditLabel', selIDs, self.contactType)
   1051             elif len(selIDs) == 1:
   1052                 self.AddToAddressBook(contactID, self.contactType, False, labelID)
   1053                 if self.IsInAddressBook(contactID, self.contactType):
   1054                     contacts[contactID].labelMask = contacts[contactID].labelMask | labelID
   1055                     sm.ScatterEvent('OnEditLabel', [contactID], self.contactType)
   1056                 else:
   1057                     return
   1058 
   1059         if len(selIDs) and displayNotify:
   1060             if not labelName:
   1061                 labels = self.GetContactLabels(self.contactType)
   1062                 if labelID in labels:
   1063                     labelName = labels[labelID].name
   1064             text = localization.GetByLabel('UI/PeopleAndPlaces/LabelsLabelAssigned', labelName=labelName, contacts=len(selIDs))
   1065             prompt_player_fsd_dialog('CustomNotify', {'notify': text})
   1066 
   1067     def RemoveLabelFromMenu(self, selIDs, labelID, labelName):
   1068         self.RemoveLabelFromWnd(selIDs, labelID)
   1069         text = localization.GetByLabel('UI/PeopleAndPlaces/LabelRemoved', labelName=labelName, numContacts=len(selIDs))
   1070         prompt_player_fsd_dialog('CustomNotify', {'notify': text})
   1071 
   1072     def RemoveLabelFromWnd(self, selIDs, labelID):
   1073         self.GetSvc().RemoveLabels(selIDs, labelID)
   1074         if self.contactType == 'contact':
   1075             contacts = self.contacts
   1076         elif self.contactType == 'corpcontact':
   1077             contacts = self.corporateContacts
   1078         elif self.contactType == 'alliancecontact':
   1079             contacts = self.allianceContacts
   1080         else:
   1081             raise RuntimeError('contact type missing')
   1082         for contactID in selIDs:
   1083             contacts[contactID].labelMask = contacts[contactID].labelMask & const.maxLong - labelID
   1084 
   1085         sm.ScatterEvent('OnEditLabel', selIDs, self.contactType)
   1086 
   1087     def GetAssignLabelMenu(self, sel, selIDs, contactType, *args):
   1088         m = []
   1089         myLabels = self.GetContactLabels(contactType).values()
   1090         labelMask = const.maxLong
   1091         for node in sel:
   1092             if not hasattr(node, 'labelMask'):
   1093                 return []
   1094             if node.labelMask is not None:
   1095                 labelMask = labelMask & node.labelMask
   1096 
   1097         for each in myLabels:
   1098             labelID = each.labelID
   1099             if labelMask & labelID == labelID:
   1100                 continue
   1101             label = each.name
   1102             m.append((label.lower(), (each.name, self.AssignLabelFromMenu, (selIDs, each.labelID, each.name))))
   1103 
   1104         m = SortListOfTuples(m)
   1105         return m
   1106 
   1107     def GetRemoveLabelMenu(self, sel, selIDs, contactType, *args):
   1108         m = []
   1109         myLabels = self.GetContactLabels(contactType).values()
   1110         labelMask = 0
   1111         for node in sel:
   1112             if not hasattr(node, 'labelMask'):
   1113                 return []
   1114             if node.labelMask is not None:
   1115                 labelMask = labelMask | node.labelMask
   1116 
   1117         for each in myLabels:
   1118             labelID = each.labelID
   1119             if labelMask & labelID != labelID:
   1120                 continue
   1121             label = each.name
   1122             m.append((label, (each.name, self.RemoveLabelFromMenu, (selIDs, each.labelID, each.name))))
   1123 
   1124         m = SortListOfTuples(m)
   1125         return m
   1126 
   1127     def GetLabelText(self, labelMask, contactType):
   1128         labelText = ''
   1129         swatchColors = sm.GetService('mailSvc').GetSwatchColors()
   1130         myLabels = self.GetContactLabels(contactType)
   1131         labelNames = self.GetLabelNameList(labelMask, myLabels)
   1132         for each, colorID in labelNames:
   1133             if colorID is None or colorID not in swatchColors:
   1134                 labelText += '%s, ' % each
   1135             else:
   1136                 color = swatchColors.get(colorID)[0]
   1137                 labelText += '<color=0xBF%s>%s</color>, ' % (color, each)
   1138 
   1139         labelText = labelText[:-2]
   1140         return labelText
   1141 
   1142     def GetLabelNameList(self, labelMask, myLabels):
   1143         labelNames = []
   1144         labels = sm.GetService('mailSvc').GetLabelMaskAsList(labelMask)
   1145         for labelID in labels:
   1146             label = myLabels.get(labelID, None)
   1147             if label is not None:
   1148                 labelNames.append((label.name.lower(), (label.name, label.color)))
   1149 
   1150         labelNames = SortListOfTuples(labelNames)
   1151         return labelNames
   1152 
   1153     def GetLabelMask(self, ownerID):
   1154         return self.GetLabelMaskForContactType(self.contactType, ownerID)
   1155 
   1156     def GetLabelMaskForContactType(self, contactType, ownerID):
   1157         contacts = None
   1158         if contactType == 'contact':
   1159             contacts = self.contacts
   1160         elif contactType == 'corpcontact':
   1161             contacts = self.corporateContacts
   1162         elif contactType == 'alliancecontact':
   1163             contacts = self.allianceContacts
   1164         if contacts is None:
   1165             contacts = self.GetContacts()
   1166         contact = contacts.get(ownerID, None)
   1167         if contact is not None:
   1168             return contact.labelMask
   1169         return 0
   1170 
   1171     def ShowLabelMenuAndManageBtn(self, formType):
   1172         if formType == TAB_CONTACTS:
   1173             return True
   1174         if formType == TAB_CORPCONTACTS:
   1175             if (const.corpRoleDirector | const.corpRoleDiplomat) & session.corprole:
   1176                 return True
   1177         elif formType == TAB_ALLIANCECONTACTS:
   1178             if session.allianceid and sm.GetService('alliance').GetAlliance(session.allianceid).executorCorpID == session.corpid:
   1179                 if (const.corpRoleDirector | const.corpRoleDiplomat) & session.corprole:
   1180                     return True
   1181         return False
   1182 
   1183     def HasLabels(self, charID, corpid, allianceid):
   1184         return bool(self.GetAllLabelsForOwnerID(charID, corpid, allianceid, hasLabelCheck=True))
   1185 
   1186     def GetAllLabelsForOwnerID(self, charID, corpid, allianceid, hasLabelCheck = False):
   1187         contactTypes = [TAB_CONTACTS]
   1188         if not idCheckers.IsNPC(session.corpid):
   1189             contactTypes.append(TAB_CORPCONTACTS)
   1190         if session.allianceid:
   1191             contactTypes.append(TAB_ALLIANCECONTACTS)
   1192         ownerList = filter(None, [charID, corpid, allianceid])
   1193         ret = collections.defaultdict(collections.OrderedDict)
   1194         for ct in contactTypes:
   1195             for ownerID in ownerList:
   1196                 labelMask = self.GetLabelMaskForContactType(ct, ownerID)
   1197                 myLabels = self.GetContactLabels(ct, False)
   1198                 labelNameList = self.GetLabelNameList(labelMask, myLabels)
   1199                 if labelNameList:
   1200                     ret[ct][ownerID] = labelNameList
   1201                     if hasLabelCheck:
   1202                         return True
   1203 
   1204         return ret