Ejemplo n.º 1
0
 def OnColumnChanged(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll OnColumnChanged NOT ACTIVE')
Ejemplo n.º 2
0
 def OnNewHeaders(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll OnNewHeaders NOT ACTIVE')
Ejemplo n.º 3
0
 def ScalingCol(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll ScalingCol NOT ACTIVE')
Ejemplo n.º 4
0
 def EndScaleCol(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll EndScaleCol NOT ACTIVE')
    def LoadTutorial(self, tutorialID = None, pageNo = None, pageID = None, sequenceID = None, force = 0, VID = None, skipCriteria = False, checkBack = 0, diffMouseClicks = 0, diffKeyboardClicks = 0):
        self.sr.browser.scrollEnabled = 0
        self.backBtn.state = uiconst.UI_HIDDEN
        self.nextBtn.state = uiconst.UI_HIDDEN
        self.backBtn.Blink(0)
        self.nextBtn.Blink(0)
        self.sr.text.text = ''
        self.done = 0
        self.reverseBack = 0
        imagePath = None
        pageCount = None
        body = '\n            <html>\n            <head>\n            <LINK REL="stylesheet" TYPE="text/css" HREF="res:/ui/css/tutorial.css">\n            </head>\n            <body>'
        tutData = None
        if VID:
            tutData = sm.RemoteSvc('tutorialSvc').GetTutorialInfo(VID)
        elif tutorialID:
            tutData = sm.GetService('tutorial').GetTutorialInfo(tutorialID)
        if tutData:
            fadeOut = uicore.animations.FadeOut(self.sr.browser.sr.clipper, duration=0.05, loops=1, curveType=2, callback=None, sleep=False)
            if self and self.destroyed:
                return
            pageCount = len(tutData.pages)
            if pageNo == -1:
                pageNo = pageCount
            else:
                pageNo = pageNo or 1
            if pageNo > pageCount:
                log.LogWarn('Open Tutorial Page Failed:, have page %s but max %s pages. falling back to page 1 :: tutorialID: %s, sequenceID: %s, VID: %s' % (pageNo,
                 pageCount,
                 tutorialID,
                 sequenceID,
                 VID))
                pageNo = 1
            with util.ExceptionEater('eventLog'):
                sm.GetService('tutorial').LogTutorialEvent(['tutorialID', 'pageNo', 'openedByUser'], 'OpenTutorial', tutorialID, pageNo, force)
            dispPageNo, dispPageCount = pageNo, pageCount
            pageData = tutData.pages[pageNo - 1]
            caption = self.captionText
            loop = 1
            while 1:
                captionTextParts = localization.GetByMessageID(tutData.tutorial[0].tutorialNameID).split(':')
                if len(captionTextParts) > 1:
                    tutorialNumber = captionTextParts[0]
                    rest = ':'.join(captionTextParts[1:]).strip()
                    captionText = '%s: %s' % (tutorialNumber, rest)
                else:
                    captionText = localization.GetByMessageID(tutData.tutorial[0].tutorialNameID)
                caption.text = captionText
                if pageData and pageData.pageNameID:
                    self.subcaption.text = localization.GetByMessageID(pageData.pageNameID)
                    self.subcaption.state = uiconst.UI_DISABLED
                else:
                    self.subcaption.state = uiconst.UI_HIDDEN
                if caption.textheight < 52 or not loop:
                    break
                caption.fontsize = 13
                caption.letterspace = 0
                caption.last = (0, 0)
                loop = 0

            if sequenceID:
                check = []
                seqTutData = sm.GetService('tutorial').GetTutorialInfo(tutorialID)
                for criteria in seqTutData.criterias:
                    cd = sm.GetService('tutorial').GetCriteria(criteria.criteriaID)
                    if cd is None:
                        continue
                    check.append(criteria)

                closeToEnd = 0
                for criteria in seqTutData.pagecriterias:
                    if criteria.pageID == pageData.pageID:
                        check.append(criteria)
                        closeToEnd = 1
                    elif not closeToEnd:
                        cd = sm.GetService('tutorial').GetCriteria(criteria.criteriaID)
                        if cd is None:
                            continue
                        if not cd.criteriaName.startswith('rookieState'):
                            continue
                        check.append(criteria)

                actionData = seqTutData.actions
                pageActionData = seqTutData.pageactions
            else:
                check = [ c for c in tutData.criterias ]
                for criteria in tutData.pagecriterias:
                    if criteria.pageID == pageData.pageID:
                        check.append(criteria)

                actionData = tutData.actions
                pageActionData = tutData.pageactions
            actions = [ sm.GetService('tutorial').GetAction(action.actionID) for action in actionData ]
            actions += [ sm.GetService('tutorial').GetAction(action.actionID) for action in pageActionData if action.pageID == pageData.pageID ]
            preRookieState = eve.rookieState
            if skipCriteria:
                criteriaCheck = None
            else:
                criteriaCheck = sm.GetService('tutorial').ParseCriterias(check, 'tut', self, tutorialID)
            if not self or getattr(self, 'sr', None) is None:
                return
            if criteriaCheck:
                if preRookieState:
                    eve.SetRookieState(preRookieState)
                body += '<br>' + localization.GetByMessageID(criteriaCheck.messageTextID)
                with util.ExceptionEater('eventLog'):
                    sm.GetService('tutorial').LogTutorialEvent(['tutorialID',
                     'pageNo',
                     'sequenceID',
                     'clickedByUser',
                     'errorMessageID',
                     'numMouseClicks',
                     'numKeyboardClicks'], 'CriteriaNotMet', tutorialID, pageNo, sequenceID, force, criteriaCheck.messageTextID, diffMouseClicks, diffKeyboardClicks)
                if pageNo > 1 or sequenceID and sm.GetService('tutorial').GetNextInSequence(tutorialID, sequenceID, -1):
                    self.backBtn.state = uiconst.UI_NORMAL
                if sm.GetService('tutorial').waitingForWarpConfirm == False:
                    self.nextBtn.state = uiconst.UI_NORMAL
                    self.nextBtn.OnClick = sm.GetService('tutorial').Reload
                    self.Confirm = sm.GetService('tutorial').Reload
                    self.nextBtn.SetLabel(localization.GetByLabel('UI/Commands/Next'))
                    self.sr.text.text = ''
                self.backBtn.OnClick = self.backFunc
                if checkBack:
                    self.reverseBack = 1
            else:
                sm.GetService('tutorial').ParseActions(actions)
                self.sr.text.text = localization.GetByLabel('UI/Tutorial/PageOf', num=dispPageNo, total=dispPageCount)
                if pageNo > 1 or sequenceID and sm.GetService('tutorial').GetNextInSequence(tutorialID, sequenceID, -1):
                    self.backBtn.state = uiconst.UI_NORMAL
                sm.GetService('tutorial').SetCriterias(check)
                if pageData:
                    page = pageData
                    body += '%s' % localization.GetByMessageID(page.textID)
                    self.nextBtn.state = uiconst.UI_NORMAL
                    self.nextBtn.OnClick = self.nextFunc
                    self.Confirm = self.nextFunc
                    self.backBtn.OnClick = self.backFunc
                    if pageNo < pageCount or sequenceID and sm.GetService('tutorial').GetNextInSequence(tutorialID, sequenceID):
                        self.nextBtn.SetLabel(localization.GetByLabel('UI/Commands/Next'))
                    else:
                        self.nextBtn.SetLabel(localization.GetByLabel('UI/Commands/Done'))
                        self.done = 1
                    imagePath = page.imagePath
                else:
                    body += '\n                        Page %s was not found in this tutorial.\n                        ' % pageNo
        else:
            self.captionText.text = localization.GetByLabel('UI/Tutorial/EveTutorials')
            body = '%s %s' % (localization.GetByLabel('UI/Tutorial/UnknownTutorial'), tutorialID)
        body += '</body></html>'
        blue.pyos.synchro.Yield()
        self.CheckTopHeight()
        self.LoadHTML('', newThread=0)
        if self.state == uiconst.UI_HIDDEN:
            self.Maximize()
        if imagePath:
            self.LoadImage(imagePath)
            self.sr.browser.left = self.img.width
        else:
            if self.imgpar.state != uiconst.UI_HIDDEN:
                self.imgpar.state = uiconst.UI_HIDDEN
            self.sr.browser.left = const.defaultPadding
        blue.pyos.synchro.Yield()
        goodies = sm.RemoteSvc('tutorialLocationSvc').GetTutorialGoodies(tutorialID, pageID, pageNo)
        goodieHtml = self.LoadAndGiveGoodies(goodies, tutorialID, pageID, pageNo)
        if goodieHtml:
            body += '<br>%s' % goodieHtml
        self.LoadHTML(body, newThread=0)
        self.SetCaption(localization.GetByLabel('UI/Tutorial/EveTutorials'))
        if not hasattr(self, 'startTime') or not hasattr(self, 'current') or self.current.sequenceID != sequenceID:
            self.startTime = blue.os.GetWallclockTime()
        tutorialPageState = TutorialPageState(tutorialID, pageNo, pageID, pageCount, sequenceID, VID, pageData.pageActionID)
        settings.char.generic.Set('tutorialPageState', tuple(tutorialPageState))
        settings.char.generic.Delete('tutorialCompleted')
        self.current = tutorialPageState
        if sequenceID:
            if self.done:
                sm.GetService('tutorial').SetSequenceStatus(sequenceID, tutorialID, pageNo, 'done')
            else:
                sm.GetService('tutorial').SetSequenceStatus(sequenceID, tutorialID, pageNo)
            if not sm.GetService('tutorial').CheckTutorialDone(sequenceID, tutorialID):
                sm.GetService('tutorial').SetSequenceDoneStatus(sequenceID, tutorialID, pageNo)
        for page in tutData.pages:
            if page.pageID == pageID or page.pageNumber == pageNo:
                if not criteriaCheck:
                    translatedText = localization.GetByMessageID(page.uiPointerTextID)
                    sm.GetService('uipointerSvc').PointTo(page.uiPointerID, translatedText)
                    break

        fadeOut.Stop()
        uicore.animations.FadeIn(self.sr.browser.sr.clipper, endVal=1.0, duration=0.3, loops=1, curveType=2, callback=None, sleep=False)
        self.CheckHeight()
Ejemplo n.º 6
0
 def CollectSubNodes(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll CollectSubNodes NOTACTIVE')
Ejemplo n.º 7
0
 def GetNodeHeight(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll GetNodeHeight NOTACTIVE')
Ejemplo n.º 8
0
 def GetSortDirection(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll GetSortDirection NOTACTIVE')
Ejemplo n.º 9
0
    def _GetForm(self,
                 format,
                 parent,
                 retfields=[],
                 reqresult=[],
                 errorcheck=None,
                 tabpanels=[],
                 tabgroup=[],
                 refresh=[],
                 wipe=1):
        if not uiutil.IsUnder(parent, uicore.desktop):
            log.LogTraceback(
                'Form parent MUST be hooked on the desktop; it is impossible to know the real dimensions of stuff within otherwise.'
            )
        self.retfields = retfields
        self.reqresult = reqresult
        self.errorcheck = errorcheck
        self.tabpanels = tabpanels
        self.tabgroup = tabgroup
        self.refresh = refresh
        if not isinstance(parent, xtriui.FormWnd):
            log.LogTraceback(
                'Incompatible formparent, please change it to xtriui.FormWnd')
        self.parent = parent
        self.parent.sr.panels = {}
        self.parent.sr.focus = None
        if wipe:
            self.retfields = []
            self.reqresult = []
            self.tabpanels = []
            self.tabgroup = []
            self.refresh = []
        for each in format:
            self.type = each
            typeName = self.type['type']
            self.leftPush = self.type.get('labelwidth', 0) or 80
            self.code = None
            if typeName == 'errorcheck':
                self.AddErrorcheck()
                continue
            elif typeName == 'data':
                self.AddData()
                continue
            elif typeName == 'tab':
                self.AddTab()
                continue
            elif typeName in ('btline', 'bbline'):
                self.AddLine()
                continue
            elif typeName == 'push':
                self.AddPush()
            elif typeName == 'header':
                self.AddHeader()
            elif typeName == 'labeltext':
                self.AddLabeltext()
            elif typeName == 'text':
                self.AddText()
            elif typeName == 'edit':
                self.AddEdit()
            elif typeName == 'textedit':
                self.AddTextedit()
            elif typeName == 'checkbox':
                self.AddCheckbox()
            elif typeName == 'combo':
                self.AddCombo()
            elif typeName == 'btnonly':
                self.AddBtnonly()
            else:
                log.LogWarn('Unknown fieldtype in form generator')
                continue
            if self.type.has_key('key'):
                if self.code:
                    self.retfields.append([self.code, self.type])
                    self.parent.sr.Set(self.type['key'], self.code)
                else:
                    self.parent.sr.Set(self.type['key'], self.new)
            if self.type.get('required', 0) == 1:
                self.reqresult.append([self.code, self.type])
            if self.type.get('selectall', 0) == 1 and getattr(
                    self.code, 'SelectAll', None):
                self.code.SelectAll()
            if self.type.get('setfocus', 0) == 1:
                self.parent.sr.focus = self.code
            if self.type.has_key('stopconfirm') and hasattr(
                    self.code, 'stopconfirm'):
                self.code.stopconfirm = self.type['stopconfirm']
            if self.type.get('frame', 0) == 1:
                idx = 0
                for child in self.new.children:
                    if child.name.startswith('Line'):
                        idx += 1

                uicls.Container(name='leftpush',
                                parent=self.new,
                                align=uiconst.TOLEFT,
                                width=6,
                                idx=idx)
                uicls.Container(name='rightpush',
                                parent=self.new,
                                align=uiconst.TORIGHT,
                                width=6,
                                idx=idx)
                uicls.Line(parent=self.new, align=uiconst.TOLEFT, idx=idx)
                uicls.Line(parent=self.new, align=uiconst.TORIGHT, idx=idx)

        if wipe and len(self.tabgroup):
            tabs = uicls.TabGroup(name='tabparent', parent=self.parent, idx=0)
            tabs.Startup(self.tabgroup, 'hybrid')
            maxheight = 0
            for panel in self.tabpanels:
                maxheight = max(maxheight, panel.height)

            self.parent.height = maxheight + tabs.height
        else:
            if len(self.tabpanels):
                for each in self.tabpanels:
                    each.state = uiconst.UI_HIDDEN

                self.tabpanels[0].state = uiconst.UI_PICKCHILDREN
            uix.RefreshHeight(self.parent)
        uicore.registry.SetFocus(self)
        return (self.parent, self.retfields, self.reqresult, self.tabpanels,
                self.errorcheck, self.refresh)
    def OnAllianceApplicationChanged(self, allianceID, corporationID, change):
        log.LogInfo('OnAllianceApplicationChanged allianceID', allianceID,
                    'corporationID', corporationID, 'change', change)
        if self.sr.scroll is None:
            log.LogInfo('OnAllianceApplicationChanged no scroll')
            return
        bAdd = 1
        bRemove = 1
        for old, new in change.itervalues():
            if old is not None:
                bAdd = 0
            if new is not None:
                bRemove = 0

        if bAdd and bRemove:
            raise RuntimeError(
                'applications::OnAllianceApplicationChanged WTF')
        if bAdd:
            log.LogInfo('OnAllianceApplicationChanged adding application')
            application = None
            activeTab = self.sr.tabs.GetSelectedArgs()
            myApplications = 0
            if eve.session.corpid == corporationID:
                if activeTab != 'myApplications':
                    return
                application = sm.GetService(
                    'corp').GetAllianceApplications()[allianceID]
                myApplications = 1
            else:
                if activeTab != 'alliance':
                    return
                application = sm.GetService(
                    'alliance').GetApplications()[corporationID]
            self.SetHint()
            scrolllist = []
            self.__AddApplicationToList(application, scrolllist,
                                        myApplications)
            if len(self.sr.scroll.sr.headers) > 0:
                self.sr.scroll.AddEntries(-1, scrolllist)
            else:
                self.sr.scroll.Load(contentList=scrolllist,
                                    headers=self.sr.headers)
        elif bRemove:
            log.LogInfo('OnAllianceApplicationChanged removing application')
            entry = self.GetEntry(allianceID, corporationID)
            if entry is not None:
                self.sr.scroll.RemoveEntries([entry])
            else:
                log.LogWarn(
                    'OnAllianceApplicationChanged application not found')
        else:
            log.LogInfo('OnAllianceApplicationChanged updating application')
            entry = self.GetEntry(allianceID, corporationID)
            if entry is None:
                log.LogWarn(
                    'OnAllianceApplicationChanged application not found')
            if entry is not None:
                if 'state' in change:
                    oldStatus, newStatus = change['state']
                    activeTab = self.sr.tabs.GetSelectedArgs()
                    if activeTab == 'alliance' and not self.sr.viewRejected.checked and newStatus == const.allianceApplicationRejected:
                        self.sr.scroll.RemoveEntries([entry])
                        return
                    status = self.__GetStatusStr(newStatus)
                    if corporationID == eve.session.corpid:
                        label = '%s<t>%s' % (
                            cfg.eveowners.Get(allianceID).ownerName, status)
                    else:
                        label = '%s<t>%s' % (
                            cfg.eveowners.Get(corporationID).ownerName, status)
                    entry.panel.sr.node.label = label
                    entry.panel.sr.label.text = label
Ejemplo n.º 11
0
    def MorphUI(self,
                item,
                attrname,
                tval,
                time=500.0,
                newthread=1,
                ifWidthConstrain=1,
                maxSteps=100,
                float=0,
                endState=None,
                timeFunc=blue.os.GetWallclockTime):
        cval = getattr(item, attrname, None)
        if cval is None:
            log.LogError('Attribute not found %s' % attrname)
            return
        if cval == tval:
            return
        if newthread:
            return uthread.new(self.MorphUI,
                               item,
                               attrname,
                               tval,
                               time,
                               0,
                               ifWidthConstrain,
                               maxSteps,
                               float,
                               endState=None)
        start, ndt = timeFunc(), 0.0
        steps = 0
        while ndt != 1.0:
            if steps > maxSteps:
                log.LogWarn('MorphUI::Exceeded maxSteps')
                setattr(item, attrname, tval)
                if attrname == 'width' and ifWidthConstrain:
                    setattr(item, 'height', tval)
                break
            try:
                ndt = max(
                    ndt,
                    min(blue.os.TimeDiffInMs(start, timeFunc()) / time, 1.0))
            except:
                log.LogWarn(
                    'MorphUI::Failed getting time diff. Diff should not exceed %s but is %s'
                    % (time, start - blue.os.GetWallclockTimeNow()))
                ndt = 1.0

            if ndt < 0.0:
                log.LogWarn(
                    'MorphUI::Got fubar TimeDiffInMs, propably because of the timesync... ignoring',
                    start, time)
                setattr(item, attrname, tval)
                if attrname == 'width' and ifWidthConstrain:
                    setattr(item, 'height', tval)
                break
            val = mathUtil.Lerp(cval, tval, ndt)
            if not float:
                val = int(val)
            setattr(item, attrname, val)
            if attrname == 'width' and ifWidthConstrain:
                setattr(item, 'height', val)
            blue.pyos.synchro.Yield()
            steps += 1

        if endState is not None:
            item.state = endState
Ejemplo n.º 12
0
    def CombineEffects(self,
                       item,
                       opacity=None,
                       alpha=None,
                       left=None,
                       top=None,
                       width=None,
                       height=None,
                       rgb=None,
                       _11=None,
                       _12=None,
                       time=250.0,
                       closeWhenDone=False,
                       abortFunction=None,
                       callback=None,
                       doneCallback=None,
                       timeFunc=blue.os.GetWallclockTime):
        sOpacity = None
        if opacity is not None and hasattr(item, 'opacity'):
            sOpacity = item.opacity
        sAlpha = None
        if alpha is not None and hasattr(item, 'GetAlpha'):
            sAlpha = item.GetAlpha()
        s_11 = None
        if _11 is not None and hasattr(item, 'transform'):
            s_11 = item.transform._11
        s_12 = None
        if _12 is not None and hasattr(item, 'transform'):
            s_12 = item.transform._12
        sLeft = None
        if left is not None:
            sLeft = item.left
        sTop = None
        if top is not None:
            sTop = item.top
        sWidth = None
        if width is not None:
            sWidth = item.width
        sHeight = None
        if height is not None:
            sHeight = item.height
        sR = sG = sB = None
        if rgb is not None and hasattr(item, 'GetRGB'):
            sR, sG, sB = item.GetRGB()
            r, g, b = rgb
        start, ndt = timeFunc(), 0.0
        while ndt != 1.0:
            if item.destroyed:
                return
            try:
                ndt = max(
                    ndt,
                    min(blue.os.TimeDiffInMs(start, timeFunc()) / time, 1.0))
            except:
                log.LogWarn(
                    'CombineEffects::Failed getting time diff. Diff should not exceed %s but is %s'
                    % (time, start - blue.os.GetWallclockTimeNow()))
                ndt = 1.0

            if sOpacity is not None:
                item.opacity = mathUtil.Lerp(sOpacity, opacity, ndt)
            if sAlpha is not None:
                item.SetAlpha(mathUtil.Lerp(sAlpha, alpha, ndt))
            _r = None
            if sR is not None:
                _r = mathUtil.Lerp(sR, r, ndt)
            _g = None
            if sG is not None:
                _g = mathUtil.Lerp(sG, g, ndt)
            _b = None
            if sB is not None:
                _b = mathUtil.Lerp(sB, b, ndt)
            if _r is not None or _g is not None or _b is not None:
                item.SetRGB(_r, _g, _b)
            if sLeft is not None:
                item.left = int(mathUtil.Lerp(sLeft, left, ndt))
            if sTop is not None:
                item.top = int(mathUtil.Lerp(sTop, top, ndt))
            if sWidth is not None:
                item.width = int(mathUtil.Lerp(sWidth, width, ndt))
            if sHeight is not None:
                item.height = int(mathUtil.Lerp(sHeight, height, ndt))
            if s_11 is not None:
                item.transform._11 = mathUtil.Lerp(s_11, _11, ndt)
            if s_12 is not None:
                item.transform._12 = mathUtil.Lerp(s_12, _12, ndt)
            if callback:
                callback(item)
            blue.pyos.synchro.Yield()
            if abortFunction and abortFunction():
                if closeWhenDone and not item.destroyed:
                    item.Close()
                return

        if doneCallback and not item.destroyed:
            doneCallback(item)
        if closeWhenDone and not item.destroyed:
            item.Close()
Ejemplo n.º 13
0
 def Unregister(self, cookie):
     if cookie in self.regs:
         del self.regs[cookie]
         self.LogInfo('Unregistered', cookie)
     else:
         log.LogWarn('inv.Unregister: Unknown cookie', cookie)
Ejemplo n.º 14
0
 def DblClickCol(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll DblClickCol NOT ACTIVE')
Ejemplo n.º 15
0
 def CheckOverlaysAndUnderlays(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll CheckOverlaysAndUnderlays NOTACTIVE')
Ejemplo n.º 16
0
 def GetSortBy(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll GetSortBy NOTACTIVE')
Ejemplo n.º 17
0
 def AddEntries(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll AddEntries NOTACTIVE')
Ejemplo n.º 18
0
 def ToggleSmartSortDirection(self, *args, **kwds):
     log.LogWarn('BasicDynamicScroll ToggleSmartSortDirection NOTACTIVE')
Ejemplo n.º 19
0
    def SaveChanges(self, *args):
        nodesToUpdate = []
        try:
            sm.GetService('loading').Cycle(
                localization.GetByLabel('UI/Common/PreparingToUpdate'))
            for node in self.sr.scroll.GetNodes():
                if not node or not node or not node.rec:
                    continue
                changed = 0
                if node.rec.roles != node.rec.oldRoles:
                    changed = 1
                elif node.rec.grantableRoles != node.rec.oldGrantableRoles:
                    changed = 1
                elif node.rec.rolesAtHQ != node.rec.oldRolesAtHQ:
                    changed = 1
                elif node.rec.grantableRolesAtHQ != node.rec.oldGrantableRolesAtHQ:
                    changed = 1
                elif node.rec.rolesAtBase != node.rec.oldRolesAtBase:
                    changed = 1
                elif node.rec.grantableRolesAtBase != node.rec.oldGrantableRolesAtBase:
                    changed = 1
                elif node.rec.rolesAtOther != node.rec.oldRolesAtOther:
                    changed = 1
                elif node.rec.grantableRolesAtOther != node.rec.oldGrantableRolesAtOther:
                    changed = 1
                elif node.rec.baseID != node.rec.oldBaseID:
                    changed = 1
                elif node.rec.titleMask != node.rec.oldTitleMask:
                    changed = 1
                if not changed:
                    continue
                nodesToUpdate.append(node)

        finally:
            sm.GetService('loading').StopCycle()

        nCount = len(nodesToUpdate)
        if nCount == 0:
            log.LogWarn('Nothing to save')
            return
        self.sr.progressCurrent = 0
        self.sr.progressTotal = nCount
        nIndex = 0
        try:
            sm.GetService('loading').ProgressWnd(
                localization.GetByLabel('UI/Common/Updating'), '', nIndex,
                nCount)
            blue.pyos.synchro.Yield()
            rows = None
            myRow = None
            for node in nodesToUpdate:
                entry = node.rec
                src = node.srcRec
                characterID = entry.characterID
                title = src.title
                divisionID = src.divisionID
                squadronID = src.squadronID
                roles = entry.roles
                grantableRoles = entry.grantableRoles
                rolesAtHQ = entry.rolesAtHQ
                grantableRolesAtHQ = entry.grantableRolesAtHQ
                rolesAtBase = entry.rolesAtBase
                grantableRolesAtBase = entry.grantableRolesAtBase
                rolesAtOther = entry.rolesAtOther
                grantableRolesAtOther = entry.grantableRolesAtOther
                baseID = entry.baseID
                titleMask = entry.titleMask
                if entry.titleMask == src.titleMask:
                    titleMask = None
                if roles & const.corpRoleDirector == const.corpRoleDirector:
                    roles = const.corpRoleDirector
                    grantableRoles = 0
                    rolesAtHQ = 0
                    grantableRolesAtHQ = 0
                    rolesAtBase = 0
                    grantableRolesAtBase = 0
                    rolesAtOther = 0
                    grantableRolesAtOther = 0
                if characterID == eve.session.charid:
                    if myRow is None:
                        myRow = Rowset([
                            'characterID', 'title', 'divisionID', 'squadronID',
                            'roles', 'grantableRoles', 'rolesAtHQ',
                            'grantableRolesAtHQ', 'rolesAtBase',
                            'grantableRolesAtBase', 'rolesAtOther',
                            'grantableRolesAtOther', 'baseID', 'titleMask'
                        ])
                    myRow.append([
                        characterID, None, None, None, roles, grantableRoles,
                        rolesAtHQ, grantableRolesAtHQ, rolesAtBase,
                        grantableRolesAtBase, rolesAtOther,
                        grantableRolesAtOther, baseID, titleMask
                    ])
                else:
                    if rows is None:
                        rows = Rowset([
                            'characterID', 'title', 'divisionID', 'squadronID',
                            'roles', 'grantableRoles', 'rolesAtHQ',
                            'grantableRolesAtHQ', 'rolesAtBase',
                            'grantableRolesAtBase', 'rolesAtOther',
                            'grantableRolesAtOther', 'baseID', 'titleMask'
                        ])
                    rows.append([
                        characterID, None, None, None, roles, grantableRoles,
                        rolesAtHQ, grantableRolesAtHQ, rolesAtBase,
                        grantableRolesAtBase, rolesAtOther,
                        grantableRolesAtOther, baseID, titleMask
                    ])

            if rows is not None:
                sm.GetService('corp').UpdateMembers(rows)
                sm.ScatterEvent('OnRoleEdit', rows)
            if myRow is not None:
                sm.GetService('sessionMgr').PerformSessionChange(
                    'corp.UpdateMembers',
                    sm.GetService('corp').UpdateMembers, myRow)
        finally:
            if nCount:
                sm.GetService('loading').ProgressWnd(
                    localization.GetByLabel('UI/Common/Updated'), '',
                    nCount - 1, nCount)
                blue.pyos.synchro.SleepWallclock(500)
                sm.GetService('loading').ProgressWnd(
                    localization.GetByLabel('UI/Common/Updated'), '', nCount,
                    nCount)
                blue.pyos.synchro.Yield()