def redraw(self, base_time, all_tars, employee_id, additional_work_timetracks, additional_presence_timetracks, special_activities=None, view_title=""): scene = QGraphicsScene() # This scene line is a hack to make sure I can control the "centerOn" # execution as I wish. This is very hackish. margin = 30 scene.addLine( QLineF(0, 0, self.width() - margin, self.height() - margin), QPen(Qt.white)) # Dat is heeeel belangerijk om de goede computation te doen all_tars = sorted(all_tars, key=lambda tar: tar.time) # chrono.chrono_click("Redraw step 1") timetracks_tars = dao.task_action_report_dao.compute_activity_timetracks_from_task_action_reports( all_tars, employee_id) # We got (timetrack, reports) tuples timetracks = [tt[0] for tt in timetracks_tars] # presence_time, off_time, presence_timetracks = dao.task_action_report_dao.recompute_presence_on_tars(employee_id, all_tars) # chrono.chrono_click("Redraw step 2") presence_intervals = dao.task_action_report_dao.compute_man_presence_periods( employee_id, base_time, all_tars, timetracks=[], commit=True) # chrono.chrono_click("Redraw step 2B") presence_timetracks = dao.task_action_report_dao.convert_intervals_to_presence_timetracks( presence_intervals, employee_id) # chrono.chrono_click("Redraw step 3") # FIXME this will trigger a session open... Must use the ID without a query first! presence_task_id = dao.task_action_report_dao.presence_task_id_regular_time( ) # chrono.chrono_click("redraw") # mainlog.debug("About to draw ...") # mainlog.debug("additional presence is") # for tt in additional_presence_timetracks: # mainlog.debug(tt) # mainlog.debug("all_tars") # mainlog.debug(all_tars) # mainlog.debug("Timetracks...") # mainlog.debug(timetracks_tars) # mainlog.debug("Presenec Timetracks...") # mainlog.debug(presence_timetracks) if presence_timetracks == [] and additional_presence_timetracks: presence_timetracks += additional_presence_timetracks timetracks += additional_work_timetracks # mainlog.debug("Augmented Timetracks...") # mainlog.debug(timetracks) # mainlog.debug("Augmented Presence Timetracks...") # for tt in presence_timetracks: # mainlog.debug(tt) y = 0 dy = 60 # Title of the view if view_title: description = QGraphicsSimpleTextItem() description.setText(view_title) description.setFont(self.title_font) br = QRect(0, 0, description.boundingRect().width(), description.boundingRect().height()) description.setPos(0, 0) # y - br.height()/2) scene.addItem(description) y += max(br.height() * 2, dy) # Presence timeline pointages = [] for tar in all_tars: # mainlog.debug(tar) # mainlog.debug(tar.kind == TaskActionReportType.presence) if tar.kind == TaskActionReportType.presence: pointages.append((tar.time, Timeline.NO_DIR, tar, self._hoover_text_for(tar))) elif tar.kind in (TaskActionReportType.day_in, TaskActionReportType.start_task): pointages.append((tar.time, Timeline.START, tar, self._hoover_text_for(tar))) elif tar.kind in (TaskActionReportType.day_out, TaskActionReportType.stop_task): pointages.append( (tar.time, Timeline.END, tar, self._hoover_text_for(tar))) else: raise Exception("Unsupported TAR.kind. I get {}".format( tar.kind)) periods = [] for tt in presence_timetracks: periods.append( (tt.start_time, tt.start_time + timedelta(tt.duration / 24.0), None)) # Show the presence timeline pointages_for_presence = [ p for p in pointages if p[2].kind not in (TaskActionReportType.start_task, TaskActionReportType.stop_task) ] if pointages_for_presence: tl = Timeline(base_time, pointages_for_presence, periods, None, _("Presence"), QColor(Qt.green).darker(150)) tl.draw(scene, y) y += dy # Special activities time line if special_activities: periods = [] for sa in special_activities: desc = None if sa.activity_type: desc = sa.activity_type.description periods.append((sa.start_time, sa.end_time, desc)) tl = Timeline(base_time, None, periods, None, _("Absence"), QColor(Qt.red).darker(150)) tl.draw(scene, y) y += dy # Group task action reports according to their task task_tar = dict() for tar in all_tars: task_id = tar.task_id if task_id and task_id != presence_task_id: if not task_id in task_tar: task_tar[task_id] = [] if tar.kind == TaskActionReportType.start_task: task_tar[task_id].append((tar.time, Timeline.START, tar, self._hoover_text_for(tar))) elif tar.kind == TaskActionReportType.stop_task: task_tar[task_id].append((tar.time, Timeline.END, tar, self._hoover_text_for(tar))) # Group timetracks according to their task task_to_timetracks = dict() for timetrack in timetracks: task_id = timetrack.task_id if task_id and task_id != presence_task_id: if not task_id in task_to_timetracks: task_to_timetracks[task_id] = [] task_to_timetracks[task_id].append(timetrack) # Figure out all the tasks (because each task gives a timeline) # It is quite possible that some timetracks are not associated # to any TAR and vice versa. all_tasks = set() for t in timetracks: if t.task_id: all_tasks.add(t.task_id) for t in all_tars: if t.task_id: all_tasks.add(t.task_id) all_tasks = dao.task_dao.find_by_ids_frozen(all_tasks) # map(lambda t:t.task and all_tasks.add(t.task),timetracks) # map(lambda t:t.task and all_tasks.add(t.task),all_tars) # The presence stuff was drawn on a separate timeline => we won't draw # it here again. # Remove presence task (because it's already drawn). # FIXME I use the ID because of session handling all_tasks = list( filter(lambda t: t.task_id != presence_task_id, all_tasks)) for task in list(sorted(all_tasks, key=lambda a: a.description)): # Not all TAR have a timetrack ! periods = [] if task.task_id in task_to_timetracks: for tt in task_to_timetracks[task.task_id]: periods.append( (tt.start_time, tt.start_time + timedelta(tt.duration / 24.0), None)) tars = [] if task.task_id in task_tar: tars = task_tar[task.task_id] timeline_title = task.description # timeline_title = self._make_time_line_title(task) # This will provide nice and complete bar titles if task.type == TaskOnOperation: tl = Timeline(base_time, tars, periods, task, timeline_title, Qt.blue) else: tl = Timeline(base_time, tars, periods, task, timeline_title, Qt.red) tl.draw(scene, y) y += dy self.setScene(scene) # See the hack top of this method ! self.centerOn(-(self.width() - margin) / 2, (self.height() - margin) / 2)
class AddItem(UsesQApplication): '''Tests for QGraphicsScene.add*''' qapplication = True def setUp(self): #Acquire resources super(AddItem, self).setUp() self.scene = QGraphicsScene() # While the scene does not inherits from QWidget, requires # an application to make the internals work. def tearDown(self): #Release resources del self.scene super(AddItem, self).tearDown() def testEllipse(self): #QGraphicsScene.addEllipse item = self.scene.addEllipse(100, 100, 100, 100) self.assertTrue(isinstance(item, QGraphicsEllipseItem)) def testLine(self): #QGraphicsScene.addLine item = self.scene.addLine(100, 100, 200, 200) self.assertTrue(isinstance(item, QGraphicsLineItem)) def testPath(self): #QGraphicsScene.addPath item = self.scene.addPath(QPainterPath()) self.assertTrue(isinstance(item, QGraphicsPathItem)) def testPixmap(self): #QGraphicsScene.addPixmap item = self.scene.addPixmap(QPixmap()) self.assertTrue(isinstance(item, QGraphicsPixmapItem)) def testPolygon(self): #QGraphicsScene.addPolygon points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)] item = self.scene.addPolygon(QPolygonF(points)) self.assertTrue(isinstance(item, QGraphicsPolygonItem)) def testRect(self): #QGraphicsScene.addRect item = self.scene.addRect(100, 100, 100, 100) self.assertTrue(isinstance(item, QGraphicsRectItem)) def testSimpleText(self): #QGraphicsScene.addSimpleText item = self.scene.addSimpleText('Monty Python 42') self.assertTrue(isinstance(item, QGraphicsSimpleTextItem)) def testText(self): #QGraphicsScene.addText item = self.scene.addText('Monty Python 42') self.assertTrue(isinstance(item, QGraphicsTextItem)) def testWidget(self): #QGraphicsScene.addWidget # XXX: printing some X11 error when using under PyQt4 item = self.scene.addWidget(QPushButton()) self.assertTrue(isinstance(item, QGraphicsProxyWidget))
class AddItem(UsesQApplication): """Tests for QGraphicsScene.add*""" qapplication = True def setUp(self): # Acquire resources super(AddItem, self).setUp() self.scene = QGraphicsScene() # While the scene does not inherits from QWidget, requires # an application to make the internals work. def tearDown(self): # Release resources del self.scene super(AddItem, self).tearDown() def testEllipse(self): # QGraphicsScene.addEllipse item = self.scene.addEllipse(100, 100, 100, 100) self.assertTrue(isinstance(item, QGraphicsEllipseItem)) def testLine(self): # QGraphicsScene.addLine item = self.scene.addLine(100, 100, 200, 200) self.assertTrue(isinstance(item, QGraphicsLineItem)) def testPath(self): # QGraphicsScene.addPath item = self.scene.addPath(QPainterPath()) self.assertTrue(isinstance(item, QGraphicsPathItem)) def testPixmap(self): # QGraphicsScene.addPixmap item = self.scene.addPixmap(QPixmap()) self.assertTrue(isinstance(item, QGraphicsPixmapItem)) def testPolygon(self): # QGraphicsScene.addPolygon points = [QPointF(0, 0), QPointF(100, 100), QPointF(0, 100)] item = self.scene.addPolygon(QPolygonF(points)) self.assertTrue(isinstance(item, QGraphicsPolygonItem)) def testRect(self): # QGraphicsScene.addRect item = self.scene.addRect(100, 100, 100, 100) self.assertTrue(isinstance(item, QGraphicsRectItem)) def testSimpleText(self): # QGraphicsScene.addSimpleText item = self.scene.addSimpleText("Monty Python 42") self.assertTrue(isinstance(item, QGraphicsSimpleTextItem)) def testText(self): # QGraphicsScene.addText item = self.scene.addText("Monty Python 42") self.assertTrue(isinstance(item, QGraphicsTextItem)) def testWidget(self): # QGraphicsScene.addWidget # XXX: printing some X11 error when using under PyQt4 item = self.scene.addWidget(QPushButton()) self.assertTrue(isinstance(item, QGraphicsProxyWidget))