def updateLabels(self, arg):
     minB4 = (arg - self.verticalSlider.minimum()) * self.minslotlength
     minL8r = (self.verticalSlider.maximum() - arg) * self.minslotlength
     self.selectedTime = localsettings.minutesPastMidnighttoPytime(
         self.starttime + minB4)
     self.minutesB4label.setText("%d minutes" % minB4)
     self.apptTimelabel.setText("%s - %s" % (
         localsettings.humanTime(arg * self.minslotlength),
         localsettings.humanTime(arg * self.minslotlength + self.length)))
     self.minutesL8Rlabel.setText("%d minutes" % minL8r)
예제 #2
0
 def updateLabels(self, arg):
     minB4 = (arg - self.verticalSlider.minimum()) * self.minslotlength
     minL8r = (self.verticalSlider.maximum() - arg) * self.minslotlength
     self.selectedTime = localsettings.minutesPastMidnighttoPytime(
         self.starttime + minB4)
     self.minutesB4label.setText("%d minutes" % minB4)
     self.apptTimelabel.setText(
         "%s - %s" %
         (localsettings.humanTime(arg * self.minslotlength),
          localsettings.humanTime(arg * self.minslotlength + self.length)))
     self.minutesL8Rlabel.setText("%d minutes" % minL8r)
예제 #3
0
    def paintEvent(self, event=None):
        '''
        draws the widget - recalled at any point by instance.update()
        '''

        if len(self.dents) == 0:
            return  # blank widget if no dents working
        self.dragLine = None

        painter = QtGui.QPainter(self)
        painter.setBrush(BGCOLOR)

        currentSlot = 0

        self.font.setPointSize(localsettings.appointmentFontSize)
        fm = QtGui.QFontMetrics(self.font)
        painter.setFont(self.font)

        self.timeOffset = fm.width(" 88:88 ")
        self.headingHeight = fm.height()

        self.slotHeight = (self.height() - self.headingHeight) / self.slotCount

        columnCount = len(self.dents)

        if columnCount == 0:
            columnCount = 1  # avoid division by zero!!
        columnWidth = (self.width() - self.timeOffset) / columnCount

        # put the times down the side

        while currentSlot < self.slotCount:
            # offset the first time.
            if (currentSlot + 2) % self.textDetail == 0:
                y = 0.8 * self.headingHeight + currentSlot * self.slotHeight
                trect = QtCore.QRectF(0, y, self.timeOffset,
                                      self.textDetail * self.slotHeight)
                painter.setPen(BLACK_PEN)
                slot_time = self.startTime + currentSlot * self.slotLength
                painter.drawText(trect, QtCore.Qt.AlignHCenter,
                                 localsettings.humanTime(slot_time))

            currentSlot += 1
            col = 0

        highlighted_rect = None
        highlighted_rects = []

        for dent in self.dents:
            leftx = self.timeOffset + col * columnWidth
            rightx = self.timeOffset + (col + 1) * columnWidth
            # headings
            painter.setPen(BLACK_PEN)
            painter.setBrush(APPTCOLORS["HEADER"])
            rect = QtCore.QRectF(leftx, 0, columnWidth, self.headingHeight)
            painter.drawRoundedRect(rect, 5, 5)
            initials = localsettings.apptix_reverse.get(dent.ix)
            if dent.memo != "":
                initials = "*%s*" % initials
            painter.drawText(rect, QtCore.Qt.AlignHCenter, initials)

            # dentist start/finish
            painter.setBrush(BGCOLOR)

            startcell = ((self.daystart[dent.ix] - self.startTime) /
                         self.slotLength)

            length = self.dayend[dent.ix] - self.daystart[dent.ix]

            startY = startcell * self.slotHeight + self.headingHeight
            endY = (length / self.slotLength) * self.slotHeight
            rect = QtCore.QRectF(leftx, startY, columnWidth, endY)

            if self.flagDict[dent.ix]:
                # don't draw a white canvas if dentist is out of office
                # a white canvas
                painter.save()
                painter.drawRect(rect)

                # grey lines
                painter.setPen(GREYLINE_PEN)
                y = startY
                while y < startY + endY:
                    painter.drawLine(leftx, y, rightx, y)
                    y += self.slotHeight / 2

                painter.restore()
                painter.setPen(BLACK_PEN)
                # emergencies
                for appt in self.eTimes[dent.ix]:
                    painter.save()
                    if (self.daystart[dent.ix] <= appt.mpm <
                            self.dayend[dent.ix]):
                        startcell = (appt.mpm -
                                     self.startTime) / self.slotLength

                        rect = QtCore.QRectF(
                            leftx,
                            startcell * self.slotHeight + self.headingHeight,
                            columnWidth,
                            (appt.length / self.slotLength) * self.slotHeight)
                        if self.mode == self.SCHEDULING_MODE:
                            painter.setBrush(APPTCOLORS["BUSY"])
                            painter.setPen(GREY_PEN)
                        elif appt.isEmergency:
                            painter.setBrush(APPTCOLORS["EMERGENCY"])
                        elif appt.name.upper() in APPTCOLORS:
                            painter.setBrush(APPTCOLORS[appt.name.upper()])
                        # elif appt.cset in APPTCOLORS:
                        #     painter.setBrush(APPTCOLORS[appt.cset])
                        else:
                            painter.setBrush(APPTCOLORS["default"])

                        painter.drawRect(rect)
                        text = appt.name[:5]
                        if len(text) < len(appt.name):
                            text += ".."
                        painter.drawText(rect, QtCore.Qt.AlignLeft, text)

                    painter.restore()

                painter.save()
                painter.setBrush(APPTCOLORS["LUNCH"])
                for appt in self.lunches[dent.ix]:
                    if (self.daystart[dent.ix] <= appt.mpm <
                            self.dayend[dent.ix]):
                        startcell = \
                            (appt.mpm - self.startTime) / self.slotLength

                        rect = QtCore.QRectF(
                            leftx,
                            startcell * self.slotHeight + self.headingHeight,
                            columnWidth,
                            (appt.length / self.slotLength) * self.slotHeight)

                        if self.mode == self.SCHEDULING_MODE:
                            painter.setPen(GREY_PEN)
                        else:
                            painter.setPen(BLACK_PEN)

                        painter.drawRect(rect)
                        painter.drawText(rect, _("Lunch"), CENTRE_OPTION)
                painter.restore()

                # appts
                for appt in self.appts[dent.ix]:
                    if (self.diary_widget.pt and appt.serialno
                            == self.diary_widget.pt.serialno):
                        painter.setBrush(APPTCOLORS["current_patient"])
                    elif self.mode == self.SCHEDULING_MODE:
                        painter.setPen(GREY_PEN)
                        painter.setBrush(APPTCOLORS["BUSY"])
                    elif appt.name.upper() in APPTCOLORS:
                        painter.setBrush(APPTCOLORS[appt.name.upper()])
                    elif appt.cset in APPTCOLORS:
                        painter.setBrush(APPTCOLORS[appt.cset])
                    else:
                        painter.setBrush(APPTCOLORS["BUSY"])

                    startcell = (appt.mpm - self.startTime) / self.slotLength

                    rect = QtCore.QRectF(
                        leftx,
                        startcell * self.slotHeight + self.headingHeight,
                        columnWidth,
                        (appt.length / self.slotLength) * self.slotHeight)

                    painter.drawRoundedRect(rect, 5, 5)

                    text = appt.trt[:5]
                    if len(text) < len(appt.trt):
                        text += ".."
                    painter.drawText(rect, text, CENTRE_OPTION)

                    h_app = self.diary_widget.highlighted_appointment
                    if h_app:
                        # print h_app, appt
                        if appt.serialno == h_app.serialno:
                            appt.apptix = dent.ix
                            if h_app == appt:
                                highlighted_rect = rect
                            else:
                                highlighted_rects.append(rect)

                # slots
                painter.save()
                for slot in self.freeslots.get(dent.ix, []):
                    slotstart = localsettings.pyTimeToMinutesPastMidnight(
                        slot.date_time.time())
                    startcell = (slotstart - self.startTime) / self.slotLength

                    rect = QtCore.QRectF(
                        leftx,
                        startcell * self.slotHeight + self.headingHeight,
                        columnWidth,
                        (slot.length / self.slotLength) * self.slotHeight)

                    if slot.is_primary:
                        brush = APPTCOLORS["SLOT"]
                    else:
                        brush = APPTCOLORS["SLOT2"]
                    if slot in self.active_slots:
                        painter.setPen(BIG_RED_PEN)
                        if self.blink_on:
                            painter.setOpacity(1)
                        else:
                            painter.setOpacity(0.3)
                    else:
                        painter.setPen(RED_PEN)
                        painter.setOpacity(0.6)
                    painter.setBrush(brush)
                    painter.drawRoundedRect(rect.adjusted(1, 0, -1, 0), 5, 5)
                    painter.setOpacity(1)
                    painter.drawText(rect, QtCore.Qt.AlignCenter,
                                     "%s" % slot.length)
                painter.restore()

                # drag drop

                if (self.is_dragging and self.mouse_drag_rect[0] == dent.ix):
                    painter.save()

                    rect = self.mouse_drag_rect[1]

                    painter.setBrush(APPTCOLORS["ACTIVE_SLOT"])
                    painter.drawRect(rect)
                    painter.setPen(RED_PEN)

                    height = (self.drag_appt.length / self.slotLength) \
                        * self.slotHeight

                    rect = QtCore.QRectF(leftx, self.dropPos.y(),
                                         columnWidth - 1, height)
                    painter.drawRect(rect)

                    self.dragLine = QtCore.QLine(0, self.dropPos.y(),
                                                 self.width(),
                                                 self.dropPos.y())

                    trect = QtCore.QRectF(0, self.dropPos.y(), self.timeOffset,
                                          height)

                    painter.drawRect(trect)
                    painter.drawText(trect, QtCore.Qt.AlignHCenter,
                                     localsettings.humanTime(self.drop_time()))

                    painter.restore()

            if col > 0:
                painter.save()
                painter.setPen(BLACK_PEN)
                painter.drawLine(leftx, 0, leftx, self.height())
                painter.restore()
            col += 1

        painter.setBrush(TRANSPARENT)
        if self.selected_rect is not None:
            painter.setPen(ORANGE_PEN)
            painter.drawRoundedRect(self.selected_rect, 5, 5)
        if highlighted_rect:
            painter.setPen(BIG_RED_PEN)
            painter.drawRect(highlighted_rect.adjusted(2, 0, -2, 0))
        for h_rect in highlighted_rects:
            painter.setPen(RED_PEN)
            painter.drawRect(h_rect)

        if self.dragLine:
            painter.setPen(RED_PEN)
            painter.drawLine(self.dragLine)
    def paintEvent(self, event=None):
        '''
        draws the widget - recalled at any point by instance.update()
        '''

        if len(self.dents) == 0:
            return  # blank widget if no dents working
        self.dragLine = None

        painter = QtGui.QPainter(self)
        painter.setBrush(BGCOLOR)

        currentSlot = 0

        self.font.setPointSize(localsettings.appointmentFontSize)
        fm = QtGui.QFontMetrics(self.font)
        painter.setFont(self.font)

        self.timeOffset = fm.width(" 88:88 ")
        self.headingHeight = fm.height()

        self.slotHeight = (
            self.height() - self.headingHeight) / self.slotCount

        columnCount = len(self.dents)

        if columnCount == 0:
            columnCount = 1  # avoid division by zero!!
        columnWidth = (self.width() - self.timeOffset) / columnCount

        # put the times down the side

        while currentSlot < self.slotCount:
            # offset the first time.
            if (currentSlot + 2) % self.textDetail == 0:
                y = 0.8 * self.headingHeight + currentSlot * self.slotHeight
                trect = QtCore.QRectF(
                    0,
                    y,
                    self.timeOffset,
                    self.textDetail * self.slotHeight)
                painter.setPen(BLACK_PEN)
                slot_time = self.startTime + currentSlot * self.slotLength
                painter.drawText(
                    trect, QtCore.Qt.AlignHCenter,
                    localsettings.humanTime(slot_time))

            currentSlot += 1
            col = 0

        highlighted_rect = None
        highlighted_rects = []

        for dent in self.dents:
            leftx = self.timeOffset + col * columnWidth
            rightx = self.timeOffset + (col + 1) * columnWidth
            # headings
            painter.setPen(BLACK_PEN)
            painter.setBrush(APPTCOLORS["HEADER"])
            rect = QtCore.QRectF(leftx, 0, columnWidth, self.headingHeight)
            painter.drawRoundedRect(rect, 5, 5)
            initials = localsettings.apptix_reverse.get(dent.ix)
            if dent.memo != "":
                initials = "*%s*" % initials
            painter.drawText(rect, QtCore.Qt.AlignHCenter, initials)

            # dentist start/finish
            painter.setBrush(BGCOLOR)

            startcell = ((self.daystart[dent.ix] - self.startTime) /
                         self.slotLength)

            length = self.dayend[dent.ix] - self.daystart[dent.ix]

            startY = startcell * self.slotHeight + self.headingHeight
            endY = (length / self.slotLength) * self.slotHeight
            rect = QtCore.QRectF(leftx, startY, columnWidth, endY)

            if self.flagDict[dent.ix]:
                # don't draw a white canvas if dentist is out of office
                # a white canvas
                painter.save()
                painter.drawRect(rect)

                # grey lines
                painter.setPen(GREYLINE_PEN)
                y = startY
                while y < startY + endY:
                    painter.drawLine(leftx, y, rightx, y)
                    y += self.slotHeight / 2

                painter.restore()
                painter.setPen(BLACK_PEN)
                # emergencies
                for appt in self.eTimes[dent.ix]:
                    painter.save()
                    if (self.daystart[dent.ix] <= appt.mpm <
                            self.dayend[dent.ix]):
                        startcell = (
                            appt.mpm - self.startTime) / self.slotLength

                        rect = QtCore.QRectF(
                            leftx,
                            startcell * self.slotHeight +
                            self.headingHeight,
                            columnWidth,
                            (appt.length / self.slotLength) * self.slotHeight)
                        if self.mode == self.SCHEDULING_MODE:
                            painter.setBrush(APPTCOLORS["BUSY"])
                            painter.setPen(GREY_PEN)
                        elif appt.isEmergency:
                            painter.setBrush(APPTCOLORS["EMERGENCY"])
                        elif appt.name.upper() in APPTCOLORS:
                            painter.setBrush(APPTCOLORS[appt.name.upper()])
                        # elif appt.cset in APPTCOLORS:
                        #     painter.setBrush(APPTCOLORS[appt.cset])
                        else:
                            painter.setBrush(APPTCOLORS["default"])

                        painter.drawRect(rect)
                        text = appt.name[:5]
                        if len(text) < len(appt.name):
                            text += ".."
                        painter.drawText(rect, QtCore.Qt.AlignLeft, text)

                    painter.restore()

                painter.save()
                painter.setBrush(APPTCOLORS["LUNCH"])
                for appt in self.lunches[dent.ix]:
                    if (self.daystart[dent.ix] <= appt.mpm <
                            self.dayend[dent.ix]):
                        startcell = \
                            (appt.mpm - self.startTime) / self.slotLength

                        rect = QtCore.QRectF(
                            leftx,
                            startcell * self.slotHeight +
                            self.headingHeight,
                            columnWidth,
                            (appt.length / self.slotLength) * self.slotHeight)

                        if self.mode == self.SCHEDULING_MODE:
                            painter.setPen(GREY_PEN)
                        else:
                            painter.setPen(BLACK_PEN)

                        painter.drawRect(rect)
                        painter.drawText(rect, _("Lunch"), CENTRE_OPTION)
                painter.restore()

                # appts
                for appt in self.appts[dent.ix]:
                    if (self.diary_widget.pt and
                            appt.serialno == self.diary_widget.pt.serialno):
                        painter.setBrush(APPTCOLORS["current_patient"])
                    elif self.mode == self.SCHEDULING_MODE:
                        painter.setPen(GREY_PEN)
                        painter.setBrush(APPTCOLORS["BUSY"])
                    elif appt.name.upper() in APPTCOLORS:
                        painter.setBrush(APPTCOLORS[appt.name.upper()])
                    elif appt.cset in APPTCOLORS:
                        painter.setBrush(APPTCOLORS[appt.cset])
                    else:
                        painter.setBrush(APPTCOLORS["BUSY"])

                    startcell = (appt.mpm - self.startTime) / self.slotLength

                    rect = QtCore.QRectF(
                        leftx,
                        startcell * self.slotHeight + self.headingHeight,
                        columnWidth,
                        (appt.length / self.slotLength) * self.slotHeight
                    )

                    painter.drawRoundedRect(rect, 5, 5)

                    text = appt.trt[:5]
                    if len(text) < len(appt.trt):
                        text += ".."
                    painter.drawText(rect, text, CENTRE_OPTION)

                    h_app = self.diary_widget.highlighted_appointment
                    if h_app:
                        # print h_app, appt
                        if appt.serialno == h_app.serialno:
                            appt.apptix = dent.ix
                            if h_app == appt:
                                highlighted_rect = rect
                            else:
                                highlighted_rects.append(rect)

                # slots
                painter.save()
                for slot in self.freeslots.get(dent.ix, []):
                    slotstart = localsettings.pyTimeToMinutesPastMidnight(
                        slot.date_time.time())
                    startcell = (
                        slotstart - self.startTime) / self.slotLength

                    rect = QtCore.QRectF(
                        leftx,
                        startcell * self.slotHeight +
                        self.headingHeight,
                        columnWidth,
                        (slot.length / self.slotLength) * self.slotHeight)

                    if slot.is_primary:
                        brush = APPTCOLORS["SLOT"]
                    else:
                        brush = APPTCOLORS["SLOT2"]
                    if slot in self.active_slots:
                        painter.setPen(BIG_RED_PEN)
                        if self.blink_on:
                            painter.setOpacity(1)
                        else:
                            painter.setOpacity(0.3)
                    else:
                        painter.setPen(RED_PEN)
                        painter.setOpacity(0.6)
                    painter.setBrush(brush)
                    painter.drawRoundedRect(
                        rect.adjusted(1, 0, -1, 0),
                        5, 5)
                    painter.setOpacity(1)
                    painter.drawText(rect,
                                     QtCore.Qt.AlignCenter,
                                     "%s" % slot.length)
                painter.restore()

                # drag drop

                if (self.is_dragging and
                        self.mouse_drag_rect[0] == dent.ix):
                    painter.save()

                    rect = self.mouse_drag_rect[1]

                    painter.setBrush(APPTCOLORS["ACTIVE_SLOT"])
                    painter.drawRect(rect)
                    painter.setPen(RED_PEN)

                    height = (self.drag_appt.length / self.slotLength) \
                        * self.slotHeight

                    rect = QtCore.QRectF(leftx,
                                         self.dropPos.y(),
                                         columnWidth - 1, height)
                    painter.drawRect(rect)

                    self.dragLine = QtCore.QLine(0,
                                                 self.dropPos.y(),
                                                 self.width(),
                                                 self.dropPos.y())

                    trect = QtCore.QRectF(0,
                                          self.dropPos.y(),
                                          self.timeOffset,
                                          height)

                    painter.drawRect(trect)
                    painter.drawText(trect, QtCore.Qt.AlignHCenter,
                                     localsettings.humanTime(self.drop_time()))

                    painter.restore()

            if col > 0:
                painter.save()
                painter.setPen(BLACK_PEN)
                painter.drawLine(leftx, 0, leftx, self.height())
                painter.restore()
            col += 1

        painter.setBrush(TRANSPARENT)
        if self.selected_rect is not None:
            painter.setPen(ORANGE_PEN)
            painter.drawRoundedRect(self.selected_rect, 5, 5)
        if highlighted_rect:
            painter.setPen(BIG_RED_PEN)
            painter.drawRect(highlighted_rect.adjusted(2, 0, -2, 0))
        for h_rect in highlighted_rects:
            painter.setPen(RED_PEN)
            painter.drawRect(h_rect)

        if self.dragLine:
            painter.setPen(RED_PEN)
            painter.drawLine(self.dragLine)
    def mousePressEvent(self, event):
        '''
        catch the mouse press event -
        and if you have clicked on an appointment, emit a signal
        the signal has a LIST as argument -
        in case there are overlapping appointments or doubles etc...
        '''

        columnCount = len(self.dents)
        if columnCount == 0:
            return  # nothing to do... and division by zero errors!

        columnWidth = (self.width() - self.timeOffset) / columnCount

        col = 0
        for dent in self.dents:  # did user click a heading?
            leftx = self.timeOffset + col * columnWidth
            rightx = self.timeOffset + (col + 1) * columnWidth
            rect = QtCore.QRect(leftx, 0, columnWidth, self.headingHeight)
            if rect.contains(event.pos()):
                self.highlightedRect = rect
                self.emit(
                    QtCore.SIGNAL("DentistHeading"), (dent.ix, self.date))
                return
            if event.button() == 1:  # left click
                for slot in self.freeslots[dent.ix]:
                    slotstart = localsettings.pyTimeToMinutesPastMidnight(
                        slot.date_time.time())
                    startcell = (
                        slotstart - self.startTime) / self.slotLength

                    rect = QtCore.QRect(leftx,
                                        startcell * self.slotHeight +
                                        self.headingHeight,
                                        columnWidth,
                                       (slot.length / self.slotLength) * self.slotHeight)

                    if rect.contains(event.pos()):
                        self.emit(QtCore.SIGNAL("SlotClicked"), slot)

                        break

            else:  # right click
                leftx = self.timeOffset + col * columnWidth
                rightx = self.timeOffset + (col + 1) * columnWidth

                for slot in self.freeslots[dent.ix]:
                    slotstart = localsettings.pyTimeToMinutesPastMidnight(
                        slot.date_time.time())
                    startcell = (
                        slotstart - self.startTime) / self.slotLength

                    rect = QtCore.QRect(leftx,
                                        startcell * self.slotHeight +
                                        self.headingHeight,
                                        columnWidth,
                                       (slot.length / self.slotLength) * self.slotHeight)

                    if rect.contains(event.pos()):
                        self.highlightedRect = rect
                        feedback = '%d mins starting at %s with %s' % (
                            slot.length,
                            localsettings.humanTime(slotstart),
                            dent.initials)

                        QtGui.QMessageBox.information(self, "Info",
                                                      "You've right clicked on a slot<br />%s" % feedback)
                        return

                for appt in self.appts[dent.ix]:
                    startcell = (appt.mpm - self.startTime) / self.slotLength

                    rect = QtCore.QRect(leftx,
                                        startcell * self.slotHeight +
                                        self.headingHeight,
                                        columnWidth,
                                       (appt.length / self.slotLength) * self.slotHeight)

                    if rect.contains(event.pos()):
                        self.highlightedRect = rect
                        feedback = '%d mins starting at %s with %s' % (
                            appt.length,
                            localsettings.humanTime(appt.mpm),
                            dent.initials)

                        QtGui.QMessageBox.information(self, "Info",
                                                      "You've right clicked on an appt<br />%s" % feedback)
                        return

                for appt in self.lunches[dent.ix]:
                    startcell = (appt.mpm - self.startTime) / self.slotLength

                    rect = QtCore.QRect(leftx,
                                        startcell * self.slotHeight +
                                        self.headingHeight,
                                        columnWidth,
                                       (appt.length / self.slotLength) * self.slotHeight)

                    if rect.contains(event.pos()):
                        self.highlightedRect = rect
                        feedback = '%d mins starting at %s with %s' % (
                            appt.length,
                            localsettings.humanTime(appt.mpm),
                            dent.initials)

                        QtGui.QMessageBox.information(self, "Info",
                                                      "You've right clicked Lunch<br />%s" % feedback)
                        return

                for appt in self.eTimes[dent.ix]:
                    startcell = (appt.mpm - self.startTime) / self.slotLength

                    rect = QtCore.QRect(leftx,
                                        startcell * self.slotHeight +
                                        self.headingHeight,
                                        columnWidth,
                                       (appt.length / self.slotLength) * self.slotHeight)

                    if rect.contains(event.pos()):
                        self.highlightedRect = rect
                        feedback = '%d mins starting at %s with %s' % (
                            appt.length,
                            localsettings.humanTime(appt.mpm),
                            dent.initials)

                        QtGui.QMessageBox.information(self, "Info",
                                                      "You've right clicked on an emergency slot<br />%s" %
                                                      feedback)
                        return
            col += 1
    def paintEvent(self, event=None):
        """
        draws the widget - recalled at any point by instance.update()
        """

        if len(self.dents) == 0:
            return  # blank widget if no dents working
        self.dragLine = None

        painter = QtGui.QPainter(self)
        painter.setBrush(BGCOLOR)

        currentSlot = 0

        self.font.setPointSize(localsettings.appointmentFontSize)
        fm = QtGui.QFontMetrics(self.font)
        painter.setFont(self.font)

        self.timeOffset = fm.width(" 88:88 ")
        self.headingHeight = fm.height()

        self.slotHeight = (self.height() - self.headingHeight) / self.slotCount

        columnCount = len(self.dents)

        if columnCount == 0:
            columnCount = 1  # avoid division by zero!!
        columnWidth = (self.width() - self.timeOffset) / columnCount
        dragWidth = columnWidth

        ## put the times down the side

        while currentSlot < self.slotCount:
            # offset the first time.
            if (currentSlot + 2) % self.textDetail == 0:
                y = 0.8 * self.headingHeight + currentSlot * self.slotHeight
                trect = QtCore.QRect(0, y, self.timeOffset, self.textDetail * self.slotHeight)
                painter.setPen(BLACK_PEN)

                painter.drawText(
                    trect,
                    QtCore.Qt.AlignHCenter,
                    localsettings.humanTime(self.startTime + (currentSlot * self.slotLength)),
                )

            currentSlot += 1
            col = 0

        for dent in self.dents:
            leftx = self.timeOffset + col * columnWidth
            rightx = self.timeOffset + (col + 1) * columnWidth
            ##headings
            painter.setPen(BLACK_PEN)
            painter.setBrush(APPTCOLORS["HEADER"])
            rect = QtCore.QRect(leftx, 0, columnWidth, self.headingHeight)
            painter.drawRect(rect)
            initials = localsettings.apptix_reverse.get(dent.ix)
            if dent.memo != "":
                initials = "*%s*" % initials
            painter.drawText(rect, QtCore.Qt.AlignHCenter, initials)

            ##dentist start/finish
            painter.setBrush(BGCOLOR)

            startcell = (self.daystart[dent.ix] - self.startTime) / self.slotLength

            length = self.dayend[dent.ix] - self.daystart[dent.ix]

            startY = startcell * self.slotHeight + self.headingHeight
            endY = (length / self.slotLength) * self.slotHeight
            rect = QtCore.QRectF(leftx, startY, columnWidth, endY)

            if self.flagDict[dent.ix]:
                # don't draw a white canvas if dentist is out of office
                # a white canvas
                painter.save()
                painter.drawRect(rect)

                ## grey lines
                painter.setPen(GREYLINE_PEN)
                y = startY
                while y < startY + endY:
                    painter.drawLine(leftx, y, rightx, y)
                    y += self.slotHeight / 2

                painter.restore()
                painter.setPen(BLACK_PEN)
                ###emergencies
                for appt in self.eTimes[dent.ix]:
                    painter.save()
                    if self.daystart[dent.ix] <= appt.mpm < self.dayend[dent.ix]:
                        startcell = (appt.mpm - self.startTime) / self.slotLength

                        rect = QtCore.QRectF(
                            leftx,
                            startcell * self.slotHeight + self.headingHeight,
                            columnWidth,
                            (appt.length / self.slotLength) * self.slotHeight,
                        )
                        if self.mode == self.SCHEDULING_MODE:
                            painter.setBrush(APPTCOLORS["BUSY"])
                            painter.setPen(GREY_PEN)
                        elif appt.isEmergency:
                            painter.setBrush(APPTCOLORS["EMERGENCY"])
                        elif APPTCOLORS.has_key(appt.name.upper()):
                            painter.setBrush(APPTCOLORS[appt.name.upper()])
                        elif APPTCOLORS.has_key(appt.cset):
                            painter.setBrush(APPTCOLORS[appt.cset])
                        else:
                            painter.setBrush(APPTCOLORS["default"])

                        painter.drawRect(rect)
                        text = appt.name[:5]
                        if len(text) < len(appt.name):
                            text += ".."
                        painter.drawText(rect, QtCore.Qt.AlignLeft, text)

                    painter.restore()

                painter.save()
                painter.setBrush(APPTCOLORS["LUNCH"])
                for appt in self.lunches[dent.ix]:
                    if self.daystart[dent.ix] <= appt.mpm < self.dayend[dent.ix]:
                        startcell = (appt.mpm - self.startTime) / self.slotLength

                        rect = QtCore.QRectF(
                            leftx,
                            startcell * self.slotHeight + self.headingHeight,
                            columnWidth,
                            (appt.length / self.slotLength) * self.slotHeight,
                        )

                        if self.mode == self.SCHEDULING_MODE:
                            painter.setPen(GREY_PEN)
                        else:
                            painter.setPen(BLACK_PEN)

                        painter.drawRect(rect)
                        painter.drawText(rect, QtCore.Qt.AlignCenter, "Lunch")
                painter.restore()

                ###appts
                for appt in self.appts[dent.ix]:
                    if self.om_gui.pt and appt.serialno == self.om_gui.pt.serialno:
                        painter.setBrush(APPTCOLORS["current_patient"])
                    elif self.mode == self.SCHEDULING_MODE:
                        painter.setPen(GREY_PEN)
                        painter.setBrush(APPTCOLORS["BUSY"])
                    elif APPTCOLORS.has_key(appt.name.upper()):
                        painter.setBrush(APPTCOLORS[appt.name.upper()])
                    elif APPTCOLORS.has_key(appt.cset):
                        painter.setBrush(APPTCOLORS[appt.cset])
                    else:
                        painter.setBrush(APPTCOLORS["BUSY"])

                    startcell = (appt.mpm - self.startTime) / self.slotLength

                    rect = QtCore.QRectF(
                        leftx,
                        startcell * self.slotHeight + self.headingHeight,
                        columnWidth,
                        (appt.length / self.slotLength) * self.slotHeight,
                    )

                    painter.drawRect(rect)

                    text = appt.trt[:5]
                    if len(text) < len(appt.trt):
                        text += ".."
                    painter.drawText(rect, QtCore.Qt.AlignLeft, text)

                ###slots

                painter.save()
                painter.setPen(GREY_PEN)
                for slot in self.freeslots[dent.ix]:
                    slotstart = localsettings.pyTimeToMinutesPastMidnight(slot.date_time.time())
                    startcell = (slotstart - self.startTime) / self.slotLength

                    rect = QtCore.QRectF(
                        leftx,
                        startcell * self.slotHeight + self.headingHeight,
                        columnWidth,
                        (slot.length / self.slotLength) * self.slotHeight,
                    )

                    painter.save()
                    if slot in self.active_slots:
                        if self.blink_on:
                            painter.setBrush(APPTCOLORS["ACTIVE_SLOT_BOLD"])
                        else:
                            painter.setBrush(APPTCOLORS["ACTIVE_SLOT"])
                        painter.setPen(RED_PEN)
                    else:
                        if slot.dent in self.enabled_clinicians:
                            painter.setOpacity(1)
                        else:
                            painter.setOpacity(0.4)
                        painter.setBrush(APPTCOLORS["SLOT"])
                    painter.drawRect(rect)

                    painter.setPen(RED_PEN)
                    painter.drawText(rect, QtCore.Qt.AlignCenter, "%s" % slot.length)
                    painter.restore()
                painter.restore()

                ## drag drop

                if self.is_dragging and self.mouse_drag_rect[0] == dent.ix:
                    painter.save()

                    rect = self.mouse_drag_rect[1]

                    painter.setBrush(APPTCOLORS["ACTIVE_SLOT"])
                    painter.drawRect(rect)
                    painter.setPen(RED_PEN)

                    height = (self.drag_appt.length / self.slotLength) * self.slotHeight

                    rect = QtCore.QRectF(leftx, self.dropPos.y(), columnWidth - 1, height)
                    painter.drawRect(rect)

                    self.dragLine = QtCore.QLine(0, self.dropPos.y(), self.width(), self.dropPos.y())

                    trect = QtCore.QRectF(0, self.dropPos.y(), self.timeOffset, height)

                    painter.drawRect(trect)
                    painter.drawText(trect, QtCore.Qt.AlignHCenter, localsettings.humanTime(self.drop_time()))

                    painter.restore()

            if col > 0:
                painter.save()
                painter.setPen(BLACK_PEN)
                painter.drawLine(leftx, 0, leftx, self.height())
                painter.restore()
            col += 1

        if self.highlightedRect != None:
            painter.setPen(RED_PEN)
            painter.setBrush(TRANSPARENT)
            painter.drawRect(self.highlightedRect)
        if self.dragLine:
            painter.setPen(RED_PEN)
            painter.drawLine(self.dragLine)