Esempio n. 1
0
    def get_displayed_data(self, index):
        d = index.model().data(index, Qt.UserRole)
        # mainlog.debug("DurationDelegate.get_displayed_data : ({}-{}) {} ({})".format(index.row(), index.column(), d, type(d)))
        if d:
            if self.format_as_float:
                return duration_to_s(d)
            else:
                return duration_to_hm(d, short_unit=True)

        else:
            return None
Esempio n. 2
0
    def data_changed_slot(self, item):
        # mainlog.debug("data_changed_slot")
        self.model_data_changed = True

        m = self.controller.model
        sum_hours = 0
        for i in range(m.rowCount()):
            ndx = m.index(i, 2)
            #mainlog.debug("editTT : {}: {}".format(i, m.data(ndx,Qt.UserRole)))
            try:
                sum_hours = sum_hours + float(m.data(ndx, Qt.UserRole))
            except:
                pass

        mainlog.debug("Sum = {}".format(sum_hours))
        self.sum_hours_label.setText(duration_to_hm(sum_hours))
Esempio n. 3
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)
Esempio n. 4
0
 def setValue(self, v):
     self.setText(duration_to_hm(v))
Esempio n. 5
0
def _make_iso_status(dao, order_id):

    global header_text, sub_header_text

    strip_style = ParagraphStyle(name="regular",
                                 fontName='Helvetica-Bold',
                                 fontSize=16,
                                 spaceAfter=0,
                                 spaceBefore=0)
    s = ParagraphStyle(name="regular",
                       fontName='Helvetica',
                       fontSize=12,
                       spaceAfter=6)

    # s = getSampleStyleSheet()['BodyText']

    title_style = ParagraphStyle(name="regular",
                                 fontName='Helvetica-Bold',
                                 fontSize=16,
                                 spaceAfter=24,
                                 spaceBefore=24)
    order_style = ParagraphStyle(name="regular",
                                 fontName='Helvetica-Bold',
                                 fontSize=14,
                                 spaceAfter=6,
                                 spaceBefore=12)
    small = ParagraphStyle(name="regular", fontName='Helvetica', fontSize=8)
    right_align = ParagraphStyle(name="right_align",
                                 fontName='Helvetica',
                                 fontSize=12,
                                 alignment=TA_RIGHT)

    complete_document = []
    spacer = platypus.Spacer(1, 50)

    metadata, timetracks = dao.order_dao.load_order_timetracks(order_id)
    issues = dao.quality_dao.find_by_order_id(order_id)

    header_text = u"{} [{}]".format(metadata['customer_name'],
                                    metadata['customer_order_name'])
    sub_header_text = _("Order activity report")

    # complete_document.append(Paragraph(_("Order information"),title_style))

    complete_document.append(
        Paragraph(_("Customer : {}").format(metadata['customer_name']), s))
    complete_document.append(
        Paragraph(
            _("Order number : {} (Horse ID:{})").format(
                metadata['accounting_label'] or "-",
                metadata['horse_order_id']), s))
    complete_document.append(
        Paragraph(
            _("Preorder number : {}").format(metadata['preorder_label']
                                             or "-"), s))
    complete_document.append(
        Paragraph(
            _("Customer number : {}").format(metadata['customer_order_name']),
            s))
    complete_document.append(
        Paragraph(
            _("Creation date : {}").format(
                date_to_dmy(metadata['creation_date'])), s))
    complete_document.append(
        Paragraph(
            _("Completion : {}").format(date_to_dmy(
                metadata['completed_date'])), s))
    complete_document.append(
        Paragraph(
            _("Current state : {}").format(metadata['state'].description), s))

    complete_document.append(Paragraph(_("Activity synthesis"), title_style))

    ts = platypus.TableStyle([('FONT', (0, 0), (-1, -1), 'Helvetica', 12)])
    tdata = []
    # tdata.append([None, _("Order part")])

    for part_id, part_desc, part_state, part_completed_date, employee_timetracks, order_part_id in timetracks:

        row = [
            part_id,
            Paragraph(
                "<b>{}</b>".format(
                    escape_html(
                        split_long_string(part_desc) + " (" + smart_join([
                            part_state.description,
                            date_to_dmy(part_completed_date)
                        ]) + ")")), s)
        ]
        tdata.append(row)
        row_ndx = len(tdata) - 1
        ts.add('BOX', (0, row_ndx), (-1, row_ndx), 1, colors.black)
        ts.add('BACKGROUND', (0, row_ndx), (-1, row_ndx),
               colors.Color(0.8, 0.8, 0.8))

        if employee_timetracks:
            # dunno why, ordered dicts are not ordered anymore when iterated over their '.items()'
            for employee in sorted(employee_timetracks.keys()):
                tt = employee_timetracks[employee]

                # mainlog.debug("employee : {}".format(employee))
                # mainlog.debug(timetracks[0])

                row = [None, None]
                row[1] = Paragraph(
                    u"{} : {}".format(
                        employee, u"; ".join(
                            map(
                                lambda z: u"{} {} <b>{}</b>".format(
                                    z[0], date_to_dmy(z[1]),
                                    duration_to_hm(z[2])), tt))), s)
                tdata.append(row)
        else:
            tdata.append(["", _("No work reported")])

        for issue in issues:
            if issue.order_part_id == order_part_id:
                name = "?"
                if issue.who:
                    name = issue.who.fullname

                row = [
                    Paragraph(_("<b>QUAL !</b>"), s),
                    Paragraph(
                        _("<b>{}</b> on {} by {} : {}").format(
                            issue.human_identifier, date_to_dmy(issue.when),
                            escape_html(name), escape_html(issue.description)),
                        s)
                ]
                tdata.append(row)

    # ts.add('FONT', (0, 0), (-1, 0), 'Helvetica-Bold', 12)

    # ts.add('INNERGRID', (0, 0), (-1, -1), 0.5, colors.black)
    ts.add('BOX', (0, 0), (-1, -1), 0.25, colors.black)

    ts.add('ALIGN', (0, 0), (-1, -1), 'LEFT')
    ts.add('VALIGN', (0, 0), (-1, -1), 'TOP')

    ts.add("LEFTPADDING", (0, 0), (0, -1), 0)
    ts.add("RIGHTPADDING", (1, 0), (-1, -1), 0)

    if tdata:
        t = platypus.Table(tdata, repeatRows=0, colWidths=[2 * cm, 17.5 * cm])
        t.setStyle(ts)
        complete_document.append(t)

    complete_document.append(Paragraph(_("Delivery slips"), title_style))

    slips = dao.order_dao.find_by_id(order_id).delivery_slips()
    if not slips:
        complete_document.append(Paragraph(_("There are no delivery slip"), s))

    for slip in slips:

        if slip.active:
            complete_document.append(
                Paragraph(
                    _("Delivery slip {} created on {}").format(
                        slip.delivery_slip_id, date_to_dmy(slip.creation)), s))

            for ds_part in sorted(slip.delivery_slip_parts,
                                  key=lambda p: p.order_part.label):
                complete_document.append(
                    Paragraph(
                        _("{} : {} unit(s)").format(ds_part.order_part.label,
                                                    ds_part.quantity_out), s))
        else:
            complete_document.append(
                Paragraph(
                    _("Delivery slip {} DESACTIVATED").format(
                        slip.delivery_slip_id), s))

    complete_document.append(Paragraph(_("Quality"), title_style))

    if not issues:
        complete_document.append(Paragraph(_("There are no quality issues"),
                                           s))
    else:
        for issue in issues:
            name = "?"
            if issue.who:
                name = issue.who.fullname
            complete_document.append(
                Paragraph(
                    _("Issue <b>{}</b> created on {} by {} : {}").format(
                        issue.human_identifier, date_to_dmy(issue.when),
                        escape_html(name), escape_html(issue.description)), s))

    def order_number_title(preorder_number, order_number, customer_number):
        t = []

        if order_number:
            t.append(str(order_number))

        if preorder_number:
            t.append(_("Preorder {}").format(preorder_number))

        # Would' be nice but takes way too much width on the paper
        # if customer_number:
        #     t.append(str(customer_number) + "lkjlkj  lkj  ///SDFSF")

        return u" / ".join(t)

    return order_number_title(
        metadata['preorder_label'], metadata['accounting_label'],
        metadata['customer_order_name']), complete_document
Esempio n. 6
0
    def refresh_action(self):
        global dao

        # mainlog.debug("refresh action started")
        self.hours_per_pers_subframe.set_title(date_to_my(
            self.base_date, True))

        chrono.chrono_start()
        all_events_in_month = people_admin_service.events_for_month(
            self.base_date)

        employee_with_events = [
            event.employee_id for event in all_events_in_month
        ]

        # mainlog.debug(all_events_in_month)

        self.all_events_in_year = people_admin_service.events_for_year(
            self.base_date.year)
        self.all_presences = all_presences = dao.employee_dao.presence_overview_for_month(
            self.base_date)

        all_correction_times = dict()
        for s in dao.month_time_synthesis_dao.load_all_synthesis(
                self.base_date.year, self.base_date.month):
            all_correction_times[s.employee_id] = s.correction_time

        special_activities = dao.special_activity_dao.find_on_month(
            self.base_date)

        employees = list(
            filter(
                lambda e: e.is_active or e.employee_id in all_presences or e.
                employee_id in all_correction_times or e.employee_id in
                special_activities or e.employee_id in employee_with_events,
                dao.employee_dao.list_overview()))
        self.employees = employees

        chrono.chrono_click()

        day_max = calendar.monthrange(self.base_date.year,
                                      self.base_date.month)[1]
        t_start = datetime(self.base_date.year, self.base_date.month, 1)
        t_end = datetime(self.base_date.year, self.base_date.month, day_max,
                         23, 59, 59, 999999)

        self._table_model.setRowCount(len(employees))
        self._table_model.setColumnCount(1 + day_max + 3)

        headers = QStandardItemModel(1, 1 + day_max + 3)

        headers.setHeaderData(0, Qt.Orientation.Horizontal, _("Employee"))
        for i in range(day_max):
            headers.setHeaderData(i + 1, Qt.Orientation.Horizontal,
                                  "{}".format(i + 1))
        headers.setHeaderData(day_max + 1, Qt.Orientation.Horizontal,
                              _("Correction"))
        headers.setHeaderData(day_max + 2, Qt.Orientation.Horizontal,
                              _("Total"))
        headers.setHeaderData(day_max + 3, Qt.Orientation.Horizontal,
                              _("Days off"))

        self.headers_view.setModel(
            headers)  # qt's doc : The view does *not* take ownership
        self.header_model = headers
        self.headers_view.setModel(
            self.header_model)  # qt's doc : The view does *not* take ownership

        # Compute all mondays indices
        monday = 0
        if t_start.weekday() > 0:
            monday = 7 - t_start.weekday()
        all_mondays = []

        while monday < day_max:
            all_mondays.append(monday)
            monday += 7

        today = date.today()

        # mainlog.debug("Running on employees")
        for row in range(self._table_model.rowCount()):

            # Clear the line
            for col in range(0, 32):
                ndx = self._table_model.index(row, col)
                self._table_model.setData(ndx, None, Qt.BackgroundRole)
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(ndx, None, Qt.DisplayRole)
                self._table_model.setData(ndx, None, Qt.UserRole)
                self._table_model.setData(ndx, None, Qt.UserRole + 1)
                #     else:
                #         self._table_model.setData(ndx,None,Qt.BackgroundRole)

                # else:
                #     self._table_model.setData(ndx,None,Qt.DisplayRole)
                #     self._table_model.setData(ndx,None,Qt.BackgroundRole)

            # Mark mondays
            for col in all_mondays:
                # col + 1 to account for the employee column
                self._table_model.setData(
                    self._table_model.index(row, col + 1),
                    QBrush(QColor(230, 230, 255)), Qt.BackgroundRole)

            # Mark today
            if today.month == self.base_date.month and today.year == self.base_date.year:
                self._table_model.setData(
                    self._table_model.index(row, today.day),
                    QBrush(QColor(255, 255, 128)), Qt.BackgroundRole)

        row = 0
        for employee in employees:  # employees are sorted

            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.fullname,
                                      Qt.DisplayRole)  # FIXME Use a delegate
            self._table_model.setData(self._table_model.index(row, 0),
                                      employee.employee_id,
                                      Qt.UserRole)  # FIXME Use a delegate

            correction = 0
            if employee.employee_id in all_correction_times:
                correction = all_correction_times[employee.employee_id]
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1),
                    duration_to_hm(correction, short_unit=True),
                    Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 1), None,
                    Qt.DisplayRole)

            presence = 0
            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                import functools
                presence = functools.reduce(
                    lambda acc, s: acc + s,
                    all_presences[employee.employee_id], 0)
            presence += correction

            if presence != 0:
                self._table_model.setData(ndx, QBrush(Qt.GlobalColor.black),
                                          Qt.TextColorRole)
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2),
                    duration_to_hm(presence, short_unit=True), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 2), None,
                    Qt.DisplayRole)

            if employee.employee_id in all_presences and len(
                    all_presences[employee.employee_id]) > 0:
                for b in range(len(all_presences[employee.employee_id])):
                    ndx = self._table_model.index(row, b + 1)

                    p = all_presences[employee.employee_id][b]

                    if p > 0:
                        self._table_model.setData(
                            ndx, duration_to_hm(p, short_unit=True),
                            Qt.DisplayRole)
                        self._table_model.setData(ndx, p, Qt.UserRole)

                        if p >= 4 and p <= 8:
                            # Regular work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(192, 255, 192)),
                                Qt.BackgroundRole)
                        elif p > 8 or (p < 4 and p > 0):
                            # Problematic work load
                            self._table_model.setData(
                                ndx, QBrush(QColor(255, 192, 192)),
                                Qt.BackgroundRole)

            if employee.employee_id in special_activities:
                sa_of_employee = special_activities[employee.employee_id]

                for sa in sa_of_employee:
                    start = max(t_start, sa.start_time)
                    end = min(t_end, sa.end_time)

                    for i in range(start.day, end.day + 1):
                        ndx = self._table_model.index(row, i)
                        self._table_model.setData(ndx,
                                                  QBrush(QColor(255, 128, 0)),
                                                  Qt.BackgroundRole)

                # self._table_model.setData(self._table_model.index(row,b+1),Qt.AlignRight | Qt.AlignVCenter,Qt.TextAlignmentRole)
            row += 1

        # Display day events

        employee_id_to_row = dict()  # little accelerator
        for row in range(len(employees)):
            employee_id_to_row[employees[row].employee_id] = row

        # Compute days off totals and show them

        self.day_event_totals = dict([(e.employee_id, dict())
                                      for e in employees])
        for day_event in all_events_in_month:
            # mainlog.debug("employee_id = {}".format(day_event.employee_id))
            # if day_event.employee_id not in self.day_event_totals:
            #    mainlog.debug(self.day_event_totals)

            t = self.day_event_totals[day_event.employee_id]
            if day_event.event_type not in t:
                t[day_event.event_type] = day_event.duration
            else:
                t[day_event.event_type] += day_event.duration

        for employee in employees:  # employees are sorted
            t = self.day_event_totals[employee.employee_id]
            mainlog.debug(t)
            total_off = sum(t.values())
            mainlog.debug(total_off)
            row = employee_id_to_row[employee.employee_id]
            mainlog.debug(row)
            if total_off:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3),
                    nice_round(total_off), Qt.DisplayRole)
            else:
                self._table_model.setData(
                    self._table_model.index(row, day_max + 3), None,
                    Qt.DisplayRole)

        # Show days off

        for day_event in all_events_in_month:
            row = employee_id_to_row[day_event.employee_id]
            col = day_event.date.day

            fg = bg = None
            if day_event.event_type in self.DAY_EVENT_PALETTE:
                fg, bg = self.DAY_EVENT_PALETTE[day_event.event_type]
            else:
                fg, bg = Qt.GlobalColor.red, Qt.GlobalColor.gray

            ndx = self._table_model.index(row, col)

            self._table_model.setData(ndx, day_event.day_event_id,
                                      Qt.UserRole + 1)

            # The problem here is to nicely blend the fact
            # that you can have a day event mixed with actual work
            # the very same day. Here's a poor man solution.

            active_time = self._table_model.data(ndx, Qt.UserRole)
            if not active_time:
                self._table_model.setData(
                    ndx, DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)
            else:
                self._table_model.setData(ndx, QBrush(fg), Qt.TextColorRole)
                self._table_model.setData(ndx, QBrush(bg), Qt.BackgroundRole)

                self._table_model.setData(
                    ndx,
                    duration_to_hm(active_time, short_unit=True) +
                    DayEventType.short_code(day_event.event_type),
                    Qt.DisplayRole)

        chrono.chrono_click()

        #for i in range(len(all_mondays)):
        self.table_view.resizeColumnsToContents()

        # mainlog.debug("Reset selection")
        ndx = self.table_view.currentIndex()

        self.table_view.selectionModel().clear()
        # self.table_view.selectionModel().clearSelection()
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        # self.table_view.selectionModel().select( self.table_view.model().index(ndx.row(),ndx.column()), QItemSelectionModel.Select)
        self.table_view.selectionModel().setCurrentIndex(
            self.table_view.model().index(ndx.row(), ndx.column()),
            QItemSelectionModel.Select)

        self.cell_entered(self.table_view.currentIndex())
Esempio n. 7
0
    def _drawUserData(self, painter):

        painter.setPen(Qt.GlobalColor.black)
        painter.setFont(self.bigfont)

        y = 50
        y += self._printAt(painter, 10, y, 700, _("Your status"))
        y += 50
        painter.setFont(self.smallfont)
        # h['presence_begin'],h['presence_total'] = self.dao.employee_dao.presence(user_id)

        if self.current_user.presence_begin[0]:
            y += self._printAt(
                painter, 10, y, 700,
                _("Day started on {}").format(
                    time_to_hm(self.current_user.presence_begin[0])))

        t = self.current_user.presence_total

        if self.current_user.presence_total[0]:
            y += self._printAt(
                painter, 10, y, 700,
                _("Hours : {}").format(
                    duration_to_hm(self.current_user.presence_total[0])))

        y += 20
        painter.drawLine(0, y, self.width(), y)
        y += 20

        nb_times = len(self.current_user.presence_begin)
        x = (self.width() - 100 * nb_times) / 2

        self._printAt(painter,
                      self.width() - nb_times * 100 - x, y + 50, 200,
                      _("Start"))
        self._printAt(painter,
                      self.width() - nb_times * 100 - x, y + 100, 200,
                      _("Total"))

        painter.drawLine(x, y + 45, self.width() - x, y + 45)

        # most recent first
        for i in range(1, nb_times):

            self._printAt(painter,
                          self.width() - i * 100 - x, y,
                          self.width() - i * 100,
                          date_to_dm(self.current_user.presence_day[i]))

            begin = self.current_user.presence_begin[i]
            txt = "-"
            if begin:
                txt = time_to_hm(begin)

            self._printAt(painter,
                          self.width() - i * 100 - x, y + 50,
                          self.width() - i * 100, txt)

            total = self.current_user.presence_total[i]
            txt = "-"
            if total:
                txt = duration_to_hm(total)

            self._printAt(painter,
                          self.width() - i * 100 - x, y + 100,
                          self.width() - i * 100, txt)