eveEditPlainText.py (22937B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\eveEditPlainText.py 2 import agency.client 3 import carbonui.const as uiconst 4 import corporation.client 5 import crimewatch.util 6 import eve.client.script.ui.shared.fittingScreen.fittingUtil as fittingUtil 7 import eveformat 8 import evelink.client 9 import evetypes 10 import evewar.client 11 import localization 12 import sharedSettings.client 13 import shipfitting.client 14 from carbon.common.script.util import commonutils 15 from carbonui.control.button import Button 16 from carbonui.control.editPlainText import EditPlainTextCore 17 from carbonui.decorative.inputUnderlay import InputUnderlay 18 from carbonui.uicore import uicore 19 from characterskills.client import format_certificate_url 20 from eve.client.script.ui.control.allUserEntries import AllUserEntries 21 from eve.client.script.ui.podGuide.link import format_pod_guide_url 22 from eve.client.script.ui.shared.bookmarks.link import format_bookmark_folder_url 23 from eve.client.script.ui.shared.killReportUtil import format_kill_report_url 24 from eve.client.script.ui.shared.neocom.contracts.link import format_contract_url 25 from eve.client.script.ui.shared.pointerTool.link import format_help_pointer_url 26 from eve.client.script.ui.util import searchOld, searchUtil, uix 27 from eve.common.lib import appConst as const 28 from eve.common.script.search.const import ResultType 29 from eve.common.script.sys import idCheckers 30 from eveagent.client import format_fleet_mission_url 31 from eveexceptions import UserError 32 from menu import MenuLabel 33 from overviewPresets.client.preset_link import overview_preset_link 34 from ownergroups.client import access_group_link 35 from player_messaging.client.ui_message import prompt_player_fsd_dialog 36 37 class EditPlainText(EditPlainTextCore): 38 __guid__ = 'uicls.EditPlainText' 39 default_align = uiconst.TOALL 40 default_left = 0 41 default_top = 0 42 default_width = 0 43 default_height = 0 44 allowPrivateDrops = 0 45 default_hasUnderlay = True 46 47 def Prepare_Underlay_(self): 48 if getattr(self, 'hasUnderlay', self.default_hasUnderlay): 49 self.sr.underlay = InputUnderlay(name='background', bgParent=self, align=uiconst.TOALL) 50 51 def OnDropDataDelegate(self, node, nodes): 52 EditPlainTextCore.OnDropDataDelegate(self, node, nodes) 53 if self.readonly: 54 return 55 uicore.registry.SetFocus(self) 56 for entry in nodes: 57 guid = getattr(entry, '__guid__', None) 58 if getattr(entry, 'get_link', None): 59 if not self.allowPrivateDrops and getattr(entry, 'is_private', False): 60 return 61 link = entry.get_link() 62 if link: 63 self.CheckLinkFits(entry) 64 self.AddLink(link.text, link.url) 65 self.CheckHintText() 66 if guid in AllUserEntries(): 67 link = evelink.character_link(entry.charID, entry.info.name) 68 self.AddLink(link.text, link.url) 69 elif guid == 'listentry.CorpAllianceEntry': 70 link = evelink.type_link(entry.typeID, entry.itemID, entry.name) 71 self.AddLink(link.text, link.url) 72 elif guid in ('listentry.InvItem', 'xtriui.InvItem', 'xtriui.ShipUIModule', 'listentry.InvAssetItem'): 73 itemID = None 74 if not isinstance(entry.rec.itemID, tuple): 75 itemID = entry.rec.itemID 76 if idCheckers.IsShipType(entry.rec.typeID): 77 link = evelink.ship_link(entry.rec.typeID, itemID, entry.rec.ownerID if entry.rec.singleton else None, entry.name) 78 else: 79 link = evelink.type_link(entry.rec.typeID, itemID, entry.name) 80 self.AddLink(link.text, link.url) 81 elif guid == 'listentry.VirtualAgentMissionEntry': 82 link = format_fleet_mission_url(entry.agentID, entry.charID) 83 self.AddLink(entry.label, link) 84 elif guid == 'listentry.CertEntry': 85 label = entry.genericDisplayLabel or entry.label 86 link = format_certificate_url(entry.certID, entry.level) 87 self.AddLink(label, link) 88 elif guid and guid.startswith('listentry.ContractEntry'): 89 url = format_contract_url(entry.solarSystemID, entry.contractID) 90 self.AddLink(entry.name.replace('>', '>'), url) 91 elif guid in ('xtriui.ListSurroundingsBtn', 'listentry.LocationTextEntry', 'listentry.LabelLocationTextTop', 'listentry.LocationGroup', 'listentry.LocationSearchItem'): 92 if not entry.typeID and not entry.itemID: 93 return 94 displayLabel = getattr(entry, 'genericDisplayLabel', None) or entry.label 95 link = evelink.type_link(entry.typeID, entry.itemID, displayLabel) 96 self.AddLink(link.text, link.url) 97 elif guid == 'listentry.FittingEntry': 98 PADDING = 12 99 link = shipfitting.client.format_fitting_url(entry.fitting) 100 roomLeft = self.RoomLeft() 101 if roomLeft is not None: 102 roomLeft = roomLeft - PADDING 103 if len(link) >= roomLeft: 104 if roomLeft < 14: 105 raise UserError('LinkTooLong') 106 if prompt_player_fsd_dialog('ConfirmTruncateLink', {'numchar': len(link), 107 'maxchar': roomLeft}, uiconst.YESNO, suppress=uiconst.ID_YES) != uiconst.ID_YES: 108 return 109 link = link[:roomLeft] 110 fittingName = eveformat.simple_html_unescape(entry.fitting.name) 111 self.AddLink(fittingName, link) 112 elif guid in ('listentry.GenericMarketItem', 'listentry.QuickbarItem', 'uicls.GenericDraggableForTypeID', 'listentry.DroneEntry', 'listentry.SkillTreeEntry'): 113 link_text = getattr(entry, 'label', None) or getattr(entry, 'text', '') 114 link = evelink.type_link(entry.typeID, link_text=link_text) 115 self.AddLink(link.text, link.url) 116 elif guid == 'TextLink': 117 self.AddLink(entry.displayText, entry.url) 118 elif guid in ('listentry.KillMail', 'listentry.KillMailCondensed', 'listentry.WarKillEntry'): 119 killmail = entry.mail 120 hashValue = crimewatch.util.GetKillReportHashValue(killmail) 121 if idCheckers.IsCharacter(killmail.victimCharacterID): 122 victimName = cfg.eveowners.Get(killmail.victimCharacterID).name 123 shipName = evetypes.GetName(killmail.victimShipTypeID) 124 label = localization.GetByLabel('UI/Corporations/Wars/Killmails/KillLinkCharacter', charName=victimName, typeName=shipName) 125 else: 126 shipName = evetypes.GetName(killmail.victimShipTypeID) 127 label = localization.GetByLabel('UI/Corporations/Wars/Killmails/KillLinkStructure', typeName=shipName) 128 link = format_kill_report_url(entry.mail.killID, hashValue) 129 self.AddLink(label, link) 130 elif guid == 'listentry.WarEntry': 131 link = evewar.client.war_report_link(war_id=entry.war.warID, attacker_id=entry.war.declaredByID, defender_id=entry.war.againstID) 132 self.AddLink(link.text, link.url) 133 elif guid == 'listentry.RecruitmentEntry': 134 link = corporation.client.recruitment_ad_link(corp_id=entry.advert.corporationID, ad_id=entry.advert.adID, title=entry.adTitle) 135 self.AddLink(link.text, link.url) 136 elif guid == 'listentry.DirectionalScanResults': 137 link = evelink.type_link(entry.typeID, entry.itemID, entry.typeName) 138 self.AddLink(link.text, link.url) 139 elif guid in ('listentry.SkillEntry', 'listentry.SkillQueueSkillEntry'): 140 link = evelink.type_link(entry.invtype) 141 self.AddLink(link.text, link.url) 142 elif guid in ('listentry.Item', 'listentry.ContractItemSelect', 'listentry.RedeemToken', 'listentry.FittingModuleEntry', 'listentry.KillItems'): 143 label = getattr(entry, 'genericDisplayLabel', None) 144 itemID = fittingUtil.GetOriginalItemID(getattr(entry, 'itemID', None)) 145 if isinstance(itemID, tuple): 146 itemID = None 147 link = evelink.type_link(entry.typeID, itemID, label) 148 self.AddLink(link.text, link.url) 149 elif guid == 'listentry.PodGuideBrowseEntry': 150 self.AddLink(entry.label, format_pod_guide_url(entry.termID)) 151 elif guid == 'fakeentry.OverviewProfile': 152 progressText = localization.GetByLabel('UI/Overview/FetchingOverviewProfile') 153 sm.GetService('loading').ProgressWnd(progressText, '', 1, 2) 154 try: 155 presetKeyVal = sm.RemoteSvc('overviewPresetMgr').StoreLinkAndGetID(entry.data) 156 if presetKeyVal is None: 157 raise UserError('OverviewProfileLoadingError') 158 else: 159 presetKey = (presetKeyVal.hashvalue, presetKeyVal.sqID) 160 finally: 161 sm.GetService('loading').ProgressWnd(progressText, '', 2, 2) 162 163 link = overview_preset_link(presetKey, entry.label) 164 self.AddLink(link.text, link.url) 165 elif guid == 'fakeentry.BroadcastSharing': 166 with sharedSettings.client.ShowFetchingSettingsProgressWnd(''): 167 settingKeyVal = sm.RemoteSvc('sharedSettingsMgr').StoreSettingLinkAndGetID(sharedSettings.SHARED_SETTING_BROADCAST, entry.data) 168 settingKey = sharedSettings.GetSettingKeyFromKeyVal(settingKeyVal, 'ItemFilterLoadingError') 169 link = sharedSettings.client.format_shared_settings_url(settingKey) 170 label = entry.label 171 self.AddLink(label, link) 172 elif guid == 'listentry.PointerWndEntry': 173 pointerObjects = entry.pointerObjects 174 numPointers = len(pointerObjects) 175 for i, pointerObj in enumerate(pointerObjects): 176 label = pointerObj.labelLong or pointerObj.label 177 link = format_help_pointer_url(pointerObj.uiElementName) 178 sm.GetService('helpPointer').LogPointerLinkCreated(pointerObj.uiElementName) 179 self.AddLink(label, link) 180 if i < numPointers - 1: 181 self.Insert(187) 182 183 elif guid == 'listentry.AgencyHelpVideoEntry': 184 link = agency.client.get_help_video_link(video_id=entry['id']) 185 sm.GetService('agencyNew').LogHelpVideoLinkCreated(entry['path']) 186 self.AddLink(link.text, link.url) 187 elif getattr(entry, 'nodeType', None) == 'AccessGroupEntry': 188 link = access_group_link(entry.groupID, entry.label) 189 self.AddLink(link.text, link.url) 190 elif getattr(entry, 'nodeType', None) == 'BookmarkFolderEntry': 191 link = format_bookmark_folder_url(entry.folderID) 192 label = entry.label 193 self.AddLink(label, link) 194 195 self.CheckHintText() 196 197 def CheckLinkFits(self, entry): 198 if not getattr(entry, 'check_link_fits', False): 199 return 200 link = entry.get_link() 201 roomLeft = self.RoomLeft() 202 if roomLeft is not None: 203 if len(link) >= roomLeft: 204 raise UserError('LinkTooLong') 205 206 def ApplyGameSelection(self, what, data, changeObjs): 207 if what == 6 and len(changeObjs): 208 key = {} 209 if data: 210 key['link'] = data['link'] 211 t = self.DoSearch(key['link'], data['text']) 212 if not t: 213 return 214 else: 215 format = [{'type': 'checkbox', 216 'label': '_hide', 217 'text': 'http://', 218 'key': 'http://', 219 'required': 1, 220 'setvalue': 1, 221 'group': 'link', 222 'onchange': self.OnLinkTypeChange}, 223 {'type': 'checkbox', 224 'label': '_hide', 225 'text': localization.GetByLabel('UI/Common/Character'), 226 'key': 'char', 227 'required': 1, 228 'setvalue': 0, 229 'group': 'link', 230 'onchange': self.OnLinkTypeChange}, 231 {'type': 'checkbox', 232 'label': '_hide', 233 'text': localization.GetByLabel('UI/Common/Corporation'), 234 'key': 'corp', 235 'required': 1, 236 'setvalue': 0, 237 'group': 'link', 238 'onchange': self.OnLinkTypeChange}, 239 {'type': 'checkbox', 240 'label': '_hide', 241 'text': localization.GetByLabel('UI/Common/ItemType'), 242 'key': 'type', 243 'required': 1, 244 'setvalue': 0, 245 'group': 'link', 246 'onchange': self.OnLinkTypeChange}, 247 {'type': 'checkbox', 248 'label': '_hide', 249 'text': localization.GetByLabel('UI/Common/SolarSystem'), 250 'key': 'solarsystem', 251 'required': 1, 252 'setvalue': 0, 253 'group': 'link', 254 'onchange': self.OnLinkTypeChange}, 255 {'type': 'checkbox', 256 'label': '_hide', 257 'text': localization.GetByLabel('UI/Common/Station'), 258 'key': 'station', 259 'required': 1, 260 'setvalue': 0, 261 'group': 'link', 262 'onchange': self.OnLinkTypeChange}, 263 {'type': 'push'}, 264 {'type': 'edit', 265 'label': localization.GetByLabel('UI/Common/Link'), 266 'text': 'http://', 267 'width': 170, 268 'required': 1, 269 'key': 'txt'}, 270 {'type': 'push'}] 271 key = self.AskLink(None, format, width=400) 272 anchor = -1 273 if key: 274 link = key['link'] 275 if link == None: 276 return 277 if link in ('char', 'corp', 'alliance', 'solarsystem', 'station', 'type'): 278 if not self.typeID and not self.DoSearch(link, key['txt']): 279 return 280 return evelink.format_show_info_url(self.typeID, self.itemID) 281 if link == 'fleet': 282 anchor = 'fleet:' + str(self.itemID) 283 elif link == 'http://': 284 if key['txt'].startswith(key['link']) or key['txt'].startswith('https://'): 285 anchor = '' 286 else: 287 anchor = key['link'] 288 anchor += key['txt'] 289 else: 290 anchor = key['link'] + key['txt'] 291 return anchor 292 return -1 293 294 def OnLinkTypeChange(self, chkbox, *args): 295 if chkbox.GetValue(): 296 self.itemID = self.typeID = None 297 self.key = chkbox.data['key'] 298 text = chkbox.GetChild('text') 299 wnd = chkbox.FindParentByName(localization.GetByLabel('UI/Common/GenerateLink')) 300 if not wnd: 301 return 302 editParent = wnd.FindChild('editField') 303 if editParent is not None: 304 label = editParent.FindChild('label') 305 label.text = text.text 306 edit = editParent.FindChild('edit_txt') 307 edit.SetValue('') 308 self.sr.searchbutt = editParent.FindChild('button') 309 if self.key in ('char', 'corp', 'type', 'solarsystem', 'station'): 310 if self.sr.searchbutt == None: 311 self.sr.searchbutt = Button(parent=editParent, label=localization.GetByLabel('UI/Common/Search'), func=self.OnSearch, btn_default=0, align=uiconst.CENTERRIGHT, left=4) 312 else: 313 self.sr.searchbutt.state = uiconst.UI_NORMAL 314 elif self.sr.searchbutt != None: 315 self.sr.searchbutt.state = uiconst.UI_HIDDEN 316 317 def OnSearch(self, *args): 318 wnd = self.sr.searchbutt.FindParentByName(localization.GetByLabel('UI/Common/GenerateLink')) 319 if not wnd: 320 return 321 editParent = wnd.FindChild('editField') 322 edit = editParent.FindChild('edit_txt') 323 val = edit.GetValue().strip().lower() 324 name = self.DoSearch(self.key, val) 325 if name is not None: 326 edit.SetValue(name) 327 328 def DoSearch(self, key, val): 329 self.itemID = None 330 self.typeID = None 331 id = None 332 name = '' 333 val = '%s*' % val 334 if key == 'type': 335 itemTypes = [] 336 results = searchUtil.GetResultsList(val, [ResultType.item_type]) 337 if results is not None: 338 for typeID in results: 339 itemTypes.append((evetypes.GetName(typeID), None, typeID)) 340 341 if not itemTypes: 342 prompt_player_fsd_dialog('NoItemTypesFound') 343 return 344 id = uix.ListWnd(itemTypes, 'item', localization.GetByLabel('UI/Common/SelectItemType'), None, 1) 345 else: 346 group = None 347 hideNPC = 0 348 if key == 'solarsystem': 349 group = const.groupSolarSystem 350 elif key == 'station': 351 group = const.groupStation 352 elif key == 'char': 353 group = const.groupCharacter 354 elif key == 'corp': 355 group = const.groupCorporation 356 elif key == 'alliance': 357 group = const.groupAlliance 358 id = searchOld.Search(val, group, hideNPC=hideNPC, listType='Generic') 359 name = '' 360 if id: 361 self.itemID = id 362 self.typeID = 0 363 if key in ('char', 'corp', 'alliance'): 364 o = cfg.eveowners.Get(id) 365 self.typeID = o.typeID 366 name = o.name 367 elif key == 'solarsystem': 368 self.typeID = const.typeSolarSystem 369 l = cfg.evelocations.Get(id) 370 name = l.name 371 elif key == 'station': 372 if idCheckers.IsStation(id): 373 self.typeID = sm.GetService('ui').GetStationStaticInfo(id).stationTypeID 374 else: 375 structureInfo = sm.GetService('structureDirectory').GetStructureInfo(id) 376 if structureInfo: 377 self.typeID = structureInfo.typeID 378 else: 379 return 380 l = cfg.evelocations.Get(id) 381 name = l.name 382 elif key == 'type': 383 self.typeID = id[2] 384 self.itemID = None 385 name = id[0] 386 return name 387 388 def AskLink(self, label = '', lines = [], width = 280): 389 icon = uiconst.QUESTION 390 format = [{'type': 'text', 391 'text': label}] + lines 392 retval = uix.HybridWnd(format, caption=localization.GetByLabel('UI/Common/GenerateLink'), windowID='askLink', modal=1, buttons=uiconst.OKCANCEL, minW=width, minH=110, icon=icon) 393 if retval: 394 return retval 395 else: 396 return None 397 398 def AddLink(self, text, link = None, addLineBreak = False): 399 self.SetSelectionRange(None, None) 400 node = self.GetActiveNode() 401 if node is None: 402 return 403 text = commonutils.StripTags(text, stripOnly=['localized']) 404 shiftCursor = len(text) 405 stackCursorIndex = self.globalCursorPos - node.startCursorIndex + node.stackCursorIndex 406 glyphString = node.glyphString 407 newGlyphString = uicore.font.GetGlyphString() 408 self._UpdateGlyphString(newGlyphString, text, link, shiftCursor, stackCursorIndex) 409 newStringText = self.GetValueForParagraphs(1, [newGlyphString]) 410 if not self.IsEnoughRoomForInsert(len(newStringText)): 411 prompt_player_fsd_dialog('uiwarning03') 412 return 413 shift = self._UpdateGlyphString(glyphString, text, link, shiftCursor, stackCursorIndex) 414 self.UpdateGlyphString(glyphString, advance=shiftCursor, stackCursorIndex=stackCursorIndex) 415 self.SetCursorPos(self.globalCursorPos + shift) 416 self.UpdatePosition() 417 cursorAdvance = 1 418 if addLineBreak: 419 self.Insert(uiconst.VK_RETURN) 420 421 def _UpdateGlyphString(self, glyphString, text, link, shiftCursor, stackCursorIndex): 422 glyphStringIndex = self.GetGlyphStringIndex(glyphString) 423 shift = 0 424 if stackCursorIndex != 0: 425 currentParams = self._activeParams.Copy() 426 self.InsertToGlyphString(glyphString, currentParams, u' ', stackCursorIndex) 427 shift += 1 428 currentParams = self._activeParams.Copy() 429 currentParams.url = link 430 self.InsertToGlyphString(glyphString, currentParams, text, stackCursorIndex + shift) 431 shift += shiftCursor 432 currentParams = self._activeParams.Copy() 433 self.InsertToGlyphString(glyphString, currentParams, u' ', stackCursorIndex + shift) 434 shift += 1 435 return shift 436 437 def GetMenuDelegate(self, node = None): 438 m = EditPlainTextCore.GetMenuDelegate(self, node) 439 if not self.readonly: 440 m.append(None) 441 linkmenu = [(MenuLabel('UI/Common/Groups/Character'), self.LinkCharacter), 442 (MenuLabel('UI/Common/Corporation'), self.LinkCorp), 443 (MenuLabel('UI/Common/Alliance'), self.LinkAlliance), 444 (MenuLabel('UI/Common/SolarSystem'), self.LinkSolarSystem), 445 (MenuLabel('UI/Common/Station'), self.LinkStation), 446 (MenuLabel('UI/Common/ItemType'), self.LinkItemType)] 447 m.append((MenuLabel('UI/Common/AutoLink'), linkmenu)) 448 return m 449 450 def LinkSomething(self, linkType): 451 if not self.HasSelection(): 452 self.SelectWordUnderCursor() 453 txt = self.GetSelectedText() 454 if txt: 455 txt = txt.strip() 456 self.ApplySelection(6, data={'text': txt, 457 'link': linkType}) 458 self.UpdateCharacterCounter() 459 460 def LinkCharacter(self): 461 self.LinkSomething('char') 462 463 def LinkCorp(self): 464 self.LinkSomething('corp') 465 466 def LinkAlliance(self): 467 self.LinkSomething('alliance') 468 469 def LinkSolarSystem(self): 470 self.LinkSomething('solarsystem') 471 472 def LinkStation(self): 473 self.LinkSomething('station') 474 475 def LinkItemType(self): 476 self.LinkSomething('type')