evemail.py (126420B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\neocom\evemail.py 2 import math 3 import sys 4 import blue 5 import carbonui.const as uiconst 6 import characterSettingsStorage.characterSettingsConsts as cSettings 7 import copy 8 import eveicon 9 import localization 10 import log 11 import types 12 import uthread 13 import utillib 14 from bannedwords.client import bannedwords 15 from brennivin.itertoolsext import Bundle 16 from carbon.client.script.environment.AudioUtil import PlaySound 17 from carbon.common.script.sys.serviceConst import ROLE_GML 18 from carbon.common.script.util import timerstuff 19 from carbon.common.script.util.commonutils import GetAttrs, StripTags 20 from carbon.common.script.util.format import FmtDate 21 from carbonui.button.const import HEIGHT_NORMAL 22 from carbonui.button.group import ButtonGroup 23 from carbonui.control.button import Button 24 from carbonui.control.buttonIcon import ButtonIcon 25 from carbonui.control.checkbox import Checkbox 26 from carbonui.control.dragResizeCont import DragResizeCont 27 from carbonui.control.radioButton import RadioButton 28 from carbonui.control.singlelineedits.baseSingleLineEdit import BaseSingleLineEdit 29 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger 30 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText 31 from carbonui.control.window import Window 32 from carbonui.primitives.container import Container 33 from carbonui.primitives.containerAutoSize import ContainerAutoSize 34 from carbonui.primitives.fill import Fill 35 from carbonui.primitives.line import Line 36 from carbonui.primitives.sprite import Sprite 37 from carbonui.uicore import uicore 38 from carbonui.util.various_unsorted import SortListOfTuples 39 from carbonui.window.header.tab_navigation import TabNavigationWindowHeader 40 from carbonui.window.underlay import WindowUnderlay 41 from eve.client.script.ui.control import eveIcon, eveLabel, eveScroll 42 from eve.client.script.ui.control.allUserEntries import AllUserEntries 43 from eve.client.script.ui.control.colorpicker import ColorSwatch 44 from eve.client.script.ui.control.divider import Divider 45 from eve.client.script.ui.control.entries.checkbox import CheckboxEntry 46 from eve.client.script.ui.control.entries.generic import Generic 47 from eve.client.script.ui.control.entries.mail import CorpAllianceEntry 48 from eve.client.script.ui.control.entries.space import Space 49 from eve.client.script.ui.control.entries.util import GetFromClass 50 from eve.client.script.ui.control.eveEditPlainText import EditPlainText 51 from eve.client.script.ui.control.listgroup import ListGroup as Group, ListGroup 52 from eve.client.script.ui.shared.neocom.ownerSearch import OwnerSearchWindow 53 from eve.client.script.ui.util import searchOld, searchUtil 54 from eve.client.script.ui.util import uix 55 from eve.client.script.ui.util.linkUtil import GetCharIDFromTextLink 56 from eve.common.lib import appConst as const 57 from eve.common.script.search.const import MatchBy 58 from eve.common.script.sys import idCheckers 59 from eve.common.script.util.notificationconst import groupNamePaths as notificationGroupNamePaths 60 from eveexceptions import UserError 61 from eveservices.menu import GetMenuService 62 from localization import GetByLabel 63 from menu import MenuLabel 64 from player_messaging.client.ui_message import prompt_player_fsd_dialog 65 GROUP_CHAR = 1 66 GROUP_LIST = 2 67 GROUP_CORP = 3 68 MAILLABELTRASH = -1 69 CORPTEXT = 'corp' 70 ALLIANCTEXT = 'alliance' 71 DEFAULTNUMMAILS = 30 72 MAXNUMMAILS = 100 73 MINNUMMAILS = 20 74 SAVE_INTERVAL = 120 * 1000 75 DELETE_INTERVAL = 0.3 * const.SEC 76 WHITE = (1.0, 1.0, 1.0) 77 78 class MailWindow(Window): 79 __guid__ = 'form.MailWindow' 80 __notifyevents__ = ['OnNewMailReceived', 'OnMailStartStopBlinkingTab'] 81 default_width = 800 82 default_height = 600 83 default_minSize = (500, 350) 84 default_windowID = 'mail' 85 default_captionLabelPath = 'Tooltips/Neocom/Mail' 86 default_descriptionLabelPath = 'Tooltips/Neocom/Mail_description' 87 default_iconNum = 'res:/ui/Texture/WindowIcons/evemail.png' 88 89 def ApplyAttributes(self, attributes): 90 Window.ApplyAttributes(self, attributes) 91 if sm.GetService('mailSvc').IsFileCacheCorrupted(): 92 self.Close() 93 raise UserError('MailCacheFileError') 94 sm.GetService('mailSvc').SetBlinkNeocomState(False) 95 self.mailInited = 0 96 self.sr.mail = MailForm(name='mailform', parent=self.content) 97 from eve.client.script.ui.shared.neocom.notifications import NotificationForm 98 self.sr.notifications = NotificationForm(name='notificationform', parent=self.content) 99 self.ConstructTabGroup() 100 shouldBlink = sm.GetService('mailSvc').ShouldTabBlink() 101 if shouldBlink: 102 uthread.new(self.OnNewMailReceived) 103 104 def ConstructTabGroup(self): 105 self.tabGroup = self.header.tab_group 106 self.tabGroup.AddTab(label=localization.GetByLabel('Tooltips/Neocom/Mail'), panel=self.sr.mail, code=self, tabID='mail') 107 self.tabGroup.AddTab(localization.GetByLabel('UI/Mail/Notifications/Notifications'), self.sr.notifications, self, 'notifications') 108 self.tabGroup.AutoSelect() 109 110 def Prepare_Header_(self): 111 self.header = TabNavigationWindowHeader() 112 113 def SelectMailTab(self): 114 self.tabGroup.SelectByIdx(0) 115 116 def SelectNotificationTab(self): 117 self.tabGroup.SelectByIdx(1) 118 119 def Load(self, key): 120 if key == 'mail': 121 self.LoadMail() 122 elif key == 'notifications': 123 self.LoadNotifications() 124 125 def LoadMail(self): 126 if getattr(self, 'mailIniting', 0): 127 return 128 if not getattr(self, 'mailInited', 0): 129 self.mailIniting = 1 130 self.sr.mail.Setup() 131 if not self or self.destroyed: 132 return 133 self.mailInited = 1 134 self.mailIniting = 0 135 sm.GetService('mailSvc').SetBlinkTabState(False) 136 self.sr.mail.LoadMailForm() 137 138 def LoadNotifications(self): 139 if not getattr(self, 'notificationsInited', 0): 140 self.sr.notifications.Setup() 141 self.notificationsInited = 1 142 self.sr.notifications.LoadNotificationForm() 143 144 def _OnClose(self, *args): 145 if getattr(self, 'mailInited', 0): 146 self.sr.mail._OnClose() 147 Window._OnClose(self, *args) 148 149 def OnNewMailReceived(self, *args): 150 self.OnMailStartStopBlinkingTab('mail', blink=1) 151 152 def OnMailStartStopBlinkingTab(self, configname, blink = 1): 153 if self.tabGroup.destroyed: 154 return 155 mailSettings = sm.GetService('mailSvc').GetMailSettings() 156 if configname == 'mail': 157 doBlinkTab = mailSettings.GetSingleValue(cSettings.MAIL_BLINK_TAB, True) 158 if blink == 0 or doBlinkTab: 159 self.tabGroup.BlinkPanelByName(localization.GetByLabel('UI/Mail/EveMail'), blink) 160 161 def GetArrowMenu(self, *args): 162 m = [(MenuLabel('UI/Common/Settings'), self.OpenMailSettings, ())] 163 return m 164 165 def GetMenuMoreOptions(self): 166 menuData = super(MailWindow, self).GetMenuMoreOptions() 167 menuData.AddEntry(text=GetByLabel('UI/Mail/CommunicationSettings'), func=self.OpenMailSettings, texturePath=eveicon.settings) 168 return menuData 169 170 def OpenMailSettings(self, *args): 171 if getattr(self, 'mailIniting', 0): 172 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/SystemLoading')}) 173 MailSettings.Open() 174 175 176 class MailForm(Container): 177 __guid__ = 'form.MailForm' 178 __notifyevents__ = ['OnMyMaillistChanged', 179 'OnMyLabelsChanged', 180 'OnNewMailReceived', 181 'OnMailTrashedDeleted', 182 'OnMailSettingsChanged', 183 'OnMailStatusUpdate', 184 'OnMailCountersUpdate'] 185 186 def Setup(self): 187 sm.RegisterNotify(self) 188 self.viewing = None 189 self.readTimer = 0 190 self.startPos = 0 191 self.scrollHeight = 0 192 self.readingPaneVisible = settings.user.ui.Get('mail_readingPaneVisible', True) 193 self.lastDeleted = 0 194 self.inited = 0 195 sortBy = settings.user.ui.Get('evemail_sortBy', localization.GetByLabel('UI/Mail/Received')) 196 if sortBy in [localization.GetByLabel('UI/Mail/Status'), 197 localization.GetByLabel('UI/Mail/Sender'), 198 localization.GetByLabel('UI/Mail/Subject'), 199 localization.GetByLabel('UI/Mail/Received')]: 200 self.sortBy = sortBy 201 else: 202 self.sortBy = localization.GetByLabel('UI/Mail/Received') 203 self.sortOrder = settings.user.ui.Get('evemail_sortOrder', True) 204 self.content = self 205 self.DrawStuff() 206 sm.GetService('mailSvc').TrySyncMail() 207 if self and not self.destroyed: 208 self.worker = uthread.new(self.SaveChangesWorker) 209 self.inited = 1 210 211 def CheckInited(self): 212 if not self.inited: 213 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/SystemLoading')}) 214 215 def DrawStuff(self, *args): 216 self.toolbarCont = Container(name='toolbarCont', parent=self.content, align=uiconst.TOTOP, height=Button.default_height, padding=(0, 0, 0, 16)) 217 leftContWidth = settings.user.ui.Get('evemail_leftContWidth', 200) 218 self.sr.leftCont = Container(name='leftCont', parent=self.content, align=uiconst.TOLEFT, width=leftContWidth) 219 self.sr.btns = ButtonGroup(btns=[(localization.GetByLabel('UI/Mail/AddMailingList'), 220 self.GetMailingListWnd, 221 'self', 222 None)], parent=self.sr.leftCont) 223 self.sr.leftScroll = eveScroll.Scroll(name='leftScroll', parent=self.sr.leftCont) 224 self.sr.leftScroll.multiSelect = 0 225 self.sr.leftScroll.allowBrowsing = 0 226 divider = Divider(name='divider', parent=self.content, state=uiconst.UI_NORMAL, align=uiconst.TOLEFT, width=const.defaultPadding) 227 divider.Startup(self.sr.leftCont, 'width', 'x', 180, 275) 228 self.sr.bottomCont = Container(name='bottomCont', parent=self.content, align=uiconst.TOBOTTOM, pos=(0, 0, 0, 22)) 229 self.sr.expanderCont = Container(name='expanderCont', parent=self.sr.bottomCont, align=uiconst.CENTER, pos=(0, 0, 16, 16)) 230 expander = Sprite(parent=self.sr.expanderCont, pos=(5, 2, 11, 11), name='expandericon', state=uiconst.UI_NORMAL, texturePath='res:/UI/Texture/Shared/expanderDown.png', align=uiconst.TOPRIGHT) 231 expander.OnClick = self.ChangeReadingPaneVisiblity 232 self.sr.expander = expander 233 self.sr.readingPaneCont = DragResizeCont(name='rightCont', parent=self.content, align=uiconst.TOBOTTOM_PROP, settingsID='evemail_readingContProporations2', minSize=0.1, defaultSize=0.4, maxSize=0.65, show_line=True) 234 self.sr.readingPane = EditPlainText(setvalue='', parent=self.sr.readingPaneCont, align=uiconst.TOALL, readonly=1) 235 self.sr.msgScroll = eveScroll.Scroll(name='msgScroll', parent=self.content) 236 self.sr.msgScroll.sr.id = 'mail_msgs' 237 self.sr.msgScroll.sr.fixedColumns = {localization.GetByLabel('UI/Mail/Status'): 52} 238 self.sr.msgScroll.sr.maxDefaultColumns = {localization.GetByLabel('UI/Mail/Subject'): 250} 239 self.sr.msgScroll.Sort = self.SortMail 240 self.sr.msgScroll.OnDelete = self.DeleteFromKeyboard 241 self.sr.msgScroll.OnSelectionChange = self.MsgScrollSelectionChange 242 self.sr.msgScroll.DrawHeaders = self.RefreshMsgScrollHeaders 243 self.sr.msgScroll.Load(contentList=[], noContentHint=localization.GetByLabel('UI/Mail/FetchingMails'), ignoreSort=1) 244 self.inited = True 245 self.DrawToolbar() 246 self.viewingLabel = 1 247 self.viewingList = None 248 249 def DrawToolbar(self, *args): 250 actions = utillib.KeyVal() 251 actions.composeClicked = self.ComposeClicked 252 actions.replyClicked = self.ReplyClicked 253 actions.replyAllClicked = self.ReplyAllClicked 254 actions.forwardClicked = self.ForwardClicked 255 actions.trashClicked = self.TrashClicked 256 actions.deleteClicked = self.DeleteClicked 257 self.mailActions = MailActionPanel(name='mailActionCont', parent=self.toolbarCont, align=uiconst.TOPLEFT, pos=(0, 258 0, 259 250, 260 Button.default_height)) 261 self.mailActions.Startup(actions) 262 labelBtn = Button(align=uiconst.TOPLEFT, texturePath='res:/ui/Texture/WindowIcons/evemailtag.png', hint=localization.GetByLabel('UI/Mail/ManageLabels'), func=self.ManageLabels) 263 self.mailActions.AddExtraButton(labelBtn, withSpace=1, size=32, hint=localization.GetByLabel('UI/Mail/ManageLabels')) 264 self.ConstructPaginationControls() 265 self.SetReadingPaneVisibility(self.readingPaneVisible) 266 267 def ConstructPaginationControls(self): 268 self.browserCont = ContainerAutoSize(name='browseCont', parent=self.toolbarCont, align=uiconst.TORIGHT, alignMode=uiconst.TOLEFT) 269 labelCont = ContainerAutoSize(name='labelCont', parent=self.browserCont, align=uiconst.TOLEFT, padRight=4) 270 self.pageCountLabel = eveLabel.EveLabelMedium(parent=labelCont, state=uiconst.UI_DISABLED, align=uiconst.CENTERRIGHT) 271 self.backBtn = Button(parent=self.browserCont, align=uiconst.TOLEFT, state=uiconst.UI_HIDDEN, texturePath='res:/UI/Texture/Icons/23_64_1.png', iconSize=24, hint=localization.GetByLabel('UI/Common/Previous'), func=lambda : self.BrowseMail(-1), args=(), padRight=2) 272 self.fwdBtn = Button(parent=self.browserCont, align=uiconst.TOLEFT, state=uiconst.UI_HIDDEN, texturePath='res:/UI/Texture/Icons/23_64_2.png', iconSize=24, hint=localization.GetByLabel('UI/Common/Next'), func=lambda : self.BrowseMail(1), args=()) 273 274 def _OnClose(self, *args): 275 if self.sr.leftCont: 276 settings.user.ui.Set('evemail_leftContWidth', self.sr.leftCont.width) 277 sm.UnregisterNotify(self) 278 sm.GetService('mailSvc').SaveChangesToDisk() 279 280 def SaveChangesWorker(self): 281 while self and not self.destroyed: 282 blue.pyos.synchro.SleepWallclock(SAVE_INTERVAL) 283 try: 284 sm.GetService('mailSvc').SaveChangesToDisk() 285 except Exception: 286 log.LogTraceback('SaveChangesWorker', 'Error while saving to disk...', severity=log.LGERR) 287 sys.exc_clear() 288 289 def LoadMailForm(self): 290 self.ReloadAll() 291 self.MsgScrollSelectionChange() 292 293 def LoadLeftSide(self, *args): 294 scrolllist = [] 295 groups = self.GetStaticLabelsGroups() 296 scrolllist += groups 297 scrolllist.insert(1, GetFromClass(Space, {'height': 16})) 298 scrolllist.append(GetFromClass(Space, {'height': 16})) 299 scrolllist.append(GetFromClass(ListGroup, {'GetSubContent': self.GetLabelsSubContent, 300 'MenuFunction': self.LabelGroupMenu, 301 'label': localization.GetByLabel('UI/Mail/Labels'), 302 'cleanLabel': localization.GetByLabel('UI/Mail/Labels'), 303 'id': ('evemail', 'Labels', localization.GetByLabel('UI/Mail/Labels')), 304 'state': 'locked', 305 'BlockOpenWindow': 1, 306 'showicon': 'ui_73_16_9', 307 'showlen': 0, 308 'groupName': 'labels', 309 'groupItems': [], 310 'updateOnToggle': 0})) 311 scrolllist.append(GetFromClass(Space, {'height': 16})) 312 scrolllist.append(GetFromClass(ListGroup, {'GetSubContent': self.GetMaillistSubContent, 313 'label': localization.GetByLabel('UI/Mail/MailingLists'), 314 'cleanLabel': localization.GetByLabel('UI/Mail/MailingLists'), 315 'id': ('evemail', 'maillists', localization.GetByLabel('UI/Mail/MailingLists')), 316 'state': 'locked', 317 'BlockOpenWindow': 1, 318 'showicon': 'ui_38_16_190', 319 'showlen': 0, 320 'groupName': 'mailinglists', 321 'groupItems': [], 322 'updateOnToggle': 0})) 323 self.sr.leftScroll.Load(contentList=scrolllist) 324 self.UpdateCounters() 325 326 def UpdateCounters(self): 327 newMailsInGroups = {'labels': False, 328 'mailinglists': False} 329 static = [None, 330 const.mailLabelInbox, 331 const.mailLabelSent, 332 const.mailLabelCorporation, 333 const.mailLabelAlliance, 334 MAILLABELTRASH] 335 unreadCountsForLabels = sm.GetService('mailSvc').GetUnreadCounts().labels 336 for key in unreadCountsForLabels.iterkeys(): 337 if unreadCountsForLabels.get(key, 0) > 0 and key not in static: 338 newMailsInGroups['labels'] = True 339 break 340 341 myLists = sm.GetService('mailinglists').GetMyMailingLists() 342 unreadCountsForLists = sm.GetService('mailSvc').GetUnreadCounts().lists 343 for key in unreadCountsForLists.iterkeys(): 344 if unreadCountsForLists.get(key, 0) > 0 and key in myLists: 345 newMailsInGroups['mailinglists'] = True 346 break 347 348 for each in self.sr.leftScroll.GetNodes(): 349 if each.get('currentView', -1) not in [-1, const.mailLabelSent]: 350 count = unreadCountsForLabels.get(each.currentView, 0) 351 self.TryChangePanelLabel(each, count) 352 elif each.listID is not None: 353 count = unreadCountsForLists.get(each.listID, 0) 354 self.TryChangePanelLabel(each, count) 355 elif each.groupName is not None: 356 new = newMailsInGroups.get(each.groupName, False) 357 self.TryChangePanelLabel(each, None, forceBold=new) 358 359 def GetStaticLabelsGroups(self): 360 myLabels = sm.GetService('mailSvc').GetAllLabels() 361 swatchColors = sm.GetService('mailSvc').GetSwatchColors() 362 if self.viewingList is not None: 363 viewingLabel = -100 364 else: 365 viewingLabel = self.viewingLabel 366 scrolllist = [] 367 for label, id, icon in [(localization.GetByLabel('UI/Mail/LabelAllMails'), None, 'ui_73_16_5'), 368 (localization.GetByLabel('UI/Mail/LabelInbox'), const.mailLabelInbox, 'ui_73_16_6'), 369 (localization.GetByLabel('UI/Mail/LabelSent'), const.mailLabelSent, 'ui_73_16_7'), 370 (localization.GetByLabel('UI/Common/Corp'), const.mailLabelCorporation, 'ui_73_16_32'), 371 (localization.GetByLabel('UI/Common/Groups/Alliance'), const.mailLabelAlliance, 'ui_73_16_31'), 372 (localization.GetByLabel('UI/Mail/LabelTrash'), MAILLABELTRASH, 'ui_73_16_11')]: 373 labelInfo = myLabels.get(id, None) 374 colorID = None 375 color = 'ffffff' 376 if labelInfo: 377 colorID = labelInfo.get('color', None) 378 color = swatchColors.get(colorID, (None, None)) 379 color = color[0] 380 if id == MAILLABELTRASH: 381 onClickFunction = self.LoadTrashGroup 382 else: 383 onClickFunction = self.LoadLabelGroup 384 scrolllist.append(GetFromClass(MailGroup, {'GetSubContent': self.GetLeftGroups, 385 'label': label, 386 'cleanLabel': label, 387 'id': ('evemail', id, label), 388 'state': 'locked', 389 'BlockOpenWindow': 1, 390 'disableToggle': 1, 391 'expandable': 0, 392 'showicon': icon, 393 'colorID': colorID, 394 'color': color, 395 'showlen': 0, 396 'groupItems': [], 397 'hideNoItem': 1, 398 'hideExpander': 1, 399 'hideExpanderLine': 1, 400 'selectGroup': 1, 401 'OnClick': onClickFunction, 402 'MenuFunction': self.StaticMenu, 403 'isSelected': viewingLabel == id, 404 'currentView': id, 405 'DropData': self.OnGroupDropData})) 406 407 return scrolllist 408 409 def GetLeftGroups(self, items, *args): 410 return [] 411 412 def GetLabelsSubContent(self, items): 413 scrolllist = [] 414 myLabels = sm.GetService('mailSvc').GetAllLabels().values() 415 unreadCounts = sm.GetService('mailSvc').GetUnreadCounts().labels 416 swatchColors = sm.GetService('mailSvc').GetSwatchColors() 417 if self.viewingList is not None: 418 viewingLabel = -100 419 else: 420 viewingLabel = self.viewingLabel 421 for each in myLabels: 422 if getattr(each, 'static', 0): 423 continue 424 count = unreadCounts.get(each.labelID, 0) 425 colorID = each.color or 0 426 scrolllist.append((each.name.lower(), GetFromClass(MailLabelEntry, {'cleanLabel': each.name, 427 'label': self.GetPanelLabel(each.name, count), 428 'sublevel': 1, 429 'currentView': each.labelID, 430 'OnClick': self.LoadLabelGroup, 431 'GetMenu': self.GetLabelMenu, 432 'isSelected': viewingLabel == each.labelID, 433 'OnDropData': self.OnGroupDropData, 434 'color': swatchColors.get(colorID, (None, None))[0], 435 'colorID': colorID}))) 436 437 scrolllist = SortListOfTuples(scrolllist) 438 return scrolllist 439 440 def GetMaillistSubContent(self, *args): 441 scrolllist = [] 442 myLists = sm.GetService('mailinglists').GetMyMailingLists() 443 unreadCounts = sm.GetService('mailSvc').GetUnreadCounts().lists 444 for key, value in myLists.iteritems(): 445 scrolllist.append((value.displayName.lower(), GetFromClass(Generic, {'cleanLabel': value.displayName, 446 'label': self.GetPanelLabel(value.displayName, unreadCounts.get(key, 0)), 447 'sublevel': 1, 448 'GetMenu': self.MaillistMenu, 449 'isSelected': key == self.viewingList, 450 'listID': key, 451 'OnClick': self.LoadMailinglistMails, 452 'listData': value}))) 453 454 scrolllist = SortListOfTuples(scrolllist) 455 return scrolllist 456 457 def GetMailingListWnd(self, *args): 458 MailinglistWnd.Open() 459 460 def LeaveMaillist(self, listID, *args): 461 sm.GetService('mailinglists').LeaveMaillist(listID) 462 463 def DeleteMaillist(self, listID, *args): 464 mailinglistName = sm.GetService('mailinglists').GetDisplayName(listID) 465 if prompt_player_fsd_dialog('DeleteMailingList', {'mailinglistName': mailinglistName}, uiconst.YESNO) == uiconst.ID_YES: 466 sm.GetService('mailinglists').DeleteMaillist(listID) 467 468 def OpenMaillistSetup(self, listID, *args): 469 windowID = 'MaillistSetupWindow_%s' % listID 470 from eve.client.script.ui.shared.neocom.evemailingListConfig import MaillistSetupWindow 471 MaillistSetupWindow.Open(windowID=windowID, mailingListID=listID) 472 473 def SendMailToList(self, listID, *args): 474 sm.GetService('mailSvc').SendMsgDlg(toListID=listID) 475 476 def SendMailToCorp(self, corpID, *args): 477 sm.GetService('mailSvc').SendMsgDlg(toCorpOrAllianceID=[corpID]) 478 479 def SendMailToAlliance(self, allianceID, *args): 480 sm.GetService('mailSvc').SendMsgDlg(toCorpOrAllianceID=[allianceID]) 481 482 def LoadMailinglistMails(self, entry, *args): 483 self.startPos = 0 484 self.viewingList = entry.sr.node.listID 485 self.viewingLabel = None 486 self.LoadFromLabelIDOrLabelID(listID=entry.sr.node.listID) 487 488 def MaillistMenu(self, entry): 489 m = [] 490 listID = entry.sr.node.listID 491 data = entry.sr.node.listData 492 if not data.isMuted: 493 m.append((MenuLabel('UI/Mail/SendMailToList'), self.SendMailToList, (listID,))) 494 if data.isOperator or data.isOwner: 495 m.append((MenuLabel('UI/Mail/OpenMailingListMgmt'), self.OpenMaillistSetup, (listID,))) 496 m.append(None) 497 name = entry.sr.node.cleanLabel 498 text = MenuLabel('UI/Mail/MarkAllAsReadWithFolderName', {'folderName': name}) 499 m.append((text, self.MarkAsReadByList, (listID, name))) 500 text = MenuLabel('UI/Mail/TrashAllWithFolderName', {'folderName': name}) 501 m.append((text, self.MoveToTrashByList, (listID, name))) 502 m.append(None) 503 if data.isOwner: 504 m.append((MenuLabel('UI/Mail/DeleteMailingList'), self.DeleteMaillist, (listID,))) 505 else: 506 m.append((MenuLabel('UI/Mail/LeaveMailingList'), self.LeaveMaillist, (listID,))) 507 return m 508 509 def GetLabelMenu(self, entry): 510 labelID = entry.sr.node.currentView 511 m = [] 512 m.append((MenuLabel('UI/Mail/AssignColor'), self.GetAssignColorWnd, (labelID,))) 513 m.append((MenuLabel('UI/Mail/LabelRename'), sm.GetService('mailSvc').RenameLabelFromUI, (labelID,))) 514 m.append(None) 515 text = MenuLabel('UI/Mail/MarkAllAsReadWithFolderName', {'folderName': entry.sr.node.cleanLabel}) 516 m.append((text, self.MarkAsReadByLabel, (labelID, entry.sr.node.cleanLabel))) 517 text = MenuLabel('UI/Mail/TrashAllWithFolderName', {'folderName': entry.sr.node.cleanLabel}) 518 m.append((text, self.MoveToTrashByLabel, (labelID, entry.sr.node.cleanLabel))) 519 m.append(None) 520 m.append((MenuLabel('UI/Common/Delete'), sm.GetService('mailSvc').DeleteLabelFromUI, (labelID, entry.sr.node.label))) 521 return m 522 523 def GetAssignColorWnd(self, labelID): 524 blue.pyos.synchro.Yield() 525 doneCallBack = sm.StartService('mailSvc').ChangeLabelColorFromUI 526 doneArgs = (labelID,) 527 sm.GetService('mailSvc').GetAssignColorWnd(labelID, doneCallBack=doneCallBack, doneArgs=doneArgs) 528 529 def CheckLabelName(self, dict, *args): 530 name = dict.get('name', '').strip() 531 myLabelNames = [ label.name for label in sm.GetService('mailSvc').GetAllLabels(assignable=0).values() ] 532 if name in myLabelNames: 533 return localization.GetByLabel('UI/Mail/LabelNameTaken') 534 535 def LoadLabelGroup(self, entry): 536 self.startPos = 0 537 self.viewingLabel = entry.sr.node.currentView 538 self.viewingList = None 539 entry.label = entry.sr.node.label 540 self.LoadFromLabelIDOrLabelID(labelID=entry.sr.node.currentView) 541 542 def LoadTrashGroup(self, entry): 543 self.startPos = 0 544 self.viewingLabel = entry.sr.node.currentView 545 self.viewingList = None 546 self.LoadFromLabelIDOrLabelID(labelID=MAILLABELTRASH) 547 548 def ReloadAll(self, *args): 549 self.LoadLeftSide() 550 self.ReloadMails() 551 552 def ReloadMails(self, refreshing = 0): 553 labelID = self.viewingLabel 554 listID = self.viewingList 555 self.LoadFromLabelIDOrLabelID(labelID=labelID, listID=listID, refreshing=refreshing) 556 557 def LoadFromLabelIDOrLabelID(self, labelID = None, listID = None, refreshing = 0): 558 mailInfo = self.GetMailInfo(labelID, listID) 559 self.LoadMails(mails=mailInfo.sorted, labelID=labelID, refreshing=refreshing, totalNum=mailInfo.totalNum) 560 self.UpdateCounters() 561 562 def GetMailInfo(self, labelID = None, listID = None): 563 mailSettings = sm.GetService('mailSvc').GetMailSettings() 564 numMails = max(1, mailSettings.GetSingleValue(cSettings.MAILS_PER_PAGE, DEFAULTNUMMAILS)) 565 if labelID == MAILLABELTRASH: 566 mailInfo = sm.GetService('mailSvc').GetTrashedMails(orderBy=self.sortBy, ascending=self.sortOrder, pos=self.startPos, count=numMails) 567 elif listID is not None: 568 mailInfo = sm.GetService('mailSvc').GetMailsByLabelOrListID(listID=listID, orderBy=self.sortBy, ascending=self.sortOrder, pos=self.startPos, count=numMails) 569 else: 570 mailInfo = sm.GetService('mailSvc').GetMailsByLabelOrListID(labelID=labelID, orderBy=self.sortBy, ascending=self.sortOrder, pos=self.startPos, count=numMails) 571 return mailInfo 572 573 def LoadMails(self, mails = [], labelID = None, refreshing = 0, totalNum = None): 574 sel = self.sr.msgScroll.GetSelected() 575 selIDs = [ msg.messageID for msg in sel ] 576 pos = self.sr.msgScroll.GetScrollProportion() 577 scrolllist = [] 578 myLabels = sm.GetService('mailSvc').GetAllLabels(assignable=0) 579 for info in mails: 580 entry = self.GetMsgEntry(info, labelID, selIDs, myLabels, refreshing) 581 scrolllist.append(entry) 582 583 self.sr.msgScroll.labelID = labelID 584 scrollHeaders = [localization.GetByLabel('UI/Mail/Status'), 585 localization.GetByLabel('UI/Mail/Sender'), 586 localization.GetByLabel('UI/Mail/Subject'), 587 localization.GetByLabel('UI/Mail/Received'), 588 localization.GetByLabel('UI/Mail/Labels')] 589 self.sr.msgScroll.Load(contentList=scrolllist, headers=scrollHeaders, noContentHint=localization.GetByLabel('UI/Mail/NoMailsFound'), ignoreSort=1, reversesort=self.sortOrder, sortby=self.sortBy) 590 if not refreshing: 591 self.ClearReadingPane() 592 else: 593 self.sr.msgScroll.ScrollToProportion(pos) 594 if totalNum is not None: 595 self.ShowHideBrowse(totalNum) 596 self.ShowHideToolbarButtons() 597 598 def RefreshMsgScrollHeaders(self, headers, tabs = []): 599 eveScroll.Scroll.DrawHeaders(self.sr.msgScroll, headers, tabs) 600 labelID = getattr(self.sr.msgScroll, 'labelID', None) 601 senderColumn = self.sr.msgScroll.FindChild(localization.GetByLabel('UI/Mail/Sender')) 602 if senderColumn is not None: 603 if labelID == const.mailLabelSent: 604 text = localization.GetByLabel('UI/Mail/Recipient') 605 else: 606 text = localization.GetByLabel('UI/Mail/Sender') 607 senderColumn.set_label(text) 608 dateColumn = self.sr.msgScroll.FindChild(localization.GetByLabel('UI/Mail/Received')) 609 if dateColumn is not None: 610 if labelID == const.mailLabelSent: 611 text = localization.GetByLabel('UI/Mail/DateSent') 612 else: 613 text = localization.GetByLabel('UI/Mail/Received') 614 dateColumn.set_label(text) 615 616 def GetMsgEntry(self, info, labelID, selIDs, myLabels, refreshing = 0): 617 labels = self.GetLabelText(info.labels, myLabels) 618 date = FmtDate(info.sentDate, 'ls') 619 if labelID == const.mailLabelSent: 620 name = sm.GetService('mailSvc').GetRecipient(info, getName=1) 621 else: 622 name = info.senderName 623 label = '<t>'.join(('', 624 name, 625 info.subject, 626 date, 627 labels)) 628 entry = GetFromClass(MailEntry, {'messageID': info.messageID, 629 'data': info.copy(), 630 'currentView': labelID, 631 'OnClick': self.LoadReadingPaneFromEntry, 632 'OnDblClick': self.DblMailClickEntry, 633 'GetMenu': self.GetMsgMenu, 634 'ignoreRightClick': 1, 635 'isSelected': refreshing and info.messageID in selIDs, 636 'id': info.messageID, 637 'name': name, 638 'label': label, 639 'cleanLabel': label}) 640 return entry 641 642 def GetLabelText(self, labels, myLabels): 643 labelText = '' 644 labelNames = [] 645 swatchColors = sm.GetService('mailSvc').GetSwatchColors() 646 for labelID in labels: 647 label = myLabels.get(labelID, None) 648 if label is not None: 649 labelNames.append((label.name, label.color)) 650 651 labelNames.sort() 652 for each, colorID in labelNames: 653 if colorID is None or colorID not in swatchColors: 654 colorID = 0 655 color = swatchColors.get(colorID)[0] 656 labelText += '<color=0xBF%s>%s</color>, ' % (color, each) 657 658 labelText = labelText[:-2] 659 return labelText 660 661 def ShowHideBrowse(self, totalNum): 662 btnDisplayed = 0 663 if self.startPos == 0: 664 self.backBtn.state = uiconst.UI_HIDDEN 665 else: 666 self.backBtn.state = uiconst.UI_NORMAL 667 btnDisplayed = 1 668 mailSettings = sm.GetService('mailSvc').GetMailSettings() 669 numMails = max(1, mailSettings.GetSingleValue(cSettings.MAILS_PER_PAGE, DEFAULTNUMMAILS)) 670 if self.startPos + numMails >= totalNum: 671 self.fwdBtn.state = uiconst.UI_HIDDEN 672 else: 673 self.fwdBtn.state = uiconst.UI_NORMAL 674 btnDisplayed = 1 675 if btnDisplayed: 676 numPages = int(math.ceil(totalNum / float(numMails))) 677 currentPage = self.startPos / numMails + 1 678 self.pageCountLabel.text = '%s/%s' % (currentPage, numPages) 679 else: 680 self.pageCountLabel.text = '' 681 682 def ClearReadingPane(self): 683 self.sr.readingPane.SetText('') 684 self.viewing = None 685 686 def ChangeReadingPaneVisiblity(self, *args): 687 if self.readingPaneVisible is True: 688 self.SetReadingPaneVisibility(on=False) 689 else: 690 self.SetReadingPaneVisibility(on=True) 691 settings.user.ui.Set('mail_readingPaneVisible', self.readingPaneVisible) 692 693 def SetReadingPaneVisibility(self, on = True): 694 if on: 695 self.readingPaneVisible = True 696 self.sr.expander.hint = localization.GetByLabel('UI/Mail/HideReadingPane') 697 self.sr.expander.texturePath = 'res:/UI/Texture/Shared/expanderDown.png' 698 sel = self.sr.msgScroll.GetSelected() 699 if len(sel) > 0: 700 self.viewing = sel[0] 701 self.ShowHideReadingPane(show=1) 702 if self.viewing is not None: 703 self.LoadReadingPane(self.viewing) 704 else: 705 self.readingPaneVisible = False 706 self.sr.expander.hint = localization.GetByLabel('UI/Mail/ShowReadingPane') 707 self.sr.expander.texturePath = 'res:/UI/Texture/Shared/expanderUp.png' 708 self.ShowHideReadingPane(show=0) 709 710 def ShowHideReadingPane(self, show): 711 if show: 712 self.sr.readingPaneCont.state = uiconst.UI_PICKCHILDREN 713 self.sr.readingPane._OnResize() 714 else: 715 self.sr.readingPaneCont.state = uiconst.UI_HIDDEN 716 717 def OpenMailSettings(self, *args): 718 MailSettings.Open() 719 720 def DblMailClickEntry(self, entry): 721 if not entry or entry.destroyed: 722 return 723 node = entry.sr.node 724 sm.GetService('mailSvc').OnOpenPopupMail(node.data) 725 mail = sm.GetService('mailSvc').GetMailByID(node.messageID) 726 if self and not self.destroyed: 727 self.TryReloadNode(node, mail) 728 729 def LoadReadingPaneFromEntry(self, entry): 730 self.ShowHideReadingPane(show=self.readingPaneVisible) 731 uthread.new(self.LoadReadingPaneFromNode, entry.sr.node) 732 733 def LoadReadingPaneFromNode(self, node): 734 shift = uicore.uilib.Key(uiconst.VK_SHIFT) 735 if not shift: 736 self.LoadReadingPane(node) 737 738 def LoadReadingPane(self, node): 739 self.readTimer = 0 740 if node not in self.sr.msgScroll.GetNodes(): 741 return 742 if self.sr.readingPaneCont.state != uiconst.UI_HIDDEN: 743 txt = sm.GetService('mailSvc').GetMailText(node.data) 744 self.sr.readingPane.SetText(txt) 745 self.viewing = node.messageID 746 if not node.data.read: 747 mail = sm.GetService('mailSvc').GetMailByID(node.messageID) 748 if self and not self.destroyed: 749 self.TryReloadNode(node, mail) 750 751 def OnMailStatusUpdate(self, replyTo, forwardedFrom, forcedIDs = []): 752 if not self.inited: 753 return 754 mailList = forcedIDs[:] 755 if replyTo: 756 mailList.append(replyTo) 757 if forwardedFrom: 758 mailList.append(forwardedFrom) 759 self.RefreshEntriesFromIDs(mailList) 760 761 def RefreshEntriesFromIDs(self, mailIDs): 762 nodes = [] 763 for node in self.sr.msgScroll.GetNodes(): 764 if node.messageID in mailIDs: 765 nodes.append(node) 766 767 self.RefreshEntries(mailIDs, nodes) 768 769 def RefreshEntries(self, mailIDs, nodes): 770 mails = sm.GetService('mailSvc').GetMailsByIDs(mailIDs) 771 for node in nodes: 772 mailData = mails.get(node.messageID, None) 773 if mailData is not None: 774 self.TryReloadNode(node, mailData) 775 776 def TryReloadNode(self, node, data): 777 node.data = data.copy() 778 panel = node.Get('panel', None) 779 if panel is None: 780 return 781 panel.LoadMailEntry(node) 782 783 def RefreshLabels(self, nodes, mailIDs): 784 myLabels = sm.GetService('mailSvc').GetAllLabels(assignable=0) 785 mails = sm.GetService('mailSvc').GetMailsByIDs(mailIDs) 786 nodesToRemove = {} 787 for node in nodes: 788 mailData = mails.get(node.messageID, None) 789 if mailData is not None: 790 shouldRemove = self.RefreshLabel(node, mailData, myLabels) 791 if shouldRemove: 792 nodesToRemove[node.messageID] = node 793 794 if len(nodesToRemove) > 0: 795 self.GoRemoveEntries(nodesToRemove.values(), nodesToRemove.keys()) 796 797 def RefreshLabel(self, node, data, myLabels): 798 if node.currentView is not None and node.currentView not in data.labels + [MAILLABELTRASH]: 799 return True 800 node.data = data.copy() 801 labelText = self.GetLabelText(data.labels, myLabels) 802 date = FmtDate(node.data.sentDate, 'ls') 803 node.cleanLabel = '<t>'.join(('', 804 node.name, 805 node.data.subject, 806 date, 807 labelText)) 808 panel = node.Get('panel', None) 809 if panel is None: 810 return 811 panel.UpdateLabel(data) 812 return False 813 814 def MsgScrollSelectionChange(self, sel = [], *args): 815 self.ShowHideToolbarButtons(sel=sel) 816 if len(sel) == 0: 817 return 818 node = sel[0] 819 if self.viewing != node.messageID: 820 self.readTimer = timerstuff.AutoTimer(1000, self.LoadReadingPane, node) 821 822 def ShowHideToolbarButtons(self, sel = []): 823 if len(sel) < 1: 824 sel = self.sr.msgScroll.GetSelected() 825 numSelected = len(sel) 826 showDelete = self.viewingLabel == MAILLABELTRASH 827 if numSelected == 0: 828 self.mailActions.SetDeleteVisibility(disabled=1, showDelete=showDelete) 829 else: 830 self.mailActions.SetDeleteVisibility(disabled=0, showDelete=showDelete) 831 if numSelected == 1: 832 if sel[0].data.statusMask & const.mailStatusMaskAutomated == const.mailStatusMaskAutomated: 833 self.mailActions.SingleMsgBtnStateAllowFwd() 834 else: 835 self.mailActions.SingleMsgBtnsState(disabled=0) 836 else: 837 self.mailActions.SingleMsgBtnsState(disabled=1) 838 839 def SortMail(self, by = None, reversesort = 0, forceHilite = 0): 840 scroll = self.sr.msgScroll 841 if by == localization.GetByLabel('UI/Mail/Labels'): 842 return 843 self.sortBy = by 844 self.sortOrder = reversesort 845 settings.user.ui.Set('evemail_sortBy', by) 846 settings.user.ui.Set('evemail_sortOrder', reversesort) 847 self.startPos = 0 848 self.ReloadMails() 849 if scroll.sr.sortBy != by or forceHilite: 850 scroll.HiliteSorted(by, reversesort) 851 scroll.sr.sortBy = by 852 853 def GetMsgMenu(self, entry, *args): 854 trashed = entry.sr.node.data.trashed 855 sel = self.sr.msgScroll.GetSelected() 856 selIDs = [ x.id for x in sel ] 857 msgID = entry.sr.node.messageID 858 if msgID not in selIDs: 859 selIDs = [msgID] 860 sel = [entry.sr.node] 861 m = [] 862 readMails = {} 863 unreadMails = {} 864 for mail in sel: 865 if mail.data.read: 866 readMails[mail.id] = mail 867 else: 868 unreadMails[mail.id] = mail 869 870 if len(readMails) > 0: 871 m.append((MenuLabel('UI/Mail/MarkAsUnread'), self.MarkAsUnread, (readMails.keys(), readMails.values()))) 872 if len(unreadMails) > 0: 873 m.append((MenuLabel('UI/Mail/MarkAsRead'), self.MarkAsRead, (unreadMails.keys(), unreadMails.values()))) 874 if trashed: 875 m.append(None) 876 m.append((MenuLabel('UI/Mail/Restore'), self.RestoreMail, (sel, selIDs))) 877 m.append(None) 878 if len(sel) == 1: 879 m += self.GetSenderMenu(sel[0]) 880 m.append((MenuLabel('UI/Mail/Delete'), self.DeleteMail, (sel, selIDs))) 881 else: 882 assignLabelMenu = self.GetAssignLabelMenu(sel, selIDs) 883 if len(assignLabelMenu) > 0: 884 m.append((MenuLabel('UI/Mail/AssignLabel'), assignLabelMenu)) 885 removeLabelMenu = self.GetRemoveLabelMenu(sel, selIDs) 886 if len(removeLabelMenu) > 0: 887 m.append((MenuLabel('UI/Mail/LabelRemove'), removeLabelMenu)) 888 m.append(None) 889 if len(sel) == 1: 890 m += self.GetSenderMenu(sel[0]) 891 m.append((MenuLabel('UI/Mail/Trash'), self.TrashMail, (sel, selIDs))) 892 if session.role & ROLE_GML: 893 m.append(('GM: MessageID=%s' % msgID, blue.pyos.SetClipboardData, (msgID,))) 894 return m 895 896 def GetSenderMenu(self, node): 897 charMenu = [] 898 m = [] 899 itemID = None 900 typeID = None 901 text = localization.GetByLabel('UI/Common/Character') 902 if node.data.statusMask & const.mailStatusMaskAutomated == const.mailStatusMaskAutomated: 903 return m 904 if node.currentView == const.mailLabelSent: 905 recipient = sm.GetService('mailSvc').GetRecipient(node.data, getName=0) 906 if recipient > 0: 907 itemID = recipient 908 if idCheckers.IsCharacter(itemID): 909 typeID = const.typeCharacter 910 elif idCheckers.IsCorporation(itemID): 911 typeID = const.typeCorporation 912 text = localization.GetByLabel('UI/Common/Corporation') 913 elif idCheckers.IsAlliance(itemID): 914 typeID = const.typeAlliance 915 text = localization.GetByLabel('UI/Common/Alliance') 916 else: 917 itemID = node.data.senderID 918 typeID = const.typeCharacter 919 if itemID: 920 charMenu = GetMenuService().GetMenuFromItemIDTypeID(itemID, typeID) 921 if len(charMenu): 922 m.append((text, charMenu)) 923 m.append(None) 924 return m 925 926 def GetAssignLabelMenu(self, sel, selIDs, *args): 927 m = [] 928 myLabels = sm.GetService('mailSvc').GetAllLabels(assignable=1).values() 929 labelMask = const.maxInt 930 for node in sel: 931 labelMask = labelMask & node.data.labelMask 932 933 for each in myLabels: 934 labelID = each.labelID 935 if labelMask & labelID == labelID: 936 continue 937 label = each.name 938 static = getattr(each, 'static', 0) 939 if static: 940 label = ' %s' % each.labelID 941 m.append((label.lower(), (each.name, self.AssignLabelFromMenu, (sel, 942 selIDs, 943 each.labelID, 944 each.name)))) 945 946 m = SortListOfTuples(m) 947 return m 948 949 def GetRemoveLabelMenu(self, sel, selIDs, *args): 950 m = [] 951 myLabels = sm.GetService('mailSvc').GetAllLabels(assignable=1).values() 952 labelMask = 0 953 for node in sel: 954 labelMask = labelMask | node.data.labelMask 955 956 for each in myLabels: 957 labelID = each.labelID 958 if labelMask & labelID != labelID: 959 continue 960 label = each.name 961 static = getattr(each, 'static', 0) 962 if static: 963 label = ' %s' % labelID 964 m.append((label.lower(), (each.name, self.RemoveLabelFromMenu, (sel, 965 selIDs, 966 each.labelID, 967 each.name)))) 968 969 m = SortListOfTuples(m) 970 return m 971 972 def AssignLabelFromMenu(self, sel, selIDs, labelID, labelName): 973 self.AssignLabelFromMailWnd(sel, selIDs, labelID) 974 text = localization.GetByLabel('UI/Mail/LabelAssigned', labelName=labelName, numMails=len(selIDs)) 975 prompt_player_fsd_dialog('CustomNotify', {'notify': text}) 976 977 def AssignLabelFromMailWnd(self, sel, selIDs, labelID): 978 sm.StartService('mailSvc').AssignLabels(selIDs, labelID) 979 self.RefreshLabels(sel, selIDs) 980 981 def RemoveLabelFromMenu(self, sel, selIDs, labelID, labelName): 982 sm.StartService('mailSvc').RemoveLabels(selIDs, labelID) 983 text = localization.GetByLabel('UI/Mail/LabelRemoved', labelName=labelName, numMails=len(selIDs)) 984 prompt_player_fsd_dialog('CustomNotify', {'notify': text}) 985 self.RefreshLabels(sel, selIDs) 986 987 def TrashMail(self, mails, mailIDs): 988 sm.GetService('mailSvc').MoveMessagesToTrash(mailIDs) 989 self.GoRemoveEntries(mails, mailIDs) 990 sm.ScatterEvent('OnMessageChanged', const.mailTypeMail, mailIDs, 'trashed') 991 self.UpdateCounters() 992 993 def DeleteMail(self, mails, mailIDs): 994 sm.GetService('mailSvc').DeleteMails(mailIDs) 995 self.GoRemoveEntries(mails, mailIDs) 996 sm.ScatterEvent('OnMessageChanged', const.mailTypeMail, mailIDs, 'deleted') 997 998 def RestoreMail(self, mails, mailIDs): 999 sm.GetService('mailSvc').MoveMessagesFromTrash(mailIDs) 1000 self.GoRemoveEntries(mails, mailIDs) 1001 1002 def MarkAsUnread(self, mailIDs, mails): 1003 sm.GetService('mailSvc').MarkMessagesAsUnread(mailIDs) 1004 self.RefreshEntries(mailIDs, mails) 1005 1006 def MarkAsRead(self, mailIDs, mails, *args): 1007 sm.GetService('mailSvc').MarkMessagesAsRead(mailIDs) 1008 self.RefreshEntries(mailIDs, mails) 1009 1010 def LabelGroupMenu(self, entry, *args): 1011 m = [] 1012 m.append((MenuLabel('UI/Mail/ManageLabels'), self.ManageLabels)) 1013 return m 1014 1015 def StaticMenu(self, entry, *args): 1016 currentView = entry.currentView 1017 m = [] 1018 if currentView == const.mailLabelCorporation and not idCheckers.IsNPC(session.corpid): 1019 m.append((MenuLabel('UI/Mail/SendMailToCorp'), self.SendMailToCorp, (session.corpid,))) 1020 elif currentView == const.mailLabelAlliance and session.allianceid is not None and session.corprole & const.corpRoleChatManager == const.corpRoleChatManager: 1021 m.append((MenuLabel('UI/Mail/SendMailToAlliance'), self.SendMailToAlliance, (session.allianceid,))) 1022 if currentView is None: 1023 text = MenuLabel('UI/Mail/MarkAllAsReadWithFolderName', {'folderName': localization.GetByLabel('UI/Common/All')}) 1024 m.append((text, self.MarkAllAsRead, ())) 1025 text = MenuLabel('UI/Mail/TrashAllWithFolderName', {'folderName': localization.GetByLabel('UI/Common/All')}) 1026 m.append((text, self.MoveAllToTrash, ())) 1027 elif currentView == MAILLABELTRASH: 1028 m.append((MenuLabel('UI/Mail/RestoreAll'), self.MoveAllFromTrash, ())) 1029 m.append((MenuLabel('UI/Mail/EmptyTrash'), self.EmptyTrash, ())) 1030 else: 1031 m.append((MenuLabel('UI/Mail/AssignColor'), self.GetAssignColorWnd, (entry.currentView,))) 1032 m.append(None) 1033 text = MenuLabel('UI/Mail/MarkAllAsReadWithFolderName', {'folderName': entry.cleanLabel}) 1034 m.append((text, self.MarkAsReadByLabel, (entry.currentView, entry.cleanLabel))) 1035 text = MenuLabel('UI/Mail/TrashAllWithFolderName', {'folderName': entry.cleanLabel}) 1036 m.append((text, self.MoveToTrashByLabel, (entry.currentView, entry.cleanLabel))) 1037 return m 1038 1039 def MarkAllAsRead(self, *args): 1040 if prompt_player_fsd_dialog('EvemailMailMarkAllRead', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1041 sm.GetService('mailSvc').MarkAllAsRead() 1042 self.ReloadAll() 1043 1044 def MoveAllToTrash(self, *args): 1045 if prompt_player_fsd_dialog('EvemailMailTrashAll', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1046 sm.GetService('mailSvc').MoveAllToTrash() 1047 self.ReloadAll() 1048 1049 def MoveAllFromTrash(self, *args): 1050 if prompt_player_fsd_dialog('EvemailMailRestoreAll', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1051 sm.GetService('mailSvc').MoveAllFromTrash() 1052 self.ReloadAll() 1053 1054 def EmptyTrash(self, *args): 1055 if prompt_player_fsd_dialog('EvemailMaillDeleteAll', {}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1056 sm.GetService('mailSvc').EmptyTrash() 1057 self.ReloadAll() 1058 1059 def MarkAsReadByLabel(self, labelID, name, *args): 1060 if prompt_player_fsd_dialog('EvemailMailReadLabelGroup', {'labelName': name}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1061 sm.GetService('mailSvc').MarkAsReadByLabel(labelID) 1062 self.ReloadAll() 1063 1064 def MarkAsReadByList(self, listID, name, *args): 1065 if prompt_player_fsd_dialog('EvemailMailReadMailinglistGroup', {'listName': name}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1066 sm.GetService('mailSvc').MarkAsReadByList(listID) 1067 self.ReloadAll() 1068 1069 def MoveToTrashByLabel(self, labelID, name, *args): 1070 if prompt_player_fsd_dialog('EvemailMailTrashLabelGroup', {'labelName': name}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1071 sm.GetService('mailSvc').MoveToTrashByLabel(labelID) 1072 self.ReloadAll() 1073 1074 def MoveToTrashByList(self, listID, name, *args): 1075 if prompt_player_fsd_dialog('EvemailMailTrashMailinglistGroup', {'listName': name}, uiconst.YESNO, suppress=uiconst.ID_YES) == uiconst.ID_YES: 1076 sm.GetService('mailSvc').MoveToTrashByList(listID) 1077 self.ReloadAll() 1078 1079 def GoRemoveEntries(self, nodes, mailIDs): 1080 if getattr(self, 'removingEntries', 0): 1081 return 1082 self.removingEntries = 1 1083 pos = self.sr.msgScroll.GetScrollProportion() 1084 self.sr.msgScroll.RemoveEntries(nodes) 1085 if self.viewing in mailIDs: 1086 self.ClearReadingPane() 1087 mailInfo = self.GetMailInfo(labelID=self.viewingLabel, listID=self.viewingList) 1088 mails = mailInfo.sorted 1089 mailsInScroll = [ msg.id for msg in self.sr.msgScroll.GetNodes() ] 1090 mailsToAdd = [] 1091 for info in mails: 1092 if info.messageID not in mailsInScroll: 1093 mailsToAdd.append(info) 1094 1095 if len(mailsToAdd) < 1: 1096 self.removingEntries = 0 1097 if len(self.sr.msgScroll.GetNodes()) < 1: 1098 self.BrowseMail(-1) 1099 return 1100 myLabels = sm.GetService('mailSvc').GetAllLabels(assignable=0) 1101 entriesToAdd = [] 1102 for each in mailsToAdd: 1103 entry = self.GetMsgEntry(each, self.viewingLabel, [], myLabels, 0) 1104 entriesToAdd.append(entry) 1105 1106 self.sr.msgScroll.AddEntries(-1, entriesToAdd, ignoreSort=1) 1107 self.sr.msgScroll.ScrollToProportion(pos) 1108 self.ShowHideBrowse(mailInfo.totalNum) 1109 self.removingEntries = 0 1110 1111 def ComposeClicked(self, *args): 1112 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1113 bannedwords.check_chat_character_allowed(session.charid) 1114 self.CheckInited() 1115 sm.GetService('mailSvc').SendMsgDlg() 1116 1117 def ReplyClicked(self, *args): 1118 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1119 bannedwords.check_chat_character_allowed(session.charid) 1120 self.CheckInited() 1121 self.Reply(all=0) 1122 1123 def ForwardClicked(self, *args): 1124 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1125 bannedwords.check_chat_character_allowed(session.charid) 1126 self.CheckInited() 1127 sel = self.sr.msgScroll.GetSelected() 1128 if len(sel) < 1: 1129 return 1130 msg = sel[0] 1131 sm.GetService('mailSvc').GetForwardWnd(msg.data) 1132 1133 def ReplyAllClicked(self, *args): 1134 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1135 bannedwords.check_chat_character_allowed(session.charid) 1136 self.CheckInited() 1137 self.Reply(all=1) 1138 1139 def DeleteFromKeyboard(self, *args): 1140 self.CheckInited() 1141 delete = self.viewingLabel == MAILLABELTRASH 1142 if blue.os.GetWallclockTime() - self.lastDeleted < DELETE_INTERVAL: 1143 prompt_player_fsd_dialog('uiwarning03') 1144 return 1145 if delete: 1146 self.DeleteClicked() 1147 else: 1148 self.TrashClicked() 1149 self.UpdateCounters() 1150 self.lastDeleted = blue.os.GetWallclockTime() 1151 1152 def TrashClicked(self, *args): 1153 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1154 self.CheckInited() 1155 self.TrashDeleteFunctionality('trashed') 1156 1157 def DeleteClicked(self, *args): 1158 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1159 self.CheckInited() 1160 self.TrashDeleteFunctionality('deleted') 1161 1162 def TrashDeleteFunctionality(self, what): 1163 selected = self.sr.msgScroll.GetSelected() 1164 if len(selected) < 1: 1165 return 1166 idx = selected[0].idx 1167 messageIDs = [ mail.messageID for mail in selected ] 1168 if what == 'trashed': 1169 self.TrashMail(selected, messageIDs) 1170 elif what == 'deleted': 1171 self.DeleteMail(selected, messageIDs) 1172 numChildren = len(self.sr.msgScroll.GetNodes()) 1173 newIdx = min(idx, numChildren - 1) 1174 newSelectedNode = self.sr.msgScroll.GetNode(newIdx) 1175 if newSelectedNode is not None: 1176 self.sr.msgScroll.SelectNode(newSelectedNode) 1177 1178 def ManageLabels(self, *args): 1179 PlaySound(uiconst.SOUND_BUTTON_CLICK) 1180 self.CheckInited() 1181 ManageLabelsExistingMails.Open() 1182 1183 def BrowseMail(self, backforth, *args): 1184 mailSettings = sm.GetService('mailSvc').GetMailSettings() 1185 numMails = max(1, mailSettings.GetSingleValue(cSettings.MAILS_PER_PAGE, DEFAULTNUMMAILS)) 1186 pos = max(0, self.startPos + numMails * backforth) 1187 self.startPos = pos 1188 self.ReloadMails() 1189 1190 def Reply(self, all = 0): 1191 sel = self.sr.msgScroll.GetSelected() 1192 if len(sel) < 1: 1193 return 1194 msg = sel[0] 1195 if msg is None: 1196 return 1197 sm.GetService('mailSvc').GetReplyWnd(msg.data, all) 1198 1199 def OnMyMaillistChanged(self, *args): 1200 if not self.inited: 1201 return 1202 self.LoadLeftSide() 1203 1204 def OnMyLabelsChanged(self, labelType, created = None, *args): 1205 if labelType == 'mail_labels': 1206 if not self.inited: 1207 return 1208 self.ReloadAll() 1209 1210 def OnMailSettingsChanged(self, *args): 1211 if not self.inited: 1212 return 1213 self.startPos = 0 1214 self.ReloadMails() 1215 1216 def OnNewMailReceived(self, *args): 1217 if not self.inited: 1218 return 1219 self.UpdateCounters() 1220 1221 def OnMailCountersUpdate(self, *args): 1222 if not self.inited: 1223 return 1224 self.UpdateCounters() 1225 1226 def OnMailTrashedDeleted(self, mail, force = 0): 1227 if not self.inited: 1228 return 1229 reload = force 1230 if not force: 1231 if self.viewingLabel == MAILLABELTRASH: 1232 reload = 1 1233 elif not mail.trashed: 1234 if self.viewingList is not None: 1235 if self.viewingList == mail.toListID: 1236 reload = 1 1237 elif self.viewingLabel is None: 1238 reload = 1 1239 elif self.viewingLabel in mail.labels: 1240 reload = 1 1241 if reload: 1242 self.ReloadMails(refreshing=1) 1243 self.UpdateCounters() 1244 1245 def TryChangePanelLabel(self, node, count, forceBold = False): 1246 panel = node.Get('panel', None) 1247 label = self.GetPanelLabel(node.cleanLabel, count, forceBold) 1248 node.label = label 1249 if panel is None: 1250 return 1251 panelLabel = label 1252 panel.sr.label.text = panelLabel 1253 if hasattr(panel, 'UpdateHint'): 1254 panel.UpdateHint() 1255 1256 def GetPanelLabel(self, label, count, forceBold = False): 1257 if count > 0: 1258 return '<b>' + localization.GetByLabel('UI/Mail/FolderLabelWithCount', folderName=label, unreadCount=count) + '</b>' 1259 elif forceBold: 1260 return '<b>' + label + '</b>' 1261 else: 1262 return label 1263 1264 def OnGroupDropData(self, groupID, nodes, *args): 1265 what, labelID, labelName = groupID 1266 shift = uicore.uilib.Key(uiconst.VK_SHIFT) 1267 if len(nodes) < 1 or nodes[0].__guid__ != 'listentry.MailEntry': 1268 return 1269 if labelID is None or labelID == const.mailLabelSent: 1270 prompt_player_fsd_dialog('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/CannotAssignLabel')}) 1271 return 1272 currentView = nodes[0].currentView 1273 allLabels = sm.GetService('mailSvc').GetAllLabels(assignable=0) 1274 currentName = allLabels.get(currentView, None) 1275 if currentName is not None: 1276 currentName = currentName.name 1277 messageIDs = [ node.messageID for node in nodes ] 1278 removeText = '' 1279 if labelID == MAILLABELTRASH: 1280 if currentView == labelID: 1281 return 1282 self.TrashMail(nodes, messageIDs) 1283 else: 1284 if currentView == MAILLABELTRASH: 1285 self.RestoreMail(nodes, messageIDs) 1286 if not shift and currentView: 1287 if currentView == labelID: 1288 return 1289 if currentView not in [MAILLABELTRASH, const.mailLabelSent]: 1290 sm.StartService('mailSvc').RemoveLabels(messageIDs, currentView) 1291 removeText = localization.GetByLabel('UI/Mail/LabelRemoved', labelName=currentName, numMails=len(messageIDs)) 1292 self.AssignLabelFromMailWnd(nodes, messageIDs, labelID) 1293 text = localization.GetByLabel('UI/Mail/LabelAssigned', labelName=labelName, numMails=len(messageIDs)) 1294 if removeText: 1295 text += '<br>%s' % removeText 1296 prompt_player_fsd_dialog('CustomNotify', {'notify': text}) 1297 1298 1299 class MailGroup(Group): 1300 __guid__ = 'listentry.MailGroup' 1301 1302 def Startup(self, *args): 1303 Group.Startup(self, args) 1304 self.sr.colorTag = Container(name='colorTag', parent=self, align=uiconst.CENTERRIGHT, pos=(4, 0, 8, 8), idx=0) 1305 1306 def Load(self, node): 1307 Group.Load(self, node) 1308 if node.Get('colorID', None) is not None and node.Get('color', None) is not None: 1309 import colorsys 1310 rgb = colorsys.hex_to_rgb(node.color) 1311 if rgb == WHITE: 1312 return 1313 Fill(parent=self.sr.colorTag, color=rgb, opacity=0.75) 1314 1315 1316 class MailEntry(Generic): 1317 __guid__ = 'listentry.MailEntry' 1318 isDragObject = True 1319 1320 def Startup(self, *args): 1321 Generic.Startup(self, args) 1322 self.sr.statusIcon = Container(name='statusIcon', parent=self, align=uiconst.TOLEFT, pos=(0, 0, 52, 0)) 1323 1324 def Load(self, node): 1325 self.sr.node = node 1326 Generic.Load(self, node) 1327 self.LoadMailEntry(node) 1328 1329 def LoadMailEntry(self, node): 1330 self.sr.statusIcon.Flush() 1331 iconPath = 'ui_73_16_15' 1332 hint = localization.GetByLabel('UI/Mail/Read') 1333 data = node.data 1334 self.UpdateLabel(data) 1335 if not data.read: 1336 iconPath = 'ui_73_16_14' 1337 hint = localization.GetByLabel('UI/Mail/Unread') 1338 elif node.Get('showAllStatus', 1): 1339 if data.Get('replied', 0): 1340 iconPath = 'ui_73_16_12' 1341 hint = localization.GetByLabel('UI/Mail/Replied') 1342 elif data.Get('forwarded', 0): 1343 iconPath = 'ui_73_16_13' 1344 hint = localization.GetByLabel('UI/Mail/Forwarded') 1345 icon = eveIcon.Icon(icon=iconPath, parent=self.sr.statusIcon, align=uiconst.CENTER, pos=(0, 0, 16, 16), state=uiconst.UI_PICKCHILDREN) 1346 icon.hint = hint 1347 1348 def GetDragData(self, *args): 1349 node = self.sr.node 1350 if node.isNotification: 1351 return [] 1352 return node.scroll.GetSelectedNodes(node) 1353 1354 def OnDropData(self, dragObj, nodes): 1355 pass 1356 1357 def UpdateLabel(self, data): 1358 label = self.sr.node.cleanLabel 1359 if not data.read: 1360 label = '<b>' + label + '</b>' 1361 self.sr.label.text = label 1362 self.sr.node.label = label 1363 self.sr.label.Update() 1364 1365 1366 class MailLabelEntry(Generic): 1367 __guid__ = 'listentry.MailLabelEntry' 1368 1369 def Startup(self, *args): 1370 Generic.Startup(self, args) 1371 self.sr.colorTag = Container(name='colorTag', parent=self, align=uiconst.CENTERRIGHT, pos=(4, 0, 8, 8), idx=0) 1372 1373 def Load(self, node): 1374 Generic.Load(self, node) 1375 self.labelID = self.sr.node.currentView 1376 self.sr.colorTag.Flush() 1377 self.sr.label.autoFadeSides = 25 1378 if node.Get('color', None) is not None: 1379 import colorsys 1380 rgb = colorsys.hex_to_rgb(node.color) 1381 if rgb == WHITE: 1382 return 1383 Fill(parent=self.sr.colorTag, color=rgb, opacity=0.75) 1384 1385 def OnDropData(self, dragObj, nodes): 1386 data = self.sr.node 1387 currentView = data.currentView 1388 if data.OnDropData: 1389 data.OnDropData(('MailLabelEntry', currentView, data.cleanLabel), nodes) 1390 1391 1392 class ManageLabelsBase(Window): 1393 __guid__ = 'form.ManageLabelsBase' 1394 __notifyevents__ = ['OnMyLabelsChanged'] 1395 default_iconNum = 'res:/ui/Texture/WindowIcons/evemailtag.png' 1396 default_minSize = (320, 320) 1397 1398 def ApplyAttributes(self, attributes): 1399 Window.ApplyAttributes(self, attributes) 1400 labelType = self.labelType = attributes.labelType 1401 self.loadingShowcontent = 0 1402 caption = localization.GetByLabel('UI/Mail/ManageLabels') 1403 if labelType == 'contact': 1404 caption = localization.GetByLabel('UI/Mail/ManageLabelsWithType', labelType=localization.GetByLabel('UI/Mail/Contacts')) 1405 elif labelType == 'corpcontact': 1406 caption = localization.GetByLabel('UI/Mail/ManageLabelsWithType', labelType=localization.GetByLabel('UI/Mail/CorpContacts')) 1407 elif labelType == 'alliancecontact': 1408 caption = localization.GetByLabel('UI/Mail/ManageLabelsWithType', labelType=localization.GetByLabel('UI/Mail/AllianceContacts')) 1409 self.SetCaption(caption) 1410 topParent = Container(name='topParent', parent=self.GetMainArea(), align=uiconst.TOTOP, height=60, clipChildren=True) 1411 self.sr.bottom = Container(name='bottom', parent=self.content, align=uiconst.TOBOTTOM, height=HEIGHT_NORMAL) 1412 self.sr.inpt = inpt = SingleLineEditText(name='input', parent=topParent, maxLength=const.mailMaxLabelSize, pos=(0, 20, 86, 0), label=localization.GetByLabel('UI/Mail/LabelName')) 1413 Button(parent=topParent, label=localization.GetByLabel('UI/Mail/Create'), pos=(inpt.left + inpt.width + 4, 1414 inpt.top, 1415 0, 1416 0), func=self.CreateLabel, btn_default=1) 1417 self.sr.textCont = ContainerAutoSize(name='textCont', parent=self.content, align=uiconst.TOTOP, state=uiconst.UI_HIDDEN, padBottom=2) 1418 self.sr.textCont2 = ContainerAutoSize(name='textCont', parent=self.content, align=uiconst.TOBOTTOM, state=uiconst.UI_HIDDEN, padBottom=2) 1419 self.sr.selectedText = eveLabel.EveLabelMedium(text='', parent=self.sr.textCont2, left=0, top=0, state=uiconst.UI_DISABLED, align=uiconst.CENTERTOP) 1420 self.sr.labelScroll = eveScroll.Scroll(name='labelScroll', parent=self.content, padding=(const.defaultPadding, 1421 0, 1422 const.defaultPadding, 1423 const.defaultPadding)) 1424 self.sr.labelScroll.sr.id = labelType 1425 1426 def FindLabelsChecked(self, *args): 1427 labelsChecked = [] 1428 for each in self.sr.labelScroll.GetNodes(): 1429 if each.checked == 1: 1430 labelsChecked.append(each.retval) 1431 1432 return labelsChecked 1433 1434 def CreateLabel(self, *args): 1435 labelName = self.sr.inpt.GetValue() 1436 labelName = labelName.strip() 1437 existingLabels = [] 1438 for each in self.sr.labelScroll.GetNodes(): 1439 existingLabels.append(each.label.lower()) 1440 1441 if labelName.lower() in existingLabels: 1442 raise UserError('MailLabelNameExists') 1443 if len(labelName) < 1: 1444 prompt_player_fsd_dialog('LookupStringMinimum', {'minimum': 1}) 1445 return 1446 if len(labelName) > const.mailMaxLabelSize: 1447 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/LabelTooLong')}) 1448 if self.labelType == 'mail_labels': 1449 wasCreated = sm.GetService('mailSvc').CreateLabel(labelName) 1450 else: 1451 sm.GetService('addressbook').CreateContactLabel(labelName) 1452 1453 def LoadScroll(self, *args): 1454 if self.labelType == 'mail_labels': 1455 labels = sm.GetService('mailSvc').GetAllLabels(assignable=1).values() 1456 else: 1457 labels = sm.GetService('addressbook').GetContactLabels(self.labelType).values() 1458 scrolllist = [] 1459 for each in labels: 1460 label = each.name 1461 static = getattr(each, 'static', 0) 1462 if static: 1463 label = ' %s' % each.labelID 1464 scrolllist.append((label.lower(), GetFromClass(CheckboxEntry, {'label': each.name, 1465 'cfgname': each.name, 1466 'retval': each.labelID, 1467 'checked': each.labelID in self.storedSelection, 1468 'OnChange': self.ShowTextHint, 1469 'GetMenu': self.GetLabelMenu, 1470 'ignoreRightClick': 1}))) 1471 1472 scrolllist = SortListOfTuples(scrolllist) 1473 self.sr.labelScroll.Load(contentList=scrolllist) 1474 self.ShowTextHint() 1475 1476 def OnMyLabelsChanged(self, labelType, created = None, *args): 1477 if labelType == self.labelType: 1478 self.UpdateLabelsList(created) 1479 1480 def UpdateLabelsList(self, created = None, *args): 1481 self.storedSelection = self.FindLabelsChecked() 1482 if created is not None: 1483 self.storedSelection.append(created) 1484 self.LoadScroll() 1485 self.storedSelection = [] 1486 1487 def ShowTextHint(self, *args): 1488 labelsChecked = self.FindLabelsChecked() 1489 numLabels = len(labelsChecked) 1490 if numLabels > 0: 1491 self.sr.selectedText.text = localization.GetByLabel('UI/Mail/LabelsSelected', numSelected=numLabels) 1492 self.sr.textCont2.state = uiconst.UI_DISABLED 1493 else: 1494 self.sr.textCont2.state = uiconst.UI_HIDDEN 1495 1496 def GetLabelMenu(self, entry): 1497 labelID = entry.sr.node.retval 1498 m = [] 1499 if self.labelType == 'mail_labels': 1500 m.append((MenuLabel('UI/Mail/AssignColor'), self.GetAssignColorWnd, (labelID,))) 1501 if const.mailLabelsSystem & labelID == 0: 1502 m.append((MenuLabel('UI/Mail/LabelRename'), sm.GetService('mailSvc').RenameLabelFromUI, (labelID,))) 1503 m.append(None) 1504 m.append((MenuLabel('UI/Mail/Delete'), sm.GetService('mailSvc').DeleteLabelFromUI, (labelID, entry.sr.node.label))) 1505 else: 1506 m.append((MenuLabel('UI/Mail/LabelRename'), sm.GetService('addressbook').RenameContactLabelFromUI, (labelID,))) 1507 m.append(None) 1508 m.append((MenuLabel('UI/Mail/Delete'), sm.GetService('addressbook').DeleteContactLabelFromUI, (labelID, entry.sr.node.label))) 1509 return m 1510 1511 def GetAssignColorWnd(self, labelID): 1512 blue.pyos.synchro.Yield() 1513 doneCallBack = sm.StartService('mailSvc').ChangeLabelColorFromUI 1514 doneArgs = (labelID,) 1515 sm.GetService('mailSvc').GetAssignColorWnd(labelID, doneCallBack=doneCallBack, doneArgs=doneArgs) 1516 1517 1518 class ManageLabelsExistingMails(ManageLabelsBase): 1519 __guid__ = 'form.ManageLabelsExistingMails' 1520 default_windowID = 'ManageLabelsExistingMails' 1521 1522 def ApplyAttributes(self, attributes): 1523 attributes.labelType = 'mail_labels' 1524 ManageLabelsBase.ApplyAttributes(self, attributes) 1525 self.storedSelection = [] 1526 self.sr.textCont.state = uiconst.UI_DISABLED 1527 eveLabel.EveLabelMedium(text=localization.GetByLabel('UI/Mail/LabelText'), parent=self.sr.textCont, padLeft=10, state=uiconst.UI_DISABLED, align=uiconst.TOTOP) 1528 ButtonGroup(btns=[[localization.GetByLabel('UI/Mail/AssignLabel'), 1529 self.AssignLabelFromBtn, 1530 None, 1531 81], [localization.GetByLabel('UI/Mail/LabelRemove'), 1532 self.RemoveLabelFromBtn, 1533 None, 1534 81]], parent=self.sr.bottom, idx=0) 1535 self.LoadScroll() 1536 1537 def AssignLabelFromBtn(self, *args): 1538 self.ManageLabel(assign=1) 1539 1540 def RemoveLabelFromBtn(self, *args): 1541 self.ManageLabel(assign=0) 1542 1543 def ManageLabel(self, assign = 1): 1544 labelsChecked = self.FindLabelsChecked() 1545 numLabels = len(labelsChecked) 1546 if numLabels < 1: 1547 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/PeopleAndPlaces/NoLabelsSelected')}) 1548 wnd = MailWindow.GetIfOpen() 1549 if not wnd: 1550 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/NoMailsSelected')}) 1551 scroll = wnd.FindChild('msgScroll') 1552 if scroll is None: 1553 selectedMails = [] 1554 else: 1555 selectedMails = scroll.GetSelected() 1556 mailIDs = [ mail.messageID for mail in selectedMails ] 1557 sum = 0 1558 for labelID in labelsChecked: 1559 sum = sum + labelID 1560 1561 if assign == 1: 1562 sm.StartService('mailSvc').AssignLabels(mailIDs, sum) 1563 else: 1564 sm.StartService('mailSvc').RemoveLabels(mailIDs, sum) 1565 numLabels = len(labelsChecked) 1566 numMails = len(mailIDs) 1567 if numMails > 0: 1568 if assign: 1569 text = localization.GetByLabel('UI/Mail/LabelsAssignedToMails', numLabels=numLabels, numMails=numMails) 1570 else: 1571 text = localization.GetByLabel('UI/Mail/LabelsRemovedFromMails', numLabels=numLabels, numMails=numMails) 1572 prompt_player_fsd_dialog('CustomNotify', {'notify': text}) 1573 wnd.sr.mail.RefreshLabels(selectedMails, mailIDs) 1574 else: 1575 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/NoMailsSelected')}) 1576 1577 1578 class ManageLabelsNewMails(ManageLabelsBase): 1579 __guid__ = 'form.ManageLabelsNewMails' 1580 default_windowID = 'ManageLabelsNewMails' 1581 1582 def ApplyAttributes(self, attributes): 1583 self.result = None 1584 attributes.labelType = 'mail_labels' 1585 ManageLabelsBase.ApplyAttributes(self, attributes) 1586 labels = attributes.labels 1587 btns = ButtonGroup(btns=[[localization.GetByLabel('UI/Mail/Apply'), 1588 self.Apply, 1589 None, 1590 81]], parent=self.sr.bottom, idx=0, line=1) 1591 self.storedSelection = labels 1592 self.LoadScroll() 1593 1594 def Apply(self, *args): 1595 labelsChecked = self.FindLabelsChecked() 1596 if labelsChecked is None or labelsChecked == []: 1597 if prompt_player_fsd_dialog('NoLabelApplied', {}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES: 1598 return 1599 self.result = labelsChecked 1600 if getattr(self, 'isModal', None): 1601 self.SetModalResult(1) 1602 1603 1604 class NewNewMessage(Window): 1605 __guid__ = 'form.NewNewMessage' 1606 __nonpersistvars__ = ['messageedit', 1607 'buddy', 1608 'input', 1609 'receivers'] 1610 default_toCharacterIDs = [] 1611 default_toListID = None 1612 default_toCorpOrAllianceID = None 1613 default_isForwardedFrom = False 1614 default_isReplyTo = False 1615 default_subject = None 1616 default_body = None 1617 default_width = 300 1618 default_height = 350 1619 default_minSize = (250, 250) 1620 default_captionLabelPath = 'UI/Mail/NewMessage' 1621 default_iconNum = 'res:/ui/Texture/WindowIcons/evemailcompose.png' 1622 1623 def ApplyAttributes(self, attributes): 1624 super(NewNewMessage, self).ApplyAttributes(attributes) 1625 toCharacterIDs = attributes.toCharacterIDs or self.default_toCharacterIDs 1626 toListID = attributes.toListID 1627 toCorpOrAllianceID = attributes.toCorpOrAllianceID 1628 isForwardedFrom = attributes.isForwardedFrom or self.default_isForwardedFrom 1629 isReplyTo = attributes.isReplyTo or self.default_isReplyTo 1630 subject = attributes.subject 1631 body = attributes.body 1632 self.messageedit = None 1633 self.parsingReceivers = 0 1634 self.labels = [] 1635 self.toChars = {} 1636 self.toCorpAlliance = {} 1637 self.toListID = None 1638 self.isForwardedFrom = 0 1639 self.isReplyTo = 0 1640 self.buddies = [] 1641 self.isForwardedFrom = isForwardedFrom 1642 self.isReplyTo = isReplyTo 1643 self.main = self.content 1644 self.configname = self.__hash__() 1645 self.buddies = [ buddy for buddy in sm.GetService('addressbook').GetAddressBook() if idCheckers.IsNPC(buddy) == False and idCheckers.IsCharacter(buddy) ] 1646 self.name = 'newmessage' 1647 self.ConstructTopContainer() 1648 self.receiver.blockSetValue = 1 1649 self.receiver.registerHistory = 0 1650 self.receiver.GetAll = self.GetAllOptions 1651 self.receiver.OnHistoryClick = self.OnReceiverHistoryClick 1652 self.receiver.OnDropData = self.OnDropReceiver 1653 self.receiver.OnInsert = self.ValidateReceiver 1654 self.receiver.OnFocusLost = self.ValidateReceivers 1655 self.receiver.receiverText = '' 1656 self.sendBtn = Button(parent=ContainerAutoSize(parent=self.main, align=uiconst.TOBOTTOM, padTop=8), align=uiconst.BOTTOMLEFT, texturePath='res:/ui/Texture/WindowIcons/evemail.png', iconSize=48, label=localization.GetByLabel('UI/Mail/SendMail'), hint=localization.GetByLabel('UI/Mail/SendMail'), func=self.ClickSend, args=()) 1657 self.messageedit = EditPlainText(parent=self.main, pos=(0, 0, 0, 0), padding=None, align=uiconst.TOALL, maxLength=const.mailMaxBodySize, showattributepanel=1) 1658 buttonCont = self.messageedit.sr.attribPanel 1659 if buttonCont is not None: 1660 ButtonIcon(name='channelWndIcon', texturePath='res:/UI/Texture/icons/73_16_9.png', parent=buttonCont, align=uiconst.TOLEFT, hint=localization.GetByLabel('UI/Mail/LabelMail'), func=self.Label) 1661 if subject is not None: 1662 self.subjecField.SetValue(subject) 1663 if body is not None: 1664 self.messageedit.SetValue(body) 1665 fontCombo = self.messageedit.FindChild('fontsize') 1666 if fontCombo: 1667 fontCombo.isTabStop = 0 1668 if toCharacterIDs: 1669 sm.GetService('mailSvc').PrimeOwners(toCharacterIDs) 1670 for each in toCharacterIDs: 1671 if each is not None: 1672 self.AddCharacterReceiver(each) 1673 1674 if toCorpOrAllianceID: 1675 for each in toCorpOrAllianceID: 1676 if each is not None: 1677 self.AddCorpAllianceReciver(each) 1678 1679 if toListID is not None: 1680 myLists = sm.GetService('mailinglists').GetMyMailingLists() 1681 if toListID in myLists: 1682 list = myLists.get(toListID) 1683 name = list.displayName 1684 self.AddList(toListID, name) 1685 if isReplyTo: 1686 uicore.registry.SetFocus(self.messageedit) 1687 else: 1688 uicore.registry.SetFocus(self.receiver) 1689 self.ValidateReceivers() 1690 1691 def ConstructTopContainer(self): 1692 topParent = Container(name='topParent', parent=self.GetMainArea(), align=uiconst.TOTOP, height=64 + 16, clipChildren=True) 1693 toCont = ContainerAutoSize(parent=topParent, align=uiconst.TOTOP, padBottom=8, alignMode=uiconst.TOTOP) 1694 subjectCont = ContainerAutoSize(parent=topParent, align=uiconst.TOTOP, alignMode=uiconst.TOTOP) 1695 buttonCont = Container(parent=toCont, align=uiconst.TOLEFT) 1696 toBtn = Button(parent=buttonCont, align=uiconst.TOPLEFT, label=localization.GetByLabel('UI/Mail/To'), func=self.OpenReceiverSearch) 1697 self.sr.receiver = self.receiver = self.GetReceiverEdit('toField', toCont, maxLength=const.mailMaxRecipients * 24, label='', align=uiconst.TOTOP) 1698 labelCont = Container(parent=subjectCont, align=uiconst.TOLEFT) 1699 self.subjectLabel = eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Mail/Subject'), parent=labelCont, state=uiconst.UI_NORMAL, align=uiconst.CENTERLEFT) 1700 self.sr.subjecField = self.subjecField = SingleLineEditText(name='subjecField', parent=subjectCont, maxLength=const.mailMaxSubjectSize, label='', align=uiconst.TOTOP) 1701 labelCont.width = buttonCont.width = max(self.subjectLabel.textwidth + 16, toBtn.width + 4) 1702 1703 def ConstructTopContainerOld(self): 1704 topParent = Container(name='topParent', parent=self.GetMainArea(), align=uiconst.TOTOP, height=64, clipChildren=True) 1705 sendCont = Container(name='sendCont', parent=topParent, align=uiconst.TOLEFT, pos=(0, 0, 64, 0)) 1706 labelCont = Container(name='labelCont', parent=topParent, align=uiconst.TOLEFT, pos=(0, 0, 50, 0)) 1707 editCont = Container(name='editCont', parent=topParent, align=uiconst.TOALL, pos=(0, 0, 0, 0)) 1708 Container(name='push', parent=editCont, align=uiconst.TORIGHT, pos=(0, 0, 5, 0)) 1709 self.sendBtn = Button(parent=sendCont, align=uiconst.TOPLEFT, top=8, left=8, texturePath='res:/ui/Texture/WindowIcons/evemail.png', iconSize=48, hint=localization.GetByLabel('UI/Mail/SendMail'), func=self.ClickSend, args=()) 1710 Container(name='push', parent=topParent, align=uiconst.TORIGHT, pos=(0, 0, 4, 0)) 1711 Container(name='push', parent=topParent, align=uiconst.TOTOP, pos=(0, 0, 0, 4)) 1712 toBtn = Button(parent=labelCont, label=localization.GetByLabel('UI/Mail/To'), pos=(0, 7, 0, 0), func=self.OpenReceiverSearch) 1713 toBtn.height = 23 1714 self.sr.receiver = self.receiver = self.GetReceiverEditOld('toField', editCont, maxLength=const.mailMaxRecipients * 24, left=0, top=10, label='', align=uiconst.TOTOP) 1715 self.sr.subjecField = self.subjecField = SingleLineEditText(name='subjecField', parent=editCont, maxLength=const.mailMaxSubjectSize, pos=(0, 10, 0, 0), label='', align=uiconst.TOTOP) 1716 self.subjectLabel = eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Mail/Subject'), parent=labelCont, top=40, left=10, state=uiconst.UI_NORMAL) 1717 labelCont.width = max(self.subjectLabel.textwidth + 15, toBtn.width + 5) 1718 1719 def GetReceiverEditOld(self, configname, where, setvalue = None, left = 0, width = 80, ints = None, top = 2, height = 18, floats = None, callback = None, label = None, maxLength = None, passwordChar = None, align = 0, readonly = 0, adjustWidth = False): 1720 edit = ReceiverEdit(name=configname, parent=where, height=height, width=width, left=left, top=top, align=align) 1721 edit.SetMaxLength(maxLength) 1722 if setvalue is not None: 1723 edit.SetValue(setvalue) 1724 if label: 1725 _label = eveLabel.EveHeaderSmall(text=label, parent=edit, align=uiconst.TOPLEFT, width=1000, height=13, left=0, top=-13) 1726 edit.sr.label = _label 1727 return edit 1728 1729 def GetReceiverEdit(self, configname, where, setvalue = None, width = 80, label = None, maxLength = None, align = 0): 1730 edit = ReceiverEdit(name=configname, parent=where, width=width, align=align) 1731 edit.SetMaxLength(maxLength) 1732 if setvalue is not None: 1733 edit.SetValue(setvalue) 1734 if label: 1735 _label = eveLabel.EveHeaderSmall(text=label, parent=edit, align=uiconst.TOPLEFT, width=1000) 1736 edit.sr.label = _label 1737 return edit 1738 1739 def _OnClose(self, *args): 1740 self.messageedit = None 1741 self.parsingReceivers = 0 1742 wnd = OwnerSearchWindow.GetIfOpen() 1743 if wnd and wnd.configname == self.configname: 1744 wnd.CloseByUser() 1745 1746 def AddCharacterReceiver(self, id, partly = 0): 1747 if not idCheckers.IsCharacter(id): 1748 return self.AddCorpAllianceReciver(id) 1749 name = cfg.eveowners.Get(id).name 1750 if len(self.toChars) >= const.mailMaxRecipients: 1751 prompt_player_fsd_dialog('EvemailMaxRecipients', {'max': const.mailMaxRecipients, 1752 'name': name}) 1753 return False 1754 self.toChars[name] = id 1755 if partly: 1756 return True 1757 self.AddReceiver(id, name) 1758 sm.ScatterEvent('OnSearcedUserAdded', id, self.configname) 1759 return True 1760 1761 def ValidateCorpOrAlliance(self, id): 1762 if idCheckers.IsCorporation(id): 1763 if id != session.corpid: 1764 prompt_player_fsd_dialog('EvemailCantSendToOtherCorp', {}) 1765 return False 1766 if idCheckers.IsNPC(id): 1767 prompt_player_fsd_dialog('EvemailCantSendToNPCCorp', {}) 1768 return False 1769 elif idCheckers.IsAlliance(id): 1770 if id != session.allianceid: 1771 prompt_player_fsd_dialog('EvemailCantSendToOtherAlliance', {}) 1772 return False 1773 if not const.corpRoleChatManager & session.corprole == const.corpRoleChatManager: 1774 prompt_player_fsd_dialog('EvemailCantSendToAllianceNoRole', {}) 1775 return False 1776 else: 1777 return False 1778 return True 1779 1780 def AddCorpAllianceReciver(self, id, partly = 0): 1781 if not self.ValidateCorpOrAlliance(id): 1782 return False 1783 name = cfg.eveowners.Get(id).name 1784 if self.TotalNumberOfGroups() >= const.mailMaxGroups: 1785 self.GetMaxGroupText(name) 1786 return False 1787 self.toCorpAlliance[name] = id 1788 if partly: 1789 return True 1790 self.AddReceiver(id, name) 1791 return True 1792 1793 def AddList(self, id, name, partly = 0): 1794 if self.TotalNumberOfGroups() >= const.mailMaxGroups: 1795 self.GetMaxGroupText(name) 1796 return False 1797 self.toListID = id 1798 if partly: 1799 return True 1800 name = localization.GetByLabel('UI/Mail/MailEntry', entryName=name, entryType=localization.GetByLabel('UI/Mail/ML')) 1801 self.AddReceiver(id, name, checkNPC=False) 1802 return True 1803 1804 def AddReceiver(self, id, name, checkNPC = True): 1805 if checkNPC and idCheckers.IsNPC(id): 1806 return 1807 c = self.sr.receiver.GetValue() 1808 if c: 1809 c += ', ' 1810 if self.name == localization.GetByLabel('UI/Common/Unknown'): 1811 self.name = name 1812 c += name 1813 self.sr.receiver.SetValue(c) 1814 self.ValidateReceivers() 1815 1816 def NewParseReceiver(self, name, *args): 1817 listReceiver = self.GetMailinglistReceiver(name.strip()) 1818 if listReceiver is not None: 1819 if self.TotalNumberOfGroups() >= const.mailMaxGroups: 1820 self.GetMaxGroupText(name) 1821 return 1822 self.toListID = listReceiver 1823 ret = utillib.KeyVal(name=name, group=GROUP_LIST, id=listReceiver) 1824 return ret 1825 name = name.strip() 1826 if name.lower() in [cfg.eveowners.Get(session.corpid).ownerName.lower(), CORPTEXT]: 1827 valid = self.ValidateCorpOrAlliance(session.corpid) 1828 if not valid: 1829 return 1830 name = cfg.eveowners.Get(session.corpid).ownerName 1831 if self.TotalNumberOfGroups() >= const.mailMaxGroups: 1832 self.GetMaxGroupText(name) 1833 return 1834 self.toCorpAlliance[name] = session.corpid 1835 ret = utillib.KeyVal(name=name, group=GROUP_CORP, id=listReceiver) 1836 return ret 1837 if session.allianceid: 1838 if name.lower() in [cfg.eveowners.Get(session.allianceid).ownerName.lower(), ALLIANCTEXT]: 1839 valid = self.ValidateCorpOrAlliance(session.allianceid) 1840 if not valid: 1841 return 1842 name = cfg.eveowners.Get(session.allianceid).ownerName 1843 if self.TotalNumberOfGroups() >= const.mailMaxGroups: 1844 self.GetMaxGroupText(name) 1845 return 1846 self.toCorpAlliance[name] = session.allianceid 1847 ret = utillib.KeyVal(name=name, group=GROUP_CORP, id=listReceiver) 1848 return ret 1849 nme, id = self.GetReceiver(name) 1850 if nme and id: 1851 if len(self.toChars) >= const.mailMaxRecipients: 1852 prompt_player_fsd_dialog('EvemailMaxRecipients', {'max': const.mailMaxRecipients, 1853 'name': nme}) 1854 return 1855 self.toChars[nme] = id 1856 sm.ScatterEvent('OnSearcedUserAdded', id, self.configname) 1857 ret = utillib.KeyVal(name=nme, group=GROUP_CHAR, id=id) 1858 return ret 1859 1860 def GetMailinglistReceiver(self, name): 1861 lists = sm.GetService('mailinglists').GetMyMailingLists() 1862 for key, value in lists.iteritems(): 1863 if name == value.displayName: 1864 if prompt_player_fsd_dialog('CustomQuestion', {'header': localization.GetByLabel('UI/Mail/SendToMailingListQ'), 1865 'question': localization.GetByLabel('UI/Mail/SendToMailingListQ2', listName=name)}, uiconst.YESNO) == uiconst.ID_YES: 1866 return key 1867 1868 def GetReceiver(self, string): 1869 if string in self.toChars: 1870 id = self.toChars[string] 1871 if id: 1872 return (string, id) 1873 ownerID = searchOld.Search(string, const.groupCharacter, hideNPC=1, exact=MatchBy.exact_phrase, searchWndName='newMessageReceiverSearch', getError=1) 1874 if ownerID: 1875 if type(ownerID) in [types.StringType, types.UnicodeType]: 1876 mailSettings = sm.GetService('mailSvc').GetMailSettings() 1877 if mailSettings.GetSingleValue(cSettings.MAIL_GET_SEARCH_WND, True): 1878 self.GetSearchWnd(input=string) 1879 else: 1880 prompt_player_fsd_dialog('EveMailNoCharFound', {'name': string}) 1881 return (string, None) 1882 return (cfg.eveowners.Get(ownerID).name, ownerID) 1883 return (string, None) 1884 1885 def GetAllOptions(self): 1886 buddies = self.buddies 1887 mailingLists = sm.GetService('mailinglists').GetMyMailingLists() 1888 myCorpAndAllicane = [session.corpid] 1889 if session.allianceid: 1890 myCorpAndAllicane.append(session.allianceid) 1891 ret = utillib.KeyVal() 1892 ret.buddies = buddies 1893 ret.mailingLists = mailingLists 1894 ret.corpAll = myCorpAndAllicane 1895 return ret 1896 1897 def OnReceiverHistoryClick(self, rest, string, info, *args): 1898 if info: 1899 string = string.strip() 1900 group, id = info 1901 canAdd = False 1902 if group == GROUP_CHAR: 1903 canAdd = self.AddCharacterReceiver(id, partly=1) 1904 elif group == GROUP_LIST: 1905 canAdd = self.AddList(id, string, partly=1) 1906 if canAdd: 1907 string = localization.GetByLabel('UI/Mail/MailEntry', entryName=string, entryType=localization.GetByLabel('UI/Mail/ML')) 1908 elif group == GROUP_CORP: 1909 canAdd = self.AddCorpAllianceReciver(id, partly=1) 1910 if canAdd: 1911 if rest: 1912 rest += ' ' 1913 self.sr.receiver.SetValue(rest + string) 1914 else: 1915 self.sr.receiver.SetValue(rest) 1916 1917 def OnDropReceiver(self, dragObj, nodes): 1918 for node in nodes: 1919 charID = GetCharIDFromTextLink(node) 1920 if charID and idCheckers.IsCharacter(charID): 1921 self.AddCharacterReceiver(charID) 1922 elif node.__guid__ in AllUserEntries(): 1923 self.AddCharacterReceiver(node.charID) 1924 elif node.__guid__ == 'listentry.CorpAllianceEntry': 1925 itemID = getattr(node, 'itemID', None) 1926 if itemID is None: 1927 mailingListID = GetAttrs(node, 'sr', 'node', 'mailingListID') 1928 if mailingListID is not None: 1929 self.AddList(mailingListID, node.Get('name', '')) 1930 else: 1931 self.AddCorpAllianceReciver(node.itemID) 1932 1933 def TotalNumberOfGroups(self): 1934 return len(self.toCorpAlliance) + int(self.toListID is not None) 1935 1936 def GetMaxGroupText(self, name, corpNamesUsed = None, listNamesUsed = None): 1937 if corpNamesUsed is None: 1938 corpNamesUsed = self.toCorpAlliance 1939 if listNamesUsed is None and self.toListID is not None: 1940 listNamesUsed = sm.GetService('mailinglists').GetMyMailingLists()[self.toListID] 1941 groupName = localization.GetByLabel('UI/Common/Unknown') 1942 groups = corpNamesUsed.keys() 1943 if listNamesUsed is not None: 1944 groups.append(listNamesUsed.displayName) 1945 if len(groups) >= const.mailMaxGroups: 1946 groupName = groups[0] 1947 return prompt_player_fsd_dialog('EvemailMaxListOrCorp', {'name': name, 1948 'groupName': groupName}) 1949 1950 def OnDropData(self, dragObj, nodes): 1951 pass 1952 1953 def ValidateReceiver(self, char, *args): 1954 text = unichr(char) 1955 if text != ',' and self.sr.receiver.GetValue().strip() != '': 1956 return None 1957 if not self or self.destroyed: 1958 return None 1959 uthread.new(self.ValidateReceivers) 1960 1961 def ValidateReceivers(self, *args): 1962 if not self or self.destroyed or getattr(self, 'parsingReceivers', 0): 1963 return 1964 self.parsingReceivers = 1 1965 inp = self.sr.receiver.GetValue() 1966 all = inp.split(',') 1967 charNamesUsed = {} 1968 corpNamesUsed = {} 1969 listNamesUsed = {} 1970 allReceivers = self.toChars.keys() + self.toCorpAlliance.keys() 1971 myLists = sm.GetService('mailinglists').GetMyMailingLists() 1972 myListsNames = [ each.displayName.lower() for each in myLists.itervalues() ] 1973 if self.toListID in myLists: 1974 allReceivers.append(myLists[self.toListID].displayName) 1975 finalString = '' 1976 for name in all: 1977 name = name.strip() 1978 if not name: 1979 continue 1980 cleanNameAndGroup = self.GetCleanNameAndGroup(name) 1981 cleanName = cleanNameAndGroup.name 1982 group = cleanNameAndGroup.group 1983 if cleanName not in allReceivers: 1984 add = self.AddUnknownToValidate(cleanName, listNamesUsed, corpNamesUsed, charNamesUsed) 1985 if add is None: 1986 prompt_player_fsd_dialog('EvemailCantFindRecipient', {'name': cleanName}) 1987 continue 1988 else: 1989 group = add.group 1990 cleanName = add.name 1991 elif group == GROUP_LIST: 1992 if cleanName.lower() in myListsNames: 1993 if cleanName not in listNamesUsed: 1994 listNamesUsed[cleanName] = True 1995 else: 1996 continue 1997 elif cleanName in self.toChars and cleanName not in charNamesUsed: 1998 charNamesUsed[cleanName] = True 1999 elif cleanName in self.toCorpAlliance and cleanName not in corpNamesUsed: 2000 corpNamesUsed[cleanName] = True 2001 else: 2002 add = self.AddUnknownToValidate(cleanName, listNamesUsed, corpNamesUsed, charNamesUsed) 2003 if add is None: 2004 continue 2005 else: 2006 group = add.group 2007 cleanName = add.name 2008 nameToAdd = cleanName 2009 if group == GROUP_LIST: 2010 nameToAdd = localization.GetByLabel('UI/Mail/MailEntry', entryName=nameToAdd, entryType=localization.GetByLabel('UI/Mail/ML')) 2011 finalString += '%s, ' % nameToAdd 2012 2013 if not self or self.destroyed: 2014 self.parsingReceivers = 0 2015 return 2016 self.sr.receiver.SetValue(finalString) 2017 toChars = self.toChars.copy() 2018 toCorpAlliance = self.toCorpAlliance.copy() 2019 charsPopped = [] 2020 for each in toChars: 2021 if each not in charNamesUsed: 2022 charsPopped.append(self.toChars.get(each, None)) 2023 self.toChars.pop(each, None) 2024 2025 sm.ScatterEvent('OnSearcedUserRemoved', charsPopped, self.configname) 2026 for each in toCorpAlliance: 2027 if each not in corpNamesUsed: 2028 self.toCorpAlliance.pop(each, None) 2029 2030 if self.toListID is not None: 2031 myLists = sm.GetService('mailinglists').GetMyMailingLists() 2032 if self.toListID not in myLists or len(listNamesUsed) < 1: 2033 self.toListID = None 2034 self.parsingReceivers = 0 2035 2036 def GetCleanNameAndGroup(self, name): 2037 name = name.strip() 2038 ret = utillib.KeyVal(name=name, group=None) 2039 strippedMaillistLabel = StripTags(localization.GetByLabel('UI/Mail/ML')) 2040 if name.endswith(strippedMaillistLabel): 2041 ret.name = name.replace(strippedMaillistLabel, '') 2042 if ret.name[-1] == ' ': 2043 ret.name = ret.name[:-1] 2044 ret.group = GROUP_LIST 2045 return ret 2046 2047 def AddUnknownToValidate(self, name, listNamesUsed, corpNamesUsed, charNamesUsed): 2048 keyVal = self.NewParseReceiver(name) 2049 if keyVal is None: 2050 return 2051 name = keyVal.name 2052 group = keyVal.group 2053 corpAndListsNum = len(corpNamesUsed) + len(listNamesUsed) 2054 ret = keyVal.copy() 2055 if group == GROUP_LIST: 2056 if corpAndListsNum >= const.mailMaxGroups: 2057 self.GetMaxGroupText(name, corpNamesUsed, listNamesUsed) 2058 elif name not in listNamesUsed: 2059 listNamesUsed[name] = True 2060 return ret 2061 elif group == GROUP_CORP: 2062 if corpAndListsNum >= const.mailMaxGroups: 2063 self.GetMaxGroupText(name, corpNamesUsed, listNamesUsed) 2064 elif name not in corpNamesUsed: 2065 corpNamesUsed[name] = True 2066 return ret 2067 elif group == GROUP_CHAR: 2068 if len(charNamesUsed) >= const.mailMaxRecipients: 2069 prompt_player_fsd_dialog('EvemailMaxRecipients', {'max': const.mailMaxRecipients, 2070 'name': name}) 2071 elif name not in charNamesUsed: 2072 charNamesUsed[name] = True 2073 return ret 2074 2075 def ClickSend(self, *args): 2076 bannedwords.check_chat_character_allowed(session.charid) 2077 self.SetSendBtnState(disable=1) 2078 self.ValidateReceivers() 2079 allReceivers = self.toChars.keys() + self.toCorpAlliance.keys() 2080 if self.toListID is not None: 2081 myLists = sm.GetService('mailinglists').GetMyMailingLists() 2082 if self.toListID in myLists: 2083 allReceivers.append(myLists[self.toListID]) 2084 if len(allReceivers) < 1: 2085 prompt_player_fsd_dialog('CustomInfo', {'info': localization.GetByLabel('UI/Mail/NoRecipientForMessage')}) 2086 self.SetSendBtnState(disable=0) 2087 return 2088 if len(allReceivers) > const.mailMaxRecipients + 1: 2089 info = localization.GetByLabel('UI/Mail/TooManyRecipients', max=const.mailMaxRecipients) 2090 prompt_player_fsd_dialog('CustomInfo', {'info': info}) 2091 self.SetSendBtnState(disable=0) 2092 return 2093 subject = self.sr.subjecField.GetValue() 2094 if subject.strip() == '': 2095 self.SetSendBtnState(disable=0) 2096 raise UserError('NoSubject') 2097 elif len(subject) > const.mailMaxSubjectSize: 2098 self.SetSendBtnState(disable=0) 2099 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/NameIsTooLong')}) 2100 body = self.messageedit.GetValue() 2101 values = self.toCorpAlliance.values() 2102 corpAlliance = None 2103 if values: 2104 corpAlliance = values[0] 2105 if not self.ValidateCorpOrAlliance(corpAlliance): 2106 self.SetSendBtnState(disable=0) 2107 raise UserError('EvemailSendingFailed') 2108 labels = self.labels 2109 try: 2110 messageID = sm.GetService('mailSvc').SendMail(toCharacterIDs=self.toChars.values(), toListID=self.toListID, toCorpOrAllianceID=corpAlliance, title=subject, body=body, isReplyTo=self.isReplyTo, isForwardedFrom=self.isForwardedFrom) 2111 except: 2112 self.SetSendBtnState(disable=0) 2113 raise 2114 2115 if messageID is None: 2116 self.SetSendBtnState(disable=0) 2117 return 2118 sum = 0 2119 for labelID in labels: 2120 sum = sum + labelID 2121 2122 sm.GetService('mailSvc').AssignLabels([messageID], sum) 2123 setattr(sm.StartService('mailSvc'), 'lastMessageTime', blue.os.GetWallclockTime()) 2124 if self and not self.destroyed: 2125 self.Close() 2126 2127 def SetSendBtnState(self, disable = 0): 2128 if disable: 2129 self.sendBtn.state = uiconst.UI_DISABLED 2130 self.sendBtn.opacity = 0.3 2131 else: 2132 self.sendBtn.state = uiconst.UI_NORMAL 2133 self.sendBtn.opacity = 1.0 2134 2135 def Label(self, *args): 2136 wnd = ManageLabelsNewMails.Open(labels=self.labels) 2137 if wnd.ShowModal() == 1: 2138 self.labels = wnd.result 2139 2140 def OpenReceiverSearch(self, *args): 2141 self.GetSearchWnd() 2142 2143 def AddReceiverFromSearch(self, func, *args): 2144 sel = apply(func) 2145 for each in sel: 2146 if not self or self.destroyed: 2147 return 2148 itemID = getattr(each, 'itemID', None) 2149 guid = getattr(each, '__guid__', None) 2150 if guid in AllUserEntries(): 2151 self.AddCharacterReceiver(itemID) 2152 elif guid == 'listentry.CorpAllianceEntry': 2153 if itemID is None: 2154 if getattr(each, 'mailingListID', None) is not None: 2155 self.AddList(each.mailingListID, getattr(each, 'name', '')) 2156 else: 2157 self.AddCorpAllianceReciver(itemID) 2158 2159 def GetSearchWnd(self, input = ''): 2160 actionBtn = [(localization.GetByLabel('UI/Mail/Add'), self.AddReceiverFromSearch, 1)] 2161 caption = localization.GetByLabel('UI/Mail/SearchForRecipients') 2162 wnd = OwnerSearchWindow.GetIfOpen() 2163 if wnd: 2164 wnd.CloseByUser() 2165 extraIconHintFlag = ['ui_73_16_13', localization.GetByLabel('UI/Mail/CharacterAdded'), False] 2166 wnd = MailSearchWindow.Open(actionBtns=actionBtn, caption=caption, input=input, showContactList=True, extraIconHintFlag=extraIconHintFlag, configname=self.configname) 2167 if wnd is not None: 2168 wnd.IsAdded = self.IsAddedToMail 2169 wnd.Maximize() 2170 searchBtn = GetAttrs(wnd, 'sr', 'searchBtn') 2171 if searchBtn is not None and input: 2172 wnd.Search() 2173 uicore.registry.SetFocus(searchBtn) 2174 2175 def IsAddedToMail(self, charID, *args): 2176 if not self or self.destroyed: 2177 return False 2178 return charID in self.toChars.values() 2179 2180 def CloseByUser(self, *args): 2181 body = self.messageedit.GetValue() 2182 if body.strip() and prompt_player_fsd_dialog('DiscardMailMessage', {}, uiconst.YESNO) != uiconst.ID_YES: 2183 return False 2184 Window.CloseByUser(self, *args) 2185 2186 2187 class ReceiverEdit(SingleLineEditText): 2188 2189 def ApplyAttributes(self, attributes): 2190 SingleLineEditText.ApplyAttributes(self, attributes) 2191 self.blockSetValue = 1 2192 2193 def RegisterHistory(self, value = None): 2194 pass 2195 2196 def ClearHistory(self, *args): 2197 pass 2198 2199 def TryDeleteFromHistory(self): 2200 pass 2201 2202 def GetValid(self): 2203 current = self.GetValue(registerHistory=0) 2204 rest = '' 2205 lastComma = current.rfind(',') 2206 if lastComma > -1: 2207 rest = current[:lastComma + 1] 2208 current = current[lastComma + 1:] 2209 current.strip() 2210 self.current = current 2211 self.rest = rest 2212 id, mine = self.GetHistory() 2213 buddies = mine.buddies 2214 lists = mine.mailingLists 2215 corpAll = mine.corpAll 2216 valid = [] 2217 sm.GetService('mailSvc').PrimeOwners(buddies) 2218 for each in buddies: 2219 name = cfg.eveowners.Get(each).ownerName 2220 if name.lower().startswith(current.lower().strip()) and name != current: 2221 valid.append((GROUP_CHAR, 2222 name, 2223 name, 2224 each)) 2225 2226 for key, value in lists.iteritems(): 2227 if value.displayName.lower().startswith(current.lower().strip()) and value.displayName != current: 2228 valid.append((GROUP_LIST, 2229 localization.GetByLabel('UI/Mail/MailEntry', entryName=value.displayName, entryType=localization.GetByLabel('UI/Mail/ML')), 2230 value.displayName, 2231 key)) 2232 2233 for each in corpAll: 2234 if idCheckers.IsNPC(each): 2235 continue 2236 if idCheckers.IsAlliance(each) and session.corprole & const.corpRoleChatManager != const.corpRoleChatManager: 2237 continue 2238 name = cfg.eveowners.Get(each).ownerName 2239 if name.lower().startswith(current.lower().strip()) and name != current: 2240 text = '' 2241 if each == session.corpid: 2242 text = localization.GetByLabel('UI/Mail/LabelCorp') 2243 elif each == session.allianceid: 2244 text = localization.GetByLabel('UI/Mail/LabelAlliance') 2245 valid.append((GROUP_CORP, 2246 localization.GetByLabel('UI/Mail/MailEntry', entryName=name, entryType=text), 2247 name, 2248 each)) 2249 2250 valid = SortListOfTuples([ (len(name), (group, 2251 displayName, 2252 name, 2253 (group, id))) for group, displayName, name, id in valid ]) 2254 return valid 2255 2256 def HEMouseDown(self, entry, *args): 2257 rest = getattr(self, 'rest', '') 2258 info = getattr(entry, 'info', None) 2259 self.OnHistoryClick(rest, entry.string, info) 2260 2261 def GetHistory(self, getAll = 0): 2262 id = 0 2263 all = self.GetAll() 2264 if getAll: 2265 return (id, all, all) 2266 return (id, all) 2267 2268 def GetAll(self, *args): 2269 return [] 2270 2271 def GetMenu(self): 2272 return BaseSingleLineEdit.GetMenu(self) 2273 2274 def PopulateHistoryMenu(self, menuParent, history): 2275 historyFormatted = [] 2276 for historyEntry in history: 2277 _, displayText, editText, info = historyEntry 2278 b = Bundle(displayText=displayText, editText=editText, info=info, historyEntry=historyEntry, removeable=False) 2279 historyFormatted.append(b) 2280 2281 menuParent.PopulateHistoryMenu(historyFormatted) 2282 2283 def Confirm(self, *args): 2284 if getattr(self, 'historyMenu', None) is None: 2285 return 2286 hm = self.historyMenu() 2287 entry = getattr(self, 'active', None) 2288 if entry: 2289 rest = getattr(self, 'rest', '') 2290 self.OnHistoryClick(rest, entry.string, entry.info) 2291 self.CloseHistoryMenu() 2292 return False 2293 2294 2295 class MailReadingWnd(Window): 2296 __guid__ = 'form.MailReadingWnd' 2297 __notifyevents__ = ['OnMessageChanged'] 2298 default_mail = None 2299 default_msgID = None 2300 default_txt = '' 2301 default_toolbar = True 2302 default_trashed = False 2303 default_type = None 2304 default_windowID = 'mailReadingWnd' 2305 2306 def ApplyAttributes(self, attributes): 2307 Window.ApplyAttributes(self, attributes) 2308 mail = attributes.mail 2309 msgID = attributes.msgID 2310 txt = attributes.get('txt', self.default_txt) 2311 toolbar = attributes.get('toolbar', self.default_toolbar) 2312 trashed = attributes.get('trashed', self.default_trashed) 2313 type = attributes.type 2314 self.messageedit = None 2315 self.scope = uiconst.SCOPE_INGAME 2316 sm.RegisterNotify(self) 2317 self.SetMinSize([250, 250]) 2318 self.SetCaption(localization.GetByLabel('UI/Mail/Message')) 2319 main = self.content 2320 self.mail = mail 2321 self.type = type 2322 self.messageID = msgID 2323 actions = utillib.KeyVal() 2324 actions.replyClicked = self.ReplyClicked 2325 actions.replyAllClicked = self.ReplyAllClicked 2326 actions.forwardClicked = self.ForwardClicked 2327 actions.trashClicked = self.TrashClicked 2328 actions.deleteClicked = self.DeleteClicked 2329 if toolbar: 2330 self.mailActions = MailActionPanel(name='mailActionCont', parent=main, align=uiconst.TOTOP, pos=(0, 2331 0, 2332 250, 2333 Button.default_height), padding=(0, 8, 0, 8)) 2334 self.mailActions.Startup(actions, showCompose=0) 2335 self.mailActions.SetDeleteVisibility(disabled=0, showDelete=trashed) 2336 if mail.statusMask & const.mailStatusMaskAutomated == const.mailStatusMaskAutomated: 2337 self.mailActions.SingleMsgBtnStateAllowFwd() 2338 else: 2339 self.mailActions.SingleMsgBtnsState(disabled=0) 2340 self.sr.rightCont = Container(name='rightCont', parent=main, align=uiconst.TOALL, pos=(const.defaultPadding, 2341 const.defaultPadding, 2342 const.defaultPadding, 2343 const.defaultPadding)) 2344 self.sr.readingPane = EditPlainText(setvalue=txt, parent=self.sr.rightCont, align=uiconst.TOALL, readonly=1) 2345 2346 def SetText(self, text): 2347 self.sr.readingPane.SetValue(text) 2348 2349 def _OnClose(self, *args): 2350 sm.UnregisterNotify(self) 2351 Window._OnClose(self, *args) 2352 2353 def ReplyClicked(self, *args): 2354 sm.GetService('mailSvc').GetReplyWnd(self.mail, all=0) 2355 2356 def ReplyAllClicked(self, *args): 2357 sm.GetService('mailSvc').GetReplyWnd(self.mail, all=1) 2358 2359 def ForwardClicked(self, *args): 2360 sm.GetService('mailSvc').GetForwardWnd(self.mail) 2361 2362 def TrashClicked(self, *arsg): 2363 if self.type == const.mailTypeMail: 2364 mailCopy = self.mail.copy() 2365 sm.GetService('mailSvc').MoveMessagesToTrash([self.mail.messageID]) 2366 self.mailActions.SetDeleteVisibility(disabled=0, showDelete=1) 2367 sm.ScatterEvent('OnMailTrashedDeleted', mailCopy) 2368 2369 def DeleteClicked(self, *args): 2370 if self.type == const.mailTypeMail: 2371 mailCopy = self.mail.copy() 2372 sm.GetService('mailSvc').DeleteMails([self.mail.messageID]) 2373 sm.ScatterEvent('OnMailTrashedDeleted', mailCopy) 2374 self.CloseByUser() 2375 2376 def OnMessageChanged(self, type, messageIDs, what): 2377 if type == self.type and self.messageID in messageIDs: 2378 if type == const.mailTypeMail: 2379 if what == 'trashed': 2380 self.mailActions.SetDeleteVisibility(disabled=0, showDelete=1) 2381 elif what == 'deleted': 2382 self.CloseByUser() 2383 elif type == const.mailTypeNotifications: 2384 if what == 'deleted': 2385 self.CloseByUser() 2386 2387 2388 class MailActionPanel(Container): 2389 __guid__ = 'xtriui.MailActionPanel' 2390 2391 def ApplyAttributes(self, attributes): 2392 Container.ApplyAttributes(self, attributes) 2393 self.sr.data = None 2394 self.topOffset = top = 0 2395 self.size = size = 32 2396 self.leftOffset = left = 0 2397 self.space = 35 2398 self.extraSpace = 15 2399 self.sr.composeBtn = Button(parent=self, align=uiconst.TOPLEFT, top=top, left=left, texturePath='res:/ui/Texture/WindowIcons/evemailcompose.png', iconSize=size, hint=localization.GetByLabel('UI/Mail/Compose')) 2400 left += self.space + self.extraSpace 2401 self.sr.replyBtn = Button(parent=self, align=uiconst.TOPLEFT, top=top, left=left, texturePath='res:/ui/Texture/Icons/94_64_2.png', iconSize=size, hint=localization.GetByLabel('UI/Mail/Reply')) 2402 left += self.space 2403 self.sr.replyAllBtn = Button(parent=self, align=uiconst.TOPLEFT, top=top, left=left, texturePath='res:/ui/Texture/Icons/94_64_3.png', iconSize=size, hint=localization.GetByLabel('UI/Mail/ReplyAll')) 2404 left += self.space 2405 self.sr.forwardBtn = Button(parent=self, align=uiconst.TOPLEFT, top=top, left=left, texturePath='res:/ui/Texture/Icons/94_64_4.png', iconSize=size, hint=localization.GetByLabel('UI/Mail/Forward')) 2406 left += self.space + self.extraSpace 2407 self.sr.trashBtn = Button(parent=self, align=uiconst.TOPLEFT, top=top, left=left, texturePath='res:/ui/Texture/Icons/94_64_5.png', iconSize=size, hint=localization.GetByLabel('UI/Mail/Trash')) 2408 self.sr.deleteBtn = Button(parent=self, align=uiconst.TOPLEFT, top=top, left=left, texturePath='res:/ui/Texture/WindowIcons/terminate.png', iconSize=size, hint=localization.GetByLabel('UI/Mail/Delete')) 2409 left += self.space + self.extraSpace 2410 self.sr.singleMsgBtn = [self.sr.replyBtn, self.sr.replyAllBtn, self.sr.forwardBtn] 2411 self.width = left 2412 2413 def Startup(self, data, showCompose = 1): 2414 self.sr.data = data 2415 self.sr.composeBtn.func = data.Get('composeClicked', self.ComposeClicked) 2416 self.sr.replyBtn.func = data.Get('replyClicked', self.ReplyClicked) 2417 self.sr.replyAllBtn.func = data.Get('replyAllClicked', self.ReplyAllClicked) 2418 self.sr.forwardBtn.func = data.Get('forwardClicked', self.ForwardClicked) 2419 self.sr.trashBtn.func = data.Get('trashClicked', self.TrashClicked) 2420 self.sr.deleteBtn.func = data.Get('deleteClicked', self.DeleteClicked) 2421 if not showCompose: 2422 self.sr.composeBtn.state = uiconst.UI_HIDDEN 2423 self.left -= self.space + self.leftOffset + self.extraSpace 2424 2425 def DisableWhenManySelected(self, *args): 2426 pass 2427 2428 def DisableDelete(self, *args): 2429 pass 2430 2431 def ComposeClicked(self, *args): 2432 pass 2433 2434 def ReplyClicked(self, *args): 2435 pass 2436 2437 def ReplyAllClicked(self, *args): 2438 pass 2439 2440 def ForwardClicked(self, *args): 2441 pass 2442 2443 def TrashClicked(self, *args): 2444 pass 2445 2446 def DeleteClicked(self, *args): 2447 pass 2448 2449 def SetDeleteVisibility(self, disabled = 0, showDelete = 0): 2450 if showDelete: 2451 hiddenParent = self.sr.trashBtn 2452 visibleBtn = self.sr.deleteBtn 2453 else: 2454 hiddenParent = self.sr.deleteBtn 2455 visibleBtn = self.sr.trashBtn 2456 if hiddenParent is not None: 2457 self.SetDeleteState(disabled, hiddenParent, visibleBtn) 2458 2459 def SetDeleteState(self, disabled, hiddenParent, visibleBtn): 2460 btnState = [uiconst.UI_NORMAL, uiconst.UI_DISABLED][disabled] 2461 opacity = [1.0, 0.3][disabled] 2462 parentState = [uiconst.UI_PICKCHILDREN, uiconst.UI_NORMAL][disabled] 2463 hiddenParent.state = uiconst.UI_HIDDEN 2464 visibleBtn.state = btnState 2465 visibleBtn.opacity = opacity 2466 visibleBtn.parent.state = parentState 2467 2468 def SingleMsgBtnsState(self, disabled = 0, btns = None): 2469 if disabled: 2470 state = uiconst.UI_DISABLED 2471 alpha = 0.3 2472 parentState = uiconst.UI_NORMAL 2473 else: 2474 state = uiconst.UI_NORMAL 2475 alpha = 1.0 2476 parentState = uiconst.UI_PICKCHILDREN 2477 if btns is None: 2478 btns = self.sr.singleMsgBtn 2479 for btn in btns: 2480 if btn.parent is None: 2481 return 2482 btn.state = state 2483 btn.opacity = alpha 2484 btn.parent.state = parentState 2485 2486 def SingleMsgBtnStateAllowFwd(self, *args): 2487 btns = self.sr.singleMsgBtn[:] 2488 btns.remove(self.sr.forwardBtn) 2489 self.SingleMsgBtnsState(disabled=1, btns=btns) 2490 self.SingleMsgBtnsState(disabled=0, btns=[self.sr.forwardBtn]) 2491 2492 def AddExtraButton(self, btn, withSpace = 1, size = None, hint = ''): 2493 left = self.width 2494 if withSpace: 2495 left += self.extraSpace 2496 if size is None: 2497 size = self.size 2498 cont = Container(name='cont', parent=self, align=uiconst.TOPLEFT, pos=(left, 2499 self.topOffset, 2500 size, 2501 size), hint=hint) 2502 cont.children.append(btn) 2503 self.width = left + self.space 2504 2505 2506 class MailSettings(Window): 2507 __guid__ = 'form.MailSettings' 2508 default_windowID = 'mailSettings' 2509 CHECKBOX_ACTIVE_ICON = 'res:/UI/Texture/classes/UtilMenu/checkBoxActive.png' 2510 CHECKBOX_INACTIVE_ICON = 'res:/UI/Texture/classes/UtilMenu/checkBoxInactive.png' 2511 default_iconNum = MailWindow.default_iconNum 2512 default_captionLabelPath = 'UI/Mail/CommunicationSettings' 2513 default_fixedWidth = 380 2514 2515 def ApplyAttributes(self, attributes): 2516 Window.ApplyAttributes(self, attributes) 2517 self.mailSettingObjectCopy = copy.deepcopy(sm.GetService('mailSvc').GetMailSettings()) 2518 self.mainCont = ContainerAutoSize(parent=self.content, align=uiconst.TOTOP, alignMode=uiconst.TOTOP, padding=const.defaultPadding, callback=self.OnMainSizeChanged) 2519 cost = sm.GetService('account').GetDefaultContactCost() 2520 uix.GetContainerHeader(localization.GetByLabel('UI/Mail/IncomingCommunications'), self.mainCont, bothlines=0) 2521 self.sr.accessCb1 = RadioButton(text=localization.GetByLabel('UI/Mail/RequireCSPNFromUnknown'), parent=self.mainCont, settingsKey='accessCb1', retval=0, checked=cost != -1, groupname='communications', callback=self.OnCheckboxChange, padding=(6, 6, 6, 0), align=uiconst.TOTOP, hint=localization.GetByLabel('UI/Mail/CSPAHint')) 2522 self.sr.accessCb2 = RadioButton(text=localization.GetByLabel('UI/Mail/BlockUnknown'), parent=self.mainCont, settingsKey='accessCb1', retval=1, checked=cost == -1, groupname='communications', callback=self.OnCheckboxChange, padding=(6, 0, 6, 6), align=uiconst.TOTOP, hint=localization.GetByLabel('UI/Mail/CSPAHint2')) 2523 self.sr.chargeCont = Container(name='chargeCont', parent=self.mainCont, align=uiconst.TOTOP, pos=(0, 0, 0, 20), padding=(0, 0, 0, 6)) 2524 if cost == -1: 2525 self.sr.chargeCont.state = uiconst.UI_HIDDEN 2526 cost = 0 2527 self.sr.chargeEdit = SingleLineEditInteger(name='chargeField', parent=self.sr.chargeCont, setvalue=cost, maxLength=32, pos=(150, 0, 60, 0), label='', align=uiconst.TOPLEFT, maxValue=1000000) 2528 eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Mail/CSPACharge'), parent=self.sr.chargeCont, align=uiconst.CENTERLEFT, width=150, left=8) 2529 uix.GetContainerHeader(localization.GetByLabel('UI/Mail/MailSettings'), self.mainCont) 2530 perPageCont = Container(name='perPageCont', parent=self.mainCont, align=uiconst.TOTOP, pos=(0, 0, 0, 20), padding=(0, 0, 0, 6)) 2531 perPageNumer = self.mailSettingObjectCopy.GetSingleValue(cSettings.MAILS_PER_PAGE, DEFAULTNUMMAILS) 2532 self.sr.perPageEdit = SingleLineEditInteger(name='perPageEdit', parent=perPageCont, setvalue=perPageNumer, maxLength=32, pos=(150, 4, 60, 0), label='', align=uiconst.TOPLEFT, minValue=MINNUMMAILS, maxValue=MAXNUMMAILS) 2533 eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Mail/MailsPerPage'), parent=perPageCont, align=uiconst.CENTERLEFT, width=150, left=8) 2534 getSearchWnd = self.mailSettingObjectCopy.GetSingleValue(cSettings.MAIL_GET_SEARCH_WND, True) 2535 self.sr.getSearchWnd = Checkbox(text=localization.GetByLabel('UI/Mail/ShowSearch'), parent=self.mainCont, settingsKey='getSearchWnd', checked=getSearchWnd, align=uiconst.TOTOP, padding=(6, 0, 0, 0)) 2536 eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Mail/WhenReceived'), parent=self.mainCont, align=uiconst.TOTOP, padding=(8, 10, 8, 0), state=uiconst.UI_DISABLED) 2537 isNeocomBlinkOnForMail = self.mailSettingObjectCopy.GetSingleValue(cSettings.MAIL_BLINK_NEOCOM, True) 2538 isTabBlinkOnForMail = self.mailSettingObjectCopy.GetSingleValue(cSettings.MAIL_BLINK_TAB, True) 2539 isPopupOnForMail = self.mailSettingObjectCopy.GetSingleValue(cSettings.MAIL_SHOW_POPUP, True) 2540 self.sr.mailBlinkNeocomCB = Checkbox(text=localization.GetByLabel('UI/Mail/BlinkMailNeoComButton'), parent=self.mainCont, settingsKey='mailBlinkNeocomCB', checked=bool(isNeocomBlinkOnForMail), align=uiconst.TOTOP, padding=(16, 0, 0, 0)) 2541 self.sr.mailBlinkTabCB = Checkbox(text=localization.GetByLabel('UI/Mail/BlinkTab'), parent=self.mainCont, settingsKey='mailBlinkTabCB', checked=bool(isTabBlinkOnForMail), align=uiconst.TOTOP, padding=(16, 0, 0, 0)) 2542 self.sr.mailNotificationCB = Checkbox(text=localization.GetByLabel('UI/Mail/ShowNotification'), parent=self.mainCont, settingsKey='mailNotificationCB', checked=bool(isPopupOnForMail), align=uiconst.TOTOP, padding=(16, 0, 0, 0)) 2543 self.GetWindowSizeForContentSize() 2544 self.settingCb = {} 2545 self.sr.standardBtns = ButtonGroup(parent=self.mainCont, align=uiconst.TOTOP, padTop=16, btns=((localization.GetByLabel('UI/Mail/Apply'), 2546 self.OnApply, 2547 (), 2548 81), (localization.GetByLabel('UI/Commands/Cancel'), 2549 self.CloseByUser, 2550 (), 2551 81))) 2552 self.mainCont.SetSizeAutomatically() 2553 2554 def OnMainSizeChanged(self, *args, **kwds): 2555 if self.mainCont: 2556 _, height = self.GetWindowSizeForContentSize(height=self.mainCont.height) 2557 self.SetFixedHeight(height) 2558 2559 def OpenMenuFunc(self, menuParent, settingKey, *args): 2560 disabledGroups = self.mailSettingObjectCopy.GetListForSettingKey(settingKey) 2561 headerChecked = not bool(disabledGroups) 2562 if headerChecked: 2563 icon = self.CHECKBOX_ACTIVE_ICON 2564 else: 2565 icon = self.CHECKBOX_INACTIVE_ICON 2566 menuParent.AddHeader(text=localization.GetByLabel('UI/Common/All'), callback=(self.ToggleAll, settingKey), icon=icon) 2567 menuParent.AddSpace() 2568 checkboxes = [] 2569 for groupID, labelPath in notificationGroupNamePaths.iteritems(): 2570 checked = groupID not in disabledGroups 2571 groupName = localization.GetByLabel(labelPath) 2572 checkboxes.append((groupName, groupID, checked)) 2573 2574 checkboxes.sort() 2575 for groupName, groupID, checked in checkboxes: 2576 menuParent.AddCheckBox(text=groupName, checked=checked, callback=(self.ToggleGroup, groupID, settingKey), indentation=10) 2577 2578 menuParent.AddSpace() 2579 self.RefreshIcon(settingKey) 2580 2581 def RefreshIcon(self, settingKey): 2582 iconOwner = self.settingCb.get(settingKey) 2583 if not iconOwner: 2584 return 2585 numGroups = len(notificationGroupNamePaths) 2586 disabledGroups = self.mailSettingObjectCopy.GetListForSettingKey(settingKey) 2587 if not disabledGroups: 2588 path = 'res:/UI/Texture/Shared/checkboxChecked.png' 2589 elif len(disabledGroups) < numGroups: 2590 path = 'res:/UI/Texture/Shared/checkboxMinus.png' 2591 else: 2592 iconOwner.iconCheckmark.display = False 2593 return 2594 iconOwner.iconCheckmark.SetTexturePath(path) 2595 iconOwner.iconCheckmark.display = True 2596 2597 def ToggleAll(self, settingKey): 2598 disabledGroups = self.mailSettingObjectCopy.GetListForSettingKey(settingKey) 2599 if disabledGroups: 2600 newGroupList = [] 2601 else: 2602 newGroupList = [ groupID for groupID in notificationGroupNamePaths.iterkeys() ] 2603 self.mailSettingObjectCopy.UpdateSettingListWithNewValues(settingKey, newGroupList) 2604 2605 def ToggleGroup(self, groupID, settingKey): 2606 if groupID in self.mailSettingObjectCopy.GetListForSettingKey(settingKey): 2607 self.mailSettingObjectCopy.RemoveValueFromListSetting(settingKey, groupID) 2608 else: 2609 self.mailSettingObjectCopy.AddValueToListSetting(settingKey, groupID) 2610 2611 def OnCheckboxChange(self, radioButton): 2612 config = radioButton.GetSettingsKey() 2613 if config == None: 2614 return 2615 value = radioButton.GetReturnValue() 2616 if value is None: 2617 return 2618 if value == 1: 2619 self.sr.chargeCont.state = uiconst.UI_HIDDEN 2620 else: 2621 self.sr.chargeCont.state = uiconst.UI_PICKCHILDREN 2622 settings.char.ui.Set('mail_accessCombo', value) 2623 2624 def OnApply(self, *args): 2625 oldCost = sm.GetService('account').GetDefaultContactCost() 2626 if self.sr.accessCb1.checked: 2627 cost = self.sr.chargeEdit.GetValue() 2628 if cost != oldCost: 2629 sm.GetService('account').SetDefaultContactCost(self.sr.chargeEdit.GetValue()) 2630 elif oldCost != -1: 2631 sm.GetService('account').BlockAll() 2632 mailBlinkNeocom = self.sr.mailBlinkNeocomCB.GetValue() 2633 mailBlinkTab = self.sr.mailBlinkTabCB.GetValue() 2634 mailNotification = self.sr.mailNotificationCB.GetValue() 2635 getSearchWnd = self.sr.getSearchWnd.GetValue() 2636 self.mailSettingObjectCopy.SetSingleValue(cSettings.MAIL_BLINK_NEOCOM, mailBlinkNeocom) 2637 self.mailSettingObjectCopy.SetSingleValue(cSettings.MAIL_BLINK_TAB, mailBlinkTab) 2638 self.mailSettingObjectCopy.SetSingleValue(cSettings.MAIL_SHOW_POPUP, mailNotification) 2639 self.mailSettingObjectCopy.SetSingleValue(cSettings.MAIL_GET_SEARCH_WND, getSearchWnd) 2640 perPage = self.sr.perPageEdit.GetValue() 2641 oldPerPage = self.mailSettingObjectCopy.GetSingleValue(cSettings.MAILS_PER_PAGE, DEFAULTNUMMAILS) 2642 self.mailSettingObjectCopy.SetSingleValue(cSettings.MAILS_PER_PAGE, perPage) 2643 sm.GetService('mailSvc').SaveMailSettingsOnServer(self.mailSettingObjectCopy) 2644 if perPage != oldPerPage: 2645 sm.ScatterEvent('OnMailSettingsChanged') 2646 self.CloseByUser() 2647 2648 2649 class MailinglistWnd(Window): 2650 __guid__ = 'form.MailinglistWnd' 2651 default_windowID = 'MailinglistWnd' 2652 default_iconNum = MailWindow.default_iconNum 2653 default_captionLabelPath = 'UI/Mail/CreateOrJoinML' 2654 default_minSize = (300, 164) 2655 2656 def ApplyAttributes(self, attributes): 2657 Window.ApplyAttributes(self, attributes) 2658 self.MakeUnResizeable() 2659 buttons = ButtonGroup(parent=ContainerAutoSize(parent=self.GetMainArea(), align=uiconst.TOBOTTOM, padTop=16)) 2660 buttons.AddButton(label=localization.GetByLabel('UI/Mail/Join'), func=self.JoinMaillist, args=(0,), isDefault=True) 2661 buttons.AddButton(label=localization.GetByLabel('UI/Mail/Create'), func=self.CreateMaillist, args=(1,)) 2662 self.sr.inpt = SingleLineEditText(name='input', parent=Container(parent=self.GetMainArea(), align=uiconst.TOALL), align=uiconst.TOBOTTOM, maxLength=const.mailingListMaxNameSize, label=localization.GetByLabel('UI/Mail/MailingListName')) 2663 2664 def CreateMaillist(self, *args): 2665 name = self.sr.inpt.GetValue() 2666 if name.strip() == '': 2667 prompt_player_fsd_dialog('LookupStringMinimum', {'minimum': 1}) 2668 return 2669 if len(name) > const.mailingListMaxNameSize: 2670 raise UserError('CustomNotify', {'notify': localization.GetByLabel('UI/Mail/NameIsTooLong')}) 2671 ret = sm.GetService('mailinglists').CreateMailingList(name) 2672 if ret is not None: 2673 self.CloseByUser() 2674 2675 def JoinMaillist(self, *args): 2676 name = self.sr.inpt.GetValue() 2677 if name.strip() == '': 2678 prompt_player_fsd_dialog('LookupStringMinimum', {'minimum': 1}) 2679 return 2680 ret = sm.GetService('mailinglists').JoinMailingList(name) 2681 if ret is not None: 2682 self.CloseByUser() 2683 2684 2685 class MailSearchWindow(OwnerSearchWindow): 2686 __guid__ = 'form.MailSearchWindow' 2687 default_windowID = 'searchWindow_mail' 2688 default_ownerGroups = [const.groupCharacter] 2689 2690 def GetExtraSearchEntries(self, searchTerm, searchBy): 2691 extraEntries = [] 2692 myLists = sm.GetService('mailinglists').GetMyMailingLists() 2693 for key, value in myLists.iteritems(): 2694 if searchUtil.IsMatch(searchTerm, value.displayName, searchBy): 2695 entry = self.GetCorpAllianceMailingListEntry(None, 1, key, value.displayName) 2696 extraEntries.append((value.displayName.lower(), entry)) 2697 2698 extraEntries = SortListOfTuples(extraEntries) 2699 if session.allianceid and session.corprole & const.corpRoleChatManager == const.corpRoleChatManager: 2700 allianceName = cfg.eveowners.Get(session.allianceid).ownerName 2701 if searchUtil.IsMatch(searchTerm, allianceName, searchBy): 2702 entry = self.GetCorpAllianceMailingListEntry(const.typeAlliance, 0, session.allianceid, allianceName) 2703 extraEntries.insert(0, entry) 2704 if not idCheckers.IsNPC(session.corpid): 2705 corpName = cfg.eveowners.Get(session.corpid).ownerName 2706 if searchUtil.IsMatch(searchTerm, corpName, searchBy): 2707 entry = self.GetCorpAllianceMailingListEntry(const.typeCorporation, 0, session.corpid, corpName) 2708 extraEntries.insert(0, entry) 2709 return extraEntries 2710 2711 def GetCorpAllianceMailingListEntry(self, type, mailingList, id, name): 2712 data = utillib.KeyVal() 2713 data.confirmOnDblClick = 1 2714 if type is None: 2715 if mailingList: 2716 data.label = localization.GetByLabel('UI/Mail/MailEntry', entryName=name, entryType=localization.GetByLabel('UI/Mail/ML')) 2717 data.itemID = None 2718 data.typeID = None 2719 data.mailingListID = id 2720 data.name = name 2721 else: 2722 return 2723 else: 2724 if type == const.typeCorporation: 2725 data.label = localization.GetByLabel('UI/Mail/MailEntry', entryName=name, entryType=localization.GetByLabel('UI/Mail/LabelCorp')) 2726 elif type == const.typeAlliance: 2727 data.label = localization.GetByLabel('UI/Mail/MailEntry', entryName=name, entryType=localization.GetByLabel('UI/Mail/LabelAlliance')) 2728 data.itemID = id 2729 data.typeID = type 2730 data.name = name 2731 data.OnClick = self.ClickEntry 2732 data.OnDblClick = self.DblClickEntry 2733 entry = GetFromClass(CorpAllianceEntry, data) 2734 return entry 2735 2736 2737 class MailAssignColorWnd(Container): 2738 __guid__ = 'xtriui.MailAssignColorWnd' 2739 2740 def Startup(self, labelID, doneCallback = None, doneArgs = (), *args): 2741 self.mouseCookie = None 2742 container = Container(name='headercontainer', parent=self, align=uiconst.TOTOP, pos=(0, 0, 0, 18), idx=0) 2743 t = eveLabel.EveHeaderSmall(text=localization.GetByLabel('UI/Mail/Select Color'), parent=container, left=8, align=uiconst.TOALL, top=5, state=uiconst.UI_DISABLED) 2744 Line(parent=container, align=uiconst.TOBOTTOM, top=-1) 2745 colorCont = Container(name='colorCont', parent=self, align=uiconst.TOALL, padding=(const.defaultPadding, 2746 const.defaultPadding, 2747 const.defaultPadding, 2748 const.defaultPadding)) 2749 self.sr.underlay = WindowUnderlay(parent=self) 2750 self.sr.underlay.padding = (0, -18, 0, -2) 2751 self.labelID = labelID 2752 colorSwatch = ColorSwatch(name='colorSwatch', parent=colorCont, align=uiconst.TOALL, pos=(0, 0, 0, 0)) 2753 colorSwatch.OnPickColor = self.PickCol 2754 colorSwatch.swatches = sm.StartService('mailSvc').GetSwatchColors().values() 2755 colorSwatch.Startup(frameColor=(0.0, 0.0, 0.0, 0.0), padding=1) 2756 self.top = uicore.uilib.y - 35 2757 self.left = uicore.uilib.x - 20 2758 self.doneCallback = doneCallback 2759 self.doneArgs = doneArgs 2760 self.mouseCookie = uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEUP, self.OnGlobalMouseUp) 2761 2762 def PickCol(self, obj, *args): 2763 if getattr(obj, 'swatchID', None) is not None: 2764 if self.doneCallback is not None: 2765 args = tuple([obj.swatchID]) + self.doneArgs 2766 self.doneCallback(*args) 2767 self.Close() 2768 2769 def OnGlobalMouseUp(self, obj, msgID, param): 2770 if uicore.uilib.mouseOver == self or obj.IsUnder(self): 2771 return 1 2772 self.Close() 2773 return 1 2774 2775 def Close(self): 2776 if getattr(self, 'mouseCookie', None): 2777 uicore.event.UnregisterForTriuiEvents(self.mouseCookie) 2778 self.mouseCookie = None 2779 Container.Close(self)