Ejemplo n.º 1
0
    def __init__(self, parent, id=wx.ID_ANY):
        wx.Panel.__init__(self, parent, id)

        self.SetBackgroundColour(wx.WHITE)

        self.hbs = wx.BoxSizer(wx.HORIZONTAL)
        self.titleLabel = wx.StaticText(self,
                                        label=u'{}:'.format(
                                            _('Unmatched RFID Tags')))
        self.excelButton = wx.Button(self, label=_('Export to Excel'))
        self.excelButton.Bind(wx.EVT_BUTTON, self.onExcel)

        self.ganttChart = GanttChartPanel.GanttChartPanel(self)
        self.ganttChart.getNowTimeCallback = GetNowTime

        self.hbs.Add(self.titleLabel,
                     flag=wx.TOP | wx.BOTTOM | wx.LEFT
                     | wx.ALIGN_CENTRE_VERTICAL,
                     border=4)
        self.hbs.AddStretchSpacer()
        self.hbs.Add(self.excelButton,
                     flag=wx.ALL | wx.ALIGN_CENTRE_VERTICAL | wx.ALIGN_RIGHT,
                     border=4)

        bs = wx.BoxSizer(wx.VERTICAL)
        bs.Add(self.hbs, flag=wx.GROW | wx.HORIZONTAL)
        bs.Add(self.ganttChart, 1, wx.GROW | wx.ALL, 5)
        self.SetSizer(bs)
        bs.SetSizeHints(self)
Ejemplo n.º 2
0
	def __init__( self, parent, id = wx.ID_ANY ):
		wx.Panel.__init__(self, parent, id)

		self.numSelect = None
		self.entry = None
		self.numBefore = None
		self.numAfter = None
		self.refreshTimer = None
		
		self.hbs = wx.BoxSizer(wx.HORIZONTAL)
		self.categoryLabel = wx.StaticText( self, label = _('Category:') )
		self.categoryChoice = wx.Choice( self )
		self.Bind( wx.EVT_CHOICE, self.doChooseCategory, self.categoryChoice )
		self.groupByStartWave = wx.CheckBox( self, label=_('Group by Start Wave') )
		self.Bind( wx.EVT_CHECKBOX, self.doGroupByStartWave, self.groupByStartWave )
		self.statsLabel = wx.StaticText( self )
		
		self.hbs.Add( self.categoryLabel, flag=wx.TOP | wx.BOTTOM | wx.LEFT | wx.ALIGN_CENTRE_VERTICAL, border=4 )
		self.hbs.Add( self.categoryChoice, flag=wx.ALL | wx.ALIGN_CENTRE_VERTICAL, border=4 )
		self.hbs.Add( self.groupByStartWave, flag=wx.ALL | wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND, border=4 )
		self.hbs.Add( self.statsLabel, flag=wx.ALL | wx.ALIGN_CENTRE_VERTICAL | wx.EXPAND, border=4 )
		
		self.ganttChart = GanttChartPanel.GanttChartPanel( self )
		self.ganttChart.dClickCallback = UpdateSetNum
		self.ganttChart.rClickCallback = self.onRightClick
		#self.ganttChart.lClickCallback = self.onLeftClick
		self.ganttChart.getNowTimeCallback = GetNowTime

		bs = wx.BoxSizer(wx.VERTICAL)
		bs.Add(self.hbs, flag=wx.GROW|wx.HORIZONTAL)
		bs.Add(self.ganttChart, 1, wx.GROW|wx.ALL, 5)
		self.SetSizer(bs)
		bs.SetSizeHints(self)
		self.SetDoubleBuffered( True )
Ejemplo n.º 3
0
	def OnPopupLapDetail( self, event ):
		with Model.LockRace() as race:
			if not race:
				return
			tLapStart = self.entryStart.t
			tLapEnd = self.entryEnd.t
			
			iLap = self.entryStart.lap
			try:
				leaderNum = GanttChartPanel.numFromLabel( self.ganttChart.labels[0] )
				leaderEntries = race.getRider(leaderNum).interpolate()
				leaderEntryStart = leaderEntries[self.entryStart.lap]
				leaderEntryEnd = leaderEntries[self.entryEnd.lap]
			except:
				leaderEntryStart = None
				leaderEntryEnd = None
		
			try:
				riderInfo = race.excelLink.read()[self.entryEnd.num]
			except:
				riderInfo = {}
				
			try:
				riderName = u'{}, {} {}'.format(riderInfo['LastName'], riderInfo['FirstName'], self.entryEnd.num)
			except KeyError:
				try:
					riderName = u'{} {}'.format(riderInfo['LastName'], self.entryEnd.num)
				except KeyError:
					try:
						riderName = u'{} {}'.format(riderInfo['FirstName'], self.entryEnd.num)
					except KeyError:
						riderName = u'{}'.format(self.entryEnd.num)
						
			if leaderEntryStart:
				tDown = tLapStart - leaderEntryStart.t
				infoDownStart = _('\nLap Start {} down from leader {}').format(Utils.formatTime(tDown, True), leaderEntryStart.num)
			else:
				infoDownStart = ''
			if leaderEntryEnd:
				tDown = tLapEnd - leaderEntryEnd.t
				infoDownEnd = _('\nLap End {} down from leader {}').format(Utils.formatTime(tDown, True), leaderEntryStart.num)
			else:
				infoDownEnd = ''
				
			infoStart = race.numTimeInfo.getInfoStr( self.entryStart.num, tLapStart )
			if infoStart:
				infoStart = _('\nLap Start ') + infoStart
			infoEnd = race.numTimeInfo.getInfoStr( self.entryEnd.num, tLapEnd )
			if infoEnd:
				infoEnd = _('\nLap End ') + infoEnd
		
			info = (_('Rider: {}  Lap: {}\nLap Start:  {} Lap End: {}\nLap Time: {}\n{}{}{}{}').format(
					riderName, self.entryEnd.lap,
					Utils.formatTime(tLapStart),
					Utils.formatTime(tLapEnd),
					Utils.formatTime(tLapEnd - tLapStart),
					infoDownStart, infoDownEnd, infoStart, infoEnd )).strip()
					
		Utils.MessageOK( self, info, _('Lap Details') )
Ejemplo n.º 4
0
	def onRightClick( self, xPos, yPos, num, iRider, iLap ):
		with Model.LockRace() as race:
			if not race or num not in race:
				return
			category = FixCategories( self.categoryChoice, getattr(race, 'ganttCategory', 0) )
			entries = race.getRider(num).interpolate()
			try:
				self.entry = entries[iLap]
				self.entryStart = entries[iLap-1]
				self.entryEnd = self.entry
			except (IndexError, KeyError):
				return
		self.setNumSelect( num )
		self.numSelect = num
		if Utils.isMainWin():
			wx.CallAfter( Utils.getMainWin().setNumSelect, self.ganttChart.numSelect )
			
		self.iLap = iLap
		self.iRow = iRider
		
		allCases = 0
		interpCase = 1
		nonInterpCase = 2
		if not hasattr(self, 'popupInfo'):
			self.popupInfo = [
				(wx.NewId(), _('Add Missing Last Lap'),			_('Add Missing Last Lap'),		self.OnPopupAddMissingLastLap, allCases),
				(None, None, None, None, None),
				(wx.NewId(), _('Pull after Lap End') + u'...',	_('Pull after Lap End'),		self.OnPopupPull, allCases),
				(wx.NewId(), _('DNF after Lap End') + u'...',	_('DNF after Lap End'),			self.OnPopupDNF, allCases),
				(None, None, None, None, None),
				(wx.NewId(), _('Correct Lap End Time') + u'...',_('Change number or lap end time'),		self.OnPopupCorrect, interpCase),
				(wx.NewId(), _('Shift Lap End Time') + u'...',	_('Move lap end time earlier/later'),	self.OnPopupShift, interpCase),
				(wx.NewId(), _('Delete Lap End Time') + u'...',	_('Delete Lap End Time'),		self.OnPopupDelete, nonInterpCase),
				(None, None, None, None, None),
				(wx.NewId(), _('Note') + u'...',				_('Add/Edit lap Note'),			self.OnPopupLapNote, allCases),
				(None, None, None, None, None),
				(wx.NewId(), _('Turn off Autocorrect') + u'...',_('Turn off Autocorrect'),		self.OnPopupAutocorrect, allCases),
				(None, None, None, None, None),
				(wx.NewId(), _('Swap with Rider before'),		_('Swap with Rider before'),	self.OnPopupSwapBefore, nonInterpCase),
				(wx.NewId(), _('Swap with Rider after'),		_('Swap with Rider after'),		self.OnPopupSwapAfter, nonInterpCase),
				(None, None, None, None, None),
				(wx.NewId(), _('Show Lap Details') + u'...', 	_('Show Lap Details'),			self.OnPopupLapDetail, allCases),
				(None, None, None, None, None),
			]
			if Model.race and Model.race.enableUSBCamera:
				self.popupInfo.append(
				(wx.NewId(), _('Photos')+ u'...', 				_('Show Photos'),				self.OnPopupPhotos, allCases),
				)
			self.popupInfo.extend( [
				(wx.NewId(), _('RiderDetail'),					_('Show RiderDetail Dialog'),	self.OnPopupRiderDetail, allCases),
				(wx.NewId(), _('Results'), 						_('Switch to Results tab'),		self.OnPopupResults, allCases),
			] )
			
			self.splitMenuInfo = [
					(wx.NewId(),
					u'{} {}'.format(split-1, _('Split') if split-1 == 1 else _('Splits')),
					lambda evt, s = self, splits = split: s.doSplitLap(splits)) for split in xrange(2,8) ] + [
					(wx.NewId(),
					_('Custom') + u'...',
					lambda evt, s = self: s.doCustomSplitLap())]
			for id, name, text, callback, cCase in self.popupInfo:
				if id:
					self.Bind( wx.EVT_MENU, callback, id=id )
			for id, name, callback in self.splitMenuInfo:
				self.Bind( wx.EVT_MENU, callback, id=id )
				
		caseCode = 1 if entries[iLap].interp else 2
		
		riderResults = dict( (r.num, r) for r in GetResults(category) )
		
		self.numBefore, self.numAfter = None, None
		for iRow, attr in [(self.iRow - 1, 'numBefore'), (self.iRow + 1, 'numAfter')]:
			if not(0 <= iRow < len(self.ganttChart.labels)):
				continue
			numAdjacent = GanttChartPanel.numFromLabel(self.ganttChart.labels[iRow])
			if RidersCanSwap( riderResults, num, numAdjacent ):
				setattr( self, attr, numAdjacent )
		
		menu = wx.Menu()
		for id, name, text, callback, cCase in self.popupInfo:
			if not id:
				Utils.addMissingSeparator( menu )
				continue
			if caseCode < cCase:
				continue
			if (name.endswith(_('before')) and not self.numBefore) or (name.endswith(_('after')) and not self.numAfter):
				continue
			menu.Append( id, name, text )
			
		if caseCode == 2:
			submenu = wx.Menu()
			for id, name, callback in self.splitMenuInfo:
				submenu.Append( id, name )
			Utils.addMissingSeparator( menu )
			menu.PrependSeparator()
			menu.PrependMenu( wx.NewId(), _('Add Missing Split'), submenu )
			
		Utils.deleteTrailingSeparators( menu )
		self.PopupMenu( menu )
		menu.Destroy()
Ejemplo n.º 5
0
    def OnPopupLapDetail(self, event):
        with Model.LockRace() as race:
            if not race:
                return
            tLapStart = self.entryStart.t
            tLapEnd = self.entryEnd.t

            iLap = self.entryStart.lap
            try:
                leaderNum = GanttChartPanel.numFromLabel(
                    self.ganttChart.labels[0])
                leaderEntries = race.getRider(leaderNum).interpolate()
                leaderEntryStart = leaderEntries[self.entryStart.lap]
                leaderEntryEnd = leaderEntries[self.entryEnd.lap]
            except:
                leaderEntryStart = None
                leaderEntryEnd = None

            try:
                riderInfo = race.excelLink.read()[self.entryEnd.num]
            except:
                riderInfo = {}

            try:
                riderName = u'{}, {} {}'.format(riderInfo['LastName'],
                                                riderInfo['FirstName'],
                                                self.entryEnd.num)
            except KeyError:
                try:
                    riderName = u'{} {}'.format(riderInfo['LastName'],
                                                self.entryEnd.num)
                except KeyError:
                    try:
                        riderName = u'{} {}'.format(riderInfo['FirstName'],
                                                    self.entryEnd.num)
                    except KeyError:
                        riderName = u'{}'.format(self.entryEnd.num)

            if leaderEntryStart:
                tDown = tLapStart - leaderEntryStart.t
                infoDownStart = u'\n' + u'{}: {} ({})'.format(
                    _('Lap Start down from leader'),
                    Utils.formatTime(tDown, True), leaderEntryStart.num)
            else:
                infoDownStart = ''
            if leaderEntryEnd:
                tDown = tLapEnd - leaderEntryEnd.t
                infoDownEnd = u'\n' + u'{}: {} {}'.format(
                    _('Lap End down from leader'), Utils.formatTime(
                        tDown, True), leaderEntryStart.num)
            else:
                infoDownEnd = ''

            infoStart = race.numTimeInfo.getInfoStr(self.entryStart.num,
                                                    tLapStart)
            if infoStart:
                infoStart = u'\n{} {}'.format(_('Lap Start'), infoStart)
            infoEnd = race.numTimeInfo.getInfoStr(self.entryEnd.num, tLapEnd)
            if infoEnd:
                infoEnd = u'\n{} {}'.format(_('Lap End'), infoEnd)

            info = (
                u'{}: {}  {}: {}\n{}: {}   {}: {}\n{}: {}\n{}{}{}{}'.format(
                    _('Rider'), riderName, _('Lap'), self.entryEnd.lap,
                    _('Lap Start'), Utils.formatTime(tLapStart), _('Lap End'),
                    Utils.formatTime(tLapEnd), _('Lap Time'),
                    Utils.formatTime(tLapEnd - tLapStart), infoDownStart,
                    infoDownEnd, infoStart, infoEnd)).strip()

        Utils.MessageOK(self, info, _('Lap Details'))
Ejemplo n.º 6
0
    def onRightClick(self, xPos, yPos, num, iRider, iLap):
        with Model.LockRace() as race:
            if not race or num not in race.riders:
                return
            category = FixCategories(self.categoryChoice,
                                     getattr(race, 'ganttCategory', 0))
            entries = race.getRider(num).interpolate()
            try:
                self.entry = entries[iLap]
                self.entryStart = entries[iLap - 1]
                self.entryEnd = self.entry
            except (IndexError, KeyError):
                return
        self.setNumSelect(num)
        self.numSelect = num
        if Utils.isMainWin():
            wx.CallAfter(Utils.getMainWin().setNumSelect,
                         self.ganttChart.numSelect)

        self.iLap = iLap
        self.iRow = iRider

        allCases = 0
        interpCase = 1
        nonInterpCase = 2
        if not hasattr(self, 'popupInfo'):
            self.popupInfo = [
                (_('Add Missing Last Lap'), _('Add Missing Last Lap'),
                 self.OnPopupAddMissingLastLap, allCases),
                (None, None, None, None),
                (_('Pull after Lap End') + u'...', _('Pull after Lap End'),
                 self.OnPopupPull, allCases),
                (_('DNF after Lap End') + u'...', _('DNF after Lap End'),
                 self.OnPopupDNF, allCases),
                (None, None, None, None),
                (_('Correct Lap End Time') + u'...',
                 _('Change number or lap end time'), self.OnPopupCorrect,
                 interpCase),
                (_('Shift Lap End Time') + u'...',
                 _('Move lap end time earlier/later'), self.OnPopupShift,
                 interpCase),
                (_('Delete Lap End Time') + u'...', _('Delete Lap End Time'),
                 self.OnPopupDelete, nonInterpCase),
                (None, None, None, None),
                (_('Mass Pull after Lap End Time') + u'...',
                 _('Pull Rider and all Riders after at Lap End'),
                 self.OnPopupMassPull, allCases),
                (None, None, None, None),
                (_('Note') + u'...', _('Add/Edit lap Note'),
                 self.OnPopupLapNote, allCases),
                (None, None, None, None),
                (_('Turn off Autocorrect') + u'...', _('Turn off Autocorrect'),
                 self.OnPopupAutocorrect, allCases),
                (None, None, None, None),
                (_('Swap with Rider before'), _('Swap with Rider before'),
                 self.OnPopupSwapBefore, nonInterpCase),
                (_('Swap with Rider after'), _('Swap with Rider after'),
                 self.OnPopupSwapAfter, nonInterpCase),
                (None, None, None, None),
                (_('Show Lap Details') + u'...', _('Show Lap Details'),
                 self.OnPopupLapDetail, allCases),
                (None, None, None, None),
                (_('RiderDetail'), _('Show RiderDetail Dialog'),
                 self.OnPopupRiderDetail, allCases),
                (_('Results'), _('Switch to Results tab'), self.OnPopupResults,
                 allCases),
            ]

            self.splitMenuInfo = [
                (u'{} {}'.format(
                    split - 1,
                    _('Split') if split - 1 == 1 else _('Splits')),
                 lambda evt, s=self, splits=split: s.doSplitLap(splits))
                for split in range(2, 8)
            ] + [(_('Custom') + u'...',
                  lambda evt, s=self: s.doCustomSplitLap())]

            self.menuOptions = {}
            for numBefore in [False, True]:
                for numAfter in [False, True]:
                    for caseCode in range(3):
                        menu = wx.Menu()
                        for name, text, callback, cCase in self.popupInfo:
                            if not name:
                                Utils.addMissingSeparator(menu)
                                continue
                            if caseCode < cCase:
                                continue
                            if (name.endswith(_('before'))
                                    and not numBefore) or (name.endswith(
                                        _('after')) and not numAfter):
                                continue
                            item = menu.Append(wx.ID_ANY, name, text)
                            self.Bind(wx.EVT_MENU, callback, item)

                        if caseCode == 2:
                            submenu = wx.Menu()
                            for name, callback in self.splitMenuInfo:
                                item = submenu.Append(wx.ID_ANY, name)
                                self.Bind(wx.EVT_MENU, callback, item)
                            Utils.addMissingSeparator(menu)
                            menu.PrependSeparator()
                            menu.Prepend(wx.ID_ANY, _('Add Missing Split'),
                                         submenu)

                        Utils.deleteTrailingSeparators(menu)
                        self.menuOptions[(numBefore, numAfter,
                                          caseCode)] = menu

        caseCode = 1 if entries[iLap].interp else 2

        riderResults = dict((r.num, r) for r in GetResults(category))

        self.numBefore, self.numAfter = None, None
        for iRow, attr in [(self.iRow - 1, 'numBefore'),
                           (self.iRow + 1, 'numAfter')]:
            if not (0 <= iRow < len(self.ganttChart.labels)):
                continue
            numAdjacent = GanttChartPanel.numFromLabel(
                self.ganttChart.labels[iRow])
            if RidersCanSwap(riderResults, num, numAdjacent):
                setattr(self, attr, numAdjacent)

        menu = self.menuOptions[(bool(self.numBefore), bool(self.numAfter),
                                 caseCode)]
        try:
            self.PopupMenu(menu)
        except Exception as e:
            Utils.writeLog('Gantt:onRightClick: {}'.format(e))