Example #1
0
class SellBuyItemsWindow(Window):
    __notifyevents__ = ['OnSessionChanged']
    default_width = 520
    default_height = 280
    default_minSize = (default_width, default_height)
    default_windowID = 'SellBuyItemsWindow'
    captionTextPath = 'UI/Inventory/ItemActions/MultiBuy'
    scrollId = 'MultiBuyScroll'
    tradeForCorpSettingConfig = 'buyUseCorp'
    tradeTextPath = 'UI/Market/MarketQuote/CommandSell'
    orderCap = 'MultiSellOrderCap'
    tradeOnConfirm = True
    MAX_PRICE = 9223372036854.0
    corpCheckboxTop = 28
    numbersGridTop = 6
    showTaxAndBrokersFee = True
    dropLabelPath = 'UI/Market/Marketbase/DropItemsToAdd'
    cannotBeTradeLabelPath = 'UI/Market/MarketQuote/CannotBeSold'
    badDeltaWarningPath = 'UI/Market/MarketQuote/MultiBuyTypesAboveAverage'

    def ApplyAttributes(self, attributes):
        Window.ApplyAttributes(self, attributes)
        self.marketQuoteSvc = sm.GetService('marketQuote')
        self.InitializeVariables(attributes)
        self.SetCaption(GetByLabel(self.captionTextPath))
        self.scope = 'station_inflight'
        self.SetTopparentHeight(0)
        self.mainCont = mainCont = Container(parent=self.sr.main,
                                             name='mainCont',
                                             padding=4)
        self.infoCont = Container(parent=mainCont,
                                  name='bottomCont',
                                  align=uiconst.TOBOTTOM,
                                  height=88,
                                  padTop=4)
        Line(parent=self.infoCont, align=uiconst.TOTOP)
        self.bottomLeft = Container(parent=self.infoCont,
                                    name='bottomLeft',
                                    padLeft=6,
                                    padTop=6)
        self.bottomRight = Container(parent=self.infoCont,
                                     name='bottomRight',
                                     align=uiconst.TORIGHT,
                                     width=250,
                                     padRight=6,
                                     padTop=6)
        self.dropCont = Container(parent=mainCont,
                                  name='dropCont',
                                  align=uiconst.TOTOP,
                                  height=28,
                                  state=uiconst.UI_NORMAL,
                                  padBottom=4)
        self.dropLabel = EveCaptionSmall(text=GetByLabel(self.dropLabelPath),
                                         parent=self.dropCont,
                                         align=uiconst.CENTER)
        self.dropLabel.opacity = 0.6
        self.fakeItemsCont = Container(parent=self.dropCont,
                                       align=uiconst.TOALL,
                                       clipChildren=True)
        self.locationCont = Container(parent=mainCont,
                                      name='locationCont',
                                      align=uiconst.TOTOP)
        scrollCont = Container(parent=mainCont, name='scrollCont')
        self.itemsScroll = ScrollContainer(parent=scrollCont, id=self.scrollId)
        btnGroup = ButtonGroup(parent=self.sr.main, idx=0, line=False)
        btnGroup.AddButton(GetByLabel(self.tradeTextPath),
                           self.PerformTrade,
                           isDefault=self.tradeOnConfirm)
        btnGroup.AddButton(GetByLabel('UI/Generic/Cancel'), self.Cancel)
        self.DrawNumbers()
        corpAcctName = self._CanTradeForCorp()
        if corpAcctName is not None:
            self.DrawCheckBox(corpAcctName)
        self.globalDragHover = uicore.event.RegisterForTriuiEvents(
            uiconst.UI_MOUSEHOVER, self.OnGlobalMouseHover)

    def StartAddItemsThread(self):
        if len(self.preItems):
            self.addItemsThread = uthread.new(self.AddPreItems, self.preItems)

    def InitializeVariables(self, attributes):
        self.globalDragHover = None
        self.cannotTradeItemList = []
        self.itemList = []
        self.preItems = attributes.preItems or []
        self.useCorp = None
        self.hasDrawn = False
        self.addItemsThread = None
        self.baseStationID = None

    def DrawNumbers(self):
        self.numbersGrid = LayoutGrid(parent=self.bottomRight,
                                      columns=2,
                                      align=uiconst.TORIGHT,
                                      top=self.numbersGridTop)
        if self.showTaxAndBrokersFee:
            self.brokersFee = EveLabelMedium(text='', padRight=4)
            self.numbersGrid.AddCell(self.brokersFee)
            self.brokersFeeAmt = EveLabelMediumBold(text='',
                                                    align=uiconst.CENTERRIGHT,
                                                    padLeft=4)
            self.numbersGrid.AddCell(self.brokersFeeAmt)
            self.salesTax = EveLabelMedium(text='', padRight=4)
            self.numbersGrid.AddCell(self.salesTax)
            self.salesTaxAmt = EveLabelMediumBold(text='',
                                                  align=uiconst.CENTERRIGHT,
                                                  padLeft=4)
            self.numbersGrid.AddCell(self.salesTaxAmt)
            spacer = Container(align=uiconst.TOTOP, height=12)
            self.numbersGrid.AddCell(spacer, colSpan=2)
        self.totalAmt = EveLabelLargeBold(text='',
                                          align=uiconst.CENTERRIGHT,
                                          padLeft=4,
                                          state=uiconst.UI_NORMAL)
        self.numbersGrid.AddCell(self.totalAmt, colSpan=2)

    def DrawCheckBox(self, corpAcctName):
        useCorpWallet = settings.user.ui.Get(self.tradeForCorpSettingConfig,
                                             False)
        top = self.corpCheckboxTop
        self.useCorp = Checkbox(text=GetByLabel(
            'UI/Market/MarketQuote/UseCorpAccount', accountName=corpAcctName),
                                parent=self.bottomLeft,
                                configName='usecorp',
                                checked=useCorpWallet,
                                callback=self.OnUseCorp,
                                pos=(0, top, 350, 0),
                                align=uiconst.TOPLEFT)

    def _CanTradeForCorp(self):
        if session.corprole & (corpRoleAccountant | corpRoleTrader):
            corpAcctName = sm.GetService('corp').GetMyCorpAccountName()
            if corpAcctName is not None:
                return corpAcctName

    def OnUseCorp(self, *args):
        if self.useCorp.checked:
            newValue = True
        else:
            newValue = False
        settings.user.ui.Set(self.tradeForCorpSettingConfig, newValue)

    def TradingForCorp(self):
        if self.useCorp:
            useCorp = self.useCorp.checked
        else:
            useCorp = False
        return useCorp

    def DropItems(self, dragObj, nodes):
        pass

    def PerformTrade(self, *args):
        pass

    def UpdateNumbers(self):
        pass

    def GetItems(self):
        return self.itemList

    def AddPreItems(self, preItems):
        pass

    def IsAllowedGuid(self, guid):
        return True

    def DrawDraggedItems(self, dragData):
        if not self.IsAllowedGuid(getattr(dragData[0], '__guid__', None)):
            return
        self.hasDrawn = True
        uicore.animations.FadeOut(self.dropLabel, duration=0.15)
        noOfItems = len(dragData)
        noOfAvailable = math.floor(
            (self.width - 16 - self.dropCont.padLeft - self.dropCont.padRight)
            / 28)
        for i, dragItem in enumerate(dragData):
            c = Container(parent=self.fakeItemsCont,
                          align=uiconst.TOLEFT,
                          padding=2,
                          width=24)
            if noOfItems > noOfAvailable and i == noOfAvailable - 1:
                icon = Sprite(
                    parent=c,
                    texturePath=
                    'res:/UI/Texture/classes/MultiSell/DotDotDot.png',
                    state=uiconst.UI_DISABLED,
                    width=24,
                    height=24,
                    align=uiconst.CENTER)
                icon.SetAlpha(0.6)
                return
            typeID = self.GetTypeIDFromDragItem(dragItem)
            icon = Icon(parent=c, typeID=typeID, state=uiconst.UI_DISABLED)
            icon.SetSize(24, 24)

    def GetTypeIDFromDragItem(self, dragItem):
        getTypeID = dragItem.item.typeID
        return getTypeID

    def OnDropData(self, dragSource, dragData):
        self.ClearDragData()

    def ClearDragData(self):
        self.fakeItemsCont.Flush()
        uicore.animations.FadeIn(self.dropLabel, 0.6, duration=0.3)
        self.hasDrawn = False

    def OnGlobalMouseHover(self, *args, **kw):
        shouldClearDragData = True
        if uicore.IsDragging() and uicore.dragObject:
            mo = uicore.uilib.mouseOver
            if mo == self or mo.IsUnder(self):
                shouldClearDragData = False
                if not self.hasDrawn:
                    self.DrawDraggedItems(uicore.dragObject.dragData)
        if shouldClearDragData:
            self.ClearDragData()
        return True

    def Cancel(self, *args):
        self.Close()

    def Close(self, *args, **kwds):
        Window.Close(self, *args, **kwds)
        if self.addItemsThread:
            self.addItemsThread.kill()
        uicore.event.UnregisterForTriuiEvents(self.globalDragHover)

    def CheckOrderAvailability(self, preItems):
        availableOrders = int(
            sm.GetService('machoNet').GetGlobalConfig().get(
                self.orderCap, 100)) - len(self.itemList)
        if len(preItems) > availableOrders:
            eve.Message('CustomNotify', {
                'notify':
                GetByLabel('UI/Market/MarketQuote/TooManyItemsForOrder')
            })
            return preItems[:availableOrders]
        return preItems

    def RemoveItem(self, itemEntry):
        self.itemsScroll._RemoveChild(itemEntry)
        self.itemList.remove(itemEntry)
        self.RemoveItemFromCollection(itemEntry)
        self.UpdateNumbers()
        self.UpdateHeaderCount()

    def RemoveItemFromCollection(self, itemEntry):
        pass

    def DoAddItem(self, item):
        itemEntry = self.GetItemEntry(item)
        self.AddItemToCollection(item, itemEntry)
        itemEntry.state = uiconst.UI_NORMAL
        self.itemsScroll._InsertChild(0, itemEntry)
        self.itemList.append(itemEntry)
        self.UpdateNumbers()
        self.UpdateHeaderCount()
        return itemEntry

    def UpdateHeaderCount(self):
        self.SetCaption('%s (%i) - %s' %
                        (GetByLabel(self.captionTextPath), len(
                            self.itemList), self.GetStationLocationText()))

    def GetStationLocationText(self):
        if self.baseStationID is None:
            return ''
        stationLocation = cfg.evelocations.Get(self.baseStationID).locationName
        return stationLocation

    def DisplayErrorHints(self):
        hintTextList = self.GetErrorHints()
        if hintTextList:
            hintText = '<br>'.join(hintTextList)
            eve.Message('CustomNotify', {'notify': hintText})

    def GetErrorHints(self):
        hintTextList = self.BuildHintTextList(self.cannotTradeItemList,
                                              self.cannotBeTradeLabelPath)
        return hintTextList

    def BuildHintTextList(self, itemList, labelPath):
        hintTextList = []
        if len(itemList):
            text = '<b>%s</b>' % GetByLabel(labelPath)
            hintTextList.append(text)
            for item in itemList:
                typeName = evetypes.GetName(item.typeID)
                typeLink = GetShowInfoLink(item.typeID, typeName)
                hintTextList.append(typeLink)

        return hintTextList

    def ClearErrorLists(self):
        self.cannotTradeItemList = []

    def GetValidatedItem(self, item):
        return None

    def GetItemsIterator(self, onlyValid=False):
        for item in self.GetItems():
            if not item:
                continue
            if onlyValid and not self.GetValidatedItem(item):
                continue
            yield item

    def GetOrderDeltaTextForWarning(self):
        return ''

    def GetItemsWithBadDelta(self, args):
        return []

    def ContinueAfterWarning(self, buyItemList):
        highItems = self.GetItemsWithBadDelta(buyItemList)
        orderText = self.GetOrderDeltaTextForWarning()
        hightText = ''
        if highItems:
            highTextList = [GetByLabel(self.badDeltaWarningPath)]
            highItems.sort(key=lambda x: x[0], reverse=True)
            for perc, item in highItems:
                percText = GetByLabel('UI/Common/Percentage',
                                      percentage=FmtAmt(perc * 100,
                                                        showFraction=0))
                highTextList.append('- %s (%s)' %
                                    (evetypes.GetName(item.typeID), percText))

            hightText = '<br>'.join(highTextList)
        if orderText or hightText:
            warningTextList = []
            if orderText:
                warningTextList.append(orderText)
                warningTextList.append('')
            if hightText:
                warningTextList.append(hightText)
                warningTextList.append('')
            warningTextList.append(
                GetByLabel(
                    'UI/Market/MarketQuote/MultiBuyAboveAverageConfirmation'))
            warningText = '<br>'.join(warningTextList)
            headerLabel = GetByLabel('UI/Generic/Warning')
            ret = eve.Message('CustomQuestion', {
                'header': headerLabel,
                'question': warningText
            },
                              uiconst.YESNO,
                              default=uiconst.ID_NO)
            if ret != uiconst.ID_YES:
                return False
        return True
Example #2
0
class SellItems(Window):
    __guid__ = 'form.SellItems'
    __notifyevents__ = ['OnSessionChanged']
    default_width = 520
    default_height = 280
    default_minSize = (default_width, default_height)
    default_windowID = 'SellItemsWindow'

    def ApplyAttributes(self, attributes):
        Window.ApplyAttributes(self, attributes)
        self.SetCaption(GetByLabel('UI/Inventory/ItemActions/MultiSell'))
        self.scope = 'station_inflight'
        self.SetTopparentHeight(0)
        mainCont = Container(parent=self.sr.main, name='mainCont', padding=4)
        infoCont = Container(parent=mainCont,
                             name='bottomCont',
                             align=uiconst.TOBOTTOM,
                             height=88,
                             padTop=4)
        Line(parent=infoCont, align=uiconst.TOTOP)
        self.bottomLeft = Container(parent=infoCont,
                                    name='bottomLeft',
                                    padLeft=6,
                                    padTop=6)
        self.bottomRight = Container(parent=infoCont,
                                     name='bottomRight',
                                     align=uiconst.TORIGHT,
                                     width=250,
                                     padRight=6,
                                     padTop=6)
        dropCont = Container(parent=mainCont,
                             name='dropCont',
                             align=uiconst.TOTOP,
                             height=28,
                             state=uiconst.UI_NORMAL,
                             padBottom=4)
        dropCont.OnDropData = self.DropItems
        self.dropLabel = EveCaptionSmall(
            text=GetByLabel('UI/Market/Marketbase/DropItemsToAdd'),
            parent=dropCont,
            align=uiconst.CENTER)
        self.dropLabel.opacity = 0.6
        self.fakeItemsCont = Container(parent=dropCont,
                                       align=uiconst.TOALL,
                                       clipChildren=True)
        self.itemList = []
        self.preItems = attributes.preItems
        self.itemDict = {}
        self.sellItemList = []
        self.cannotSellItemList = []
        self.itemsNeedRepackaging = []
        self.itemAlreadyInList = []
        self.hasDrawn = False
        self.baseStationID = None
        self.useCorp = None
        self.addItemsThread = None
        scrollCont = Container(parent=mainCont, name='scrollCont')
        self.itemsScroll = ScrollContainer(parent=scrollCont,
                                           id='MultiSellScroll')
        self.DefineButtons(
            uiconst.OKCANCEL,
            okLabel=GetByLabel('UI/Market/MarketQuote/CommandSell'),
            okFunc=self.SellItems,
            cancelFunc=self.Cancel)
        self.DrawNumbers()
        self.DrawCombos()
        durationValue = settings.user.ui.Get('multiSellDuration', 0)
        self.durationCombo.SetValue(durationValue)
        top = 30
        corpAcctName = self._CanSellForCorp()
        if corpAcctName is not None:
            self.DrawCheckBox(corpAcctName)
            top += 18
        self.orderCountLabel = EveLabelSmall(parent=self.bottomLeft,
                                             top=top,
                                             left=2)
        self.maxCount, self.myOrderCount = self.GetOrderCount()
        if len(self.preItems):
            self.addItemsThread = uthread.new(self.AddPreItems, self.preItems)
        self.UpdateOrderCount()
        self.globalDragHover = uicore.event.RegisterForTriuiEvents(
            uiconst.UI_MOUSEHOVER, self.OnGlobalMouseHover)

    def _CanSellForCorp(self):
        if session.corprole & (const.corpRoleAccountant
                               | const.corpRoleTrader):
            corpAcctName = sm.GetService('corp').GetMyCorpAccountName()
            if corpAcctName is not None:
                return corpAcctName

    def GetOrderCount(self):
        limits = sm.GetService('marketQuote').GetSkillLimits()
        maxCount = limits['cnt']
        myOrders = sm.GetService('marketQuote').GetMyOrders()
        return (maxCount, len(myOrders))

    def DrawCheckBox(self, corpAcctName):
        useCorpWallet = settings.user.ui.Get('sellUseCorp', False)
        self.useCorp = Checkbox(text=GetByLabel(
            'UI/Market/MarketQuote/UseCorpAccount', accountName=corpAcctName),
                                parent=self.bottomLeft,
                                configName='usecorp',
                                checked=useCorpWallet,
                                callback=self.OnUseCorp,
                                top=28)

    def OnUseCorp(self, *args):
        if self.useCorp.checked:
            settings.user.ui.Set('sellUseCorp', True)
        else:
            settings.user.ui.Set('sellUseCorp', False)
        self.UpdateOrderCount()

    def UpdateOrderCount(self):
        self.orderCountLabel.text = GetByLabel(
            'UI/Market/MarketQuote/OpenOrdersRemaining',
            orders=FmtAmt(self.maxCount - self.myOrderCount),
            maxOrders=FmtAmt(self.maxCount))

    def GetItems(self):
        return self.itemList

    def AddPreItems(self, preItems):
        if not self.CheckItemLocation(preItems[0][0]):
            return
        items = self.CheckOrderAvailability(preItems)
        self.ClearErrorLists()
        for item in items:
            self.AddItem(item[0])

        self.DisplayErrorHints()

    def CheckItemLocation(self, item):
        if not self.CheckStation(item) and len(self.itemList) > 0:
            eve.Message('CustomNotify', {
                'notify':
                GetByLabel('UI/Market/MarketQuote/LocationNotShared')
            })
            return False
        return True

    def CheckOrderAvailability(self, preItems):
        availableOrders = int(
            sm.GetService('machoNet').GetGlobalConfig().get(
                'MultiSellOrderCap', 100)) - len(self.itemList)
        if len(preItems) > availableOrders:
            eve.Message('CustomNotify', {
                'notify':
                GetByLabel('UI/Market/MarketQuote/TooManyItemsForOrder')
            })
            return preItems[:availableOrders]
        return preItems

    def DisplayErrorHints(self):
        hintText = ''
        if len(self.itemAlreadyInList):
            hintText = '<b>%s</b><br>' % GetByLabel(
                'UI/Market/MarketQuote/AlreadyInList')
            for item in self.itemAlreadyInList:
                hintText += TypeName(item.typeID) + '<br>'

        if len(self.cannotSellItemList):
            if hintText:
                hintText += '<br>'
            hintText += '<b>%s</b><br>' % GetByLabel(
                'UI/Market/MarketQuote/CannotBeSold')
            for item in self.cannotSellItemList:
                hintText += TypeName(item.typeID) + '<br>'

        if len(self.itemsNeedRepackaging):
            if hintText:
                hintText += '<br>'
            hintText += '<b>%s</b><br>' % GetByLabel(
                'UI/Market/MarketQuote/NeedsRepackaging')
            for item in self.itemsNeedRepackaging:
                hintText += TypeName(item.typeID) + '<br>'

        if hintText:
            eve.Message('CustomNotify', {'notify': hintText})

    def AddItem(self, item):
        if not self.IsSellable(item):
            return
        self.itemDict[item.itemID] = item
        itemEntry = SellItemContainer(item=item,
                                      editFunc=self.OnEntryEdit,
                                      align=uiconst.TOTOP,
                                      parentFunc=self.RemoveItem)
        itemEntry.state = uiconst.UI_NORMAL
        self.itemsScroll._InsertChild(0, itemEntry)
        self.itemList.append(itemEntry)
        self.UpdateNumbers()
        if len(self.itemList) == 1:
            self.UpdateStationInfo(itemEntry.stationID)
        self.CheckItemSize()
        self.UpdateHeaderCount()
        uicore.registry.SetFocus(itemEntry.priceEdit)

    def CheckItemSize(self):
        if not len(self.itemList):
            return
        firstItem = self.itemList[0]
        if len(self.itemList) == 1:
            firstItem.MakeSingle()
        elif len(self.itemList) == 2:
            firstItem.RemoveSingle()

    def UpdateStationInfo(self, stationID):
        self.baseStationID = stationID
        if self.baseStationID:
            self.UpdateHeaderCount()
        else:
            self.SetCaption(GetByLabel('UI/Inventory/ItemActions/MultiSell'))

    def UpdateHeaderCount(self):
        self.SetCaption('%s (%i) - %s' %
                        (GetByLabel('UI/Inventory/ItemActions/MultiSell'),
                         len(self.itemList), self.GetStationLocationText()))

    def RemoveItem(self, itemEntry):
        self.itemsScroll._RemoveChild(itemEntry)
        self.itemList.remove(itemEntry)
        self.itemDict.pop(itemEntry.itemID)
        self.CheckItemSize()
        self.UpdateNumbers()
        if len(self.itemList) == 0:
            self.baseStationID = None
            self.UpdateStationInfo(None)

    def CheckStation(self, item):
        itemStationID, _, _ = sm.GetService(
            'invCache').GetStationIDOfficeFolderIDOfficeIDOfItem(item)
        if itemStationID != self.baseStationID:
            return False
        return True

    def ClearErrorLists(self):
        self.cannotSellItemList = []
        self.itemsNeedRepackaging = []
        self.itemAlreadyInList = []

    def IsSellable(self, item):
        sellable = True
        if item.itemID in self.itemDict.keys():
            self.itemAlreadyInList.append(item)
            sellable = False
        elif item.singleton:
            self.itemsNeedRepackaging.append(item)
            sellable = False
        elif IsStation(item.itemID):
            self.cannotSellItemList.append(item)
            sellable = False
        elif cfg.invtypes.Get(item.typeID).marketGroupID is None:
            self.cannotSellItemList.append(item)
            sellable = False
        elif item.ownerID not in [session.corpid, session.charid]:
            self.cannotSellItemList.append(item)
            sellable = False
        elif item.itemID == GetActiveShip():
            self.cannotSellItemList.append(item)
            sellable = False
        elif bool(
                item.singleton) and item.categoryID == const.categoryBlueprint:
            self.cannotSellItemList.append(item)
            sellable = False
        elif not CheckIfInHangarOrCorpHangarAndCanTake(item):
            self.cannotSellItemList.append(item)
            sellable = False
        return sellable

    def OnEntryEdit(self, *args):
        uthread.new(self.UpdateNumbers)

    def DropItems(self, dragObj, nodes):
        if not self.CheckItemLocation(nodes[0].item):
            return
        items = self.CheckOrderAvailability(nodes)
        self.ClearErrorLists()
        for node in items:
            if getattr(node, '__guid__', None) == 'xtriui.InvItem':
                self.AddItem(node.item)

        self.DisplayErrorHints()

    def Cancel(self, *args):
        self.Close()

    def Close(self, setClosed=False, *args, **kwds):
        Window.Close(self, *args, **kwds)
        if self.addItemsThread:
            self.addItemsThread.kill()
        uicore.event.UnregisterForTriuiEvents(self.globalDragHover)

    def DrawCombos(self):
        durations = [[GetByLabel('UI/Market/MarketQuote/Immediate'), 0],
                     [GetByLabel('UI/Common/DateWords/Day'), 1],
                     [GetByLabel('UI/Market/MarketQuote/ThreeDays'), 3],
                     [GetByLabel('UI/Common/DateWords/Week'), 7],
                     [GetByLabel('UI/Market/MarketQuote/TwoWeeks'), 14],
                     [GetByLabel('UI/Common/DateWords/Month'), 30],
                     [GetByLabel('UI/Market/MarketQuote/ThreeMonths'), 90]]
        self.durationCombo = Combo(parent=self.bottomLeft,
                                   options=durations,
                                   top=6,
                                   callback=self.OnDurationChange)

    def OnDurationChange(self, *args):
        settings.user.ui.Set('multiSellDuration',
                             self.durationCombo.GetValue())
        self.UpdateNumbers()
        for item in self.GetItems():
            if self.durationCombo.GetValue() == 0:
                item.ShowNoSellOrders()
            else:
                item.HideNoSellOrders()

    def DrawNumbers(self):
        self.numbersGrid = LayoutGrid(parent=self.bottomRight,
                                      columns=2,
                                      align=uiconst.TORIGHT,
                                      top=6)
        self.brokersFee = EveLabelMedium(text='', padRight=4)
        self.numbersGrid.AddCell(self.brokersFee)
        self.brokersFeeAmt = EveLabelMediumBold(text='',
                                                align=uiconst.CENTERRIGHT,
                                                padLeft=4)
        self.numbersGrid.AddCell(self.brokersFeeAmt)
        self.salesTax = EveLabelMedium(text='', padRight=4)
        self.numbersGrid.AddCell(self.salesTax)
        self.salesTaxAmt = EveLabelMediumBold(text='',
                                              align=uiconst.CENTERRIGHT,
                                              padLeft=4)
        self.numbersGrid.AddCell(self.salesTaxAmt)
        spacer = Container(align=uiconst.TOTOP, height=12)
        self.numbersGrid.AddCell(spacer, colSpan=2)
        self.totalAmt = EveLabelLargeBold(text='',
                                          align=uiconst.CENTERRIGHT,
                                          padLeft=4,
                                          color=COL_GREEN)
        self.numbersGrid.AddCell(self.totalAmt, colSpan=2)

    def UpdateNumbers(self):
        brokersFee, salesTax, totalSum = self.GetSums()
        totalShown = totalSum - salesTax - brokersFee
        if totalSum > 0:
            brokersPerc = round(brokersFee / totalSum * 100, 2)
            salesPerc = round(salesTax / totalSum * 100, 2)
        else:
            brokersPerc = 0.0
            salesPerc = 0.0
        self.brokersFeeAmt.text = FmtISK(brokersFee)
        self.brokersFee.text = GetByLabel(
            'UI/Market/MarketQuote/BrokersFeePerc', percentage=brokersPerc)
        self.salesTaxAmt.text = FmtISK(salesTax)
        self.salesTax.text = GetByLabel('UI/Market/MarketQuote/SalesTaxPerc',
                                        percentage=salesPerc)
        self.totalAmt.text = FmtISK(totalShown)
        if totalShown < 0:
            self.totalAmt.color = COL_RED
        else:
            self.totalAmt.color = COL_GREEN

    def GetSums(self):
        brokersFee = 0.0
        salesTax = 0
        totalSum = 0
        isImmediate = self.durationCombo.GetValue() == 0
        for item in self.GetItems():
            if item:
                brokersFee += item.brokersFee
                if isImmediate and item.bestBid is None:
                    salesTax += 0
                else:
                    salesTax += item.salesTax
                totalSum += item.totalSum

        if isImmediate:
            brokersFee = 0.0
        return (brokersFee, salesTax, totalSum)

    def SellItems(self, *args):
        self.sellItemList = []
        unitCount = self.GetUnitCount()
        allItems = self.GetItems()
        if unitCount == 0:
            return
        if eve.Message('ConfirmSellingItems', {'noOfItems': int(unitCount)},
                       uiconst.OKCANCEL,
                       suppress=uiconst.ID_OK) != uiconst.ID_OK:
            return
        self.errorItemList = []
        if self.useCorp:
            useCorp = self.useCorp.checked
        else:
            useCorp = False
        duration = self.durationCombo.GetValue()
        for item in allItems:
            if duration == 0:
                if item.bestBid:
                    self.ValidateItem(item)
                else:
                    continue
            else:
                self.ValidateItem(item)

        if not len(self.sellItemList):
            return
        sm.GetService('marketQuote').SellMulti(self.sellItemList, useCorp,
                                               duration)
        self.Close()

    def GetUnitCount(self):
        unitCount = 0
        for item in self.itemList:
            if self.durationCombo.GetValue() == 0:
                if item.bestBid:
                    if item.bestBid.volRemaining > item.GetQty():
                        unitCount += item.GetQty()
                    else:
                        unitCount += item.bestBid.volRemaining
            else:
                unitCount += item.GetQty()

        return unitCount

    def ValidateItem(self, item):
        price = round(item.GetPrice(), 2)
        if price > 9223372036854.0:
            return
        if self.durationCombo.GetValue() == 0:
            if not item.bestBid:
                return
        qty = item.GetQty()
        validatedItem = KeyVal(stationID=int(item.stationID),
                               typeID=int(item.typeID),
                               itemID=item.itemID,
                               price=price,
                               quantity=int(qty),
                               located=item.located)
        self.sellItemList.append(validatedItem)

    def GetStationLocationText(self):
        stationLocation = cfg.evelocations.Get(self.baseStationID).locationName
        return stationLocation

    def OnGlobalMouseHover(self, *args, **kw):
        if uicore.IsDragging() and uicore.dragObject:
            mo = uicore.uilib.mouseOver
            if mo == self or mo.IsUnder(self):
                if not self.hasDrawn:
                    self.DrawDraggedItems(uicore.dragObject.dragData)
            else:
                self.ClearDragData()
        else:
            self.ClearDragData()
        return True

    def DrawDraggedItems(self, dragData):
        if getattr(dragData[0], '__guid__', None) != 'xtriui.InvItem':
            return
        self.hasDrawn = True
        uicore.animations.FadeOut(self.dropLabel, duration=0.15)
        noOfItems = len(dragData)
        noOfAvailable = math.floor((self.width - 16) / 28)
        for i, dragItem in enumerate(dragData):
            c = Container(parent=self.fakeItemsCont,
                          align=uiconst.TOLEFT,
                          padding=2,
                          width=24)
            if noOfItems > noOfAvailable and i == noOfAvailable - 1:
                icon = Sprite(
                    parent=c,
                    texturePath=
                    'res:/UI/Texture/classes/MultiSell/DotDotDot.png',
                    state=uiconst.UI_DISABLED,
                    width=24,
                    height=24,
                    align=uiconst.CENTER)
                icon.SetAlpha(0.6)
                return
            icon = Icon(parent=c,
                        typeID=dragItem.item.typeID,
                        state=uiconst.UI_DISABLED)
            icon.SetSize(24, 24)

    def ClearDragData(self):
        self.fakeItemsCont.Flush()
        uicore.animations.FadeIn(self.dropLabel, 0.6, duration=0.3)
        self.hasDrawn = False

    def OnDropData(self, dragSource, dragData):
        self.ClearDragData()
class SellBuyItemsWindow(Window):
    __notifyevents__ = ['OnSessionChanged']
    default_width = 520
    default_height = 280
    default_minSize = (default_width, default_height)
    default_windowID = 'SellBuyItemsWindow'
    captionTextPath = 'UI/Inventory/ItemActions/MultiBuy'
    scrollId = 'MultiBuyScroll'
    tradeForCorpSettingConfig = 'buyUseCorp'
    tradeTextPath = 'UI/Market/MarketQuote/CommandSell'
    orderCap = 'MultiSellOrderCap'
    tradeOnConfirm = True
    MAX_PRICE = 9223372036854.0
    corpCheckboxTop = 28
    numbersGridTop = 6
    showTaxAndBrokersFee = True
    dropLabelPath = 'UI/Market/Marketbase/DropItemsToAdd'

    def ApplyAttributes(self, attributes):
        Window.ApplyAttributes(self, attributes)
        self.marketQuoteSvc = sm.GetService('marketQuote')
        self.InitializeVariables(attributes)
        self.SetCaption(GetByLabel(self.captionTextPath))
        self.scope = 'station_inflight'
        self.SetTopparentHeight(0)
        mainCont = Container(parent=self.sr.main, name='mainCont', padding=4)
        self.infoCont = Container(parent=mainCont, name='bottomCont', align=uiconst.TOBOTTOM, height=88, padTop=4)
        Line(parent=self.infoCont, align=uiconst.TOTOP)
        self.bottomLeft = Container(parent=self.infoCont, name='bottomLeft', padLeft=6, padTop=6)
        self.bottomRight = Container(parent=self.infoCont, name='bottomRight', align=uiconst.TORIGHT, width=250, padRight=6, padTop=6)
        self.dropCont = Container(parent=mainCont, name='dropCont', align=uiconst.TOTOP, height=28, state=uiconst.UI_NORMAL, padBottom=4)
        self.dropLabel = EveCaptionSmall(text=GetByLabel(self.dropLabelPath), parent=self.dropCont, align=uiconst.CENTER)
        self.dropLabel.opacity = 0.6
        self.fakeItemsCont = Container(parent=self.dropCont, align=uiconst.TOALL, clipChildren=True)
        self.locationCont = Container(parent=mainCont, name='locationCont', align=uiconst.TOTOP)
        scrollCont = Container(parent=mainCont, name='scrollCont')
        self.itemsScroll = ScrollContainer(parent=scrollCont, id=self.scrollId)
        btnGroup = ButtonGroup(parent=self.sr.main, idx=0, line=False)
        btnGroup.AddButton(GetByLabel(self.tradeTextPath), self.PerformTrade, isDefault=self.tradeOnConfirm)
        btnGroup.AddButton(GetByLabel('UI/Generic/Cancel'), self.Cancel)
        self.DrawNumbers()
        corpAcctName = self._CanTradeForCorp()
        if corpAcctName is not None:
            self.DrawCheckBox(corpAcctName)
        self.globalDragHover = uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEHOVER, self.OnGlobalMouseHover)

    def StartAddItemsThread(self):
        if len(self.preItems):
            self.addItemsThread = uthread.new(self.AddPreItems, self.preItems)

    def InitializeVariables(self, attributes):
        self.globalDragHover = None
        self.cannotTradeItemList = []
        self.itemList = []
        self.preItems = attributes.preItems or []
        self.useCorp = None
        self.hasDrawn = False
        self.addItemsThread = None
        self.baseStationID = None

    def DrawNumbers(self):
        self.numbersGrid = LayoutGrid(parent=self.bottomRight, columns=2, align=uiconst.TORIGHT, top=self.numbersGridTop)
        if self.showTaxAndBrokersFee:
            self.brokersFee = EveLabelMedium(text='', padRight=4)
            self.numbersGrid.AddCell(self.brokersFee)
            self.brokersFeeAmt = EveLabelMediumBold(text='', align=uiconst.CENTERRIGHT, padLeft=4)
            self.numbersGrid.AddCell(self.brokersFeeAmt)
            self.salesTax = EveLabelMedium(text='', padRight=4)
            self.numbersGrid.AddCell(self.salesTax)
            self.salesTaxAmt = EveLabelMediumBold(text='', align=uiconst.CENTERRIGHT, padLeft=4)
            self.numbersGrid.AddCell(self.salesTaxAmt)
            spacer = Container(align=uiconst.TOTOP, height=12)
            self.numbersGrid.AddCell(spacer, colSpan=2)
        self.totalAmt = EveLabelLargeBold(text='', align=uiconst.CENTERRIGHT, padLeft=4, state=uiconst.UI_NORMAL)
        self.numbersGrid.AddCell(self.totalAmt, colSpan=2)

    def DrawCheckBox(self, corpAcctName):
        useCorpWallet = settings.user.ui.Get(self.tradeForCorpSettingConfig, False)
        top = self.corpCheckboxTop
        self.useCorp = Checkbox(text=GetByLabel('UI/Market/MarketQuote/UseCorpAccount', accountName=corpAcctName), parent=self.bottomLeft, configName='usecorp', checked=useCorpWallet, callback=self.OnUseCorp, pos=(0,
         top,
         350,
         0), align=uiconst.TOPLEFT)

    def _CanTradeForCorp(self):
        if session.corprole & (corpRoleAccountant | corpRoleTrader):
            corpAcctName = sm.GetService('corp').GetMyCorpAccountName()
            if corpAcctName is not None:
                return corpAcctName

    def OnUseCorp(self, *args):
        if self.useCorp.checked:
            newValue = True
        else:
            newValue = False
        settings.user.ui.Set(self.tradeForCorpSettingConfig, newValue)

    def TradingForCorp(self):
        if self.useCorp:
            useCorp = self.useCorp.checked
        else:
            useCorp = False
        return useCorp

    def DropItems(self, dragObj, nodes):
        pass

    def PerformTrade(self, *args):
        pass

    def UpdateNumbers(self):
        pass

    def GetItems(self):
        return self.itemList

    def AddPreItems(self, preItems):
        pass

    def IsAllowedGuid(self, guid):
        return True

    def DrawDraggedItems(self, dragData):
        if not self.IsAllowedGuid(getattr(dragData[0], '__guid__', None)):
            return
        self.hasDrawn = True
        uicore.animations.FadeOut(self.dropLabel, duration=0.15)
        noOfItems = len(dragData)
        noOfAvailable = math.floor((self.width - 16) / 28)
        for i, dragItem in enumerate(dragData):
            c = Container(parent=self.fakeItemsCont, align=uiconst.TOLEFT, padding=2, width=24)
            if noOfItems > noOfAvailable and i == noOfAvailable - 1:
                icon = Sprite(parent=c, texturePath='res:/UI/Texture/classes/MultiSell/DotDotDot.png', state=uiconst.UI_DISABLED, width=24, height=24, align=uiconst.CENTER)
                icon.SetAlpha(0.6)
                return
            typeID = self.GetTypeIDFromDragItem(dragItem)
            icon = Icon(parent=c, typeID=typeID, state=uiconst.UI_DISABLED)
            icon.SetSize(24, 24)

    def GetTypeIDFromDragItem(self, dragItem):
        getTypeID = dragItem.item.typeID
        return getTypeID

    def OnDropData(self, dragSource, dragData):
        self.ClearDragData()

    def ClearDragData(self):
        self.fakeItemsCont.Flush()
        uicore.animations.FadeIn(self.dropLabel, 0.6, duration=0.3)
        self.hasDrawn = False

    def OnGlobalMouseHover(self, *args, **kw):
        shouldClearDragData = True
        if uicore.IsDragging() and uicore.dragObject:
            mo = uicore.uilib.mouseOver
            if mo == self or mo.IsUnder(self):
                shouldClearDragData = False
                if not self.hasDrawn:
                    self.DrawDraggedItems(uicore.dragObject.dragData)
        if shouldClearDragData:
            self.ClearDragData()
        return True

    def Cancel(self, *args):
        self.Close()

    def Close(self, *args, **kwds):
        Window.Close(self, *args, **kwds)
        if self.addItemsThread:
            self.addItemsThread.kill()
        uicore.event.UnregisterForTriuiEvents(self.globalDragHover)

    def CheckOrderAvailability(self, preItems):
        availableOrders = int(sm.GetService('machoNet').GetGlobalConfig().get(self.orderCap, 100)) - len(self.itemList)
        if len(preItems) > availableOrders:
            eve.Message('CustomNotify', {'notify': GetByLabel('UI/Market/MarketQuote/TooManyItemsForOrder')})
            return preItems[:availableOrders]
        return preItems

    def RemoveItem(self, itemEntry):
        self.itemsScroll._RemoveChild(itemEntry)
        self.itemList.remove(itemEntry)
        self.RemoveItemFromCollection(itemEntry)
        self.UpdateNumbers()
        self.UpdateHeaderCount()

    def RemoveItemFromCollection(self, itemEntry):
        pass

    def DoAddItem(self, item):
        itemEntry = self.GetItemEntry(item)
        self.AddItemToCollection(item, itemEntry)
        itemEntry.state = uiconst.UI_NORMAL
        self.itemsScroll._InsertChild(0, itemEntry)
        self.itemList.append(itemEntry)
        self.UpdateNumbers()
        self.UpdateHeaderCount()
        return itemEntry

    def UpdateHeaderCount(self):
        self.SetCaption('%s (%i) - %s' % (GetByLabel(self.captionTextPath), len(self.itemList), self.GetStationLocationText()))

    def GetStationLocationText(self):
        if self.baseStationID is None:
            return ''
        stationLocation = cfg.evelocations.Get(self.baseStationID).locationName
        return stationLocation

    def DisplayErrorHints(self):
        hintTextList = self.GetErrorHints()
        if hintTextList:
            hintText = '<br>'.join(hintTextList)
            eve.Message('CustomNotify', {'notify': hintText})

    def GetErrorHints(self):
        hintTextList = self.BuildHintTextList(self.cannotTradeItemList, 'UI/Market/MarketQuote/CannotBeSold')
        return hintTextList

    def BuildHintTextList(self, itemList, labelPath):
        hintTextList = []
        if len(itemList):
            text = '<b>%s</b>' % GetByLabel(labelPath)
            hintTextList.append(text)
            for item in itemList:
                hintTextList.append(evetypes.GetName(item.typeID))

        return hintTextList

    def ClearErrorLists(self):
        self.cannotTradeItemList = []