def mouseMoveEvent(self, event): columnCount = len(self.dents) if columnCount == 0: return # nothing to do... and division by zero errors! columnWidth = (self.width() - self.timeOffset) / columnCount rect = QtCore.QRectF(0, self.headingHeight, self.timeOffset, self.height() - self.headingHeight) if rect.contains(event.pos()): # mouse is over the time column self.leaveEvent(event) return for col, dent in enumerate(self.dents): leftx = self.timeOffset + col * columnWidth # headings rect = QtCore.QRectF(leftx, 0, columnWidth, self.headingHeight) if rect.contains(event.pos()): self.selected_rect = rect QtWidgets.QToolTip.showText(event.globalPos(), dent.memo) return 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 rect.contains(event.pos()): self.selected_rect = rect feedback = '%d %s %s %s %s' % ( slot.length, _("mins starting at"), slot.date_time.strftime("%H:%M"), _("with"), dent.initials) QtWidgets.QToolTip.showText(event.globalPos(), feedback) self.update() return for appt in (self.appts[dent.ix] + self.eTimes[dent.ix] + 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 rect.contains(event.pos()): self.selected_rect = rect self.update() return self.selected_rect = None self.update()
def block_appt(bldate, apptix, start, end, bl_start, bl_end, reason): ''' put a block in the book, with text set as reason ''' #- 1st check the block is free slots = future_slots(bldate, bldate, (apptix,)) date_time = datetime.datetime.combine(bldate, start) block_length = (localsettings.pyTimeToMinutesPastMidnight(end) - localsettings.pyTimeToMinutesPastMidnight(start)) this_slot = FreeSlot(date_time, apptix, block_length) #-- check block still available!! found = False for slot in slots: if slot == this_slot: found = True break if not found: return False db = connect() cursor = db.cursor() query = '''INSERT INTO aslot (adate, apptix, start, end, name, serialno, code0, code1, code2, note, flag0, flag1, flag2, flag3) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)''' values = (bldate, apptix, localsettings.pyTimetoWystime(bl_start), localsettings.pyTimetoWystime(bl_end), reason, 0, "", "", "", "", -128, 0, 0, 0) if cursor.execute(query, values): #-- insert call.. so this will always be true unless we have key #-- value errors? db.commit() result = True else: print "couldn't insert into aslot %s %s %s" % ( bldate, apptix, start) result = False cursor.close() # db.close() return result
def block_appt(bldate, apptix, start, end, bl_start, bl_end, reason): ''' put a block in the book, with text set as reason ''' #- 1st check the block is free slots = future_slots(bldate, bldate, (apptix, )) date_time = datetime.datetime.combine(bldate, start) block_length = (localsettings.pyTimeToMinutesPastMidnight(end) - localsettings.pyTimeToMinutesPastMidnight(start)) this_slot = FreeSlot(date_time, apptix, block_length) #-- check block still available!! found = False for slot in slots: if slot == this_slot: found = True break if not found: return False db = connect() cursor = db.cursor() query = '''INSERT INTO aslot (adate, apptix, start, end, name, serialno, code0, code1, code2, note, flag0, flag1, flag2, flag3) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)''' values = (bldate, apptix, localsettings.pyTimetoWystime(bl_start), localsettings.pyTimetoWystime(bl_end), reason, 0, "", "", "", "", -128, 0, 0, 0) if cursor.execute(query, values): #-- insert call.. so this will always be true unless we have key #-- value errors? db.commit() result = True else: print "couldn't insert into aslot %s %s %s" % (bldate, apptix, start) result = False cursor.close() # db.close() return result
def mouseMoveEvent(self, event): col = 0 columnCount = len(self.dents) if columnCount == 0: return # nothing to do... and division by zero errors! columnWidth = (self.width() - self.timeOffset) / columnCount for dent in self.dents: leftx = self.timeOffset + (col) * columnWidth rightx = self.timeOffset + (col + 1) * columnWidth ###headings rect = QtCore.QRect(leftx, 0, columnWidth, self.headingHeight) if rect.contains(event.pos()): self.highlightedRect = rect QtGui.QToolTip.showText(event.globalPos(), dent.memo) 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, slot.date_time.strftime("%H:%M"), dent.initials, ) QtGui.QToolTip.showText(event.globalPos(), QtCore.QString(feedback)) break for appt in self.appts[dent.ix] + self.eTimes[dent.ix] + self.lunches[dent.ix]: if self.daystart[dent.ix] <= appt.mpm < self.dayend[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 break col += 1 self.update()
def fill_appt(bldate, apptix, start, end, bl_start, bl_end, reason, pt): ''' this is the procedure called when making an appointment via clicking on a free slot in a DAY view. ''' #- 1st check the block is free slots = future_slots(bldate, bldate, (apptix,)) date_time = datetime.datetime.combine(bldate, start) block_length = (localsettings.pyTimeToMinutesPastMidnight(end) - localsettings.pyTimeToMinutesPastMidnight(start)) this_slot = FreeSlot(date_time, apptix, block_length) #-- check block still available!! found = False for slot in slots: if slot == this_slot: found = True break if not found: return False name = "%s %s *" % (pt.fname, pt.sname) try: cset = ord(pt.cset[0]) except: cset = 0 make_appt(bldate, apptix, localsettings.pyTimetoWystime(bl_start), localsettings.pyTimetoWystime(bl_end), name, pt.serialno, reason, "", "", "", 1, cset, 0, 0) block_length = (localsettings.pyTimeToMinutesPastMidnight(bl_end) - localsettings.pyTimeToMinutesPastMidnight(bl_start)) aprix = add_pt_appt(pt.serialno, apptix, block_length, reason) print "adjust pt diary" return pt_appt_made(pt.serialno, aprix, bldate, localsettings.pyTimetoWystime(bl_start), apptix)
def fill_appt(bldate, apptix, start, end, bl_start, bl_end, reason, pt): ''' this is the procedure called when making an appointment via clicking on a free slot in a DAY view. ''' #- 1st check the block is free slots = future_slots(bldate, bldate, (apptix, )) date_time = datetime.datetime.combine(bldate, start) block_length = (localsettings.pyTimeToMinutesPastMidnight(end) - localsettings.pyTimeToMinutesPastMidnight(start)) this_slot = FreeSlot(date_time, apptix, block_length) #-- check block still available!! found = False for slot in slots: if slot == this_slot: found = True break if not found: return False name = "%s %s *" % (pt.fname, pt.sname) try: cset = ord(pt.cset[0]) except: cset = 0 make_appt(bldate, apptix, localsettings.pyTimetoWystime(bl_start), localsettings.pyTimetoWystime(bl_end), name, pt.serialno, reason, "", "", "", 1, cset, 0, 0) block_length = (localsettings.pyTimeToMinutesPastMidnight(bl_end) - localsettings.pyTimeToMinutesPastMidnight(bl_start)) aprix = add_pt_appt(pt.serialno, apptix, block_length, reason) print "adjust pt diary" return pt_appt_made(pt.serialno, aprix, bldate, localsettings.pyTimetoWystime(bl_start), apptix)
def __init__(self, slotstarttime, slotLength, apptLength, parent=None): super(ftDialog, self).__init__(parent) self.setupUi(self) self.starttime = localsettings.pyTimeToMinutesPastMidnight(slotstarttime) self.maxtime = self.starttime + slotLength self.length = apptLength self.minslotlength = 5 self.selectedTime = slotstarttime # the value the user chooses self.verticalSlider.setMinimum(self.starttime // self.minslotlength) self.verticalSlider.setMaximum((self.maxtime - self.length) // self.minslotlength) self.verticalSlider.valueChanged.connect(self.updateLabels) self.updateLabels(self.verticalSlider.value())
def mouseMoveEvent(self, event): col = 0 columnCount = len(self.dents) if columnCount == 0: return # nothing to do... and division by zero errors! columnWidth = (self.width() - self.timeOffset) / columnCount for dent in self.dents: leftx = self.timeOffset + (col) * columnWidth rightx = self.timeOffset + (col + 1) * columnWidth # headings rect = QtCore.QRect(leftx, 0, columnWidth, self.headingHeight) if rect.contains(event.pos()): self.highlightedRect = rect QtGui.QToolTip.showText(event.globalPos(), dent.memo) 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, slot.date_time.strftime("%H:%M"), dent.initials) QtGui.QToolTip.showText(event.globalPos(), QtCore.QString(feedback)) break for appt in (self.appts[dent.ix] + self.eTimes[dent.ix] + self.lunches[dent.ix]): if (self.daystart[dent.ix] <= appt.mpm < self.dayend[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 break col += 1 self.update()
def __init__(self, slotstarttime, slotLength, apptLength, parent=None): super(ftDialog, self).__init__(parent) self.setupUi(self) self.starttime = localsettings.pyTimeToMinutesPastMidnight( slotstarttime) self.maxtime = self.starttime + slotLength self.length = apptLength self.minslotlength = 5 self.selectedTime = slotstarttime # the value the user chooses self.verticalSlider.setMinimum(self.starttime // self.minslotlength) self.verticalSlider.setMaximum( (self.maxtime - self.length) // self.minslotlength) self.verticalSlider.valueChanged.connect(self.updateLabels) self.updateLabels(self.verticalSlider.value())
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 for col, dent in enumerate(self.dents): # did user click a heading? leftx = self.timeOffset + col * columnWidth rect = QtCore.QRect(leftx, 0, columnWidth, self.headingHeight) if rect.contains(event.pos()): self.selected_rect = rect self.header_clicked_signal.emit(dent.ix, self.date) return for slot in self.freeslots.get(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.slot_clicked_signal.emit(slot) return special_click = (event.type() == QtCore.QEvent.MouseButtonDblClick or event.button() == QtCore.Qt.RightButton ) # double or right click leftx = self.timeOffset + col * columnWidth 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.selected_rect = rect if special_click: self.cancel_appointment_signal.emit( (appt.serialno, ), "%d:%02d" % (appt.mpm // 60, appt.mpm % 60), dent.ix, self.date.toPyDate()) else: self.appt_clicked_signal.emit( appt.to_appt(self.date.toPyDate(), dent.ix)) return self.appt_clicked_signal.emit(None) for appt in self.lunches[dent.ix] + 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.selected_rect = rect start = "%d:%02d" % (appt.mpm // 60, appt.mpm % 60) finish = "%d:%02d" % ((appt.mpm + appt.length) // 60, (appt.mpm + appt.length) % 60) self.clear_slot_signal.emit(start, finish, dent.ix, self.date.toPyDate()) return
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 for col, dent in enumerate(self.dents): # did user click a heading? leftx = self.timeOffset + col * columnWidth rect = QtCore.QRect(leftx, 0, columnWidth, self.headingHeight) if rect.contains(event.pos()): self.selected_rect = rect self.header_clicked_signal.emit(dent.ix, self.date) return for slot in self.freeslots.get(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.slot_clicked_signal.emit(slot) return special_click = ( event.type() == QtCore.QEvent.MouseButtonDblClick or event.button() == QtCore.Qt.RightButton ) # double or right click leftx = self.timeOffset + col * columnWidth 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.selected_rect = rect if special_click: self.cancel_appointment_signal.emit( (appt.serialno,), "%d:%02d" % (appt.mpm // 60, appt.mpm % 60), dent.ix, self.date.toPyDate()) else: self.appt_clicked_signal.emit( appt.to_appt(self.date.toPyDate(), dent.ix)) return self.appt_clicked_signal.emit(None) for appt in self.lunches[dent.ix] + 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.selected_rect = rect start = "%d:%02d" % (appt.mpm // 60, appt.mpm % 60) finish = "%d:%02d" % ((appt.mpm + appt.length) // 60, (appt.mpm + appt.length) % 60) self.clear_slot_signal.emit(start, finish, dent.ix, self.date.toPyDate()) return
def mpm(self): return localsettings.pyTimeToMinutesPastMidnight(self.time())
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)
def mouseMoveEvent(self, event): columnCount = len(self.dents) if columnCount == 0: return # nothing to do... and division by zero errors! columnWidth = (self.width() - self.timeOffset) / columnCount rect = QtCore.QRectF(0, self.headingHeight, self.timeOffset, self.height() - self.headingHeight) if rect.contains(event.pos()): # mouse is over the time column self.leaveEvent(event) return for col, dent in enumerate(self.dents): leftx = self.timeOffset + col * columnWidth # headings rect = QtCore.QRectF(leftx, 0, columnWidth, self.headingHeight) if rect.contains(event.pos()): self.selected_rect = rect QtWidgets.QToolTip.showText(event.globalPos(), dent.memo) return 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 rect.contains(event.pos()): self.selected_rect = rect feedback = '%d %s %s %s %s' % ( slot.length, _("mins starting at"), slot.date_time.strftime("%H:%M"), _("with"), dent.initials) QtWidgets.QToolTip.showText(event.globalPos(), feedback) self.update() return for appt in (self.appts[dent.ix] + self.eTimes[dent.ix] + 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 rect.contains(event.pos()): self.selected_rect = rect self.update() return self.selected_rect = None self.update()