listwindow.py (12671B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\listwindow.py 2 import sys 3 import weakref 4 import evetypes 5 import localization 6 import log 7 import utillib 8 from carbonui import uiconst 9 from carbonui.primitives.container import Container 10 from carbonui.primitives.containerAutoSize import ContainerAutoSize 11 from carbonui.control.buttonIcon import ButtonIcon 12 from eve.client.script.ui.control.entries.generic import Generic 13 from eve.client.script.ui.control.entries.util import GetFromClass 14 from eve.client.script.ui.control.eveLabel import EveLabelMedium 15 from eve.client.script.ui.control.eveScroll import Scroll 16 from carbonui.control.window import Window 17 from eve.client.script.ui.control.listgroup import ListGroup 18 from eve.client.script.ui.shared.userentry import AgentEntry, User 19 from eve.common.script.sys import idCheckers 20 21 class ListWindow(Window): 22 __guid__ = 'form.ListWindow' 23 __nonpersistvars__ = ['scroll', 24 'listentry', 25 'result', 26 'listtype', 27 'minChoices', 28 'maxChoices'] 29 default_minSize = (128, 240) 30 default_width = 256 31 default_height = 128 32 33 def ApplyAttributes(self, attributes): 34 Window.ApplyAttributes(self, attributes) 35 lst = attributes.get('lst', []) 36 self.listtype = attributes.get('listtype') 37 self.ordered = attributes.get('ordered', False) 38 caption = attributes.get('caption') 39 self.minChoices = attributes.get('minChoices', 1) 40 self.maxChoices = attributes.get('maxChoices', 1) 41 initChoices = attributes.get('initChoices', []) 42 validator = attributes.get('validator') 43 scrollHeaders = attributes.get('scrollHeaders') 44 iconMargin = attributes.get('iconMargin') 45 lstDataIsGrouped = attributes.get('lstDataIsGrouped') 46 self.noContentHint = attributes.get('noContentHint') 47 showCollapseBtn = attributes.get('showCollapseBtn', False) 48 if validator is not None: 49 self.customValidator = weakref.proxy(validator) 50 self.selecting = 0 51 self.result = None 52 Container(name='errorParent', parent=self.sr.main, align=uiconst.TOBOTTOM, height=16, state=uiconst.UI_HIDDEN) 53 self.hintparent = ContainerAutoSize(name='hintparent', parent=self.sr.main, align=uiconst.TOTOP, state=uiconst.UI_PICKCHILDREN, alignMode=uiconst.TOTOP) 54 self.hintparent.display = False 55 self.hintLabel = EveLabelMedium(text='', parent=self.hintparent, state=uiconst.UI_DISABLED, align=uiconst.TOTOP, padding=(20, 4, 20, 4)) 56 self.collapseBtn = ButtonIcon(name='collapse', parent=self.hintparent, align=uiconst.CENTERLEFT, pos=(6, 0, 12, 12), iconSize=12, texturePath='res:/UI/Texture/classes/Scroll/Collapse.png', func=self.CollapseAllGroups, hint=localization.GetByLabel('UI/Common/Buttons/CollapseAll')) 57 self.collapseBtn.display = bool(showCollapseBtn) 58 self.scroll = Scroll(parent=self.sr.main, padding=(uiconst.defaultPadding, 59 uiconst.defaultPadding, 60 uiconst.defaultPadding, 61 uiconst.defaultPadding + 2)) 62 self.scroll.sr.iconMargin = iconMargin 63 self.scroll.multiSelect = self.maxChoices > 1 64 self.MakeUnMinimizable() 65 self.SetCaption(caption or localization.GetByLabel('UI/Control/ListWindow/PickOne')) 66 if not lstDataIsGrouped: 67 self.GenerateList(lst, self.ordered, scrollHeaders) 68 else: 69 self.GenerateGroupedList(lst, self.ordered, scrollHeaders) 70 for each in initChoices or []: 71 for entry in self.scroll.GetNodes(): 72 if entry.listvalue == each: 73 self.scroll.SelectNode(entry) 74 break 75 76 self.RefreshSelection() 77 78 def SetSize(self, width, height, *args): 79 if not self or self.destroyed: 80 return 81 minw, minh = self.minsize 82 self.width = max(width, minw) 83 self.height = max(height, minh) 84 85 def Cancel(self, *etc): 86 if getattr(self, 'isModal', None): 87 self.SetModalResult(uiconst.ID_CANCEL) 88 else: 89 self.Close() 90 91 def SetResult(self, result): 92 self.result = result 93 94 def ClickOK(self, *args): 95 self.Confirm() 96 97 def DblClickEntry(self, entry, *args): 98 if entry.confirmOnDblClick: 99 self.scroll.SelectNode(entry.sr.node) 100 self.RefreshSelection() 101 self.Confirm() 102 103 def ClickEntry(self, *args): 104 self.RefreshSelection() 105 106 def GetError(self, checkNumber = 1): 107 result = [] 108 for entry in self.scroll.GetSelected(): 109 if entry.listvalue: 110 result.append(entry.listvalue) 111 112 if hasattr(self, 'customValidator'): 113 ret = self.customValidator and self.customValidator(result) or '' 114 if ret: 115 return ret 116 try: 117 if checkNumber: 118 if self.maxChoices and len(result) > self.maxChoices: 119 return localization.GetByLabel('UI/Control/ListWindow/SelectTooManyError', num=self.maxChoices) 120 if len(result) < self.minChoices: 121 if self.minChoices == self.maxChoices: 122 label = localization.GetByLabel('UI/Control/ListWindow/MustSelectError', num=self.minChoices) 123 else: 124 label = localization.GetByLabel('UI/Control/ListWindow/SelectTooFewError', num=self.minChoices) 125 return label 126 except ValueError as e: 127 log.LogException() 128 sys.exc_clear() 129 return 130 131 return '' 132 133 def CollapseAllGroups(self, *args): 134 self.scroll.CollapseAll() 135 136 def Confirm(self, *etc): 137 if not self.isModal: 138 return 139 self.Error(self.GetError()) 140 if not self.GetError(): 141 self.result = [ entry.listvalue for entry in self.scroll.GetSelected() ] 142 if self.maxChoices == 1: 143 self.result = self.result[0] 144 self.SetModalResult(uiconst.ID_OK) 145 146 def Error(self, error): 147 ep = self.GetChild('errorParent') 148 ep.Flush() 149 if error: 150 t = EveLabelMedium(text=localization.GetByLabel('UI/Control/ListWindow/DisplayError', errorMessage=error), top=-3, parent=ep, width=self.minsize[0] - 32, state=uiconst.UI_DISABLED, color=(1.0, 0.0, 0.0, 1.0), align=uiconst.CENTER) 151 ep.state = uiconst.UI_DISABLED 152 ep.height = t.height + 8 153 else: 154 ep.state = uiconst.UI_HIDDEN 155 156 def RefreshSelection(self): 157 self.Error(self.GetError()) 158 159 def SetHint(self, hint): 160 if hint: 161 self.hintLabel.text = hint 162 self.hintparent.display = True 163 else: 164 self.hintparent.display = False 165 166 def GenerateList(self, lst, ordered = 0, scrollHeaders = []): 167 if ordered == 1: 168 169 def Compare(a, b): 170 a, b = a[0], b[0] 171 try: 172 a = a.lower() 173 except: 174 pass 175 176 try: 177 b = b.lower() 178 except: 179 pass 180 181 return cmp(a, b) 182 183 lst.sort(Compare) 184 _height = 16 185 scrolllist = [] 186 for info in lst: 187 height, entry = self.AddEntry(info) 188 _height = max(height, _height) 189 scrolllist.append(entry) 190 191 self.scroll.Load(contentList=scrolllist, headers=scrollHeaders, noContentHint=self.noContentHint) 192 193 def GenerateGroupedList(self, lst, ordered = 0, scrollHeaders = []): 194 if ordered == 1: 195 lst.sort(self.GroupItemCompare) 196 rootnode = utillib.KeyVal() 197 rootnode.groupItems = lst 198 scrolllist = self.GetGroupData(rootnode) 199 _height = 24 200 self.scroll.Load(contentList=scrolllist, headers=scrollHeaders, noContentHint=self.noContentHint) 201 202 def AddEntry(self, info): 203 confirmOnDblClick = self.minChoices == self.maxChoices == 1 204 if self.listtype in ('character', 'corporation', 'alliance', 'faction', 'owner'): 205 name, itemID, typeID = info 206 typeExists = False 207 if typeID: 208 typeExists = evetypes.Exists(typeID) 209 if not typeExists: 210 owner = cfg.eveowners.GetIfExists(itemID) 211 if owner: 212 typeExists = evetypes.Exists(owner.typeID) 213 if typeExists: 214 charID = itemID 215 if idCheckers.IsCharacter(charID) and idCheckers.IsNPC(charID): 216 entryType = AgentEntry 217 else: 218 entryType = User 219 return (40, GetFromClass(entryType, {'charID': charID, 220 'OnDblClick': self.DblClickEntry, 221 'OnClick': self.ClickEntry, 222 'dblconfirm': confirmOnDblClick, 223 'charIndex': name})) 224 else: 225 if self.listtype in ('pickStation',): 226 data = info 227 data.confirmOnDblClick = confirmOnDblClick 228 data.OnDblClick = self.DblClickEntry 229 data.OnClick = self.ClickEntry 230 return (32, GetFromClass(Generic, data)) 231 if self.listtype == 'generic': 232 name, listvalue = info 233 data = utillib.KeyVal() 234 data.confirmOnDblClick = confirmOnDblClick 235 data.label = name 236 data.listvalue = info 237 data.OnDblClick = self.DblClickEntry 238 data.OnClick = self.ClickEntry 239 return (32, GetFromClass(Generic, data)) 240 name, itemID, typeID = info 241 data = utillib.KeyVal() 242 data.confirmOnDblClick = confirmOnDblClick 243 data.label = name 244 data.itemID = itemID 245 data.typeID = typeID 246 data.listvalue = [name, itemID, typeID] 247 data.isStation = self.listtype == 'station' 248 data.getIcon = self.listtype == 'item' 249 data.OnDblClick = self.DblClickEntry 250 data.OnClick = self.ClickEntry 251 return (24, GetFromClass(Generic, data)) 252 253 def GetGroupData(self, nodedata, newItems = 0): 254 if not nodedata.groupItems: 255 return [] 256 if self.ordered: 257 nodedata.groupItems.sort(self.GroupItemCompare) 258 confirmOnDblClick = self.minChoices == self.maxChoices == 1 259 scrolllist = [] 260 for subnode in nodedata.groupItems: 261 if subnode.get('groupItems', None) is not None: 262 if not hasattr(subnode, 'GetSubContent'): 263 subnode.GetSubContent = self.GetGroupData 264 scrolllist.append(GetFromClass(ListGroup, subnode)) 265 else: 266 subnode.OnDblClick = self.DblClickEntry 267 subnode.OnClick = self.ClickEntry 268 subnode.confirmOnDblClick = confirmOnDblClick 269 subnode.isStation = self.listtype == 'station' 270 subnode.getIcon = self.listtype == 'item' 271 scrolllist.append(GetFromClass(Generic, subnode)) 272 273 return scrolllist 274 275 def GroupItemCompare(self, a, b): 276 a = a.label or a[0] 277 b = b.label or b[0] 278 try: 279 a = a.lower() 280 except: 281 pass 282 283 try: 284 b = b.lower() 285 except: 286 pass 287 288 return cmp(a, b) 289 290 @classmethod 291 def ShowList(cls, lst, listtype = None, caption = None, hint = None, ordered = 0, minw = 340, minh = 400, minChoices = 1, maxChoices = 1, initChoices = [], validator = None, isModal = 1, scrollHeaders = [], iconMargin = 0, windowName = 'listwindow', lstDataIsGrouped = 0, unstackable = 0, noContentHint = None, showCollapseBtn = False): 292 if caption is None: 293 caption = localization.GetByLabel('UI/Search/SelectItem') 294 cls.CloseIfOpen(windowID=windowName) 295 wnd = cls(windowID=windowName, lst=lst, listtype=listtype, ordered=ordered, minSize=(minw, minh), caption=caption, minChoices=minChoices, maxChoices=maxChoices, initChoices=initChoices, validator=validator, scrollHeaders=scrollHeaders, iconMargin=iconMargin, lstDataIsGrouped=lstDataIsGrouped, noContentHint=noContentHint, showCollapseBtn=showCollapseBtn) 296 if hint: 297 wnd.SetHint(['<center>', hint]) 298 if unstackable: 299 wnd.MakeUnstackable() 300 if isModal: 301 wnd.DefineButtons(uiconst.OKCANCEL) 302 if wnd.ShowModal() == uiconst.ID_OK: 303 return wnd.result 304 else: 305 return 306 else: 307 wnd.DefineButtons(uiconst.CLOSE) 308 wnd.Maximize() 309 wnd.SetOrder(0)