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

contractsearch.py (82500B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\neocom\contracts\contractsearch.py
      2 import copy
      3 import sys
      4 import evetypes
      5 from carbonui.control.combo import Combo
      6 from carbonui.control.dragResizeCont import DragResizeCont
      7 from carbonui.control.scrollContainer import ScrollContainer
      8 from carbonui.primitives.container import Container
      9 from carbonui.primitives.containerAutoSize import ContainerAutoSize
     10 from carbonui.primitives.fill import Fill
     11 from carbonui.primitives.flowcontainer import FlowContainer
     12 from carbonui.primitives.layoutGrid import LayoutGrid
     13 from carbonui.primitives.line import Line
     14 from carbonui.primitives.sprite import Sprite
     15 from clientsettings.setting import UserSettingBool
     16 from carbonui.uianimations import animations
     17 from eve.client.script.ui.control import eveLabel, eveScroll
     18 from eve.client.script.ui.control.allUserEntries import AllUserEntries
     19 from carbonui.control.checkbox import Checkbox
     20 from eve.client.script.ui.control.collapseLine import CollapseLine
     21 from eve.client.script.ui.control.entries.util import GetFromClass
     22 from eve.client.script.ui.shared.neocom.contracts.contractentry import ContractEntrySearchAuction, ContractEntrySearchCourier, ContractEntrySearchItemExchange
     23 from eve.client.script.ui.util import uix, utilWindows
     24 import uthread
     25 import blue
     26 import carbonui.const as uiconst
     27 from carbon.client.script.environment.AudioUtil import PlaySound
     28 from carbonui.control.singlelineedits.singleLineEditInteger import SingleLineEditInteger
     29 from carbonui.control.singlelineedits.singleLineEditText import SingleLineEditText
     30 from eve.client.script.ui.control.eveLoadingWheel import LoadingWheel
     31 from eve.client.script.ui.util import searchUtil
     32 from eve.client.script.util.contractutils import GetContractTitle, SelectItemTypeDlg
     33 from eve.common.lib import appConst
     34 from eve.common.script.search import const as search_const
     35 from eve.common.script.sys import idCheckers
     36 from eve.common.script.util import contractscommon as cc
     37 import localization
     38 from eveuniverse.security import securityClassZeroSec, securityClassLowSec, securityClassHighSec, securityClassSafeSec, security_classes
     39 CONTRACT_SCROLL_COLUMN_WIDTHS = {localization.GetByLabel('UI/Contracts/ContractsSearch/columPickup'): 120,
     40  localization.GetByLabel('UI/Contracts/ContractsSearch/columnContract'): 200,
     41  localization.GetByLabel('UI/Contracts/ContractsSearch/columnBids'): 20,
     42  localization.GetByLabel('UI/Contracts/ContractsSearch/columnJumps'): 90,
     43  localization.GetByLabel('UI/Contracts/ContractsSearch/columnRoute'): 80,
     44  localization.GetByLabel('UI/Contracts/ContractsSearch/columnVolume'): 60,
     45  localization.GetByLabel('UI/Contracts/ContractsSearch/columnTimeLeft'): 70,
     46  localization.GetByLabel('UI/Contracts/ContractsSearch/columnPrice'): 100,
     47  localization.GetByLabel('UI/Contracts/ContractsSearch/columnLocation'): 100,
     48  localization.GetByLabel('UI/Contracts/ContractsSearch/columnIssuer'): 100}
     49 CONTRACT_TYPE_OPTIONS = [(localization.GetByLabel('UI/Contracts/ContractsSearch/comboAll'), None),
     50  (localization.GetByLabel('UI/Contracts/ContractsSearch/comboSellContracts'), 2),
     51  (localization.GetByLabel('UI/Contracts/ContractsSearch/comboWantToBuy'), 3),
     52  (localization.GetByLabel('UI/Contracts/ContractsSearch/combo'), 1),
     53  (localization.GetByLabel('UI/Contracts/ContractsSearch/comboExcluedWantToBuy'), 4)]
     54 from carbonui.control.buttonIcon import ButtonIcon
     55 from carbonui.control.button import Button
     56 from eve.client.script.ui.control.toggleButtonGroup import ToggleButtonGroup
     57 from carbonui.uicore import uicore
     58 import eve.client.script.ui.shared.pointerTool.pointerToolConst as pConst
     59 from eve.client.script.ui.util import searchOld
     60 from eveexceptions import UserError
     61 from eveprefs import prefs
     62 from menu import MenuLabel
     63 import metaGroups
     64 LEFT_WIDTH = 170
     65 MILLION = 1000000
     66 MAXJUMPROUTENUM = 100
     67 PAGINGRANGE = 10
     68 NUM_SAVED_LOCATIONS = 5
     69 MAX_NUM_MILLIONS = 100000
     70 CONTRACT_SEARCH_MAPPINGS = {cc.SORT_ID: 'UI/Contracts/ContractsSearch/columnCreated',
     71  cc.SORT_EXPIRED: 'UI/Contracts/ContractsSearch/columnTimeLeft',
     72  cc.SORT_PRICE: 'UI/Contracts/ContractsSearch/columnPrice',
     73  cc.SORT_REWARD: 'UI/Contracts/ContractsSearch/columnReward',
     74  cc.SORT_COLLATERAL: 'UI/Contracts/ContractsSearch/columnCollateral'}
     75 EDIT_WIDTH = 61
     76 
     77 class ContractSearchPanel(Container):
     78 
     79     def ApplyAttributes(self, attributes):
     80         super(ContractSearchPanel, self).ApplyAttributes(attributes)
     81         parentContentPadding = attributes.get('parentContentPadding', 16)
     82         self.contractsSvc = sm.GetService('contracts')
     83         self.inited = False
     84         self.searchThread = None
     85         self.currPage = 0
     86         self.numPages = 0
     87         self.pageData = {}
     88         self.pages = {0: None}
     89         self.fetchingContracts = 0
     90         self.fltIssuerID = None
     91         self.ConstructLeftCont(parentContentPadding)
     92         self.topContainer = Container(name='topCont', parent=self, pos=(0, 0, 0, 32), align=uiconst.TOTOP)
     93         self.ConstructViewModeButtons()
     94         self.ConstructSortCombo()
     95         self.ConstructBottomFilterCont(parentContentPadding)
     96         self.ConstructContractsScroll()
     97         self.ReconstructLeftFilters()
     98         self.inited = True
     99 
    100     def ConstructLeftCont(self, parentContentPadding):
    101         resizeCont = DragResizeCont(name='resizeCont', parent=self, align=uiconst.TOLEFT, minSize=180, maxSize=280, defaultSize=200, settingsID='contractSearch_resizer')
    102         leftPanelPadding = 8
    103         self.leftCont = Container(name='leftCont', parent=resizeCont, align=uiconst.TOALL, padding=(0,
    104          0,
    105          leftPanelPadding,
    106          0))
    107         self.ConstructBuySellOrCourierToggleButtons()
    108         self.searchBtn = Button(name='searchBtn', align=uiconst.TOBOTTOM, parent=self.leftCont, padTop=4, func=self.DoSearch, label=localization.GetByLabel('UI/Contracts/ContractsSearch/buttonSearch'))
    109         self.leftFilterScroll = ScrollContainer(name='leftFilterScroll', parent=self.leftCont, align=uiconst.TOALL)
    110         if isinstance(parentContentPadding, tuple):
    111             fillPadding = [ -x for x in parentContentPadding ]
    112         else:
    113             fillPadding = 4 * [-parentContentPadding]
    114         fillPadding[2] = 4
    115         fillPadding = tuple(fillPadding)
    116         Fill(bgParent=resizeCont, padding=fillPadding, color=(1.0, 1.0, 1.0), opacity=0.05)
    117 
    118     def ConstructViewModeButtons(self):
    119         currentViewMode = int(prefs.GetValue('contractsSimpleView', 0) or 0)
    120         self.viewModeDetailsButton = ButtonIcon(parent=self.topContainer, align=uiconst.TOPLEFT, pos=(6, 10, 16, 16), texturePath='res:/UI/Texture/Icons/38_16_157.png', hint=localization.GetByLabel('UI/Common/Details'), func=self.ChangeViewModeDetails)
    121         if currentViewMode == 0:
    122             self.viewModeDetailsButton.SetSelected()
    123         self.viewModeListButton = ButtonIcon(parent=self.topContainer, align=uiconst.TOPLEFT, pos=(22, 10, 16, 16), texturePath='res:/UI/Texture/Icons/38_16_158.png', hint=localization.GetByLabel('UI/Inventory/List'), func=self.ChangeViewModeList, isActive=currentViewMode == 1)
    124         if currentViewMode == 1:
    125             self.viewModeListButton.SetSelected()
    126 
    127     def ConstructSortCombo(self):
    128         self.sortCombo = Combo(name='sort', label=localization.GetByLabel('UI/Contracts/ContractsSearch/SortPageBy'), width=160, parent=self.topContainer, align=uiconst.TOPRIGHT, callback=self.ComboChange)
    129         self.PopulateSortCombo()
    130 
    131     def ConstructBottomFilterCont(self, parentContentPadding):
    132         if settings.user.ui.Get('contracts_search_expander_clientFilterExpander', 0):
    133             filterState = uiconst.UI_PICKCHILDREN
    134         else:
    135             filterState = uiconst.UI_HIDDEN
    136         self.bottomFilterCont = Container(name='bottomFilterCont', parent=self, align=uiconst.TOBOTTOM, state=filterState, clipChildren=True)
    137         bottomFilterExpanderCont = Container(name='bottomFilterExpanderCont', parent=self, pos=(0, 0, 0, 20), align=uiconst.TOBOTTOM, state=uiconst.UI_PICKCHILDREN, padTop=0, padBottom=4)
    138         self.collapseLine = CollapseLine(parent=self, collapsingSectionWidth=30, align=uiconst.TOBOTTOM, collapsingSection=self.bottomFilterCont, useCustomTransition=True, settingKey='contracts_search_expander_clientFilterExpander')
    139         self.collapseLine.on_section_expand.connect(self.ToggleClientFilters)
    140         self.collapseLine.on_section_collapse.connect(self.ToggleClientFilters)
    141         hint = self.GetClientFilterText()
    142         self.collapseLine.SetHint(hint)
    143         padRight = parentContentPadding[3] if isinstance(parentContentPadding, tuple) else parentContentPadding
    144         Line(parent=self, align=uiconst.TOBOTTOM, color=(1, 1, 1, 0.15), top=-self.collapseLine.height / 2, padRight=-padRight)
    145         self.pageArea = Container(name='pageArea', parent=bottomFilterExpanderCont, pos=(10,
    146          0,
    147          25 * PAGINGRANGE + 40,
    148          0), align=uiconst.TORIGHT, state=uiconst.UI_NORMAL)
    149         expanderTextContParent = Container(name='expanderTextContParent', parent=bottomFilterExpanderCont, pos=(0, 0, 0, 20), align=uiconst.TOTOP, state=uiconst.UI_PICKCHILDREN)
    150         foundLabelText = localization.GetByLabel('UI/Contracts/ContractsSearch/NoSearch')
    151         self.foundLabel = eveLabel.EveLabelSmall(text=foundLabelText, parent=expanderTextContParent, align=uiconst.CENTERLEFT, left=4, autoFadeSides=16, state=uiconst.UI_NORMAL)
    152         self.foundLabel.OnClick = self.ToggleClientFiltersOnLabelClick
    153         fwdCont = Container(name='fwdCont', parent=self.pageArea, pos=(0, 0, 20, 0), align=uiconst.TORIGHT, state=uiconst.UI_NORMAL)
    154         self.pageFwdBtn = ButtonIcon(name='pageFwdBtn', parent=fwdCont, align=uiconst.CENTERRIGHT, state=uiconst.UI_HIDDEN, width=20, height=20, texturePath='res:/UI/Texture/Icons/38_16_224.png', func=self.DoPageNext)
    155         self.pagingCont = Container(name='pagingCont', parent=self.pageArea, pos=(0,
    156          0,
    157          25 * PAGINGRANGE,
    158          0), align=uiconst.TORIGHT)
    159         backCont = Container(name='backCont', parent=self.pageArea, pos=(0, 0, 20, 0), align=uiconst.TORIGHT, state=uiconst.UI_NORMAL)
    160         self.pageBackBtn = ButtonIcon(name='pageBackBtn', parent=backCont, align=uiconst.CENTERLEFT, state=uiconst.UI_HIDDEN, width=20, height=20, texturePath='res:/UI/Texture/Icons/38_16_223.png', func=self.DoPagePrev)
    161 
    162     def ConstructContractsScroll(self):
    163         self.contractsScroll = eveScroll.Scroll(parent=self, name='contractsScroll', padding=(0, 8, 0, 0))
    164         self.contractsScroll.sr.id = 'contractlist'
    165         self.contractsScroll.multiSelect = 0
    166         self.contractsScroll.ShowHint(localization.GetByLabel('UI/Contracts/ContractsSearch/ClickSearchHint'))
    167         self.contractsScroll.sr.defaultColumnWidth = CONTRACT_SCROLL_COLUMN_WIDTHS
    168         self.loadingWheel = LoadingWheel(parent=self.contractsScroll, align=uiconst.CENTER, state=uiconst.UI_NORMAL, idx=0)
    169         self.loadingWheel.Hide()
    170 
    171     def GetTypesFromName(self, itemTypeName, categoryID, groupID):
    172         itemTypes = searchUtil.GetResultsList(itemTypeName, [search_const.ResultType.item_type])
    173         retDict = {}
    174         for x in itemTypes or []:
    175             try:
    176                 if not evetypes.IsPublished(x):
    177                     continue
    178             except evetypes.TypeNotFoundException:
    179                 self.contractsSvc.LogException('Type not found while searching in contracts')
    180                 continue
    181 
    182             if groupID and evetypes.GetGroupID(x) != groupID:
    183                 continue
    184             if categoryID and evetypes.GetCategoryID(x) != categoryID:
    185                 continue
    186             retDict[x] = evetypes.GetName(x)
    187 
    188         return retDict
    189 
    190     def ChangeViewModeList(self):
    191         prefs.SetValue('contractsSimpleView', 1)
    192         blue.pyos.synchro.Yield()
    193         self.viewModeListButton.SetSelected()
    194         self.viewModeDetailsButton.SetDeselected()
    195         if self.currPage in self.pageData:
    196             self.RenderPage()
    197 
    198     def ChangeViewModeDetails(self):
    199         prefs.SetValue('contractsSimpleView', 0)
    200         blue.pyos.synchro.Yield()
    201         self.viewModeListButton.SetDeselected()
    202         self.viewModeDetailsButton.SetSelected()
    203         if self.currPage in self.pageData:
    204             self.RenderPage()
    205 
    206     def PopulateSortCombo(self):
    207         contractType = self.GetContractTypeSetting()
    208         oldestFirst = localization.GetByLabel('UI/Contracts/ContractsSearch/OldestFirst')
    209         newestFirst = localization.GetByLabel('UI/Contracts/ContractsSearch/NewestFirst')
    210         shortestFirst = localization.GetByLabel('UI/Contracts/ContractsSearch/ShortestFirst')
    211         longestFirst = localization.GetByLabel('UI/Contracts/ContractsSearch/LongestFirst')
    212         lowFirst = localization.GetByLabel('UI/Contracts/ContractsSearch/LowerstFirst')
    213         highFirst = localization.GetByLabel('UI/Contracts/ContractsSearch/HighestFirst')
    214         opt = [(localization.GetByLabel('UI/Contracts/ContractsSearch/DateCreatedOption', text=oldestFirst), (cc.SORT_ID, 0)),
    215          (localization.GetByLabel('UI/Contracts/ContractsSearch/DateCreatedOption', text=newestFirst), (cc.SORT_ID, 1)),
    216          (localization.GetByLabel('UI/Contracts/ContractsSearch/TimeLeftOption', text=shortestFirst), (cc.SORT_EXPIRED, 0)),
    217          (localization.GetByLabel('UI/Contracts/ContractsSearch/TimeLeftOption', text=longestFirst), (cc.SORT_EXPIRED, 1))]
    218         if contractType == const.conTypeCourier:
    219             opt.extend([(localization.GetByLabel('UI/Contracts/ContractsSearch/RewardOption', text=lowFirst), (cc.SORT_REWARD, 0)),
    220              (localization.GetByLabel('UI/Contracts/ContractsSearch/RewardOption', text=highFirst), (cc.SORT_REWARD, 1)),
    221              (localization.GetByLabel('UI/Contracts/ContractsSearch/CollateralOption', text=lowFirst), (cc.SORT_COLLATERAL, 0)),
    222              (localization.GetByLabel('UI/Contracts/ContractsSearch/CollateralOption', text=highFirst), (cc.SORT_COLLATERAL, 1)),
    223              (localization.GetByLabel('UI/Contracts/ContractsSearch/VolumnOptions', text=lowFirst), (cc.SORT_VOLUME, 0)),
    224              (localization.GetByLabel('UI/Contracts/ContractsSearch/VolumnOptions', text=highFirst), (cc.SORT_VOLUME, 1))])
    225         else:
    226             opt.extend([(localization.GetByLabel('UI/Contracts/ContractsSearch/PriceOption', text=lowFirst), (cc.SORT_PRICE, 0)), (localization.GetByLabel('UI/Contracts/ContractsSearch/PriceOption', text=highFirst), (cc.SORT_PRICE, 1))])
    227         sel = settings.user.ui.Get('contracts_search_sort_%s' % contractType, (cc.SORT_PRICE, 0) if contractType == cc.CONTYPE_AUCTIONANDITEMECHANGE else None)
    228         self.sortCombo.LoadOptions(opt, sel)
    229 
    230     def GetContractTypeSetting(self):
    231         return settings.user.ui.Get('contracts_search_type', cc.CONTYPE_AUCTIONANDITEMECHANGE)
    232 
    233     def GetContractFiltersMenu(self, *args):
    234         m = []
    235         m.append((MenuLabel('UI/Contracts/ContractsSearch/ExcludeUnreacable'), self.ToggleExcludeUnreachable, (None,)))
    236         m.append((MenuLabel('UI/Contracts/ContractsSearch/ExcludeIgnored'), self.ToggleExcludeIgnored, (None,)))
    237         return m
    238 
    239     def ToggleExcludeUnreachable(self, *args):
    240         k = 'contracts_search_client_excludeunreachable'
    241         v = 0 if settings.user.ui.Get(k, 0) else 1
    242         settings.user.ui.Set(k, v)
    243         if self.currPage in self.pageData:
    244             self.RenderPage()
    245 
    246     def ToggleExcludeIgnored(self, *args):
    247         k = 'contracts_search_client_excludeignore'
    248         v = 0 if settings.user.ui.Get(k, 1) else 1
    249         settings.user.ui.Set(k, v)
    250         if self.currPage in self.pageData:
    251             self.RenderPage()
    252 
    253     def ReconstructLeftFilters(self):
    254         self.leftFilterScroll.Flush()
    255         contractType = self.GetContractTypeSetting()
    256         if contractType != const.conTypeCourier:
    257             self.ConstructTypeNameEdit()
    258         self.ConstructLocationCombo()
    259         self.ConstructAdvancedCont()
    260         if contractType != const.conTypeCourier:
    261             self.ConstructContractTypeCombo()
    262             self.ConstructContractCategoryCombo()
    263             self.ConstructContractGroupCombo()
    264             self.ConstructBuySellFilterCheckboxes()
    265             self.ConstructPriceEdits()
    266             self.fltDropOff = None
    267         elif contractType == const.conTypeCourier:
    268             self.ConstructDropOffEdit()
    269             self.ConstructRewardEdits()
    270             self.ConstructCollateralEdits()
    271             self.ConstructVolumeEdits()
    272         self.ConstructAvailabilityCombo()
    273         self.ConstrucSecurityCheckboxes()
    274         self.ConstructIssuerEdit()
    275         for editName in ['fltMinPrice',
    276          'fltMaxPrice',
    277          'fltMinReward',
    278          'fltMaxReward',
    279          'fltMinCollateral',
    280          'fltMaxCollateral',
    281          'fltMinVolume',
    282          'fltMaxVolume']:
    283             edit = getattr(self, editName, None)
    284             try:
    285                 if not settings.user.ui.Get('contracts_search_%s' % edit.name, ''):
    286                     edit.SetText('')
    287                     edit.CheckHintText()
    288             except:
    289                 sys.exc_clear()
    290 
    291         self.ReconstructBottomFilters(contractType)
    292 
    293     def ReconstructBottomFilters(self, contractType):
    294         self.bottomFilterCont.Flush()
    295         grid = LayoutGrid(parent=self.bottomFilterCont, align=uiconst.TOPLEFT, columns=3, left=14, cellSpacing=(8, 2))
    296         editWidth = 60
    297         totalHeight = 0
    298         self.fltClientExcludeNoGateToGateJumps = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/ExcludeNoGateToGateJumps'), settingsKey='contracts_search_client_excludeunreachable', checked=settings.user.ui.Get('contracts_search_client_excludeunreachable', 1), parent=grid, callback=self.FilterCheckBoxChange, align=uiconst.CENTERLEFT)
    299         jumpSettings = settings.user.ui.Get('contracts_search_client_maxjumps', 0)
    300         fltClientMaxJumps = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/labelMaximumJumps'), settingsKey='maxjumps', checked=jumpSettings, parent=grid, callback=self.FilterCheckBoxChange, align=uiconst.CENTERLEFT)
    301         numJumps = settings.user.ui.Get('contracts_search_client_maxjumps_num', 10)
    302         self.maxjumpsInput = SingleLineEditInteger(name='maxjumpsInput', parent=grid, align=uiconst.CENTERLEFT, pos=(0,
    303          0,
    304          editWidth,
    305          10), label='', setvalue=str(numJumps), hintText=localization.GetByLabel('UI/Contracts/ContractsSearch/hintMax'), maxValue=MAXJUMPROUTENUM, OnReturn=self.OnJumpInputReturn, OnFocusLost=self.OnJumpFocusLost)
    306         if not jumpSettings:
    307             self.maxjumpsInput.Disable()
    308         totalHeight += self.maxjumpsInput.height
    309         self.fltClientExcludeIgnore = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/ExcludeIgnored'), settingsKey='contracts_search_client_excludeignore', checked=settings.user.ui.Get('contracts_search_client_excludeignore', 1), parent=grid, callback=self.FilterCheckBoxChange, align=uiconst.CENTERLEFT)
    310         if contractType == const.conTypeCourier:
    311             routeSettings = settings.user.ui.Get('contracts_search_client_maxroute', 0)
    312             fltClientMaxRoute = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/labelMaxRoute'), settingsKey='maxroute', checked=routeSettings, parent=grid, callback=self.FilterCheckBoxChange, align=uiconst.CENTERLEFT)
    313             numRoute = settings.user.ui.Get('contracts_search_client_maxroute_num', 10)
    314             self.maxrouteInput = SingleLineEditInteger(name='maxrouteInput', parent=grid, align=uiconst.CENTERLEFT, pos=(0,
    315              0,
    316              editWidth,
    317              10), label='', setvalue=numRoute, hintText=localization.GetByLabel('UI/Contracts/ContractsSearch/hintMax'), maxValue=MAXJUMPROUTENUM, OnReturn=self.OnRouteInputReturn, OnFocusLost=self.OnRouteFocusLost)
    318             if not routeSettings:
    319                 self.maxrouteInput.Disable()
    320             totalHeight += self.maxrouteInput.height
    321         self.fltClientOnlyCurrentSecurity = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/OnlyCurrentSecurity'), settingsKey='contracts_search_client_currentsecurity', checked=settings.user.ui.Get('contracts_search_client_currentsecurity', 0), parent=grid, callback=self.FilterCheckBoxChange, pos=(0, 0, 160, 20), align=uiconst.CENTERLEFT)
    322         totalHeight += self.fltClientOnlyCurrentSecurity.height
    323         self.bottomFilterCont.height = totalHeight + 8
    324 
    325     def ConstructIssuerEdit(self):
    326         issuerID = settings.user.ui.Get('contracts_search_issuer_id', None)
    327         issuerName = ''
    328         if issuerID is not None:
    329             issuerName = cfg.eveowners.Get(issuerID).name
    330         self.fltIssuer = SingleLineEditText(name='issuer', parent=self.advancedCont, align=uiconst.TOTOP, padTop=8, setvalue=issuerName, hintText=localization.GetByLabel('UI/Contracts/ContractsSearch/columnIssuer'), OnReturn=self.ParseIssuers, OnChange=self.OnIssuerChange)
    331         self.fltIssuer.ShowClearButton(showOnLetterCount=3)
    332         self.OnIssuerChange(issuerName)
    333         self.fltIssuerID = issuerID
    334         self.fltIssuer.OnDropData = self.OnDropIssuer
    335 
    336     def ConstructAvailabilityCombo(self):
    337         contractAvailability = settings.user.ui.Get('contracts_search_avail', const.conAvailPublic)
    338         self.fltAvail = Combo(label=localization.GetByLabel('UI/Contracts/ContractsSearch/Availability'), parent=self.advancedCont, options=self.GetAvailabilityOptions(), name='avail', select=contractAvailability, callback=self.ComboChange, align=uiconst.TOTOP, padTop=24, uniqueUiName=pConst.UNIQUE_NAME_CONTRACT_AVAILABILITY_SETTINGS)
    339 
    340     def ConstrucSecurityCheckboxes(self):
    341         eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Contracts/ContractsSearch/SecurityFilters'), parent=self.advancedCont, state=uiconst.UI_DISABLED, align=uiconst.TOTOP, padTop=8)
    342         securityCont = FlowContainer(name='securityCont', parent=self.advancedCont, align=uiconst.TOTOP, contentSpacing=(8, 8))
    343         self.fltSecHigh = Checkbox(text=localization.GetByLabel('UI/Common/HighSecurityShort'), settingsKey='contracts_search_sechigh', checked=settings.user.ui.Get('contracts_search_sechigh', 1), parent=securityCont, callback=self.CheckBoxChange, hint=localization.GetByLabel('UI/Common/HighSec'), align=uiconst.NOALIGN)
    344         self.fltSecLow = Checkbox(text=localization.GetByLabel('UI/Common/LowSecurityShort'), settingsKey='contracts_search_seclow', checked=settings.user.ui.Get('contracts_search_seclow', 1), parent=securityCont, callback=self.CheckBoxChange, hint=localization.GetByLabel('UI/Common/LowSec'), align=uiconst.NOALIGN)
    345         self.fltSecNull = Checkbox(text=localization.GetByLabel('UI/Common/NullSecurityShort'), settingsKey='contracts_search_secnull', checked=settings.user.ui.Get('contracts_search_secnull', 1), parent=securityCont, callback=self.CheckBoxChange, hint=localization.GetByLabel('UI/Common/NullSec'), align=uiconst.NOALIGN)
    346 
    347     def ConstructVolumeEdits(self):
    348         vars = EditFieldVariables(headerText=localization.GetByLabel('UI/Contracts/ContractsSearch/columnVolume'), configName='fltVolume', fromConfigName='minvolume', fromMaxValue=None, fromSettingName='contracts_search_minvolume', toConfigName='maxvolume', toMaxValue=None, toSettingName='contracts_search_maxvolume')
    349         self.fltMinVolume, self.fltMaxVolume, self.fltCbVolume = self.ConstructFromToEditCont(self.advancedCont, vars)
    350 
    351     def ConstructCollateralEdits(self):
    352         vars = EditFieldVariables(headerText=localization.GetByLabel('UI/Contracts/ContractsSearch/CourierCollateralInMillions'), configName='fltCollateral', fromConfigName='mincollateral', fromMaxValue=MAX_NUM_MILLIONS, fromSettingName='contracts_search_mincollateral', toConfigName='maxcollateral', toMaxValue=MAX_NUM_MILLIONS, toSettingName='contracts_search_maxcollateral')
    353         self.fltMinCollateral, self.fltMaxCollateral, self.fltCbCollateral = self.ConstructFromToEditCont(self.advancedCont, vars)
    354 
    355     def ConstructRewardEdits(self):
    356         vars = EditFieldVariables(headerText=localization.GetByLabel('UI/Contracts/ContractsSearch/CourierRewardInMillions'), configName='fltReward', fromConfigName='minreward', fromMaxValue=MAX_NUM_MILLIONS, fromSettingName='contracts_search_minreward', toConfigName='maxreward', toMaxValue=MAX_NUM_MILLIONS, toSettingName='contracts_search_maxreward')
    357         self.fltMinReward, self.fltMaxReward, self.fltCbReward = self.ConstructFromToEditCont(self.advancedCont, vars)
    358 
    359     def ConstructFromToEditCont(self, parent, editVariables, padTop = 8):
    360         eveLabel.EveLabelSmall(text=editVariables.headerText, parent=parent, align=uiconst.TOTOP, top=padTop)
    361         cont = Container(name='cont', parent=parent, align=uiconst.TOTOP)
    362         innerCont = Container(name='innerCont', parent=cont, align=uiconst.TOALL)
    363         toEditCont = Container(name='toEditCont', parent=innerCont, align=uiconst.TOLEFT_PROP, width=0.5)
    364         fromSetValue = settings.user.ui.Get(editVariables.fromSettingName, '')
    365         fromEdit = SingleLineEditInteger(name=editVariables.fromConfigName, parent=toEditCont, width=EDIT_WIDTH, hintText=localization.GetByLabel('UI/Contracts/ContractsSearch/hintMin'), align=uiconst.TOTOP, maxValue=editVariables.fromMaxValue, setvalue=fromSetValue, OnReturn=self.DoSearch)
    366         cont.height = fromEdit.height
    367         toLabel = eveLabel.EveLabelSmall(text=localization.GetByLabel('UI/Common/ToNumber'), parent=innerCont, align=uiconst.CENTER)
    368         fromEditCont = Container(name='fromEditCont', parent=innerCont, align=uiconst.TORIGHT_PROP, width=0.5)
    369         toSetValue = settings.user.ui.Get(editVariables.toSettingName, '')
    370         toEdit = SingleLineEditInteger(name=editVariables.toConfigName, parent=fromEditCont, label='', hintText=localization.GetByLabel('UI/Contracts/ContractsSearch/hintMax'), align=uiconst.TOTOP, maxValue=editVariables.toMaxValue, setvalue=toSetValue, OnReturn=self.DoSearch)
    371         toEditCont.padRight = toLabel.width
    372         fromEditCont.padLeft = toLabel.width
    373 
    374         def SetState(cb):
    375             if cb.GetValue():
    376                 toEdit.Enable()
    377                 fromEdit.Enable()
    378                 innerCont.Enable()
    379                 toLabel.opacity = 0.75
    380             else:
    381                 toEdit.Disable()
    382                 fromEdit.Disable()
    383                 innerCont.Disable()
    384                 toLabel.opacity = 0.3
    385 
    386         cbConfigName = 'contracterSearch_%s_cbChecked' % editVariables.configName
    387         enabled_setting = UserSettingBool(settings_key=cbConfigName, default_value=True)
    388         filterCb = Checkbox(parent=cont, align=uiconst.CENTERLEFT, callback=SetState, setting=enabled_setting)
    389         innerCont.padLeft = filterCb.width
    390         SetState(filterCb)
    391         return (fromEdit, toEdit, filterCb)
    392 
    393     def ConstructDropOffEdit(self):
    394         self.fltDropOff = SingleLineEditText(name='dropoff', parent=self.advancedCont, setvalue=settings.user.ui.Get('contracts_search_dropoff', ''), padTop=8, align=uiconst.TOTOP, label='', hintText=localization.GetByLabel('UI/Contracts/ContractsSearch/DropOffLocation'), OnReturn=self.OnDropOffReturn, isLocationField=True)
    395         self.fltDropOff.ShowClearButton(showOnLetterCount=3)
    396         self.fltDropOffID = settings.user.ui.Get('contracts_search_dropoff_id', None)
    397 
    398     def GetAvailabilityOptions(self):
    399         options = [(localization.GetByLabel('UI/Generic/Public'), const.conAvailPublic), (localization.GetByLabel('UI/Contracts/ContractsWindow/Me'), const.conAvailMyself)]
    400         if not idCheckers.IsNPC(session.corpid):
    401             options.append((localization.GetByLabel('UI/Generic/MyCorp'), const.conAvailMyCorp))
    402         if session.allianceid:
    403             options.append((localization.GetByLabel('UI/Generic/MyAlliance'), const.conAvailMyAlliance))
    404         return options
    405 
    406     def ConstructPriceEdits(self):
    407         vars = EditFieldVariables(headerText=localization.GetByLabel('UI/Contracts/ContractsSearch/labelPriceMillions'), configName='fltPrice', fromConfigName='minprice', fromMaxValue=None, fromSettingName='contracts_search_minprice', toConfigName='maxprice', toMaxValue=None, toSettingName='contracts_search_maxprice')
    408         self.fltMinPrice, self.fltMaxPrice, self.fltCbPrice = self.ConstructFromToEditCont(self.advancedCont, vars)
    409 
    410     def ConstructBuySellFilterCheckboxes(self):
    411         self.fltExcludeMultiple = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/labelExcludeMultipleItems'), settingsKey='contracts_search_excludemultiple', checked=settings.user.ui.Get('contracts_search_excludemultiple', 0), parent=self.advancedCont, callback=self.CheckBoxChange, padTop=4, align=uiconst.TOTOP)
    412         self.fltExactType = Checkbox(text=localization.GetByLabel('UI/Contracts/ContractsSearch/labelExactTypeMatch'), settingsKey='contracts_search_exacttype', checked=settings.user.ui.Get('contracts_search_exacttype', 0), parent=self.advancedCont, callback=self.CheckBoxChange)
    413 
    414     def ConstructContractGroupCombo(self):
    415         grpOptions = [(localization.GetByLabel('UI/Contracts/ContractsSearch/SelectCategory'), None)]
    416         self.fltGroups = Combo(label=localization.GetByLabel('UI/Contracts/ContractsSearch/contractroup'), parent=self.advancedCont, options=grpOptions, name='group', select=settings.user.ui.Get('contracts_search_group', None), align=uiconst.TOTOP, callback=self.ComboChange, padTop=24)
    417         self.PopulateGroupCombo(isSel=True)
    418 
    419     def ConstructContractCategoryCombo(self):
    420         self.fltCategories = Combo(label=localization.GetByLabel('UI/Contracts/ContractsSearch/ContractCategory'), parent=self.advancedCont, options=self.GetContractCategoryOptions(), name='category', select=settings.user.ui.Get('contracts_search_category', None), align=uiconst.TOTOP, callback=self.ComboChange, padTop=24)
    421 
    422     def GetContractCategoryOptions(self):
    423         catOptions = [(localization.GetByLabel('UI/Contracts/ContractsSearch/comboAll'), None)]
    424         categories = []
    425         principalCategories = [const.categoryBlueprint,
    426          const.categoryModule,
    427          const.categoryStructureModule,
    428          const.categoryShip]
    429         for categoryID in evetypes.IterateCategories():
    430             if categoryID > 0 and evetypes.IsCategoryPublishedByCategory(categoryID) and categoryID not in principalCategories:
    431                 categories.append([evetypes.GetCategoryNameByCategory(categoryID), categoryID, 0])
    432 
    433         categories.sort()
    434         for catID in principalCategories:
    435             categoryName = evetypes.GetCategoryNameByCategory(catID)
    436             catOptions.append([categoryName, (catID, 0)])
    437             if catID == const.categoryBlueprint:
    438                 catOptions.append([localization.GetByLabel('UI/Contracts/ContractsSearch/BlueprintCategoryOriginal', categoryName=categoryName), (catID, cc.SEARCHHINT_BPO)])
    439                 catOptions.append([localization.GetByLabel('UI/Contracts/ContractsSearch/BlueprintCategoryCopy', categoryName=categoryName), (catID, cc.SEARCHHINT_BPC)])
    440 
    441         catOptions.append(['', -1])
    442         for c in categories:
    443             catOptions.append((c[0], (c[1], c[2])))
    444 
    445         return catOptions
    446 
    447     def ConstructContractTypeCombo(self):
    448         self.fltContractOptions = Combo(label=localization.GetByLabel('UI/Contracts/ContractsWindow/ContractType'), parent=self.advancedCont, options=CONTRACT_TYPE_OPTIONS, name='contractOptions', select=settings.user.ui.Get('contracts_search_contractOptions', None), align=uiconst.TOTOP, callback=self.ComboChange, padTop=24)
    449 
    450     def ConstructAdvancedCont(self):
    451         self.advancedCont = ContainerAutoSize(name='advancedCont', parent=self.leftFilterScroll, align=uiconst.TOTOP)
    452         isExpanded = settings.user.ui.Get('contracts_search_expander_advanced', 0)
    453         expanderCont = Container(name='advanced', parent=self.leftFilterScroll, height=18, align=uiconst.TOTOP, state=uiconst.UI_NORMAL, padTop=8, uniqueUiName=pConst.UNIQUE_NAME_SHOW_CONTRACT_OPTIONS)
    454         expanderCont.onText = localization.GetByLabel('UI/Contracts/ContractsSearch/buttonShowLessOptions')
    455         expanderCont.offText = localization.GetByLabel('UI/Contracts/ContractsSearch/buttonShowMoreOptions')
    456         expanderCont.collapsingCont = self.advancedCont
    457         expandText = [localization.GetByLabel('UI/Contracts/ContractsSearch/buttonShowMoreOptions'), localization.GetByLabel('UI/Contracts/ContractsSearch/buttonShowLessOptions')][isExpanded]
    458         expanderCont.label = eveLabel.EveLabelSmallBold(parent=expanderCont, align=uiconst.CENTERLEFT, state=uiconst.UI_DISABLED, text=expandText)
    459         expanderCont.OnClick = (self.ToggleAdvanced, expanderCont)
    460         texturePath = 'res:/UI/Texture/classes/Neocom/arrowUp.png' if isExpanded else 'res:/UI/Texture/classes/Neocom/arrowDown.png'
    461         expanderCont.expander = Sprite(parent=expanderCont, align=uiconst.CENTERRIGHT, state=uiconst.UI_DISABLED, width=7, height=7, texturePath=texturePath)
    462         self.advancedCont.state = [uiconst.UI_HIDDEN, uiconst.UI_PICKCHILDREN][isExpanded]
    463         self.advancedDivider = expanderCont
    464 
    465     def ConstructLocationCombo(self):
    466         self.fltLocation = Combo(label=localization.GetByLabel('UI/Common/Location'), parent=self.leftFilterScroll, align=uiconst.TOTOP, padTop=24, options=[], name='location', callback=self.ComboChange)
    467         self.PopulateLocationCombo()
    468 
    469     def ConstructTypeNameEdit(self):
    470         self.typeName = SingleLineEditText(name='type', parent=self.leftFilterScroll, label='', hintText=localization.GetByLabel('UI/Wallet/WalletWindow/ItemType'), setvalue=settings.user.ui.Get('contracts_search_typename', ''), align=uiconst.TOTOP, padTop=8, OnReturn=self.DoSearch, isTypeField=True)
    471         self.typeName.ShowClearButton(showOnLetterCount=3)
    472 
    473     def ConstructBuySellOrCourierToggleButtons(self):
    474         buttonGroup = ToggleButtonGroup(parent=self.leftCont, align=uiconst.TOTOP, callback=self.OnButtonSelected, padding=(2, 8, 2, 0))
    475         buttonGroup.AddButton(cc.CONTYPE_AUCTIONANDITEMECHANGE, localization.GetByLabel('UI/Contracts/ContractsSearch/tabBuyAndSell'))
    476         buttonGroup.AddButton(appConst.conTypeCourier, localization.GetByLabel('UI/Contracts/ContractsSearch/tabCourier'))
    477         buttonGroup.SelectByID(self.GetContractTypeSetting())
    478 
    479     def SetInitialFocus(self):
    480         uicore.registry.SetFocus(self.contractsScroll)
    481 
    482     def OnButtonSelected(self, mode, *args):
    483         if mode == self.GetContractTypeSetting():
    484             return
    485         settings.user.ui.Set('contracts_search_type', mode)
    486         self.PopulateSortCombo()
    487         uthread.new(self.ReconstructLeftFilters)
    488 
    489     def ComboChange(self, wnd, *args):
    490         if wnd.name == 'sort':
    491             contractType = self.GetContractTypeSetting()
    492             settings.user.ui.Set('contracts_search_sort_%s' % contractType, wnd.GetValue())
    493         else:
    494             settings.user.ui.Set('contracts_search_%s' % wnd.name, wnd.GetValue())
    495         if wnd.name == 'category':
    496             self.PopulateGroupCombo()
    497         elif wnd.name == 'type':
    498             self.ReconstructLeftFilters()
    499         elif wnd.name == 'location':
    500             v = wnd.GetValue()
    501             if v == 10:
    502                 self.PickLocation()
    503         elif wnd.name == 'sort':
    504             val = wnd.GetValue()
    505             sortBy = localization.GetByLabel(CONTRACT_SEARCH_MAPPINGS.get(val[0], 'UI/Contracts/ContractsSearch/columnCreated'))
    506             pr = settings.user.ui.Get('scrollsortby_%s' % uiconst.SCROLLVERSION, {})
    507             pr[self.contractsScroll.sr.id] = (sortBy, not not val[1])
    508             if self.currPage in self.pageData:
    509                 self.DoSearch()
    510 
    511     def PickLocation(self):
    512         desc = localization.GetByLabel('UI/Contracts/ContractsSearch/labelEnterLocationName')
    513         ret = utilWindows.NamePopup(localization.GetByLabel('UI/Contracts/ContractsSearch/labelEnterName'), desc, '', maxLength=20)
    514         if ret:
    515             name = ret.lower()
    516             locationID = self.SearchLocation(name)
    517             if locationID:
    518                 self.DoPickLocation(locationID)
    519 
    520     def DoPickLocation(self, locationID):
    521         settings.user.ui.Set('contracts_search_location', locationID)
    522         customLocations = settings.user.ui.Get('contracts_search_customlocations', [])
    523         loc = (cfg.evelocations.Get(locationID).name, locationID)
    524         try:
    525             customLocations.remove(loc)
    526         except:
    527             pass
    528 
    529         customLocations.append(loc)
    530         if len(customLocations) > NUM_SAVED_LOCATIONS:
    531             del customLocations[0]
    532         settings.user.ui.Set('contracts_search_customlocations', customLocations)
    533         self.PopulateLocationCombo()
    534 
    535     def CheckBoxChange(self, wnd, *args):
    536         pass
    537 
    538     def GetClientFilterText(self):
    539         contractType = self.GetContractTypeSetting()
    540         excluded = ''
    541         for each, text, default in [('excludeunreachable', localization.GetByLabel('UI/Contracts/ContractsSearch/ExcludeUnreacable'), 1), ('excludeignore', localization.GetByLabel('UI/Contracts/ContractsSearch/ExcludeIgnored'), 1), ('currentsecurity', localization.GetByLabel('UI/Contracts/ContractsSearch/OnlyCurrentSecurity'), 0)]:
    542             isChecked = settings.user.ui.Get('contracts_search_client_%s' % each, default)
    543             if isChecked is None:
    544                 continue
    545             if isChecked:
    546                 excluded += '<br>%s' % text
    547 
    548         isChecked = settings.user.ui.Get('contracts_search_client_maxjumps', None)
    549         if isChecked:
    550             maxJumps = settings.user.ui.Get('contracts_search_client_maxjumps_num', '-')
    551             excluded += '<br>%s' % localization.GetByLabel('UI/Contracts/ContractsSearch/labelMaximumJumpsDisttance', maxJumps=maxJumps)
    552         if contractType == const.conTypeCourier:
    553             isChecked = settings.user.ui.Get('contracts_search_client_maxroute', None)
    554             if isChecked:
    555                 maxRoute = settings.user.ui.Get('contracts_search_client_maxroute_num', '-')
    556                 excluded += '<br>%s' % localization.GetByLabel('UI/Contracts/ContractsSearch/labelMaxRouteDistance', maxRoute=maxRoute)
    557         hintText = '<b>%s</b>' % localization.GetByLabel('UI/Contracts/ContractsSearch/hintPageFilter')
    558         if excluded:
    559             hintText += excluded
    560         else:
    561             hintText += '<br>%s' % localization.GetByLabel('UI/Common/Show all')
    562         return hintText
    563 
    564     def UpdatePaging(self, currentPage, numPages):
    565         self.pagingCont.Flush()
    566         if numPages == 1:
    567             self.pageBackBtn.state = uiconst.UI_HIDDEN
    568             self.pageFwdBtn.state = uiconst.UI_HIDDEN
    569             return
    570         currentRange = (currentPage - 1) / PAGINGRANGE * PAGINGRANGE
    571         pages = []
    572         for i in xrange(0, PAGINGRANGE):
    573             page = currentRange + i
    574             if page >= numPages:
    575                 break
    576             pages.append(page)
    577 
    578         for i, pageNum in enumerate(pages):
    579             PageLink(name='pageNum', parent=self.pagingCont, align=uiconst.TOLEFT, left=0 if i == 0 else 4, label=str(pageNum + 1), onClick=lambda page = pageNum: self.GoToPage(page), selected=pageNum + 1 == currentPage)
    580 
    581         self.pageArea.width = 25 * len(pages) + 40
    582         backState = uiconst.UI_NORMAL
    583         if currentPage <= 1:
    584             backState = uiconst.UI_HIDDEN
    585         fwdState = uiconst.UI_NORMAL
    586         if currentPage >= numPages:
    587             fwdState = uiconst.UI_HIDDEN
    588         self.pageBackBtn.state = backState
    589         self.pageFwdBtn.state = fwdState
    590         self.pagingCont.width = 24 * len(pages) - 4
    591 
    592     def ToggleAdvanced(self, expanderCont, force = None, *args):
    593         settingsName = 'contracts_search_expander_%s' % expanderCont.name
    594         if force is None:
    595             expanded = not settings.user.ui.Get(settingsName, 0)
    596         else:
    597             expanded = force
    598         settings.user.ui.Set(settingsName, expanded)
    599         if expanded:
    600             expanderCont.expander.texturePath = 'res:/UI/Texture/classes/Neocom/arrowUp.png'
    601         else:
    602             expanderCont.expander.texturePath = 'res:/UI/Texture/classes/Neocom/arrowDown.png'
    603         expanderCont.label.text = [expanderCont.offText, expanderCont.onText][expanded]
    604         if expanded:
    605             expanderCont.collapsingCont.state = uiconst.UI_PICKCHILDREN
    606         else:
    607             expanderCont.collapsingCont.state = uiconst.UI_HIDDEN
    608 
    609     def ToggleClientFiltersOnLabelClick(self, *args):
    610         isExpanded = not self.collapseLine.isCollapsedSetting.get()
    611         if isExpanded:
    612             self.collapseLine.SetCollapsed()
    613         else:
    614             self.collapseLine.SetExpanded()
    615 
    616     def ToggleClientFilters(self, *args):
    617         settingsName = 'contracts_search_expander_clientFilterExpander'
    618         expanded = not settings.user.ui.Get(settingsName, 0)
    619         settings.user.ui.Set(settingsName, expanded)
    620         self.UpdateClientFilterHint()
    621 
    622     def UpdateClientFilterHint(self):
    623         expanded = settings.user.ui.Get('contracts_search_expander_clientFilterExpander', 0)
    624         if expanded:
    625             self.bottomFilterCont.state = uiconst.UI_PICKCHILDREN
    626         else:
    627             self.bottomFilterCont.state = uiconst.UI_HIDDEN
    628         hint = self.GetClientFilterText()
    629         self.collapseLine.SetHint(hint)
    630 
    631     def FilterCheckBoxChange(self, cb, *args):
    632         if cb.settingsKey in ('maxjumps', 'maxroute'):
    633             cfgname = 'contracts_search_client_%s' % cb.settingsKey
    634             cfgnameNum = '%s_num' % cfgname
    635             inputField = getattr(self, '%sInput' % cb.settingsKey, None)
    636             if cb.checked:
    637                 inputField.Enable()
    638                 input = inputField.GetValue()
    639                 num = min(input, MAXJUMPROUTENUM)
    640                 inputField.SetValue(str(num))
    641                 settings.user.ui.Set(cfgname, 1)
    642                 settings.user.ui.Set(cfgnameNum, num)
    643             else:
    644                 inputField.Disable()
    645                 settings.user.ui.Set(cfgname, 0)
    646         self.UpdateClientFilterHint()
    647         if self.currPage in self.pageData:
    648             self.RenderPage()
    649 
    650     def OnJumpInputReturn(self, *args):
    651         value = min(self.maxjumpsInput.GetValue(), MAXJUMPROUTENUM)
    652         settings.user.ui.Set('contracts_search_client_maxjumps_num', value)
    653         self.UpdateClientFilterHint()
    654         if self.currPage in self.pageData:
    655             self.RenderPage()
    656 
    657     def OnJumpFocusLost(self, *args):
    658         value = min(self.maxjumpsInput.GetValue(), MAXJUMPROUTENUM)
    659         settingsValue = settings.user.ui.Get('contracts_search_client_maxjumps_num', MAXJUMPROUTENUM)
    660         if settingsValue != value:
    661             self.OnJumpInputReturn()
    662 
    663     def OnRouteInputReturn(self, *args):
    664         value = min(self.maxrouteInput.GetValue(), MAXJUMPROUTENUM)
    665         settings.user.ui.Set('contracts_search_client_maxroute_num', value)
    666         if self.currPage in self.pageData:
    667             self.RenderPage()
    668 
    669     def OnRouteFocusLost(self, *args):
    670         value = min(self.maxrouteInput.GetValue(), MAXJUMPROUTENUM)
    671         settingsValue = settings.user.ui.Get('contracts_search_client_maxroute_num', MAXJUMPROUTENUM)
    672         if settingsValue != value:
    673             self.OnJumpInputReturn()
    674 
    675     def OnDropOffReturn(self, *args):
    676         self.ParseDropOff()
    677         self.DoSearch()
    678 
    679     def OnDropIssuer(self, dragObj, nodes):
    680         node = nodes[0]
    681         if node.Get('__guid__', None) not in AllUserEntries():
    682             return
    683         charID = node.charID
    684         if idCheckers.IsCharacter(charID) or idCheckers.IsCorporation(charID):
    685             issuerName = cfg.eveowners.Get(charID).name
    686             self.fltIssuer.SetValue(issuerName)
    687             self.fltIssuerID = charID
    688 
    689     def OnDropType(self, dragObj, nodes):
    690         node = nodes[0]
    691         guid = node.Get('__guid__', None)
    692         typeID = None
    693         if guid in ('xtriui.InvItem', 'listentry.InvItem'):
    694             typeID = getattr(node.item, 'typeID', None)
    695         elif guid in ('listentry.GenericMarketItem', 'listentry.QuickbarItem'):
    696             typeID = getattr(node, 'typeID', None)
    697         if typeID:
    698             typeName = evetypes.GetName(typeID)
    699             self.typeName.SetValue(typeName)
    700             self.fltExactType.SetChecked(1, 0)
    701 
    702     def PopulateLocationCombo(self):
    703         self.locationOptions = [(localization.GetByLabel('UI/Generic/CurrentStation'), 0),
    704          (localization.GetByLabel('UI/Generic/CurrentSystem'), 1),
    705          (localization.GetByLabel('UI/Generic/CurrentConstellation'), 3),
    706          (localization.GetByLabel('UI/Corporations/Assets/CurrentRegion'), 2),
    707          (localization.GetByLabel('UI/Corporations/Assets/AllRegions'), 7),
    708          (localization.GetByLabel('UI/Contracts/ContractsSearch/PickLocation'), 10)]
    709         settingsLocationID = settings.user.ui.Get('contracts_search_location', 2)
    710         customLocations = copy.copy(settings.user.ui.Get('contracts_search_customlocations', []))
    711         customLocations.reverse()
    712         if customLocations:
    713             mrk = ''
    714             self.locationOptions.append((mrk, None))
    715             for l in customLocations:
    716                 self.locationOptions.append((l[0], l[1]))
    717 
    718         if settingsLocationID is not None and settingsLocationID > 100:
    719             try:
    720                 self.locationOptions.insert(0, (cfg.evelocations.Get(settingsLocationID).name, settingsLocationID))
    721             except:
    722                 pass
    723 
    724         self.fltLocation.LoadOptions(self.locationOptions, settingsLocationID)
    725 
    726     def PopulateGroupCombo(self, isSel = False):
    727         v = self.fltCategories.GetValue()
    728         categoryID = v[0] if v and v != -1 else None
    729         groups = [(localization.GetByLabel('UI/Contracts/ContractsSearch/SelectCategory'), None)]
    730         if categoryID and evetypes.CategoryExists(categoryID):
    731             groups = []
    732             for groupID in evetypes.GetGroupIDsByCategory(categoryID):
    733                 if evetypes.IsGroupPublishedByGroup(groupID):
    734                     groups.append((evetypes.GetGroupNameByGroup(groupID), groupID))
    735 
    736             groups.sort(key=lambda x: x[0].lower())
    737             groups.insert(0, (localization.GetByLabel('UI/Contracts/ContractsSearch/comboAll'), None))
    738         sel = None
    739         if isSel:
    740             sel = settings.user.ui.Get('contracts_search_group', None)
    741         self.fltGroups.LoadOptions(groups, sel)
    742         if categoryID is None:
    743             self.fltGroups.state = uiconst.UI_HIDDEN
    744         else:
    745             self.fltGroups.state = uiconst.UI_NORMAL
    746 
    747     def Load(self, args):
    748         if not self.inited:
    749             return
    750 
    751     def Height(self):
    752         return self.height or self.absoluteBottom - self.absoluteTop
    753 
    754     def Width(self):
    755         return self.width or self.absoluteRight - self.absoluteLeft
    756 
    757     def ShowLoad(self):
    758         from eve.client.script.ui.shared.neocom.contracts.contractsWnd import ContractsWindow
    759         ContractsWindow.GetIfOpen().ShowLoad()
    760 
    761     def HideLoad(self):
    762         from eve.client.script.ui.shared.neocom.contracts.contractsWnd import ContractsWindow
    763         ContractsWindow.GetIfOpen().HideLoad()
    764 
    765     def DoSearch(self, *args):
    766         if self.searchBtn.state == uiconst.UI_DISABLED:
    767             raise UserError('ConPleaseWait')
    768         PlaySound(uiconst.SOUND_BUTTON_CLICK)
    769         self.pageData = {}
    770         self.searchBtn.state = uiconst.UI_DISABLED
    771         self.searchBtn.SetLabel('<color=gray>' + localization.GetByLabel('UI/Contracts/ContractsSearch/buttonSearch') + '</color>')
    772         uthread.new(self.EnableSearchButton)
    773         self.ShowLoad()
    774         try:
    775             self.SearchContracts(reset=True)
    776         finally:
    777             self.HideLoad()
    778             self.IndicateLoading(loading=0)
    779 
    780     def EnableSearchButton(self):
    781         blue.pyos.synchro.SleepWallclock(2000)
    782         try:
    783             self.searchBtn.state = uiconst.UI_NORMAL
    784             self.searchBtn.SetLabel(localization.GetByLabel('UI/Contracts/ContractsSearch/buttonSearch'))
    785         except:
    786             pass
    787 
    788     def GoToPage(self, pageNum):
    789         if pageNum < 0:
    790             return
    791         if pageNum >= self.numPages:
    792             return
    793         self.currPage = pageNum
    794         self.DoPage(nav=0)
    795 
    796     def DoPagePrev(self, *args):
    797         self.DoPage(-1)
    798 
    799     def DoPageNext(self, *args):
    800         self.DoPage(1)
    801 
    802     def DoPage(self, nav = 1, *args):
    803         p = self.currPage + nav
    804         if p < 0:
    805             return
    806         if p >= self.numPages:
    807             return
    808         self.currPage = p
    809         if self.currPage in self.pageData:
    810             self.contractsSvc.LogInfo('Page', self.currPage, 'found in cache')
    811             self.RenderPage()
    812             return
    813         self.contractsSvc.LogInfo('Page', self.currPage, 'not found in cache')
    814         if self.searchThread:
    815             self.searchThread.kill()
    816         self.searchThread = uthread.new(self.DoPageThread)
    817 
    818     def DoPageThread(self):
    819         self.IndicateLoading(loading=1)
    820         blue.pyos.synchro.SleepWallclock(500)
    821         self.SearchContracts(page=self.currPage, contractType=self.contractType, availability=self.availability, override=self.override)
    822 
    823     def OnIssuerChange(self, text, *args):
    824         if self.fltIssuerID is not None:
    825             self.fltIssuerID = None
    826             settings.user.ui.Set('contracts_search_issuer_id', None)
    827 
    828     def ClearEditField(self, editField, *args):
    829         editField.SetValue('')
    830 
    831     def ParseIssuers(self, *args):
    832         if self.destroyed:
    833             return
    834         wnd = self.fltIssuer
    835         if not wnd or wnd.destroyed:
    836             return
    837         name = wnd.GetValue().strip()
    838         if not name:
    839             return
    840         ownerID = searchOld.Search(name.lower(), const.groupCharacter, const.categoryOwner, hideNPC=1, searchWndName='contractIssuerSearch')
    841         if ownerID:
    842             self.fltIssuer.SetValue(cfg.eveowners.Get(ownerID).name)
    843             self.fltIssuerID = ownerID
    844 
    845     def GetLocationGroupID(self, locationID):
    846         if idCheckers.IsSolarSystem(locationID):
    847             return const.groupSolarSystem
    848         if idCheckers.IsConstellation(locationID):
    849             return const.groupConstellation
    850         if idCheckers.IsRegion(locationID):
    851             return const.groupRegion
    852 
    853     def ParseDropOff(self, *args):
    854         if self.destroyed:
    855             return
    856         wnd = self.fltDropOff
    857         if not wnd or wnd.destroyed:
    858             return
    859         name = wnd.GetValue().strip().lower()
    860         locationID = self.SearchLocation(name)
    861         if locationID:
    862             name = cfg.evelocations.Get(locationID).name
    863             self.fltDropOffID = locationID
    864             wnd.SetValue(name)
    865 
    866     def SearchLocation(self, name):
    867         if not name:
    868             return None
    869         resultList = searchUtil.GetResultsList(name, search_const.location_result_types)
    870         foundList = []
    871         for l in resultList:
    872             groupID = self.GetLocationGroupID(l)
    873             if not groupID:
    874                 continue
    875             groupName = {const.groupSolarSystem: localization.GetByLabel('UI/Common/LocationTypes/SolarSystem'),
    876              const.groupConstellation: localization.GetByLabel('UI/Common/LocationTypes/Constellation'),
    877              const.groupRegion: localization.GetByLabel('UI/Common/LocationTypes/Region')}.get(groupID, '')
    878             foundList.append((localization.GetByLabel('UI/Contracts/ContractsSearch/FormatSearchLocation', locationID=l, groupName=groupName), l, groupID))
    879 
    880         if not foundList:
    881             raise UserError('NoLocationFound', {'name': name})
    882         if len(foundList) == 1:
    883             chosen = foundList[0]
    884         else:
    885             chosen = uix.ListWnd(foundList, '', localization.GetByLabel('UI/Contracts/ContractsSearch/SelectLocation'), localization.GetByLabel('UI/Contracts/ContractsSearch/LocationSearchHint', foundList=len(foundList)), 1, minChoices=1, isModal=1, windowName='locationsearch', unstackable=1)
    886         if chosen:
    887             return chosen[1]
    888         else:
    889             return None
    890 
    891     def ResetTypeFilters(self):
    892         self.typeName.SetValue('')
    893         self.fltExactType.SetChecked(0, 0)
    894         self.fltCategories.SelectItemByValue(None)
    895         settings.user.ui.Set('contracts_search_category', None)
    896         self.PopulateGroupCombo()
    897 
    898     def ResetFields(self, *args):
    899         fields = ['fltMaxPrice',
    900          'fltMinPrice',
    901          'fltMaxVolume',
    902          'fltMinVolume',
    903          'fltMaxCollateral',
    904          'fltMinCollateral',
    905          'fltMinReward',
    906          'fltMaxReward']
    907         for name in fields:
    908             field = getattr(self, name, None)
    909             if field is None or field.destroyed:
    910                 continue
    911             field.SetValue('')
    912             field.SetText('')
    913             field.CheckHintText()
    914 
    915         if self.fltDropOff:
    916             self.fltDropOff.SetValue('')
    917             self.fltDropOffID = None
    918         if self.fltIssuer:
    919             self.fltIssuer.SetValue('')
    920         self.fltIssuerID = None
    921         try:
    922             if self.fltDropOff:
    923                 self.fltDropOff.SetValue('')
    924                 self.fltDropOffID = None
    925         except:
    926             pass
    927 
    928     def ResetCheckboxes(self, *args):
    929         checkboxes = [('fltExcludeTrade', 0),
    930          ('fltExcludeMultiple', 0),
    931          ('fltSecNull', 1),
    932          ('fltSecLow', 1),
    933          ('fltSecHigh', 1)]
    934         for name, val in checkboxes:
    935             cb = getattr(self, name, None)
    936             if cb is None or cb.destroyed:
    937                 continue
    938             cb.SetValue(val)
    939 
    940     def FindMyContracts(self, contractType = cc.CONTYPE_AUCTIONANDITEMECHANGE, isCorp = False):
    941         self.SearchContracts(contractType=contractType, availability=const.conAvailMyCorp if isCorp else const.conAvailMyself, override=True)
    942 
    943     def FindRelated(self, typeID, groupID, categoryID, issuerID, locationID, endLocationID, avail, contractType, reset = True):
    944         self.ToggleAdvanced(expanderCont=self.advancedDivider, force=1)
    945         if contractType and self.GetContractTypeSetting() != contractType:
    946             settings.user.ui.Set('contracts_search_type', contractType)
    947             self.PopulateSortCombo()
    948             self.ReconstructLeftFilters()
    949         if reset:
    950             if self.fltAvail.GetValue() != avail:
    951                 settings.user.ui.Set('contracts_search_avail', avail)
    952                 self.ReconstructLeftFilters()
    953             if contractType and contractType != const.conTypeCourier:
    954                 self.ResetTypeFilters()
    955             self.ResetFields()
    956             self.fltLocation.SelectItemByValue(7)
    957         if issuerID:
    958             issuerName = cfg.eveowners.Get(issuerID).name
    959             self.fltIssuer.SetValue(issuerName)
    960             self.fltIssuerID = issuerID
    961         if typeID:
    962             typeName = evetypes.GetName(typeID)
    963             self.typeName.SetValue(typeName)
    964             self.fltExactType.SetChecked(1, 0)
    965         elif categoryID:
    966             self.fltCategories.SelectItemByValue((categoryID, 0))
    967             self.PopulateGroupCombo()
    968         elif groupID:
    969             categoryID = evetypes.GetCategoryIDByGroup(groupID)
    970             self.fltCategories.SelectItemByValue((categoryID, 0))
    971             self.PopulateGroupCombo()
    972             self.fltGroups.SelectItemByValue(groupID)
    973         if locationID:
    974             self.DoPickLocation(locationID)
    975         if endLocationID:
    976             locationName = cfg.evelocations.Get(endLocationID).name
    977             self.fltDropOff.SetValue(locationName)
    978             self.fltDropOffID = endLocationID
    979         self.SearchContracts()
    980 
    981     def SearchContracts(self, page = 0, reset = False, contractType = None, availability = None, override = False):
    982         self.IndicateLoading(loading=1)
    983         self.currPage = page
    984         self.override = override
    985         self.contractType = contractType
    986         self.availability = availability
    987         advancedVisible = self.advancedCont.state != uiconst.UI_HIDDEN
    988         if override:
    989             itemTypes = None
    990             itemTypeName = None
    991             itemCategoryID = None
    992             itemGroupID = None
    993             contractType = contractType
    994             securityClasses = list(security_classes)
    995             locationID = None
    996             endLocationID = None
    997             issuerID = None
    998             minPrice = None
    999             maxPrice = None
   1000             minReward = None
   1001             maxReward = None
   1002             minCollateral = None
   1003             maxCollateral = None
   1004             minVolume = None
   1005             maxVolume = None
   1006             excludeTrade = False
   1007             excludeMultiple = False
   1008             excludeNoBuyout = False
   1009             availability = availability
   1010             searchHint = None
   1011         else:
   1012             issuerID = None
   1013             if advancedVisible:
   1014                 if self.fltIssuerID is None and self.fltIssuer.GetValue():
   1015                     self.ParseIssuers()
   1016                 if self.fltIssuerID:
   1017                     issuerID = self.fltIssuerID
   1018                     settings.user.ui.Set('contracts_search_issuer_id', issuerID)
   1019             if contractType is None:
   1020                 contractType = self.GetContractTypeSetting()
   1021             if availability is None:
   1022                 if advancedVisible:
   1023                     availability = self.fltAvail.GetValue()
   1024                 else:
   1025                     availability = const.conAvailPublic
   1026             locationID = self.fltLocation.GetValue()
   1027             if locationID < 100:
   1028                 if locationID == 0 and not (session.stationid or session.structureid):
   1029                     raise UserError('ConNotInStation')
   1030                 locationID = {0: session.stationid or session.structureid,
   1031                  1: session.solarsystemid2,
   1032                  2: session.regionid,
   1033                  3: session.constellationid}.get(locationID, None)
   1034             endLocationID = None
   1035             if advancedVisible and contractType == const.conTypeCourier:
   1036                 endLocationName = self.fltDropOff.GetValue()
   1037                 if endLocationName and self.fltDropOffID:
   1038                     endLocationID = self.fltDropOffID
   1039                     if endLocationID is None:
   1040                         raise UserError('ConDropOffNotFound', {'name': endLocationName})
   1041                 settings.user.ui.Set('contracts_search_dropoff', endLocationName or '')
   1042                 settings.user.ui.Set('contracts_search_dropoff_id', endLocationID)
   1043             securityClasses = None
   1044             if advancedVisible:
   1045                 secNull = not not self.fltSecNull.checked
   1046                 secLow = not not self.fltSecLow.checked
   1047                 secHigh = not not self.fltSecHigh.checked
   1048                 if False in (secNull, secLow, secHigh):
   1049                     securityClasses = []
   1050                     if secNull:
   1051                         securityClasses.append(securityClassZeroSec)
   1052                     if secLow:
   1053                         securityClasses.append(securityClassLowSec)
   1054                     if secHigh:
   1055                         securityClasses.append(securityClassHighSec)
   1056                         securityClasses.append(securityClassSafeSec)
   1057                     securityClasses = securityClasses or None
   1058             minPrice = None
   1059             maxPrice = None
   1060             if advancedVisible and const.conTypeCourier != contractType:
   1061                 if self.fltCbPrice.GetValue():
   1062                     m = self.fltMinPrice.GetValue()
   1063                     settings.user.ui.Set('contracts_search_minprice', m)
   1064                     if m:
   1065                         minPrice = int(m) * MILLION
   1066                     m = self.fltMaxPrice.GetValue()
   1067                     settings.user.ui.Set('contracts_search_maxprice', m)
   1068                     if m:
   1069                         maxPrice = int(m) * MILLION
   1070             minReward = None
   1071             maxReward = None
   1072             minCollateral = None
   1073             maxCollateral = None
   1074             minVolume = None
   1075             maxVolume = None
   1076             if advancedVisible and const.conTypeCourier == contractType:
   1077                 if self.fltCbReward.GetValue():
   1078                     m = self.fltMinReward.GetValue()
   1079                     settings.user.ui.Set('contracts_search_minreward', m)
   1080                     if m:
   1081                         minReward = int(m) * MILLION
   1082                     m = self.fltMaxReward.GetValue()
   1083                     settings.user.ui.Set('contracts_search_maxreward', m)
   1084                     if m:
   1085                         maxReward = int(m) * MILLION
   1086                 if self.fltCbCollateral.GetValue():
   1087                     m = self.fltMinCollateral.GetValue()
   1088                     settings.user.ui.Set('contracts_search_mincollateral', m)
   1089                     if m:
   1090                         minCollateral = int(m) * MILLION
   1091                     m = self.fltMaxCollateral.GetValue()
   1092                     settings.user.ui.Set('contracts_search_maxcollateral', m)
   1093                     if m:
   1094                         maxCollateral = int(m) * MILLION
   1095                 if self.fltCbVolume.GetValue():
   1096                     m = self.fltMinVolume.GetValue()
   1097                     settings.user.ui.Set('contracts_search_minvolume', m)
   1098                     if m:
   1099                         minVolume = int(m)
   1100                     m = self.fltMaxVolume.GetValue()
   1101                     settings.user.ui.Set('contracts_search_maxvolume', m)
   1102                     if m:
   1103                         maxVolume = int(m)
   1104             itemCategoryID = None
   1105             itemGroupID = None
   1106             itemTypes = None
   1107             excludeTrade = None
   1108             excludeMultiple = None
   1109             excludeNoBuyout = None
   1110             itemTypeName = None
   1111             searchHint = None
   1112             if contractType != const.conTypeCourier:
   1113                 isExact = False
   1114                 if advancedVisible:
   1115                     cv = self.fltCategories.GetValue()
   1116                     if cv and cv != -1:
   1117                         itemCategoryID = int(cv[0])
   1118                         searchHint = int(cv[1])
   1119                     if self.fltGroups.GetValue():
   1120                         itemGroupID = int(self.fltGroups.GetValue())
   1121                     isExact = self.fltExactType.checked
   1122                 typeName = self.typeName.GetValue()
   1123                 if typeName:
   1124                     metaLevels = []
   1125                     if '|' in typeName:
   1126                         lst = typeName.split('|')
   1127                         typeName = lst[0]
   1128                         metaNames = lst[1].lower()
   1129                         for metaName in metaNames.split(','):
   1130                             groupIDsByName = {'tech i': 1,
   1131                              'tech ii': 2,
   1132                              'tech iii': 14,
   1133                              'storyline': 3,
   1134                              'faction': 4,
   1135                              'officer': 5,
   1136                              'deadspace': 6}
   1137                             vals = groupIDsByName.values()
   1138                             legalGroups = {}
   1139                             for v in vals:
   1140                                 legalGroups[metaGroups.get_name(v)] = v
   1141 
   1142                             groupIDsByName = {k.lower():v for k, v in legalGroups.iteritems()}
   1143                             legalGroups = legalGroups.keys()
   1144                             legalGroups.sort()
   1145                             metaLevel = groupIDsByName.get(metaName, None)
   1146                             if metaName and metaLevel is None:
   1147                                 raise UserError('ConMetalevelNotFound', {'level': metaName,
   1148                                  'legal': ', '.join(legalGroups)})
   1149                             metaLevels.append(metaLevel)
   1150 
   1151                     groupOrCategory = ''
   1152                     if ':' in typeName:
   1153                         lst = typeName.split(':')
   1154                         groupOrCategory = lst[0].lower()
   1155                         found = False
   1156                         for groupID in evetypes.IterateGroups():
   1157                             if evetypes.GetGroupNameByGroup(groupID).lower() == groupOrCategory:
   1158                                 itemGroupID = groupID
   1159                                 itemCategoryID = evetypes.GetCategoryIDByGroup(groupID)
   1160                                 found = True
   1161                                 sm.GetService('contracts').LogInfo('Found group:', groupID)
   1162                                 break
   1163 
   1164                         for categoryID in evetypes.IterateCategories():
   1165                             if evetypes.GetCategoryNameByCategory(categoryID).lower() == groupOrCategory:
   1166                                 itemGroupID = None
   1167                                 itemCategoryID = categoryID
   1168                                 found = True
   1169                                 sm.GetService('contracts').LogInfo('Found category:', categoryID)
   1170                                 break
   1171 
   1172                         if found:
   1173                             typeName = lst[1]
   1174                         else:
   1175                             sm.GetService('contracts').LogInfo('Did not find group or category matching', groupOrCategory)
   1176                             groupOrCategory = ''
   1177                     itemTypes = self.GetTypesFromName(typeName, itemCategoryID, itemGroupID)
   1178                     if metaLevels:
   1179                         typeIDs = itemTypes.keys()
   1180                         itemTypes = set()
   1181                         for typeID in typeIDs:
   1182                             try:
   1183                                 tech = evetypes.GetTechLevel(typeID)
   1184                                 meta = evetypes.GetMetaGroupID(typeID)
   1185                                 if meta:
   1186                                     if meta in metaLevels:
   1187                                         itemTypes.add(typeID)
   1188                                 elif tech in metaLevels:
   1189                                     itemTypes.add(typeID)
   1190                             except:
   1191                                 pass
   1192 
   1193                     else:
   1194                         itemTypes = set(itemTypes.keys())
   1195                     if isExact and itemTypes:
   1196                         if len(itemTypes) > 1:
   1197                             for checkTypeID in itemTypes:
   1198                                 if evetypes.GetName(checkTypeID).lower() == typeName.lower():
   1199                                     typeID = checkTypeID
   1200                                     break
   1201                             else:
   1202                                 typeID = SelectItemTypeDlg(itemTypes)
   1203 
   1204                         else:
   1205                             typeID = list(itemTypes)[0]
   1206                         if not typeID:
   1207                             return
   1208                         name = evetypes.GetName(typeID)
   1209                         if groupOrCategory:
   1210                             name = '%s:%s' % (groupOrCategory, name)
   1211                         self.typeName.SetValue(name)
   1212                         itemTypes = {typeID: None}
   1213                 if not itemTypes and typeName:
   1214                     raise UserError('ConNoTypeMatchFound', {'name': typeName})
   1215                 itemTypeName = self.typeName.GetValue() or None
   1216                 settings.user.ui.Set('contracts_search_typename', itemTypeName or '')
   1217                 excludeMultiple = self.fltExcludeMultiple.checked
   1218                 if contractType != const.conTypeCourier:
   1219                     opt = self.fltContractOptions.GetValue()
   1220                     if opt:
   1221                         if opt == 1:
   1222                             contractType = const.conTypeAuction
   1223                         elif opt == 2:
   1224                             contractType = const.conTypeItemExchange
   1225                             if not minPrice:
   1226                                 minPrice = 1
   1227                             excludeTrade = True
   1228                         elif opt == 3:
   1229                             contractType = const.conTypeItemExchange
   1230                             if not maxPrice:
   1231                                 maxPrice = 0
   1232                         elif opt == 4:
   1233                             contractType = cc.CONTYPE_AUCTIONANDITEMECHANGE
   1234                             if not minPrice:
   1235                                 minPrice = 1
   1236                             excludeTrade = True
   1237         startNum = page * cc.CONTRACTS_PER_PAGE
   1238         sortBy, sortDir = self.sortCombo.GetValue()
   1239         description = None
   1240         ret = sm.ProxySvc('contractProxy').SearchContracts(itemTypes=itemTypes, itemTypeName=itemTypeName, itemCategoryID=itemCategoryID, itemGroupID=itemGroupID, contractType=contractType, securityClasses=securityClasses, locationID=locationID, endLocationID=endLocationID, issuerID=issuerID, minPrice=minPrice, maxPrice=maxPrice, minReward=minReward, maxReward=maxReward, minCollateral=minCollateral, maxCollateral=maxCollateral, minVolume=minVolume, maxVolume=maxVolume, excludeTrade=excludeTrade, excludeMultiple=excludeMultiple, excludeNoBuyout=excludeNoBuyout, availability=availability, description=description, searchHint=searchHint, sortBy=sortBy, sortDir=sortDir, startNum=startNum)
   1241         contracts = ret.contracts
   1242         numFound = ret.numFound
   1243         searchTime = ret.searchTime
   1244         maxResults = ret.maxResults
   1245         self.numPages = int(int(numFound) / cc.CONTRACTS_PER_PAGE)
   1246         if not numFound or self.numPages * cc.CONTRACTS_PER_PAGE < numFound:
   1247             self.numPages += 1
   1248         if numFound >= maxResults:
   1249             numFound = '%s+' % maxResults
   1250         if len(contracts) >= 2:
   1251             self.pages[self.currPage] = contracts[0].contract.contractID
   1252             self.pages[self.currPage + 1] = contracts[-1].contract.contractID - 1
   1253         ownerIDs = set()
   1254         for r in contracts:
   1255             ownerIDs.add(r.contract.issuerID)
   1256             ownerIDs.add(r.contract.issuerCorpID)
   1257             ownerIDs.add(r.contract.assigneeID)
   1258 
   1259         cfg.eveowners.Prime(ownerIDs)
   1260         self.contractsScroll.sr.id = None
   1261         pathfinderSvc = sm.GetService('clientPathfinderService')
   1262         securitySvc = sm.StartService('securitySvc')
   1263         jumpsCache = {}
   1264         routes = {}
   1265         data = []
   1266         for _c in contracts:
   1267             blue.pyos.BeNice()
   1268             items = _c.items
   1269             bids = _c.bids
   1270             c = _c.contract
   1271             typeID = None
   1272             routeLength = 0
   1273             if len(items) == 1:
   1274                 typeID = items[0].itemTypeID
   1275             if c.startStationID == session.stationid:
   1276                 numJumps = 0
   1277             elif c.startSolarSystemID == session.solarsystemid2:
   1278                 numJumps = 0
   1279             elif c.startSolarSystemID not in jumpsCache:
   1280                 numJumps = pathfinderSvc.GetAutopilotJumpCount(session.solarsystemid2, c.startSolarSystemID)
   1281                 jumpsCache[c.startSolarSystemID] = numJumps
   1282             else:
   1283                 numJumps = jumpsCache[c.startSolarSystemID]
   1284             route = None
   1285             if c.type == const.conTypeCourier:
   1286                 r = [c.startSolarSystemID, c.endSolarSystemID]
   1287                 r.sort()
   1288                 route = (r[0], r[1])
   1289                 if route not in routes:
   1290                     routes[route] = pathfinderSvc.GetAutopilotJumpCount(c.startSolarSystemID, c.endSolarSystemID)
   1291                 routeLength = routes[route]
   1292             startSecurityClass = None
   1293             endSecurityClass = None
   1294             if c.startSolarSystemID != session.solarsystemid2:
   1295                 startSecurityClass = int(securitySvc.get_modified_security_class(c.startSolarSystemID))
   1296             if c.endSolarSystemID and c.endSolarSystemID != session.solarsystemid2:
   1297                 endSecurityClass = int(securitySvc.get_modified_security_class(c.endSolarSystemID))
   1298             issuer = cfg.eveowners.Get(c.issuerCorpID if c.forCorp else c.issuerID).name
   1299             startSystemName = cfg.evelocations.Get(c.startSolarSystemID).name
   1300             endSystemName = cfg.evelocations.Get(c.endSolarSystemID).name
   1301             contractTitle = GetContractTitle(c, items)
   1302             getLabel = lambda columnName: localization.GetByLabel('UI/Contracts/ContractsSearch/%s' % columnName)
   1303             d = {'contract': c,
   1304              'title': contractTitle,
   1305              'startSolarSystemName': startSystemName,
   1306              'endSolarSystemName': endSystemName,
   1307              'issuer': issuer,
   1308              'searchresult': _c,
   1309              'contractItems': items,
   1310              'bids': bids,
   1311              'rec': '',
   1312              'text': '',
   1313              'label': '',
   1314              'typeID': typeID,
   1315              'numJumps': numJumps,
   1316              'routeLength': routeLength,
   1317              'route': route,
   1318              'startSecurityClass': startSecurityClass,
   1319              'endSecurityClass': endSecurityClass,
   1320              'dateIssued': c.dateIssued,
   1321              'sort_%s' % getLabel('columnCurrentBid'): (c.price if not bids else bids[0].amount, c.contractID),
   1322              'sort_%s' % getLabel('columnCollateral'): (c.collateral, c.contractID),
   1323              'sort_%s' % getLabel('columnLocation'): (startSystemName, c.contractID),
   1324              'sort_%s' % getLabel('columnPrice'): (int(c.price) or -int(c.reward), c.contractID),
   1325              'sort_%s' % getLabel('columnReward'): (c.reward, c.contractID),
   1326              'sort_%s' % getLabel('columnVolume'): (c.volume, c.contractID),
   1327              'sort_%s' % getLabel('columnContract'): (contractTitle, c.contractID),
   1328              'sort_%s' % getLabel('columnTimeLeft'): (c.dateExpired, c.contractID),
   1329              'sort_%s' % getLabel('columnJumps'): (numJumps, c.contractID),
   1330              'sort_%s' % getLabel('columPickup'): (startSystemName, c.contractID),
   1331              'sort_%s' % getLabel('columnDropOff'): (endSystemName, c.contractID),
   1332              'sort_%s' % getLabel('columnCreated'): c.dateIssued,
   1333              'sort_%s' % getLabel('columnIssuer'): issuer.lower(),
   1334              'sort_%s' % getLabel('columnBids'): bids,
   1335              'sort_%s' % getLabel('columnRoute'): (routeLength, c.contractID),
   1336              'sort_%s' % localization.GetByLabel('UI/Contracts/ContractsWindow/InfoByIssuer'): c.title.lower()}
   1337             data.append(d)
   1338 
   1339         self.numFound = numFound
   1340         self.contractType = contractType
   1341         self.pageData[self.currPage] = data
   1342         self.RenderPage()
   1343         self.contractsSvc.LogInfo('Found', numFound, 'contracts in %.4f seconds' % (searchTime / float(const.SEC)))
   1344 
   1345     def RenderPage(self):
   1346         self.contractsSvc.IsStationInaccessible.clear_memoized()
   1347         try:
   1348             data = self.pageData[self.currPage]
   1349             contractType = self.contractType
   1350             if contractType == cc.CONTYPE_AUCTIONANDITEMECHANGE:
   1351                 contractType = const.conTypeItemExchange
   1352             scrolllist = []
   1353             entryType = {const.conTypeAuction: ContractEntrySearchAuction,
   1354              const.conTypeItemExchange: ContractEntrySearchItemExchange,
   1355              const.conTypeCourier: ContractEntrySearchCourier}[contractType]
   1356             securityClassMe = sm.GetService('securitySvc').get_modified_security_class(session.solarsystemid2)
   1357             ignoreList = set(settings.user.ui.Get('contracts_ignorelist', []))
   1358             numContractsFiltered = 0
   1359             for d in data:
   1360                 contract = d['contract']
   1361                 if settings.user.ui.Get('contracts_search_client_maxjumps', False):
   1362                     maxNumJumps = settings.user.ui.Get('contracts_search_client_maxjumps_num', None)
   1363                     if maxNumJumps is not None and d['numJumps'] > maxNumJumps:
   1364                         numContractsFiltered += 1
   1365                         continue
   1366                 if d['route'] and settings.user.ui.Get('contracts_search_client_maxroute', False):
   1367                     maxNumJumps = settings.user.ui.Get('contracts_search_client_maxroute_num', 0)
   1368                     if maxNumJumps and d['routeLength'] > maxNumJumps:
   1369                         numContractsFiltered += 1
   1370                         continue
   1371                 if settings.user.ui.Get('contracts_search_client_excludeunreachable', 1):
   1372                     if d['numJumps'] > cc.NUMJUMPS_UNREACHABLE or d['routeLength'] > cc.NUMJUMPS_UNREACHABLE or self.contractsSvc.IsStationInaccessible(contract.startStationID) or self.contractsSvc.IsStationInaccessible(contract.endStationID):
   1373                         numContractsFiltered += 1
   1374                         continue
   1375                 if settings.user.ui.Get('contracts_search_client_excludeignore', 1):
   1376                     skipIt = False
   1377                     for ownerID in ignoreList:
   1378                         if ownerID in [contract.issuerID, contract.issuerCorpID]:
   1379                             skipIt = True
   1380                             break
   1381 
   1382                     if skipIt:
   1383                         numContractsFiltered += 1
   1384                         continue
   1385                 if settings.user.ui.Get('contracts_search_client_currentsecurity', False):
   1386                     if d['startSecurityClass'] is not None and d['startSecurityClass'] != securityClassMe:
   1387                         numContractsFiltered += 1
   1388                         continue
   1389                     if d['endSecurityClass'] is not None and d['endSecurityClass'] != securityClassMe:
   1390                         numContractsFiltered += 1
   1391                         continue
   1392                 scrolllist.append(GetFromClass(entryType, d))
   1393 
   1394             if contractType == const.conTypeItemExchange:
   1395                 columns = [localization.GetByLabel('UI/Contracts/ContractsSearch/columnContract'),
   1396                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnLocation'),
   1397                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnPrice'),
   1398                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnJumps'),
   1399                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnTimeLeft'),
   1400                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnIssuer'),
   1401                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnCreated'),
   1402                  localization.GetByLabel('UI/Contracts/ContractsWindow/InfoByIssuer')]
   1403             elif contractType == const.conTypeAuction:
   1404                 columns = [localization.GetByLabel('UI/Contracts/ContractsSearch/columnContract'),
   1405                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnLocation'),
   1406                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnCurrentBid'),
   1407                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnBuyOut'),
   1408                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnBids'),
   1409                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnJumps'),
   1410                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnTimeLeft'),
   1411                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnIssuer'),
   1412                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnCreated'),
   1413                  localization.GetByLabel('UI/Contracts/ContractsWindow/InfoByIssuer')]
   1414             else:
   1415                 columns = [localization.GetByLabel('UI/Contracts/ContractsSearch/columPickup'),
   1416                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnDropOff'),
   1417                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnVolume'),
   1418                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnReward'),
   1419                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnCollateral'),
   1420                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnRoute'),
   1421                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnJumps'),
   1422                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnTimeLeft'),
   1423                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnIssuer'),
   1424                  localization.GetByLabel('UI/Contracts/ContractsSearch/columnCreated'),
   1425                  localization.GetByLabel('UI/Contracts/ContractsWindow/InfoByIssuer')]
   1426             self.contractsScroll.sr.id = 'contractlist'
   1427             self.contractsScroll.sr.minColumnWidth = {localization.GetByLabel('UI/Contracts/ContractsSearch/columnContract'): 100,
   1428              localization.GetByLabel('UI/Contracts/ContractsSearch/columnBuyOut'): 200}
   1429             self.contractsScroll.LoadContent(contentList=scrolllist, headers=columns, noContentHint=localization.GetByLabel('UI/Contracts/ContractsSearch/labelNoContractsFound'), ignoreSort=False, scrolltotop=True)
   1430             txt = localization.GetByLabel('UI/Contracts/ContractsSearch/labelNumberContractsFound', num=self.numFound)
   1431             if numContractsFiltered:
   1432                 txt += localization.GetByLabel('UI/Contracts/ContractsSearch/ContractsFilteredOut', numFilteredOut=numContractsFiltered)
   1433             self.foundLabel.SetText(txt)
   1434             self.UpdatePaging(self.currPage + 1, self.numPages)
   1435         finally:
   1436             self.IndicateLoading(loading=0)
   1437 
   1438     def IndicateLoading(self, loading = 0):
   1439         try:
   1440             if loading:
   1441                 self.loadingWheel.Show()
   1442                 self.contractsScroll.sr.maincontainer.opacity = 0.5
   1443             else:
   1444                 self.loadingWheel.Hide()
   1445                 self.contractsScroll.sr.maincontainer.opacity = 1.0
   1446         except:
   1447             pass
   1448 
   1449     def DoNothing(self, *args):
   1450         pass
   1451 
   1452 
   1453 class PageLink(Container):
   1454 
   1455     def __init__(self, parent, label, onClick, selected = False, align = uiconst.TOPLEFT, left = 0, name = None):
   1456         self._label = label
   1457         self._onClick = onClick
   1458         self._selected = selected
   1459         super(PageLink, self).__init__(name=name or 'PageLink', parent=parent, align=align, state=uiconst.UI_NORMAL, left=left, width=20, height=20)
   1460         eveLabel.EveLabelMedium(parent=self, align=uiconst.CENTER, text=self._label, bold=self._selected)
   1461         self._background = Fill(parent=self, align=uiconst.TOALL, opacity=0.05 if self._selected else 0.0)
   1462 
   1463     def OnMouseEnter(self, *args):
   1464         if not self._selected:
   1465             animations.FadeIn(self._background, endVal=0.2, duration=0.1)
   1466 
   1467     def OnMouseExit(self, *args):
   1468         if not self._selected:
   1469             animations.FadeTo(self._background, endVal=0.05 if self._selected else 0.0, duration=0.3)
   1470 
   1471     def OnClick(self, *args):
   1472         if not self._selected:
   1473             self._onClick()
   1474 
   1475 
   1476 class EditFieldVariables(object):
   1477 
   1478     def __init__(self, headerText, configName, fromConfigName, fromMaxValue, fromSettingName, toConfigName, toMaxValue, toSettingName):
   1479         self.headerText = headerText
   1480         self.configName = configName
   1481         self.fromConfigName = fromConfigName
   1482         self.fromMaxValue = fromMaxValue
   1483         self.fromSettingName = fromSettingName
   1484         self.toConfigName = toConfigName
   1485         self.toMaxValue = toMaxValue
   1486         self.toSettingName = toSettingName