예제 #1
0
    def hoverEnterEvent(self, event):
        super(HooverBar, self).hoverEnterEvent(event)

        if self.gi == None:
            self.gi = QGraphicsRectItem(0, 0, 100, 100)
            self.gi.setBrush(QBrush(QColor(0, 64, 0, 192)))
            self.gi.setPen(QPen(Qt.transparent))
            self.gi.setPos(event.scenePos().x() + 20,
                           event.scenePos().y() + 20)

            x = y = 10
            w = 0
            for t in self.description:
                description = QGraphicsSimpleTextItem()
                description.setFont(self.base_font)
                description.setBrush(QBrush(Qt.white))
                description.setText(t)
                description.setParentItem(self.gi)
                description.setPos(x, y)
                y += description.boundingRect().height()
                w = max(w, description.boundingRect().width())
            y += x
            w += 2 * x

            self.gi.setRect(0, 0, w, y)
            self.scene().addItem(self.gi)
예제 #2
0
파일: PostView.py 프로젝트: wiz21b/koi
    def hoverEnterEvent(self, event):  # QGraphicsSceneHoverEvent * event )
        # BUG I had a crash running this, I suspect ownership issues regarding
        # graphics items...

        global configuration
        #mainlog.debug("hoverEnterEvent pos={}-{}".format(event.scenePos().x(),event.scenePos().y()))
        # mainlog.debug("hoverEnterEvent data={}".format(self.data))
        super(HooverBar, self).hoverEnterEvent(event)

        if self.gi == None:
            if self.hoover_text:
                self.gi = QGraphicsRectItem(0, 0, 100, 100)
                self.gi.setBrush(QBrush(QColor(0, 64, 0, 192)))
                self.gi.setPen(QPen(Qt.transparent))
                self.gi.setPos(event.scenePos().x() + 20,
                               event.scenePos().y() + 20)

                # txt = [ "" ]

                # txt = [ u"{} {}".format(self.data.production_file.order_part.human_identifier,
                #                        date_to_dmy(self.data.production_file.order_part.deadline)),
                #         nstr(self.data.production_file.order_part.description),
                #         nstr(self.data.description),
                #         _("{}x{}={}h, rest:{}h").format(self.data.production_file.order_part.qty,
                #                                         nice_round(self.data.planned_hours),
                #                                         nice_round(self.data.production_file.order_part.qty*self.data.planned_hours),
                #                                         nice_round(self.data.planned_hours*self.data.production_file.order_part.qty - self.data.done_hours))]

                x = y = 10
                w = 0
                for t in self.hoover_text:
                    description = QGraphicsSimpleTextItem()
                    description.setFont(self.base_font)
                    description.setBrush(QBrush(Qt.white))
                    description.setText(t)
                    description.setParentItem(self.gi)
                    description.setPos(x, y)
                    y += description.boundingRect().height()
                    w = max(w, description.boundingRect().width())
                y += x
                w += 2 * x

                # description.setHtml(u"|{}| <b>{}</b><br/>{}<br>{}x{}={}h".format(
                #         self.data.production_file.order_part.human_identifier,
                #         self.data.production_file.order_part.description,
                #         self.data.description,
                #         self.data.production_file.order_part.qty, self.data.planned_hours, self.data.production_file.order_part.qty*self.data.planned_hours))

                # description.setDefaultTextColor(Qt.white)
                # br = description.boundingRect()

                self.gi.setRect(0, 0, w, y)
                self.scene().addItem(self.gi)
예제 #3
0
    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)
예제 #4
0
    def draw(self, scene, y):
        span_height = 15
        flag_height = span_height * 1.2

        min_time, max_time = day_span(self.base_time)

        # Draw a time line

        nb_hours = 12

        length = self.time_to_x(self.base_time +
                                timedelta(float(nb_hours) / 24.0))
        scene.addLine(QLineF(0, y, length, y), QPen(Qt.gray))

        x = self.base_time - timedelta(0,
                                       seconds=self.base_time.second,
                                       minutes=self.base_time.minute,
                                       microseconds=self.base_time.microsecond)
        end_x = self.base_time + timedelta(hours=12)

        while x <= end_x:
            tx = self.time_to_x(x)
            scene.addLine(QLineF(tx, y - 5, tx, y + 5), QPen(Qt.gray))

            description = QGraphicsSimpleTextItem()
            description.setText(str(x.hour))
            description.setPos(tx + 5, y)  # y - br.height()/2)
            description.setBrush(QBrush(Qt.gray))
            scene.addItem(description)

            x = x + timedelta(hours=1)

        # Draw spans

        total_time = timedelta(0)

        for start, end, description in self.spans:

            mainlog.debug("Span : {} -> {}".format(start, end))
            s = self.time_to_x(max(min_time, start))
            e = self.time_to_x(min(max_time, end))
            total_time += end - start

            # mainlog.debug("Total time += {}".format(end - start))

            glass_path(scene, s, y - span_height / 2, e - s, span_height,
                       QColor(self.span_color))

            r = HooverBar(QRect(s, y - span_height / 2, e - s, span_height),
                          None)

            if not description:
                r.description = [
                    _("Duration"),
                    duration_to_hm((end - start).total_seconds() / 3600.0)
                ]
            elif isinstance(description, list):
                r.description = description
            else:
                r.description = [description]

            scene.addItem(r)

        # Make the timeline clickable

        r = QGraphicsRectItem(QRect(0, 0, length, 30), None)
        scene.addItem(r)
        r.setPos(0, y - 15)
        r.setPen(QPen(Qt.transparent))
        r.setCursor(Qt.PointingHandCursor)
        r.setFlags(r.flags() | QGraphicsItem.ItemIsSelectable)
        r.setData(0, self.task)

        # Draw flags

        for t, kind, data, hoover_text in self.flags:
            x = self.time_to_x(t)

            # mainlog.debug("Drawing a flag on {} at {}".format(t,x))

            l = QGraphicsLineItem(0.0, float(-flag_height), 0.0,
                                  float(+flag_height), None)
            l.setPen(QPen(Qt.black))
            scene.addItem(l)
            l.setPos(x, y)

            #scene.addLine ( QLineF(x,y-flag_height,x,y+flag_height), QPen(Qt.black) )

            if kind == Timeline.START:
                scene.addRect(QRect(x, y - flag_height, 5, 5), QPen(Qt.black),
                              QBrush(Qt.black))
                scene.addRect(QRect(x, y + flag_height - 5, 5, 5),
                              QPen(Qt.black), QBrush(Qt.black))
            elif kind == Timeline.END:
                scene.addRect(QRect(x - 5, y - flag_height, 5, 5),
                              QPen(Qt.black), QBrush(Qt.black))
                scene.addRect(QRect(x - 5, y + flag_height - 5, 5, 5),
                              QPen(Qt.black), QBrush(Qt.black))

            r = HooverBar(QRect(0, 0, 10, 2 * flag_height), None)
            r.description = hoover_text
            scene.addItem(r)

            r.setPos(x - 5, y - flag_height)
            r.setPen(QPen(Qt.transparent))
            # item = scene.addRect ( QRect(x-5,y-flag_height,10,2*flag_height), QPen(Qt.white))
            r.setCursor(Qt.PointingHandCursor)
            r.setFlags(r.flags() | QGraphicsItem.ItemIsSelectable)
            r.setData(0, data)

        # Timeline's text

        description = QGraphicsSimpleTextItem()

        duration = ""
        if total_time.seconds > 60 or total_time.days > 0:
            duration = " - " + duration_to_hm(
                total_time.total_seconds() / 3600.0)

        tname = self.task_name.replace('\n', ' ')
        if len(tname) > 80:
            tname = tname[0:80] + u"..."

        description.setText(u"{}{}".format(tname, duration))
        br = QRect(0, 0,
                   description.boundingRect().width(),
                   description.boundingRect().height())
        description.setPos(0,
                           y - br.height() - flag_height)  # y - br.height()/2)

        r = QGraphicsRectItem(QRect(0, 0,
                                    br.width() + 10,
                                    br.height() + 10), None)
        r.setPos(-5,
                 y - 5 - br.height() - flag_height)  # y - br.height()/2 - 5)
        r.setPen(QPen(Qt.transparent))
        r.setBrush(QBrush(QColor(255, 255, 255, 128)))

        scene.addItem(r)
        scene.addItem(description)
예제 #5
0
파일: PostView.py 프로젝트: wiz21b/koi
    def reload(self, order_overview_widget, all_ops, all_operations, sort=1):

        # mainlog.debug("reload...")
        progress = QProgressDialog(_("Collecting data..."), None, 0,
                                   len(all_ops) + 3, order_overview_widget)
        progress.setWindowTitle("Horse")
        progress.setMinimumDuration(0)
        progress.setWindowModality(Qt.WindowModal)
        progress.setValue(progress.value() + 1)
        progress.show()

        for i in self.items():
            self.removeItem(i)

        self.posts_offsets = dict()
        self.drawn_operations_data = dict()

        self.cursor = QGraphicsRectItem(0, 0, 50, 300)
        self.cursor.setBrush(QBrush(QColor(208, 208, 255, 255)))
        self.cursor.setPen(QPen(Qt.transparent))
        self.addItem(self.cursor)

        bar_width = 8
        bar_height = int(bar_width * 60.0 / 8.0)

        ascent = QFontMetrics(self.base_font).ascent()
        ascent_big = QFontMetrics(self.base_font_big).ascent()

        post_ops = {}

        # mainlog.debug("reload...2")

        # z = 0
        # for op,order_part,parts in all_operations:
        #     z = op.planned_hours
        #     z = order_part.deadline
        #     z = order_part.qty
        #     z = order_part.human_identifier

        # all_operations = map(lambda i:i[0],all_operations)

        y = 0
        for opdef in all_ops:
            progress.setValue(progress.value() + 1)

            operations = filter(
                lambda op: op.operation_definition_id == opdef.
                operation_definition_id, all_operations)

            # We're only interested in the effort/time that remains
            # to be put on an operation. We're only interested in
            # the future.

            # We want the oeprations that are either
            # - ongoing
            # - ready to start.
            # In all cases we're only interested in operations
            # that are "active"

            if sort == 1:
                operations = sorted(
                    operations, key=lambda op: op.deadline or date(3000, 1, 1))
            elif sort == 2:
                operations = sorted(
                    operations,
                    key=lambda op: op.planned_hours * op.qty - op.done_hours)
            else:
                # Don't sort
                pass

            maximum = 16.0  #float !
            small_hours = 0
            op_ndx = 0
            current_x = 50
            bar_drawn = False

            total_done_hours = total_estimated = 0

            # --------------------------------------------------------------
            # Started operations

            bars_line = BarsLine(16, bar_width, bar_height, current_x, y, self,
                                 order_overview_widget)
            total_hours_to_do = 0

            for op in filter(lambda op: op.done_hours > 0, operations):
                hours_to_do = max(
                    0, op.planned_hours * op.qty -
                    op.done_hours)  # max protects against reporting errors
                total_hours_to_do += hours_to_do

                total_estimated += op.planned_hours * op.qty
                total_done_hours += op.done_hours

                bars_line.add_bar(hours_to_do, QBrush(Qt.green),
                                  self._operation_hoover_description(op),
                                  False,
                                  None)  # op.production_file.order_part)

            # --------------------------------------------------------------
            bars_line_unstarted_operations = BarsLine(16, bar_width,
                                                      bar_height,
                                                      current_x + 30, y, self,
                                                      order_overview_widget)
            total_hours_to_do_on_unstarted_operations = 0
            for op in filter(lambda op: op.done_hours == 0, operations):

                hours_to_do = op.planned_hours * op.qty
                total_hours_to_do_on_unstarted_operations += hours_to_do

                total_estimated += hours_to_do

                bars_line_unstarted_operations.add_bar(
                    hours_to_do, QBrush(Qt.yellow),
                    self._operation_hoover_description(op), False,
                    None)  #op.production_file.order_part)

            y_start = y

            total = total_hours_to_do + total_hours_to_do_on_unstarted_operations

            if total > 0:

                self.drawn_operations_data[
                    opdef.operation_definition_id] = "{}h".format(
                        int(round(total_estimated)))

                gi = QGraphicsSimpleTextItem(
                    _("{} - Estimated to do : {}h; done : {}h").format(
                        opdef.description, int(round(total)),
                        int(round(total_done_hours))))
                gi.setFont(self.base_font_big)
                gi.setPos(0, y - gi.boundingRect().height())
                self.addItem(gi)

                th = gi.boundingRect().height()

                gi = QGraphicsLineItem(-ascent_big, y, 1024 + 2 * ascent_big,
                                       y)
                gi.setPen(QPen(Qt.black))
                self.addItem(gi)

                y += th
            else:
                continue

            y_bars = y

            if total_hours_to_do > 0:
                # There's something to draw

                head = QGraphicsSimpleTextItem(_("Started"))
                head.setFont(self.base_font)
                head.setPos(current_x, y)
                self.addItem(head)
                y += head.boundingRect().height()

                y += bar_height
                bars_line.set_start_pos(current_x, y)
                bars_line.finish_bar()

                foot = QGraphicsSimpleTextItem(
                    _("{}h").format(int(total_hours_to_do + 0.5)))
                foot.setFont(self.base_font)
                foot.setPos(current_x, y)
                self.addItem(foot)
                y += foot.boundingRect().height()

                current_x = max(current_x + bars_line.estimate_width(),
                                head.boundingRect().right(),
                                foot.boundingRect().right())

                bar_drawn = True

            if total_hours_to_do_on_unstarted_operations > 0:

                if bars_line_unstarted_operations.estimate_width(
                ) + current_x > 1200:
                    x = 50
                    y += ascent_big
                else:
                    y = y_bars
                    x = current_x + 50

                head = QGraphicsSimpleTextItem(_("Not started yet"))
                head.setFont(self.base_font)
                head.setPos(x, y)
                self.addItem(head)
                y += head.boundingRect().height()

                y += bar_height
                bars_line_unstarted_operations.set_start_pos(x, y)
                bars_line_unstarted_operations.finish_bar()

                foot = QGraphicsSimpleTextItem(
                    _("{}h").format(
                        int(total_hours_to_do_on_unstarted_operations + 0.5)))
                foot.setFont(self.base_font)
                foot.setPos(x, y)
                self.addItem(foot)
                y += foot.boundingRect().height()

                bar_drawn = True

            y += 3 * ascent_big

            r = self.sceneRect()
            self.posts_offsets[opdef.operation_definition_id] =  \
                QRectF(r.x() - 2*ascent_big, y_start - 1.5*ascent_big,
                       r.width() + 4*ascent_big, (y - ascent_big) - (y_start - 1.5*ascent_big) )
            y += ascent_big

        # mainlog.debug("reload...3")
        import functools
        max_width = functools.reduce(lambda acc, po: max(acc, po.width()),
                                     self.posts_offsets.values(), 0)
        map(lambda po: po.setWidth(max_width), self.posts_offsets.values())

        # for r in self.posts_offsets.values():
        #     gi = QGraphicsLineItem(r.x(),r.y(),r.x()+r.width(),r.y())
        #     gi.setPen(QPen(Qt.lightGray))
        #     self.addItem(gi)

        progress.close()