Exemple #1
0
    def getGrid(self):
        headerNames = [u'', u'']

        grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        grid.DisableDragRowSize()
        grid.SetRowLabelSize(0)
        grid.EnableReorderRows(False)
        grid.CreateGrid(len(self.modelFields) + 1, len(headerNames))
        for col, h in enumerate(headerNames):
            grid.SetColLabelValue(col, h)
        grid.Show(False)

        for row, fd in enumerate(self.modelFields):
            grid.SetCellValue(row, 0, fd.name)
            grid.SetCellAlignment(row, 0, wx.ALIGN_RIGHT, wx.ALIGN_BOTTOM)
            grid.SetCellValue(row, 1, fd.getText())

        row = len(self.modelFields)
        grid.SetCellValue(row, 0, _('Competition Format'))
        grid.SetCellAlignment(row, 0, wx.ALIGN_RIGHT, wx.ALIGN_BOTTOM)
        grid.SetCellValue(
            row, 1,
            self.competitionFormatCtrl.GetStringSelection().split(
                u'.', 1)[1].strip())

        return grid
	def writeKOMGC():
		if not model.kom_gc:
			return
		
		riderFields = set( model.registration.getFieldsInUse() )
		headers = (
			['place', 'bib', 'last_name', 'first_name', 'team'] +
			(['uci_id'] if 'uci_id' in riderFields else []) +
			(['license'] if 'license' in riderFields else []) +
			['KOM Total', 'HC Wins', 'C1 Wins', 'C2 Wins', 'C3 Wins', 'C4 Wins', 'GC']
		)
		
		grid = ReorderableGrid( notebook )
		grid.CreateGrid( len(model.kom_gc), len(headers) )
		grid.EnableReorderRows( False )
		
		for col, h in enumerate(headers):
			attr = gridlib.GridCellAttr()
			attr.SetReadOnly()
			if h in Model.Result.NumericFields or h in {'KOM Total', 'HC Wins', 'C1 Wins', 'C2 Wins', 'C3 Wins', 'C4 Wins', 'GC'}:
				attr.SetAlignment( wx.ALIGN_RIGHT, wx.ALIGN_CENTRE )
			grid.SetColAttr( col, attr )
			grid.SetColLabelValue( col, Utils.fieldToHeader(h, True) )
		
		rowNum = 0
		for place, r in enumerate(model.kom_gc, 1):
			try:
				rider = model.registration.bibToRider[r[-1]]
			except KeyError:
				continue
		
			col = 0
			grid.SetCellValue( rowNum, col, unicode(place) ); col += 1			
			grid.SetCellValue( rowNum, col, unicode(rider.bib) ); col += 1
			grid.SetCellValue( rowNum, col, unicode(rider.last_name).upper()); col += 1
			grid.SetCellValue( rowNum, col, unicode(rider.first_name) ); col += 1
			grid.SetCellValue( rowNum, col, unicode(rider.team) ); col += 1
			
			if 'uci_id' in riderFields:
				grid.SetCellValue( rowNum, col, unicode(rider.uci_id) ); col += 1
			if 'license' in riderFields:
				grid.SetCellValue( rowNum, col, unicode(rider.license) ); col += 1

			for v in r[:-1]:
				grid.SetCellValue( rowNum, col, unicode(v) if v else u'' ); col += 1
				
			rowNum +=1
			
		grid.AutoSize()
		return grid
	def writeTeamClass( stage ):
		
		headers = ['Place', 'Team', 'Gap', 'Combined\nTimes', 'Combined\nPlaces', 'Best\nRider GC']
		
		grid = ReorderableGrid( notebook )
		grid.CreateGrid( len(stage.team_classification), len(headers) )
		grid.EnableReorderRows( False )
		
		for col, h in enumerate(headers):
			attr = gridlib.GridCellAttr()
			attr.SetReadOnly()
			if h != 'Team':
				attr.SetAlignment( wx.ALIGN_RIGHT, wx.ALIGN_CENTRE )
			grid.SetColAttr( col, attr )
			grid.SetColLabelValue( col, h )
		
		rowNum = 0
		gapLast = None
		timeLast = None
		for place, tc in enumerate(stage.team_classification, 1):
			col = 0
			grid.SetCellValue( rowNum, col, unicode(place) ); col += 1
			grid.SetCellValue( rowNum, col, tc.team ); col += 1
			
			grid.SetCellValue( rowNum, col, Utils.formatTime(tc.gap, twoDigitHours=True) if tc.gap != gapLast else sameGap )
			gapLast = tc.gap
			col += 1
			
			timeCur = tc.sum_best_top_times.value
			grid.SetCellValue( rowNum, col, Utils.formatTime(timeCur, forceHours=True) if timeCur != timeLast else sameTime )
			timeLast = timeCur
			setComment( rowNum, col, formatContext(tc.sum_best_top_times.context), {'width':256} )
			col += 1
			
			grid.SetCellValue( rowNum, col, unicode(tc.sum_best_top_places.value) )
			setComment( rowNum, col, formatContext(tc.sum_best_top_places.context), {'width':256} )
			col += 1
			
			grid.SetCellValue( rowNum, col, unicode(tc.best_place.value) )
			setComment( rowNum, col, formatContext(tc.best_place.context), {'width':256} )
			col += 1
			rowNum +=1
			
		grid.GetGridWindow().Bind(wx.EVT_MOTION, getCommentCallback(grid))
		grid.AutoSize()
		return grid
Exemple #4
0
class Qualifiers(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        font = GetFont()
        self.title = wx.StaticText(
            self, wx.ID_ANY,
            "Enter each rider's qualifying time in hh:mm:ss.ddd format.  Use a colon ':' a space, or a dash '-' to separate hour, minute and seconds."
        )
        self.title.SetFont(font)

        self.renumberButton = wx.Button(self, wx.ID_ANY,
                                        'Renumber Bibs by Time')
        self.renumberButton.SetFont(font)
        self.renumberButton.Bind(wx.EVT_BUTTON, self.doRenumber)

        hs = wx.BoxSizer(wx.HORIZONTAL)
        hs.Add(self.title, 0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=6)
        hs.AddStretchSpacer()
        hs.Add(self.renumberButton, 0, flag=wx.ALL, border=6)

        self.headerNames = ['Bib', 'Name', 'Team', 'Time', 'Status']
        self.iTime = next(i for i, n in enumerate(self.headerNames)
                          if n.startswith('Time'))
        self.iStatus = next(i for i, n in enumerate(self.headerNames)
                            if n.startswith('Status'))

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.DisableDragRowSize()
        self.grid.SetRowLabelSize(64)
        self.grid.CreateGrid(0, len(self.headerNames))
        self.setColNames()
        self.grid.EnableReorderRows(False)

        # Set specialized editors for appropriate columns.
        self.grid.SetLabelFont(font)
        for col in six.moves.range(self.grid.GetNumberCols()):
            attr = gridlib.GridCellAttr()
            attr.SetFont(font)
            if col == self.iTime:
                attr.SetEditor(HighPrecisionTimeEditor())
                attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
            elif col == self.iStatus:
                attr.SetEditor(
                    gridlib.GridCellChoiceEditor(choices=['', 'DNQ']))
                attr.SetReadOnly(False)
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
            else:
                if col == 0:
                    attr.SetRenderer(gridlib.GridCellNumberRenderer())
                attr.SetReadOnly(True)
            self.grid.SetColAttr(col, attr)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(hs, 0, flag=wx.ALL | wx.EXPAND, border=6)
        sizer.Add(self.grid, 1, flag=wx.EXPAND | wx.ALL, border=6)
        self.SetSizer(sizer)

    def getGrid(self):
        return self.grid

    def setColNames(self):
        for col, headerName in enumerate(self.headerNames):
            self.grid.SetColLabelValue(col, headerName)

    def setTestData(self):
        self.grid.ClearGrid()

        testData = TestData.getTestData()
        Utils.AdjustGridSize(self.grid, rowsRequired=len(testData))

        for row, data in enumerate(testData):
            bib = data[0]
            name = data[1] + ' ' + data[2]
            team = data[3]
            time = data[-1]
            for col, d in enumerate([bib, name, team, time]):
                self.grid.SetCellValue(row, col, u' {}'.format(d))

        # Fix up the column and row sizes.
        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

    def refresh(self):
        model = Model.model
        riders = model.riders

        self.renumberButton.Show(model.competition.isMTB)

        Utils.AdjustGridSize(self.grid, rowsRequired=len(riders))
        for row, r in enumerate(riders):
            for col, value in enumerate([
                    u'{}'.format(r.bib), r.full_name, r.team,
                    r.qualifyingTimeText
            ]):
                self.grid.SetCellValue(row, col, value)

        # Fix up the column and row sizes.
        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)
        self.grid.SetColSize(self.grid.GetNumberCols() - 1, 96)

        self.Layout()
        self.Refresh()

    def setQT(self):
        # The qualifying times can be changed at any time, however, if the competition is under way, the events cannot
        # be adjusted.
        model = Model.model
        riders = model.riders

        self.grid.SaveEditControlValue()

        for row in six.moves.range(self.grid.GetNumberRows()):
            v = self.grid.GetCellValue(row, self.iTime).strip()
            if v:
                qt = Utils.StrToSeconds(v)
            else:
                qt = Model.QualifyingTimeDefault

            qt = min(qt, Model.QualifyingTimeDefault)
            status = self.grid.GetCellValue(row, self.iStatus).strip()

            rider = riders[row]
            if rider.qualifyingTime != qt or rider.status != status:
                rider.qualifyingTime = qt
                rider.status = status
                model.setChanged(True)

    def commit(self):
        # The qualifying times can be changed at any time, however, if the competition is underway, the events cannot
        # be adusted.
        model = Model.model
        riders = model.riders
        self.setQT()
        if model.canReassignStarters():
            model.setQualifyingTimes()
            Utils.getMainWin().resetEvents()

    def doRenumber(self, event):
        if not Utils.MessageOKCancel(
                self,
                'Sequence Bib numbers in Increasing Order by Qualifying Time.\n\nContinue?',
                'Renumber Riders'):
            return

        self.setQT()

        model = Model.model
        riders = sorted(model.riders, key=lambda x: x.keyQualifying())
        for r, rider in enumerate(riders, 1):
            rider.bib = r

        wx.CallAfter(self.refresh)
Exemple #5
0
class RestartDialog(wx.Dialog):
    def __init__(self, parent, id=wx.ID_ANY):
        wx.Dialog.__init__(self,
                           parent,
                           id,
                           "Restart",
                           style=wx.DEFAULT_DIALOG_STYLE | wx.TAB_TRAVERSAL)

        font = GetFont()

        sizer = wx.BoxSizer(wx.VERTICAL)

        self.SetBackgroundColour(wx.WHITE)

        bitmap = wx.Bitmap(os.path.join(Utils.getImageFolder(), 'refresh.png'),
                           wx.BITMAP_TYPE_PNG)
        restartBitmap = wx.StaticBitmap(self, wx.ID_ANY, bitmap)

        title = wx.StaticText(self, label='Restart Status Changes')
        title.SetFont(font)
        self.titleText = title

        hsTitle = wx.BoxSizer(wx.HORIZONTAL)
        hsTitle.Add(restartBitmap, 0, flag=wx.EXPAND | wx.ALL, border=4)
        hsTitle.Add(title, 0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=4)

        sizer.Add(hsTitle, flag=wx.EXPAND)

        self.headerNames = ['Bib', 'Name', 'Team', 'Status    ']
        self.iColStatus = len(self.headerNames) - 1

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.EnableReorderRows(False)
        self.grid.SetRowLabelSize(0)
        self.grid.CreateGrid(0, len(self.headerNames))

        sizer.Add(self.grid, 1, flag=wx.ALL | wx.EXPAND, border=4)

        hs = wx.BoxSizer(wx.HORIZONTAL)
        self.okButton = MakeRoundButton(self, 'OK')
        self.cancelButton = MakeRoundButton(self, 'Cancel', isCancel)
        hs.Add(self.cancelButton, flag=wx.ALL, border=4)
        hs.AddStretchSpacer()
        hs.Add(self.okButton, flag=wx.ALL, border=4)

        self.okButton.Bind(wx.EVT_BUTTON, self.onOK)
        self.cancelButton.Bind(wx.EVT_BUTTON, self.onCancel)

        sizer.Add(hs, 0, flag=wx.EXPAND)

        self.SetSizer(sizer)

    def refresh(self, event):
        self.event = event

        start = event.starts[-1]
        state = event.competition.state

        font = GetFont()

        startPositions = start.startPositions
        Utils.AdjustGridSize(self.grid, rowsRequired=len(startPositions))

        self.grid.SetLabelFont(font)
        for col in six.moves.range(self.grid.GetNumberCols()):
            self.grid.SetColLabelValue(col, self.headerNames[col])
            attr = gridlib.GridCellAttr()
            attr.SetFont(font)
            if self.headerNames[col] == 'Bib':
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
                attr.SetReadOnly(True)
            elif col == 1 or col == 2:
                attr.SetReadOnly(True)
            elif self.headerNames[col].startswith('Status'):
                if len(start.getRemainingComposition()) > 2:
                    choices = ['DQ', 'DNF', '']
                    self.titleText.SetLabel(u'Restart Status Change')
                else:
                    choices = ['Inside', '']
                    self.titleText.SetLabel(u'Restart Position Change')
                attr.SetEditor(gridlib.GridCellChoiceEditor(choices=choices))
            self.grid.SetColAttr(col, attr)

        for row, p in enumerate(startPositions):
            rider = state.labels[p]
            for col, v in enumerate(
                [rider.bib, rider.full_name, rider.team, '']):
                self.grid.SetCellValue(row, col, u' {}'.format(v))

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

        self.GetSizer().Layout()
        self.GetSizer().Fit(self)

        self.CentreOnParent(wx.BOTH)
        self.SetFocus()

    def commit(self):
        places = []
        for row in six.moves.range(self.grid.GetNumberRows()):
            bib = self.grid.GetCellValue(row, 0)
            status = self.grid.GetCellValue(row, self.iColStatus)
            warning = self.grid.GetCellValue(row, self.iColWarning)
            relegation = self.grid.GetCellValue(row, self.iColRelegation)
            places.append((bib, status, warning, relegation))

        start = self.event.starts[-1]
        start.setPlaces(places)
        start.restartRequired = True
        self.event.propagate()
        Model.model.competition.propagate()
        Model.model.setChanged(True)
        Utils.setTitle()

    def onOK(self, event):
        self.commit()
        self.EndModal(wx.ID_OK)

    def onCancel(self, event):
        self.EndModal(wx.ID_CANCEL)
Exemple #6
0
class EventFinishOrderConfirmDialog(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent)

        self.SetBackgroundColour(wx.WHITE)

        vs = wx.BoxSizer(wx.VERTICAL)

        font = GetFont()

        bitmap = wx.Bitmap(
            os.path.join(Utils.getImageFolder(), 'checkered_flag_wavy.png'),
            wx.BITMAP_TYPE_PNG)
        flagBitmap = wx.StaticBitmap(self, wx.ID_ANY, bitmap)

        title = wx.StaticText(self, label='Confirm Event Result')
        title.SetFont(
            wx.Font((0, int(FontSize * 1.5)), wx.FONTFAMILY_SWISS,
                    wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))

        hsTitle = wx.BoxSizer(wx.HORIZONTAL)
        hsTitle.Add(flagBitmap, 0, flag=wx.EXPAND | wx.ALL, border=4)
        hsTitle.Add(title, 0, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=4)

        vs.Add(hsTitle, flag=wx.EXPAND)

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.EnableReorderRows(False)
        self.grid.CreateGrid(2, 6)
        self.grid.SetRowLabelSize(0)

        self.grid.SetLabelFont(font)

        vs.Add(self.grid, 1, flag=wx.ALL | wx.EXPAND, border=4)

        self.okButton = MakeRoundButton(self, 'OK')
        self.okButton.Bind(wx.EVT_BUTTON, self.onOK)

        self.cancelButton = MakeRoundButton(self, 'Cancel', isCancel)
        self.cancelButton.Bind(wx.EVT_BUTTON, self.onCancel)

        hs = wx.BoxSizer(wx.HORIZONTAL)
        hs.Add(self.okButton, 0, flag=wx.ALL | wx.EXPAND, border=4)
        hs.AddStretchSpacer()
        hs.Add(self.cancelButton, 0, flag=wx.ALL | wx.EXPAND, border=4)

        vs.Add(hs, 0, flag=wx.ALL | wx.EXPAND, border=4)

        self.SetSizer(vs)

    def refresh(self, grid):
        font = GetFont()

        Utils.AdjustGridSize(self.grid,
                             rowsRequired=grid.GetNumberRows(),
                             colsRequired=grid.GetNumberCols() + 1)
        self.grid.SetColLabelValue(0, 'Pos')
        attr = gridlib.GridCellAttr()
        attr.SetFont(font)
        attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
        attr.SetReadOnly(True)
        self.grid.SetColAttr(0, attr)

        iColStatus = None
        for col in six.moves.range(grid.GetNumberCols()):
            headerName = grid.GetColLabelValue(col)
            self.grid.SetColLabelValue(col + 1, headerName)
            attr = gridlib.GridCellAttr()
            attr.SetFont(font)
            if headerName == 'Bib':
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
            elif headerName.startswith('Time'):
                attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
            elif headerName.startswith('Status'):
                iColStatus = col
            elif headerName.startswith('Warn'):
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
                attr.SetRenderer(gridlib.GridCellBoolRenderer())
            elif headerName.startswith('Rel'):
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
                attr.SetRenderer(gridlib.GridCellBoolRenderer())
            attr.SetReadOnly(True)
            self.grid.SetColAttr(col + 1, attr)

        results = [[
            grid.GetCellValue(row, col)
            for col in six.moves.range(grid.GetNumberCols())
        ] for row in six.moves.range(grid.GetNumberRows())]
        results.sort(key=lambda x: x[iColStatus])

        for row in six.moves.range(grid.GetNumberRows()):
            self.grid.SetCellValue(row, 0, u'{}'.format(row + 1))
            for col in six.moves.range(grid.GetNumberCols()):
                v = results[row][col]
                self.grid.SetCellValue(row, col + 1, v if v != '0.000' else '')

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

        self.GetSizer().Layout()
        self.GetSizer().Fit(self)

        self.CentreOnParent(wx.BOTH)
        self.SetFocus()

    def onOK(self, event):
        self.EndModal(wx.ID_OK)

    def onCancel(self, event):
        self.EndModal(wx.ID_CANCEL)
Exemple #7
0
class EventSelect(EnablePanel):
    def __init__(self, parent):
        EnablePanel.__init__(self, parent)
        self.box = wx.StaticBox(self, label=u'Available Events')
        boxSizer = wx.StaticBoxSizer(self.box, wx.HORIZONTAL)

        self.SetBackgroundColour(wx.WHITE)

        self.events = []
        self.event = None

        self.activeBar = EnableBar(self)
        self.activeBar.SetToolTip(
            wx.ToolTip(u'\n'.join([
                u'Click on an available Event in the table.',
                u'Then press Select.',
            ])))

        self.selectButton = MakeRoundButton(self, 'Select', isSelect)

        self.headerNames = ['Event', 'Bib', 'Name', 'Team', 'In', 'Out']
        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.CreateGrid(0, len(self.headerNames))
        self.grid.EnableReorderRows(False)
        self.grid.SetRowLabelSize(40)
        self.grid.SetSelectionMode(gridlib.Grid.SelectRows)

        font = GetFont()
        self.grid.SetLabelFont(font)
        for col in six.moves.range(self.grid.GetNumberCols()):
            self.grid.SetColLabelValue(col, self.headerNames[col])
            attr = gridlib.GridCellAttr()
            attr.SetFont(font)
            attr.SetRenderer(GridCellMultiLineStringRenderer())
            attr.SetReadOnly(True)
            if self.headerNames[col] == 'Bib':
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
            self.grid.SetColAttr(col, attr)

        self.clock = Clock(self, size=(128, 128))
        self.clock.SetBackgroundColour(wx.WHITE)

        boxSizer.Add(self.activeBar, 0, flag=wx.ALL | wx.EXPAND, border=4)
        vs = wx.BoxSizer(wx.VERTICAL)
        vs.AddSpacer(
            int(self.grid.GetColLabelSize() + FontSize * 1.15 -
                RoundButtonSize / 2))
        vs.Add(self.selectButton,
               flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
               border=4)
        boxSizer.Add(vs, 0, flag=wx.ALL, border=4)
        boxSizer.Add(self.grid, 1, flag=wx.ALL | wx.EXPAND, border=4)
        boxSizer.Add(self.clock, 0, flag=wx.ALL, border=4)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(boxSizer, 1, flag=wx.EXPAND)
        self.SetSizer(sizer)

    def SetEnable(self, enable):
        EnablePanel.SetEnable(self, enable)
        for b, t in [(self.selectButton, isSelect)]:
            EnableRoundButton(b, enable, t)
        self.activeBar.SetBackgroundColour(
            wx.Colour(0, 128, 0) if enable else wx.WHITE)
        self.Refresh()

    def refresh(self):
        self.grid.ClearGrid()
        model = Model.model
        if not model:
            return

        self.events = [e for t, s, e in model.competition.getCanStart()]
        self.events.sort(
            key=lambda e: (0 if e == self.event else 1, e.tournament.i, e.
                           system.i, e.getHeat(), e.i))

        Utils.AdjustGridSize(self.grid, rowsRequired=len(self.events))
        for row, e in enumerate(self.events):
            for col, v in enumerate([
                    e.multi_line_name, e.multi_line_bibs,
                    e.multi_line_rider_names, e.multi_line_rider_teams,
                    e.multi_line_inlabels, e.multi_line_outlabels
            ]):
                self.grid.SetCellValue(row, col, u' {}'.format(v))
            if e.system != self.events[0].system:
                for col in six.moves.range(self.grid.GetNumberCols()):
                    self.grid.SetCellBackgroundColour(
                        row, col, InactiveBackgroundColour)
            else:
                for col in six.moves.range(self.grid.GetNumberCols()):
                    self.grid.SetCellBackgroundColour(row, col, wx.WHITE)

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

        if self.events:
            self.grid.SelectRow(0)
Exemple #8
0
class TimeTrialRecord( wx.Panel ):
	def __init__( self, parent, controller, id = wx.ID_ANY ):
		wx.Panel.__init__(self, parent, id)
		self.SetBackgroundColour( wx.WHITE )

		self.controller = controller

		self.headerNames = [_('Time'), _('Bib')]
		
		self.maxRows = 10
		
		fontSize = 18
		self.font = wx.FontFromPixelSize( wx.Size(0,fontSize), wx.FONTFAMILY_SWISS, wx.NORMAL, wx.FONTWEIGHT_NORMAL )
		self.bigFont = wx.FontFromPixelSize( wx.Size(0,int(fontSize*1.3)), wx.FONTFAMILY_SWISS, wx.NORMAL, wx.FONTWEIGHT_NORMAL )
		self.vbs = wx.BoxSizer(wx.VERTICAL)
		
		tapForTimeLabel = _('Tap for Time')
		if 'WXMAC' in wx.Platform:
			self.recordTimeButton = wx.lib.buttons.ThemedGenButton( self, label=tapForTimeLabel )
			self.recordTimeButton.Bind( wx.EVT_BUTTON, self.doRecordTime )
		else:
			self.recordTimeButton = wx.Button( self, label=tapForTimeLabel )
			self.recordTimeButton.Bind( wx.EVT_LEFT_DOWN, self.doRecordTime )
		
		self.recordTimeButton.SetFont( self.bigFont )
		self.recordTimeButton.SetToolTip(wx.ToolTip(u'\n'.join(
			[_('Tap to Record Times (or press the "t" key).'), _('Then enter the Bib numbers and Save as soon as possible.')]) ))
		
		hbs = wx.BoxSizer( wx.HORIZONTAL )
		hbs.Add( self.recordTimeButton, 0 )
		
		self.grid = ReorderableGrid( self, style = wx.BORDER_SUNKEN )
		self.grid.SetFont( self.font )
		self.grid.EnableReorderRows( False )
		
		dc = wx.WindowDC( self.grid )
		dc.SetFont( self.font )
		width, height = dc.GetTextExtent(" 999 ")
		self.rowLabelSize = width
		self.grid.SetRowLabelSize( self.rowLabelSize )
		
		self.grid.CreateGrid( self.maxRows, len(self.headerNames) )
		self.grid.Bind( gridlib.EVT_GRID_LABEL_LEFT_CLICK, self.doClickLabel )
		for col, name in enumerate(self.headerNames):
			self.grid.SetColLabelValue( col, name )
		self.grid.SetLabelFont( self.font )
		for col in xrange(self.grid.GetNumberCols()):
			attr = gridlib.GridCellAttr()
			attr.SetFont( self.font )
			if col == 0:
				attr.SetEditor( HighPrecisionTimeEditor() )
			elif col == 1:
				attr.SetRenderer( gridlib.GridCellNumberRenderer() )
				attr.SetEditor( gridlib.GridCellNumberEditor() )
			self.grid.SetColAttr( col, attr )
		
		saveLabel = _('Save')
		if 'WXMAC' in wx.Platform:
			self.commitButton = wx.lib.buttons.ThemedGenButton( self, label=saveLabel )
		else:
			self.commitButton = wx.Button( self, label=saveLabel )
		self.commitButton.Bind( wx.EVT_BUTTON, self.doCommit )
		self.commitButton.SetFont( self.bigFont )
		self.commitButton.SetToolTip(wx.ToolTip(_('Save Entries (or press the "s" key)')))
		
		self.vbs.Add( hbs, 0, flag=wx.ALL|wx.EXPAND, border = 4 )
		self.vbs.Add( self.grid, 1, flag=wx.ALL|wx.EXPAND, border = 4 )
		self.vbs.Add( self.commitButton, flag=wx.ALL|wx.ALIGN_RIGHT, border = 4 )
		
		idRecordAcceleratorId, idCommitAccelleratorId = wx.NewId(), wx.NewId()
		self.Bind(wx.EVT_MENU, self.doRecordTime, id=idRecordAcceleratorId)
		self.Bind(wx.EVT_MENU, self.doCommit, id=idCommitAccelleratorId)
		accel_tbl = wx.AcceleratorTable([
			(wx.ACCEL_NORMAL,  ord('T'), idRecordAcceleratorId),
			(wx.ACCEL_NORMAL,  ord('S'), idCommitAccelleratorId),
		])
		self.SetAcceleratorTable(accel_tbl)
		
		self.SetSizer(self.vbs)
		self.Fit()
		
	def doClickLabel( self, event ):
		if event.GetCol() == 0:
			self.doRecordTime( event )
	
	def doRecordTime( self, event ):
		t = Model.race.curRaceTime()
		
		# Trigger the camera.
		with Model.LockRace() as race:
			if not race:
				return
			if race.enableUSBCamera:
				race.photoCount += TakePhoto( 0, StrToSeconds(formatTime(t)) )
	
		# Find the last row without a time.
		self.grid.SetGridCursor( 0, 0, )
		
		emptyRow = self.grid.GetNumberRows() + 1
		success = False
		for i in xrange(2):
			for row in xrange(self.grid.GetNumberRows()):
				if not self.grid.GetCellValue(row, 0):
					emptyRow = row
					break
			if emptyRow >= self.grid.GetNumberRows():
				self.doCommit( event )
			else:
				success = True
				break
		
		if not success:
			Utils.MessageOK( self, u'\n'.join([
                _('Insufficient space to Record Time.'),
                _('Enter Bib numbers and press Commit.'),
                _('Or delete some entries')]), _('Record Time Failed.') )
			return
			
		self.grid.SetCellValue( emptyRow, 0, formatTime(t) )
		
		# Set the edit cursor at the first empty bib position.
		for row in xrange(self.grid.GetNumberRows()):
			text = self.grid.GetCellValue(row, 1)
			if not text or text == '0':
				self.grid.SetGridCursor( row, 1 )
				break
		
	def doCommit( self, event ):
		self.grid.SetGridCursor( 0, 0, )
	
		# Find the last row without a time.
		timesBibs = []
		timesNoBibs = []
		for row in xrange(self.grid.GetNumberRows()):
			tStr = self.grid.GetCellValue(row, 0).strip()
			if not tStr:
				continue
			
			bib = self.grid.GetCellValue(row, 1).strip()
			try:
				bib = int(bib)
			except (TypeError, ValueError):
				bib = 0
			
			if bib:
				timesBibs.append( (tStr, bib) )
			else:
				timesNoBibs.append( tStr )
				
		for row in xrange(self.grid.GetNumberRows()):
			for column in xrange(self.grid.GetNumberCols()):
				self.grid.SetCellValue(row, column, '' )
		
		'''
		for row, tStr in enumerate(timesNoBibs):
			self.grid.SetCellValue( row, 0, tStr )
		'''
			
		self.grid.SetGridCursor( 0, 1 )
			
		if timesBibs and Model.race:
			with Model.LockRace() as race:
				bibRaceSeconds = []
				
				for tStr, bib in timesBibs:
					raceSeconds = StrToSeconds(tStr)
					race.addTime( bib, raceSeconds )
					OutputStreamer.writeNumTime( bib, raceSeconds )
					bibRaceSeconds.append( (bib, raceSeconds) )
				
			wx.CallAfter( Utils.refresh )
			
		self.grid.SetGridCursor( 0, 1 )
	
	def refresh( self ):
		self.grid.AutoSizeRows( False )
		
		dc = wx.WindowDC( self.grid )
		dc.SetFont( self.font )
		
		widthTotal = self.rowLabelSize
		width, height = dc.GetTextExtent(" 00:00:00.000 ")
		self.grid.SetColSize( 0, width )
		widthTotal += width
		
		width, height = dc.GetTextExtent(" 9999 ")
		self.grid.SetColSize( 1, width )
		widthTotal += width
		
		scrollBarWidth = 48
		self.grid.SetSize( (widthTotal + scrollBarWidth, -1) )
		self.GetSizer().SetMinSize( (widthTotal + scrollBarWidth, -1) )
		
		self.grid.ForceRefresh()
		self.Fit()
		
		wx.CallAfter( self.recordTimeButton.SetFocus )
		
	def commit( self ):
		pass
Exemple #9
0
class TeamResults(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        self.categoryLabel = wx.StaticText(self, label='Category:')
        self.categoryChoice = wx.Choice(self, choices=['No Categories'])
        self.categoryChoice.SetSelection(0)
        self.categoryChoice.Bind(wx.EVT_CHOICE, self.onCategoryChoice)
        self.statsLabel = wx.StaticText(self, label='   /   ')
        self.refreshButton = wx.Button(self, label='Refresh')
        self.refreshButton.Bind(wx.EVT_BUTTON, self.onRefresh)
        self.publishToHtml = wx.Button(self, label='Publish to Html')
        self.publishToHtml.Bind(wx.EVT_BUTTON, self.onPublishToHtml)
        self.publishToFtp = wx.Button(self, label='Publish to Html with FTP')
        self.publishToFtp.Bind(wx.EVT_BUTTON, self.onPublishToFtp)
        self.publishToExcel = wx.Button(self, label='Publish to Excel')
        self.publishToExcel.Bind(wx.EVT_BUTTON, self.onPublishToExcel)

        self.postPublishCmdLabel = wx.StaticText(self,
                                                 label='Post Publish Cmd:')
        self.postPublishCmd = wx.TextCtrl(self, size=(300, -1))
        self.postPublishExplain = wx.StaticText(
            self,
            label=
            'Command to run after publish.  Use %* for all filenames (eg. "copy %* dirname")'
        )

        hs = wx.BoxSizer(wx.HORIZONTAL)
        hs.Add(self.categoryLabel, flag=wx.TOP, border=4)
        hs.Add(self.categoryChoice)
        hs.AddSpacer(4)
        hs.Add(self.statsLabel, flag=wx.TOP | wx.LEFT | wx.RIGHT, border=4)
        hs.AddStretchSpacer()
        hs.Add(self.refreshButton)
        hs.Add(self.publishToHtml, flag=wx.LEFT, border=48)
        hs.Add(self.publishToFtp, flag=wx.LEFT, border=4)
        hs.Add(self.publishToExcel, flag=wx.LEFT, border=4)

        hs2 = wx.BoxSizer(wx.HORIZONTAL)
        hs2.Add(self.postPublishCmdLabel, flag=wx.ALIGN_CENTRE_VERTICAL)
        hs2.Add(self.postPublishCmd, flag=wx.ALIGN_CENTRE_VERTICAL)
        hs2.Add(self.postPublishExplain,
                flag=wx.ALIGN_CENTRE_VERTICAL | wx.LEFT,
                border=4)

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.DisableDragRowSize()
        self.grid.SetRowLabelSize(64)
        self.grid.CreateGrid(0, len(HeaderNamesTemplate) + 1)
        self.grid.SetRowLabelSize(0)
        self.grid.EnableReorderRows(False)
        self.grid.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.doLabelClick)
        self.grid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self.doCellClick)
        self.sortCol = None

        self.setColNames(getHeaderNames())

        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(hs, flag=wx.TOP | wx.LEFT | wx.RIGHT, border=4)
        sizer.Add(hs2,
                  flag=wx.ALIGN_RIGHT | wx.TOP | wx.LEFT | wx.RIGHT,
                  border=4)
        sizer.Add(self.grid, 1, flag=wx.EXPAND | wx.TOP | wx.ALL, border=4)
        self.SetSizer(sizer)

    def onRefresh(self, event):
        SeriesModel.model.clearCache()
        self.refresh()

    def onCategoryChoice(self, event):
        wx.CallAfter(self.refresh)

    def readReset(self):
        self.sortCol = None

    def doLabelClick(self, event):
        col = event.GetCol()
        label = self.grid.GetColLabelValue(col)
        if self.sortCol == col:
            self.sortCol = -self.sortCol
        elif self.sortCol == -col:
            self.sortCol = None
        else:
            self.sortCol = col

        if not self.sortCol:
            self.sortCol = None
        wx.CallAfter(self.refresh)

    def doCellClick(self, event):
        if not hasattr(self, 'popupInfo'):
            self.popupInfo = [
                (u'{}...'.format(_('Copy Team to Clipboard')), wx.NewId(),
                 self.onCopyTeam),
            ]
            for p in self.popupInfo:
                if p[2]:
                    self.Bind(wx.EVT_MENU, p[2], id=p[1])

        menu = wx.Menu()
        for i, p in enumerate(self.popupInfo):
            if p[2]:
                menu.Append(p[1], p[0])
            else:
                menu.AppendSeparator()

        self.rowCur, self.colCur = event.GetRow(), event.GetCol()
        self.PopupMenu(menu)
        menu.Destroy()

    def copyCellToClipboard(self, r, c):
        if wx.TheClipboard.Open():
            # Create a wx.TextDataObject
            do = wx.TextDataObject()
            do.SetText(self.grid.GetCellValue(r, c))

            # Add the data to the clipboard
            wx.TheClipboard.SetData(do)
            # Close the clipboard
            wx.TheClipboard.Close()
        else:
            wx.MessageBox(u"Unable to open the clipboard", u"Error")

    def onCopyTeam(self, event):
        self.copyCellToClipboard(self.rowCur, 1)

    def setColNames(self, headerNames):
        for col, headerName in enumerate(headerNames):
            self.grid.SetColLabelValue(col, headerName)
            attr = gridlib.GridCellAttr()
            if headerName in ('Team', ):
                attr.SetAlignment(wx.ALIGN_LEFT, wx.ALIGN_TOP)
            elif headerName in ('Pos', 'Points', 'Gap'):
                attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_TOP)
            else:
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)

            attr.SetReadOnly(True)
            self.grid.SetColAttr(col, attr)

    def getGrid(self):
        return self.grid

    def getTitle(self):
        return self.showResults.GetStringSelection() + ' Series Results'

    def fixCategories(self):
        model = SeriesModel.model
        categoryNames = model.getCategoryNamesSortedTeamPublish()
        lastSelection = self.categoryChoice.GetStringSelection()
        self.categoryChoice.SetItems(categoryNames)
        iCurSelection = 0
        for i, n in enumerate(categoryNames):
            if n == lastSelection:
                iCurSelection = i
                break
        self.categoryChoice.SetSelection(iCurSelection)
        self.GetSizer().Layout()

    def refresh(self):
        model = SeriesModel.model
        HeaderNames = getHeaderNames()
        scoreByPoints = model.scoreByPoints
        scoreByTime = model.scoreByTime

        self.postPublishCmd.SetValue(model.postPublishCmd)

        wait = wx.BusyCursor()
        self.raceResults = model.extractAllRaceResults(False)
        del wait

        self.fixCategories()

        categoryName = self.categoryChoice.GetStringSelection()
        if not categoryName or not (scoreByPoints or scoreByTime):
            Utils.AdjustGridSize(self.grid, 0, 0)
            return

        self.grid.ClearGrid()

        pointsForRank = {
            r.getFileName(): r.pointStructure
            for r in model.races
        }

        results, races = GetModelInfo.GetCategoryResultsTeam(
            categoryName,
            self.raceResults,
            pointsForRank,
            useMostEventsCompleted=model.useMostEventsCompleted,
            numPlacesTieBreaker=model.numPlacesTieBreaker,
        )
        results = [rr for rr in results if rr[1] > 0]

        headerNames = HeaderNames + [
            u'{}\n{}'.format(r[1], r[0].strftime('%Y-%m-%d') if r[0] else u'')
            for r in races
        ]

        Utils.AdjustGridSize(self.grid, len(results), len(headerNames))
        self.setColNames(headerNames)

        for row, (team, points, gap, rrs) in enumerate(results):
            self.grid.SetCellValue(row, 0, unicode(row + 1))
            self.grid.SetCellValue(row, 1, unicode(team))
            self.grid.SetCellValue(row, 2, unicode(points))
            self.grid.SetCellValue(row, 3, unicode(gap))
            for q, rt in enumerate(rrs):
                self.grid.SetCellValue(row, 4 + q,
                                       formatTeamResults(scoreByPoints, rt))

            for c in xrange(0, len(headerNames)):
                self.grid.SetCellBackgroundColour(row, c, wx.WHITE)
                self.grid.SetCellTextColour(row, c, wx.BLACK)

        if self.sortCol is not None:

            def getBracketedNumber(v):
                numberMax = 99999
                if not v:
                    return numberMax
                try:
                    return int(reNoDigits.sub('', v.split('(')[1]))
                except (IndexError, ValueError):
                    return numberMax

            data = []
            for r in xrange(0, self.grid.GetNumberRows()):
                rowOrig = [
                    self.grid.GetCellValue(r, c)
                    for c in xrange(0, self.grid.GetNumberCols())
                ]
                rowCmp = rowOrig[:]
                rowCmp[0] = int(rowCmp[0])
                rowCmp[4] = Utils.StrToSeconds(rowCmp[4])
                rowCmp[5:] = [getBracketedNumber(v) for v in rowCmp[5:]]
                rowCmp.extend(rowOrig)
                data.append(rowCmp)

            if self.sortCol > 0:
                fg = wx.WHITE
                bg = wx.Colour(0, 100, 0)
            else:
                fg = wx.BLACK
                bg = wx.Colour(255, 165, 0)

            iCol = abs(self.sortCol)
            data.sort(key=lambda x: x[iCol], reverse=(self.sortCol < 0))
            for r, row in enumerate(data):
                for c, v in enumerate(row[self.grid.GetNumberCols():]):
                    self.grid.SetCellValue(r, c, v)
                    if c == iCol:
                        self.grid.SetCellTextColour(r, c, fg)
                        self.grid.SetCellBackgroundColour(r, c, bg)
                        if c < 4:
                            halign = wx.ALIGN_LEFT
                        elif c == 4 or c == 5:
                            halign = wx.ALIGN_RIGHT
                        else:
                            halign = wx.ALIGN_CENTRE
                        self.grid.SetCellAlignment(r, c, halign, wx.ALIGN_TOP)

        self.statsLabel.SetLabel('{} / {}'.format(
            self.grid.GetNumberRows(),
            GetModelInfo.GetTotalUniqueTeams(self.raceResults)))

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

        self.GetSizer().Layout()

    def onPublishToExcel(self, event):
        model = SeriesModel.model

        scoreByPoints = model.scoreByPoints
        scoreByTime = model.scoreByTime
        scoreByPercent = model.scoreByPercent
        scoreByTrueSkill = model.scoreByTrueSkill
        HeaderNames = getHeaderNames()

        if Utils.mainWin:
            if not Utils.mainWin.fileName:
                Utils.MessageOK(self,
                                'You must save your Series to a file first.',
                                'Save Series')
                return

        self.raceResults = model.extractAllRaceResults(False)

        categoryNames = model.getCategoryNamesSortedTeamPublish()
        if not categoryNames:
            return

        pointsForRank = {
            r.getFileName(): r.pointStructure
            for r in model.races
        }

        wb = xlwt.Workbook()

        for categoryName in categoryNames:
            results, races = GetModelInfo.GetCategoryResultsTeam(
                categoryName,
                self.raceResults,
                pointsForRank,
                useMostEventsCompleted=model.useMostEventsCompleted,
                numPlacesTieBreaker=model.numPlacesTieBreaker,
            )
            results = [rr for rr in results if rr[1] > 0]

            headerNames = HeaderNames + [r[1] for r in races]

            ws = wb.add_sheet(re.sub('[:\\/?*\[\]]', ' ', categoryName))
            wsFit = FitSheetWrapper(ws)

            fnt = xlwt.Font()
            fnt.name = 'Arial'
            fnt.bold = True
            fnt.height = int(fnt.height * 1.5)

            headerStyle = xlwt.XFStyle()
            headerStyle.font = fnt

            rowCur = 0
            ws.write_merge(rowCur, rowCur, 0, 8, model.name, headerStyle)
            rowCur += 1
            if model.organizer:
                ws.write_merge(rowCur, rowCur, 0, 8,
                               u'by {}'.format(model.organizer), headerStyle)
                rowCur += 1
            rowCur += 1
            colCur = 0
            ws.write_merge(rowCur, rowCur, colCur, colCur + 4, categoryName,
                           xlwt.easyxf("font: name Arial, bold on;"))

            rowCur += 2
            for c, headerName in enumerate(headerNames):
                wsFit.write(rowCur, c, headerName, labelStyle, bold=True)
            rowCur += 1

            for pos, (team, points, gap, rrs) in enumerate(results):
                wsFit.write(rowCur, 0, pos + 1, numberStyle)
                wsFit.write(rowCur, 1, team, textStyle)
                wsFit.write(rowCur, 2, points, numberStyle)
                wsFit.write(rowCur, 3, gap, numberStyle)
                for q, rt in enumerate(rrs):
                    wsFit.write(rowCur, 4 + q,
                                formatTeamResults(scoreByPoints, rt),
                                centerStyle)
                rowCur += 1

            # Add branding at the bottom of the sheet.
            style = xlwt.XFStyle()
            style.alignment.horz = xlwt.Alignment.HORZ_LEFT
            ws.write(rowCur + 2, 0, brandText, style)

        if Utils.mainWin:
            xlfileName = os.path.splitext(
                Utils.mainWin.fileName)[0] + 'Team.xls'
        else:
            xlfileName = 'ResultsTestTeam.xls'

        try:
            wb.save(xlfileName)
            webbrowser.open(xlfileName, new=2, autoraise=True)
            Utils.MessageOK(
                self, 'Excel file written to:\n\n   {}'.format(xlfileName),
                'Excel Write')
            self.callPostPublishCmd(xlfileName)
        except IOError:
            Utils.MessageOK(
                self,
                'Cannot write "{}".\n\nCheck if this spreadsheet is open.\nIf so, close it, and try again.'
                .format(xlfileName),
                'Excel File Error',
                iconMask=wx.ICON_ERROR)

    def onPublishToHtml(self, event):
        if Utils.mainWin:
            if not Utils.mainWin.fileName:
                Utils.MessageOK(self,
                                'You must save your Series to a file first.',
                                'Save Series')
                return

        htmlfileName = getHtmlFileName()
        model = SeriesModel.model
        model.postPublishCmd = self.postPublishCmd.GetValue().strip()

        try:
            getHtml(htmlfileName)
            webbrowser.open(htmlfileName, new=2, autoraise=True)
            Utils.MessageOK(
                self, u'Html file written to:\n\n   {}'.format(htmlfileName),
                'html Write')
        except IOError:
            Utils.MessageOK(
                self,
                'Cannot write "%s".\n\nCheck if this file is open.\nIf so, close it, and try again.'
                % htmlfileName,
                'Html File Error',
                iconMask=wx.ICON_ERROR)
        self.callPostPublishCmd(htmlfileName)

    def onPublishToFtp(self, event):
        if Utils.mainWin:
            if not Utils.mainWin.fileName:
                Utils.MessageOK(self,
                                'You must save your Series to a file first.',
                                'Save Series')
                return

        htmlfileName = getHtmlFileName()

        try:
            getHtml(htmlfileName)
        except IOError:
            return

        html = io.open(htmlfileName, 'r', encoding='utf-8', newline='').read()
        with FtpWriteFile.FtpPublishDialog(self, html=html) as dlg:
            dlg.ShowModal()
        self.callPostPublishCmd(htmlfileName)

    def commit(self):
        model = SeriesModel.model
        if model.postPublishCmd != self.postPublishCmd.GetValue().strip():
            model.postPublishCmd = self.postPublishCmd.GetValue().strip()
            model.setChanged()

    def callPostPublishCmd(self, fname):
        self.commit()
        postPublishCmd = SeriesModel.model.postPublishCmd
        if postPublishCmd and fname:
            allFiles = [fname]
            if platform.system() == 'Windows':
                files = ' '.join('""{}""'.format(f) for f in allFiles)
            else:
                files = ' '.join('"{}"'.format(f) for f in allFiles)

            if '%*' in postPublishCmd:
                cmd = postPublishCmd.replace('%*', files)
            else:
                cmd = ' '.join([postPublishCmd, files])

            try:
                subprocess.check_call(cmd, shell=True)
            except subprocess.CalledProcessError as e:
                Utils.MessageOK(
                    self,
                    u'{}\n\n    {}\n{}: {}'.format('Post Publish Cmd Error', e,
                                                   'return code',
                                                   e.returncode),
                    _('Post Publish Cmd Error'))
            except Exception as e:
                Utils.MessageOK(
                    self, u'{}\n\n    {}'.format('Post Publish Cmd Error', e),
                    'Post Publish Cmd Error')
	def writeIC( stage ):
		ic_fields = ['gap'] + list(Model.IndividualClassification._fields[1:-1])
		riderFields = set( model.registration.getFieldsInUse() )
		headers = (
			['place', 'bib', 'last_name', 'first_name', 'team'] +
			(['uci_id'] if 'uci_id' in riderFields else []) +
			(['license'] if 'license' in riderFields else []) +
			list(ic_fields)
		)
		
		grid = ReorderableGrid( notebook )
		grid.CreateGrid( len(getattr(stage, 'individual_gc', [])), len(headers) )
		grid.EnableReorderRows( False )
		
		for col, h in enumerate(headers):
			attr = gridlib.GridCellAttr()
			attr.SetReadOnly()
			if h in Model.Result.NumericFields or any(t in h for t in ('place', 'time')):
				attr.SetAlignment( wx.ALIGN_RIGHT, wx.ALIGN_CENTRE )
			grid.SetColAttr( col, attr )
			grid.SetColLabelValue( col, Utils.fieldToHeader(h, True) )

		rowNum = 0
		gapLast = None
		timeLast = None
		for place, r in enumerate(stage.individual_gc, 1):
			try:
				rider = model.registration.bibToRider[r.bib]
			except KeyError:
				continue
		
			col = 0
			if r.retired_stage > 0:
				grid.SetCellValue( rowNum, col, u'AB' ); col += 1
			else:
				grid.SetCellValue( rowNum, col, unicode(place) ); col += 1
			
			grid.SetCellValue( rowNum, col, unicode(r.bib) ); col += 1
			grid.SetCellValue( rowNum, col, unicode(rider.last_name).upper()); col += 1
			grid.SetCellValue( rowNum, col, unicode(rider.first_name) ); col += 1
			grid.SetCellValue( rowNum, col, unicode(rider.team) ); col += 1
			
			if 'uci_id' in riderFields:
				grid.SetCellValue( rowNum, col, unicode(rider.uci_id) ); col += 1
			if 'license' in riderFields:
				grid.SetCellValue( rowNum, col, unicode(rider.license) ); col += 1
			
			if r.retired_stage == 0:
				grid.SetCellValue( rowNum, col, Utils.formatTime(r.gap, twoDigitHours=True) if gapLast != r.gap else sameGap )
				gapLast = r.gap
				col += 1
				
				timeCur = r.total_time_with_bonus_plus_penalty
				grid.SetCellValue( rowNum, col, Utils.formatTime(timeCur, twoDigitHours=True) if timeCur != timeLast else sameTime )
				timeLast = timeCur
				col += 1
				
				grid.SetCellValue( rowNum, col, Utils.formatTime(r.total_time_with_bonus_plus_penalty_plus_second_fraction, twoDigitHours=True, extraPrecision=True) ); col += 1
				grid.SetCellValue( rowNum, col, unicode(r.sum_of_places) ); col += 1
				grid.SetCellValue( rowNum, col, unicode(r.last_stage_place) ); col += 1
			
			rowNum +=1
			
		grid.GetGridWindow().Bind(wx.EVT_MOTION, getCommentCallback(grid))
		grid.AutoSize()
		return grid
	def writeTeamGC():
		headers = (
			['Place', 'Team', 'Gap', 'Combined\nTime'] +
			['{}s'.format(Utils.ordinal(i+1)) for i in xrange(len(model.all_teams))] +
			['Best\nRider GC']
		)
		
		grid = ReorderableGrid( notebook )
		grid.CreateGrid( len(model.team_gc) + len(model.unranked_teams), len(headers) )
		grid.EnableReorderRows( False )
		
		for col, h in enumerate(headers):
			attr = gridlib.GridCellAttr()
			attr.SetReadOnly()
			if h != 'Team':
				attr.SetAlignment( wx.ALIGN_RIGHT, wx.ALIGN_CENTRE )
			grid.SetColAttr( col, attr )
			grid.SetColLabelValue( col, h )
		
		rowNum = 0
		leaderTime = None
		gapLast = None
		timeLast = None
		for place, tgc in enumerate(model.team_gc, 1):
			col = 0
			grid.SetCellValue( rowNum, col, unicode(place) ); col += 1
			grid.SetCellValue( rowNum, col, unicode(tgc[-1]) ); col += 1
			
			combinedTime = tgc[0].value
			if leaderTime is None:
				leaderTime = combinedTime
			gap = combinedTime - leaderTime
			grid.SetCellValue( rowNum, col, Utils.formatTime(gap, twoDigitHours=True) if gap != gapLast else sameGap ); col += 1
			gapLast = gap
			
			grid.SetCellValue( rowNum, col, Utils.formatTime(combinedTime, forceHours=True) if combinedTime != timeLast else sameTime)
			timeLast = combinedTime
			setComment( rowNum, col, formatContextList(tgc[0].context), {'width':512} )
			col += 1
			
			for i in xrange(1, len(tgc)-2):
				if tgc[i].value:
					grid.SetCellValue( rowNum, col, unicode(tgc[i].value) )
					setComment( rowNum, col, u'\n'.join(tgc[i].context), {'width':128} )
				col += 1
			
			grid.SetCellValue( rowNum, col, unicode(tgc[-2].value) )
			setComment( rowNum, col, formatContext(tgc[-2].context), {'width':256} )
			col += 1
			
			rowNum +=1
		
		for team in model.unranked_teams:
			col = 0
			grid.SetCellValue( rowNum, col, 'DNF' ); col += 1
			grid.SetCellValue( rowNum, col, team ); col += 1
			rowNum +=1
	
		grid.GetGridWindow().Bind(wx.EVT_MOTION, getCommentCallback(grid))
		grid.AutoSize()
		return grid
Exemple #12
0
class Chart(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        font = GetFont()

        self.title = wx.StaticText(self, wx.ID_ANY, "Competition Table:")
        self.title.SetFont(font)
        self.showNames = wx.ToggleButton(self, wx.ID_ANY, 'Show Names')
        self.showNames.SetFont(font)
        self.showNames.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleShow)
        self.showTeams = wx.ToggleButton(self, wx.ID_ANY, 'Show Teams')
        self.showTeams.SetFont(font)
        self.showTeams.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleShow)

        self.headerNames = [
            '', 'System', 'Event', 'Heats', 'In', 'Bib', 'Name', 'Team', 'H1',
            'H2', 'H3', 'Out', 'Bib', 'Name', 'Team'
        ]
        self.numericFields = set(['Event', 'Heats', 'Bib', 'In', 'Out'])

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.DisableDragRowSize()
        self.grid.SetRowLabelSize(0)
        self.grid.EnableReorderRows(False)
        self.grid.CreateGrid(0, len(self.headerNames))
        self.setColNames()

        # Set a larger font for the table.
        # Set specialized editors for appropriate columns.
        self.grid.SetLabelFont(font)

        sizer = wx.BoxSizer(wx.VERTICAL)
        hs = wx.BoxSizer(wx.HORIZONTAL)
        hs.Add(self.title, 0, flag=wx.ALL | wx.ALIGN_CENTRE_VERTICAL, border=4)
        hs.Add(self.showNames, 0, flag=wx.ALL, border=4)
        hs.Add(self.showTeams, 0, flag=wx.ALL, border=4)

        sizer.Add(hs, flag=wx.ALL, border=4)
        sizer.Add(self.grid, 1, flag=wx.EXPAND | wx.ALL, border=6)
        self.SetSizer(sizer)

    def onToggleShow(self, e):
        model = Model.model
        model.chartShowNames = self.showNames.GetValue()
        model.chartShowTeams = self.showTeams.GetValue()
        self.refresh()

    def getHideCols(self, headerNames):
        model = Model.model
        toHide = set()
        for col, h in enumerate(headerNames):
            if h == 'Name' and not getattr(model, 'chartShowNames', True):
                toHide.add(col)
            elif h == 'Team' and not getattr(model, 'chartShowTeams', True):
                toHide.add(col)
        return toHide

    def setColNames(self):
        for col, headerName in enumerate(self.headerNames):
            self.grid.SetColLabelValue(col, headerName)

    def getGrid(self):
        return self.grid

    def refresh(self):
        model = Model.model
        competition = model.competition
        state = competition.state

        self.showNames.SetValue(getattr(model, 'chartShowNames', True))
        self.showTeams.SetValue(getattr(model, 'chartShowTeams', True))

        font = GetFont()

        self.headerNames = [
            '', 'System', 'Event', 'Heats', 'In', 'Bib', 'Name', 'Team', 'H1',
            'H2', 'H3', 'Out', 'Bib', 'Name', 'Team'
        ]
        hideCols = self.getHideCols(self.headerNames)
        self.headerNames = [
            h for c, h in enumerate(self.headerNames) if c not in hideCols
        ]
        Utils.AdjustGridSize(self.grid,
                             rowsRequired=sum(
                                 1 for t, s, e in competition.allEvents()),
                             colsRequired=len(self.headerNames))
        self.grid.ClearGrid()
        self.setColNames()

        for col in six.moves.range(self.grid.GetNumberCols()):
            attr = gridlib.GridCellAttr()
            attr.SetFont(font)
            attr.SetReadOnly(True)
            if col >= 4:
                attr.SetRenderer(GridCellMultiLineStringRenderer())
            if self.headerNames[col] in self.numericFields:
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
            elif self.headerNames[col].startswith('H'):
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
            self.grid.SetColAttr(col, attr)

        row = 0
        for tournament in competition.tournaments:
            self.grid.SetCellValue(row, 0, tournament.name)
            for system in tournament.systems:
                self.grid.SetCellValue(row, 1, system.name)
                for i, event in enumerate(system.events):
                    writeCell = WriteCell(self.grid, row, 2)

                    writeCell(u'{}'.format(i + 1))
                    writeCell(u' {}'.format(event.heatsMax))
                    writeCell(u'\n'.join(event.composition).replace(
                        u'\n', u' ({})\n'.format(len(event.composition)), 1))

                    riders = [
                        state.labels.get(c, None) for c in event.composition
                    ]
                    writeCell(u'\n'.join([
                        u'{}'.format(rider.bib if rider.bib else u'')
                        if rider else '' for rider in riders
                    ]))
                    if getattr(model, 'chartShowNames', True):
                        writeCell(u'\n'.join([
                            rider.full_name if rider else u''
                            for rider in riders
                        ]))
                    if getattr(model, 'chartShowTeams', True):
                        writeCell(u'\n'.join([
                            rider.team if rider else u'' for rider in riders
                        ]))

                    for heat in six.moves.range(3):
                        if event.heatsMax > 1:
                            writeCell(u'\n'.join(event.getHeatPlaces(heat +
                                                                     1)))
                        else:
                            writeCell(u'')

                    out = [event.winner] + event.others
                    writeCell(u'\n'.join(out).replace(
                        u'\n', u' ({})\n'.format(len(out)), 1))
                    riders = [state.labels.get(c, None) for c in out]
                    writeCell(u'\n'.join([
                        u'{}'.format(rider.bib if rider.bib else '')
                        if rider else '' for rider in riders
                    ]))
                    if getattr(model, 'chartShowNames', True):
                        writeCell('\n'.join([
                            rider.full_name if rider else ''
                            for rider in riders
                        ]))
                    if getattr(model, 'chartShowTeams', True):
                        writeCell('\n'.join(
                            [rider.team if rider else '' for rider in riders]))
                    row += 1

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

    def commit(self):
        pass
Exemple #13
0
class Results(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        self.font = wx.Font((0, FontSize), wx.FONTFAMILY_SWISS,
                            wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)

        self.showResultsLabel = wx.StaticText(self, wx.ID_ANY, u'Show:')
        self.showResultsLabel.SetFont(self.font)
        self.showResults = wx.Choice(self, wx.ID_ANY, choices=['Qualifiers'])
        self.showResults.SetFont(self.font)
        self.showResults.SetSelection(0)

        self.communiqueLabel = wx.StaticText(self, wx.ID_ANY,
                                             u'Communiqu\u00E9:')
        self.communiqueLabel.SetFont(self.font)
        self.communiqueNumber = wx.TextCtrl(self, wx.ID_ANY, '', size=(80, -1))
        self.communiqueNumber.SetFont(self.font)

        self.showResults.Bind(wx.EVT_LEFT_DOWN, self.onClickResults)
        self.showResults.Bind(wx.EVT_CHOICE, self.onShowResults)
        self.showNames = wx.ToggleButton(self, wx.ID_ANY, u'Show Names')
        self.showNames.SetFont(self.font)
        self.showNames.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleShow)
        self.showTeams = wx.ToggleButton(self, wx.ID_ANY, u'Show Teams')
        self.showTeams.SetFont(self.font)
        self.showTeams.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleShow)
        self.competitionTime = wx.StaticText(self)

        self.headerNames = ['uPos', u'Bib', u'Rider', u'Team', u'License']

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.DisableDragRowSize()
        self.grid.SetRowLabelSize(64)
        self.grid.CreateGrid(0, len(self.headerNames))
        self.grid.SetRowLabelSize(0)
        self.grid.EnableReorderRows(False)
        self.setColNames()

        sizer = wx.BoxSizer(wx.VERTICAL)

        hs = wx.BoxSizer(wx.HORIZONTAL)
        hs.Add(self.showResultsLabel,
               0,
               flag=wx.ALIGN_CENTRE_VERTICAL,
               border=4)
        hs.Add(self.showResults,
               0,
               flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
               border=4)
        hs.Add(self.communiqueLabel,
               0,
               flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
               border=4)
        hs.Add(self.communiqueNumber,
               0,
               flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND,
               border=4)
        hs.Add(self.showNames,
               flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
               border=4)
        hs.Add(self.showTeams,
               flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
               border=4)
        hs.Add(self.competitionTime,
               flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
               border=4)

        sizer.Add(hs,
                  0,
                  flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT,
                  border=6)
        sizer.Add(self.grid, 1, flag=wx.EXPAND | wx.ALL, border=6)
        self.SetSizer(sizer)

    def onToggleShow(self, e):
        model = Model.model
        model.resultsShowNames = self.showNames.GetValue()
        model.resultsShowTeams = self.showTeams.GetValue()
        self.refresh()

    def setColNames(self):
        self.grid.SetLabelFont(self.font)
        for col, headerName in enumerate(self.headerNames):
            self.grid.SetColLabelValue(col, headerName)

            attr = gridlib.GridCellAttr()
            attr.SetFont(self.font)
            if self.headerNames[col] in {u'Bib', u'Event'}:
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
            elif u'Time' in self.headerNames[col]:
                attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_TOP)
            elif self.headerNames[col] == u'Pos':
                attr.SetAlignment(wx.ALIGN_RIGHT, wx.ALIGN_TOP)
            elif Arrow in self.headerNames[col]:
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_VERTICAL_CENTRE)
            elif self.headerNames[col].startswith(u'H'):
                attr.SetAlignment(wx.ALIGN_CENTRE, wx.ALIGN_TOP)
            attr.SetReadOnly(True)
            self.grid.SetColAttr(col, attr)

    def getResultChoices(self):
        model = Model.model
        competition = model.competition
        choices = [u'Qualifiers']
        for tournament in competition.tournaments:
            for system in tournament.systems:
                name = ('%s: ' % tournament.name
                        if tournament.name else '') + system.name
                choices.append(name)
        choices.append(u'Final Classification')
        return choices

    def fixShowResults(self):
        model = Model.model
        competition = model.competition

        choices = self.getResultChoices()
        self.showResults.SetItems(choices)

        if model.showResults >= len(choices):
            model.showResults = 0
        self.showResults.SetSelection(model.showResults)

    def getHideCols(self, headerNames):
        model = Model.model
        toHide = set()
        for col, h in enumerate(headerNames):
            if h == u'Name' and not getattr(model, 'resultsShowNames', True):
                toHide.add(col)
            elif h == u'Team' and not getattr(model, 'resultsShowTeams', True):
                toHide.add(col)
        return toHide

    def getGrid(self):
        return self.grid

    def getPhase(self, num=None):
        if num is None:
            num = self.showResults.GetSelection()
        choices = self.getResultChoices()
        return choices[num]

    def getTitle(self):
        phase = self.getPhase()
        title = u'Communiqu\u00E9: {}\n{} {} '.format(
            self.communiqueNumber.GetValue(), phase,
            '' if phase.startswith(u'Final') or phase.startswith('Time') else
            u'Draw Sheet/Intermediate Results')
        return title

    def onClickResults(self, event):
        self.commit()
        event.Skip()

    def onShowResults(self, event):
        Model.model.showResults = self.showResults.GetSelection()
        self.refresh()

    def refresh(self):
        self.fixShowResults()
        self.grid.ClearGrid()

        model = Model.model
        competition = model.competition

        self.showNames.SetValue(getattr(model, 'resultsShowNames', True))
        self.showTeams.SetValue(getattr(model, 'resultsShowTeams', True))

        self.communiqueNumber.SetValue(
            model.communique_number.get(self.getPhase(), ''))

        resultName = self.showResults.GetStringSelection()

        if 'Qualifiers' in resultName:
            starters = competition.starters

            self.headerNames = [u'Pos', u'Bib', u'Name', u'Team', u'Time']
            hideCols = self.getHideCols(self.headerNames)
            self.headerNames = [
                h for c, h in enumerate(self.headerNames) if c not in hideCols
            ]

            riders = sorted(model.riders, key=lambda r: r.keyQualifying())
            for row, r in enumerate(riders):
                if row >= starters or r.status == 'DNQ':
                    riders[row:] = sorted(riders[row:],
                                          key=lambda r: r.keyQualifying()[1:])
                    break
            Utils.AdjustGridSize(self.grid,
                                 rowsRequired=len(riders),
                                 colsRequired=len(self.headerNames))
            Utils.SetGridCellBackgroundColour(self.grid, wx.WHITE)
            self.setColNames()
            for row, r in enumerate(riders):
                if row < starters and r.status != 'DNQ':
                    pos = u'{}'.format(row + 1)
                    for col in six.moves.range(self.grid.GetNumberCols()):
                        self.grid.SetCellBackgroundColour(row, col, wx.WHITE)
                else:
                    pos = 'DNQ'
                    for col in six.moves.range(self.grid.GetNumberCols()):
                        self.grid.SetCellBackgroundColour(
                            row, col, wx.Colour(200, 200, 200))

                writeCell = WriteCell(self.grid, row)
                for col, value in enumerate([
                        pos, u' {}'.format(r.bib), r.full_name, r.team,
                        r.qualifyingTimeText
                ]):
                    if col not in hideCols:
                        writeCell(value)

            competitionTime = model.qualifyingCompetitionTime
            self.competitionTime.SetLabel(u'{}: {}'.format(
                _('Est. Competition Time'), Utils.formatTime(competitionTime)
            ) if competitionTime else u'')

        elif 'Final Classification' in resultName:
            self.headerNames = [u'Pos', u'Bib', u'Name', u'Team', u'License']
            hideCols = self.getHideCols(self.headerNames)
            self.headerNames = [
                h for c, h in enumerate(self.headerNames) if c not in hideCols
            ]

            results, dnfs, dqs = competition.getResults()
            Utils.AdjustGridSize(self.grid,
                                 rowsRequired=len(model.riders),
                                 colsRequired=len(self.headerNames))
            Utils.SetGridCellBackgroundColour(self.grid, wx.WHITE)

            self.setColNames()
            for row, (classification, r) in enumerate(results):
                writeCell = WriteCell(self.grid, row)
                if not r:
                    for col in six.moves.range(self.grid.GetNumberCols()):
                        writeCell('')
                else:
                    for col, value in enumerate([
                            classification, r.bib if r.bib else '',
                            r.full_name, r.team, r.license
                    ]):
                        if col not in hideCols:
                            writeCell(u' {}'.format(value))
            self.competitionTime.SetLabel(u'')
        else:
            # Find the Tournament and System selected.
            keepGoing = True
            for tournament in competition.tournaments:
                for system in tournament.systems:
                    name = (u'%s: ' % tournament.name
                            if tournament.name else '') + system.name
                    if name == resultName:
                        keepGoing = False
                        break
                if not keepGoing:
                    break

            heatsMax = max(event.heatsMax for event in system.events)
            if heatsMax == 1:
                self.headerNames = [
                    u'Event', u'Bib', u'Name', u'Note', u'Team', u'    ',
                    u'Pos', u'Bib', u'Name', u'Note', u'Team', u'Time'
                ]
            else:
                self.headerNames = [
                    u'Event', u'Bib', u'Name', u'Note', u'Team', u'H1', u'H2',
                    u'H3', u'    ', u'Pos', u'Bib', u'Name', u'Note', u'Team',
                    u'Time'
                ]
            hideCols = self.getHideCols(self.headerNames)
            self.headerNames = [
                h for c, h in enumerate(self.headerNames) if c not in hideCols
            ]

            Utils.AdjustGridSize(self.grid,
                                 rowsRequired=len(system.events),
                                 colsRequired=len(self.headerNames))
            Utils.SetGridCellBackgroundColour(self.grid, wx.WHITE)

            self.setColNames()
            state = competition.state

            for row, event in enumerate(system.events):
                writeCell = WriteCell(self.grid, row)

                writeCell(u'{}'.format(row + 1))

                riders = [state.labels.get(c, None) for c in event.composition]
                writeCell(u'\n'.join([
                    u'{}'.format(rider.bib) if rider and rider.bib else ''
                    for rider in riders
                ]))
                if getattr(model, 'resultsShowNames', True):
                    writeCell(u'\n'.join([
                        rider.full_name if rider else u'' for rider in riders
                    ]))
                writeCell(u'\n'.join([
                    competition.getRelegationsWarningsStr(
                        rider.bib, event, True) if rider else u''
                    for rider in riders
                ]))
                if getattr(model, 'resultsShowTeams', True):
                    writeCell(u'\n'.join(
                        [rider.team if rider else '' for rider in riders]))

                if heatsMax != 1:
                    for heat in six.moves.range(heatsMax):
                        if event.heatsMax != 1:
                            writeCell(u'\n'.join(event.getHeatPlaces(heat +
                                                                     1)))
                        else:
                            writeCell(u'')

                #writeCell( u' ===> ', vert=wx.ALIGN_CENTRE )
                writeCell(' '.join(['', Arrow, '']), vert=wx.ALIGN_CENTRE)

                out = [event.winner] + event.others
                riders = [state.labels.get(c, None) for c in out]
                writeCell(u'\n'.join(u'{}'.format(i + 1)
                                     for i in six.moves.range(len(riders))))
                writeCell(u'\n'.join([
                    u'{}'.format(rider.bib if rider.bib else '')
                    if rider else '' for rider in riders
                ]))
                if getattr(model, 'resultsShowNames', True):
                    writeCell(u'\n'.join([
                        rider.full_name if rider else '' for rider in riders
                    ]))
                writeCell(u'\n'.join([
                    competition.getRelegationsWarningsStr(
                        rider.bib, event, False) if rider else u''
                    for rider in riders
                ]))
                if getattr(model, 'resultsShowTeams', True):
                    writeCell(u'\n'.join(
                        [rider.team if rider else '' for rider in riders]))
                if event.winner in state.labels:
                    try:
                        value = u'%.3f' % event.starts[-1].times[1]
                    except (KeyError, IndexError, ValueError):
                        value = ''
                    writeCell(value)

            competitionTime = system.competitionTime
            self.competitionTime.SetLabel(u'{}: {}'.format(
                _('Est. Competition Time'), Utils.formatTime(competitionTime)
            ) if competitionTime else u'')

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

    def commit(self):
        model = Model.model
        phase = self.getPhase()
        cn = self.communiqueNumber.GetValue()
        if cn != model.communique_number.get(phase, u''):
            model.communique_number[phase] = cn
            model.setChanged()
Exemple #14
0
class TTResults(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.headerNames = ['Pos', 'Bib', 'Name', 'Team', 'Time']

        self.grid = ReorderableGrid(self, style=wx.BORDER_SUNKEN)
        self.grid.DisableDragRowSize()
        self.grid.SetRowLabelSize(0)
        self.grid.CreateGrid(0, len(self.headerNames))
        self.setColNames()
        self.grid.EnableReorderRows(False)

        # Set a larger font for the table.
        # Set specialized editors for appropriate columns.
        font = GetFont()
        self.grid.SetLabelFont(font)
        for col in six.moves.range(self.grid.GetNumberCols()):
            attr = gridlib.GridCellAttr()
            attr.SetFont(font)
            if col == self.grid.GetNumberCols() - 1:
                attr.SetRenderer(gridlib.GridCellFloatRenderer(-1, 3))
                attr.SetEditor(gridlib.GridCellFloatEditor(-1, 3))
            else:
                if col in (0, 1):
                    attr.SetRenderer(gridlib.GridCellNumberRenderer())
                attr.SetReadOnly(True)
            self.grid.SetColAttr(col, attr)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.grid, 1, flag=wx.EXPAND | wx.ALL, border=6)
        self.SetSizer(sizer)

    def setColNames(self):
        for col, headerName in enumerate(self.headerNames):
            self.grid.SetColLabelValue(col, headerName)

    def getGrid(self):
        return self.grid

    def refresh(self):
        riders = sorted(Model.model.riders, key=lambda r: r.qualifyingTime)
        starters = Model.model.competition.starters

        Utils.AdjustGridSize(self.grid, rowsRequired=len(riders))
        for row, r in enumerate(riders):
            if row < starters:
                pos = u'{}'.format(row + 1)
            else:
                pos = 'DNQ'
                for col in six.moves.range(self.grid.GetNumberCols()):
                    self.grid.SetCellBackgroundColour(row, col,
                                                      wx.Colour(200, 200, 200))
            for col, value in enumerate([
                    pos, u' {}'.format(r.bib), r.full_name, r.team,
                    '%.3f' % r.qualifyingTime
            ]):
                self.grid.SetCellValue(row, col, value)

        self.grid.AutoSizeColumns(False)
        self.grid.AutoSizeRows(False)

    def commit(self):
        pass