Ejemplo n.º 1
0
 def onMonoFontChange(self, propagate=True):
     font = QFont(self.monoFontComboBox.currentFont())
     font.setPointSize(self.monoFontSizeSpinBox.value())
     if propagate and bool(self.state.model):
         self.state.model.setConfig(Gconf.Key.MonoFont, font.family())
         self.state.model.setConfig(Gconf.Key.MonoFontSize,
                                    font.pointSize())
Ejemplo n.º 2
0
def createFontBoxesFor(parent,
                       name,
                       family,
                       size,
                       *,
                       mono=False,
                       tooltips=None,
                       which="Font"):
    font = QFont(family, size)
    fontComboBox = QFontComboBox(parent)
    if not mono:
        fontFilter = QFontComboBox.ScalableFonts
    else:
        fontFilter = (QFontComboBox.ScalableFonts
                      | QFontComboBox.MonospacedFonts)
    fontComboBox.setFontFilters(fontFilter)
    fontComboBox.setCurrentFont(font)
    fontSizeSpinBox = QSpinBox(parent)
    fontSizeSpinBox.setAlignment(Qt.AlignRight)
    fontSizeSpinBox.setRange(6, 36)
    fontSizeSpinBox.setSuffix(" pt")
    fontSizeSpinBox.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
    fontSizeSpinBox.setValue(font.pointSize())
    if tooltips is not None:
        tooltips.append((fontComboBox, """\
<p><b>{0} Font</b></p><p>The font family to use for the {0} Font.</p>""".
                         format(which)))
        tooltips.append((fontSizeSpinBox, """\
<p><b>{0} Font Size</b></p><p>The font point size to use for the {0}
Font.</p>""".format(which)))
    setattr(parent, "{}FontComboBox".format(name.lower()), fontComboBox)
    setattr(parent, "{}FontSizeSpinBox".format(name.lower()), fontSizeSpinBox)
Ejemplo n.º 3
0
 def setTitleFont(self):
     '''
     Sets font for the widget text
     '''
     fontValue = QFont('Times New Roman')
     fontValue.setPointSize(fontValue.pointSize() + 15)
     self.setFont(fontValue)
Ejemplo n.º 4
0
 def onDisplayMonoFontChange(self, propagate=True):
     font = QFont(self.displaymonoFontComboBox.currentFont())
     font.setPointSize(self.displaymonoFontSizeSpinBox.value())
     if propagate:
         settings = QSettings()
         settings.setValue(Gopt.Key.MonoFont, font.family())
         settings.setValue(Gopt.Key.MonoFontSize, font.pointSize())
         self.state.updateDisplayFonts()
Ejemplo n.º 5
0
    def __init__(self, parent=None):
        super(AutoInfo, self).__init__(parent)
        self.setupUi(self)
        # Remove the question mark widget from dialog
        # self.setWindowFlags(self.windowFlags() ^
        #                     Qt.WindowContextHelpButtonHint)
        self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint)
        self.hide()

        font = QFont()
        font.setBold(True)
        font.setPointSize(QFont.pointSize(QFont()) + 3)
        self.label.setFont(font)
Ejemplo n.º 6
0
class Panel(QWidget):

    characterSelected = Signal(str)
    fontResized = Signal(float)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.displayFont = QFont()
        self.displayFont.setStyleStrategy(QFont.PreferDefault)
        self.updateFont(self.displayFont.family())
        self.currentChar = ""
        self.setMouseTracking(True)
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)

    def updateFont(self, family):
        self.displayFont.setFamily(family)
        self.updateSize(self.displayFont.pointSize())

    def updateSize(self, size):
        size = int(size)
        self.displayFont.setPointSize(size)
        self.squareSize = max(SQUARE_SIZE,
                              QFontMetrics(self.displayFont).xHeight() * 3)
        self.fontResized.emit(self.squareSize)
        self.adjustSize()
        self.update()

    def minimumWidth(self):
        return COLUMNS * self.squareSize

    def sizeHint(self):
        return QSize(self.minimumWidth(),
                     (MAX_CHAR / COLUMNS) * self.squareSize)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.currentChar = chr((event.y() // self.squareSize) * COLUMNS +
                                   event.x() // self.squareSize)
            if not unicodedata.category(self.currentChar).startswith("C"):
                self.characterSelected.emit(self.currentChar)
            self.update()
        else:
            super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        pos = self.mapFromGlobal(event.globalPos())
        code = ((pos.y() // self.squareSize) * COLUMNS +
                pos.x() // self.squareSize)
        name = "unnamed"
        try:
            name = unicodedata.name(chr(code)).capitalize()
        except ValueError:
            pass
        text = """<p><span style="font-size: 18pt;">{0:c}</span></p>
<p><span style="font-size: 13pt;">U+{0:04X}<br>{1}</span></p>""".format(
            code, name)
        QToolTip.showText(event.globalPos(), text, self)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(event.rect(), Qt.white)
        painter.setFont(self.displayFont)

        redrawRect = event.rect()
        beginRow = redrawRect.top() // self.squareSize
        endRow = redrawRect.bottom() // self.squareSize
        beginColumn = redrawRect.left() // self.squareSize
        endColumn = redrawRect.right() // self.squareSize

        painter.setPen(Qt.gray)
        for row in range(beginRow, endRow + 1):
            for column in range(beginColumn, endColumn + 1):
                painter.drawRect(column * self.squareSize,
                                 row * self.squareSize, self.squareSize,
                                 self.squareSize)

        fontMetrics = QFontMetrics(self.displayFont)
        painter.setPen(Qt.black)
        for row in range(beginRow, endRow + 1):
            for column in range(beginColumn, endColumn + 1):
                char = chr(row * COLUMNS + column)
                painter.setClipRect(column * self.squareSize,
                                    row * self.squareSize, self.squareSize,
                                    self.squareSize)
                if char == self.currentChar:
                    painter.fillRect(column * self.squareSize + 1,
                                     row * self.squareSize + 1,
                                     self.squareSize, self.squareSize,
                                     Qt.green)
                painter.drawText(
                    column * self.squareSize + (self.squareSize / 2) -
                    fontMetrics.width(char) / 2,
                    row * self.squareSize + 4 + fontMetrics.ascent(), char)
Ejemplo n.º 7
0
class HooverBar(QGraphicsRectItem):
    def __init__(self, x, y, w, h, hoover_text, doubleclick_callback_widget,
                 order_part_id):
        """ doubleclick_callback_widget : we will call the set_on_orderpart method
        of that object if a doubleclik happens here.
        """

        super(HooverBar, self).__init__(x, y, w, h)
        self.setAcceptHoverEvents(True)
        self.gi = None
        self.hoover_text = hoover_text
        self.description = None
        self.doubleclick_callback_widget = doubleclick_callback_widget
        self.order_part_id = order_part_id

        self.base_font = QFont()
        if configuration.font_select:
            self.base_font.setPointSize(self.base_font.pointSize() * 2)

    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)
                #mainlog.debug("hoverEnterEvent GI={}".format(self.gi))

        # mainlog.debug("hoverEnterEvent Done")

    def hoverMoveEvent(self, event):
        super(HooverBar, self).hoverMoveEvent(event)

        # if self.gi:
        #     mainlog.debug("hoverMoveEvent GI pos={}-{}".format(self.gi.pos().x(),self.gi.pos().y()))
        # mainlog.debug("hoverMoveEvent pos={}-{}".format(event.scenePos().x(),event.scenePos().y()))
        if self.gi:
            self.gi.setPos(event.scenePos().x() + 20,
                           event.scenePos().y() + 20)

    def hoverLeaveEvent(self, event):
        super(HooverBar, self).hoverLeaveEvent(event)

        if self.gi:
            # mainlog.debug("hoverLeaveEvent GI={}".format(self.gi))
            # self.gi.setActive(False)
            # self.gi.setVisible(False)
            # return

            if self.description:
                # I do this so that I can handle the destruction of description
                # graphics item myself (i.e. description won't be deleted
                # as a children of self.gi)
                self.description.setParentItem(None)
                self.description = None  # and delete...

            # QtDoc : Removes the item item and all its children from the scene.
            #         The ownership of item is passed on to the caller

            self.gi.setParentItem(None)
            # self.scene().removeItem(self.gi)
            self.gi = None
            # mainlog.debug("hoverLeaveEvent -- done")

    # order_part_double_clicked = Signal(int)

    def mouseDoubleClickEvent(self,
                              event):  # QGraphicsSceneHoverEvent * event )
        # mainlog.debug("mouseDoubleClickEvent {}".format(self.data))
        super(HooverBar, self).mouseDoubleClickEvent(event)
        self.doubleclick_callback_widget.set_on_order_part(self.order_part_id)
Ejemplo n.º 8
0
class PostViewScene(QGraphicsScene):
    def set_cursor_on(self, opdef_id):
        if opdef_id in self.posts_offsets:
            coord = self.posts_offsets[opdef_id]
            cover = self.cursor.rect().united(coord)
            self.cursor.setRect(coord)
            self.update(cover)

    def _operation_hoover_description(self, op):
        # order_part = op.production_file.order_part

        txt = [
            u"{} {}".format(op.order_part_human_identifier,
                            date_to_dmy(op.deadline)),  # order_part.deadline
            op.order_part_description or "",
            op.description or "",
            _("{}x{}={}h, rest:{}h").format(
                op.qty, nice_round(op.planned_hours),
                nice_round(op.qty * op.planned_hours),
                nice_round(op.planned_hours * op.qty - op.done_hours))
        ]
        return txt

    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()

    def __init__(self, parent, order_overview_widget):
        global configuration
        super(PostViewScene, self).__init__(parent)
        self.base_font = QFont()

        self.base_font_big = QFont()
        self.base_font_big.setPointSize(self.base_font.pointSize() * 1.5)
        if configuration.font_select:
            self.base_font_big.setPointSize(self.base_font.pointSize() * 2)
Ejemplo n.º 9
0
class OrderWorkflowDialog(QDialog):

    def _makeArrow( self, ra, rb, both_ways=True):

        ca = QPointF( ra.x() + float(ra.width()) / 2.0, ra.y() + float(ra.height()) / 2.0)
        cb = QPointF( rb.x() + rb.width() / 2.0, rb.y() + rb.height() / 2.0)

        dx = cb.x() - ca.x()
        dy = cb.y() - ca.y()
        d = dist(dx,dy)


        a = math.atan2(float(dy),float(dx)) # The result is between -pi and pi

        # ra_rad = dist(ra.width() / 2, ra.height() / 2)
        # rb_rad = dist(rb.width() / 2, rb.height() / 2)

        x,y = squircle(ra.width() / 2, ra.height() / 2, to_squircle_angle(ra.width() / 2, ra.height() / 2,a))
        ra_rad = dist(x,y) + 10
        # painter.drawLine(ca,QPoint(ca.x() + x, ca.y() + y))

        na = a
        if a < 0:
            na += math.pi
        else:
            na -= math.pi

        x,y = squircle(float(rb.width()) / 2.0, float(rb.height()) / 2.0, to_squircle_angle(float(rb.width()) / 2.0, float(rb.height()) / 2.0,na))
        rb_rad = dist(x,y)+10

        # ra_rad = rb_rad = 0


        # painter.drawLine(ca,cb)
        # painter.drawRect(ra)
        # painter.setPen(Qt.GlobalColor.red)
        # painter.drawRect(rb)
        # painter.setPen(Qt.GlobalColor.black)

        # for t in range(100):
        #     ang = 6.28/100.0*float(t)
        #     x,y = squircle( 200,50,ang)
        #     painter.drawPoint(300 + x,100 + y)

        qp = QPolygonF()
        h = 5

        v = []
        v.append(QPointF(ra_rad,0))

        if not both_ways:
            v.append(QPointF(ra_rad,-h/2))
        else:
            v.append(QPointF(ra_rad + 2*h,-2*h))
            v.append(QPointF(ra_rad + 2*h,-h/2))


        v.append(QPointF(d - rb_rad - 2*h,-h/2))
        v.append(QPointF(d - rb_rad - 2*h,-2*h))
        v.append(QPointF(d - rb_rad, 0))
        v.append(QPointF(d - rb_rad - 2*h,+2*h))
        v.append(QPointF(d - rb_rad - 2*h,+h/2))

        if not both_ways:
            v.append(QPointF(ra_rad,+h/2))
        else:
            v.append(QPointF(ra_rad + 2*h,+h/2))
            v.append(QPointF(ra_rad + 2*h,+2*h))

        v.append(QPointF(ra_rad,0))

        p = QPolygonF(v)
        item = QGraphicsPolygonItem(p)
        item.translate(ca.x(),ca.y())
        item.rotate(math.degrees(a))
        return item


    def _drawNodes(self,scene,selected_state,initial_state):
        for i in scene.items():
            scene.removeItem(i)

        pos = dict()

        sx = 1
        sy = 1
        if configuration.font_select:
            sx = sx * 2
            sy = sy

        pos[OrderStatusType.preorder_definition] = (200*sx,200*sy)
        pos[OrderStatusType.order_definition] = (10*sx,300*sy)
        pos[OrderStatusType.order_ready_for_production] = (300*sx,300*sy)
        pos[OrderStatusType.order_production_paused] = (200*sx,550*sy)
        pos[OrderStatusType.order_completed] = (400*sx,600*sy)
        pos[OrderStatusType.order_aborted] = (10*sx,600*sy)

        mainlog.debug("_drawNodes : selected_state {}".format(selected_state))
        mainlog.debug("_drawNodes : initial_state {}".format(initial_state))

        for org in OrderStatusType.symbols():
            x,y = pos[org]

            item = QGraphicsSimpleTextItem(org.description)

            if (selected_state and org in OrderStatusType.next_states(selected_state)) or org == initial_state or org == selected_state:
                item = MyQGraphicsSimpleTextItem(org, self)
                item.setFlags( item.flags() | QGraphicsItem.ItemIsSelectable)

                if org == selected_state:
                    mainlog.debug("Preselcting {}".format(org))
                    item.setSelected(True)

            item.setFont(self.thinfont)
            item.setPos(x,y)
            scene.addItem(item)

            pos[org] = item.boundingRegion( item.sceneTransform()).boundingRect()

            # scene.addRect(pos[org])


        g_orgs = dict()
        for org in OrderStatusType.symbols():
            g_orgs[org] = OrderStatusType.next_states(org)


        # Draw all arrows which don't end up or leave the selected_state
        drawn = []
        for org,dests in g_orgs.iteritems():
            for dest in dests:
                if selected_state != org and ((org,dest) not in drawn) and ((dest,org) not in drawn):
                    # If an arrow must have two directions, we draw it
                    # like that directly.
                    item = self._makeArrow( pos[org],pos[dest],dest in g_orgs and org in g_orgs[dest])
                    item.setPen(self.grey_pen)
                    scene.addItem( item)
                    drawn.append((org,dest))



        if initial_state:
            scene.addRect(pos[initial_state])

        if selected_state:
            for dest in OrderStatusType.next_states(selected_state):
                item = self._makeArrow( pos[selected_state],pos[dest],False)
                item.setBrush(QBrush(Qt.green))
                scene.addItem( item)
                drawn.append((org,dest))

    @Slot()
    def selectionChanged(self):
        pass

    def __init__(self,parent):
        global configuration
        super(OrderWorkflowDialog,self).__init__(parent)

        self.grey_pen = QPen(Qt.gray)

        title = _("Order workflow")
        self.setWindowTitle(title)
        self.title_widget = TitleWidget(title,self)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton( QDialogButtonBox.Ok)
        self.buttons.addButton( QDialogButtonBox.Cancel)

        self.thinfont = QFont()
        if configuration.font_select:
            self.thinfont.setPointSize(self.thinfont.pointSize()*2)

        self.scene = QGraphicsScene()
        self.scene.selectionChanged.connect(self.selectionChanged)

        self.view = QGraphicsView(self)
        self.view.setRenderHint(QPainter.Antialiasing)
        self.view.setScene(self.scene)

        top_layout = QVBoxLayout()
        top_layout.addWidget(self.title_widget)
        top_layout.addWidget(self.view)
        top_layout.addWidget(self.buttons)

        self.setLayout(top_layout) # QWidget takes ownership of the layout
        self.buttons.accepted.connect(self.save_and_accept)
        self.buttons.rejected.connect(self.cancel)

        self.initial_state = None
        self.selected_state = None
        self._drawNodes(self.scene,self.selected_state,self.initial_state)

    def set_selected_state(self,selected_state,initial_state):
        mainlog.debug("selected_state {}".format(selected_state))
        mainlog.debug("initial_state {}".format(initial_state))

        self.initial_state = initial_state
        self.selected_state = selected_state
        self._drawNodes(self.scene,selected_state,self.initial_state)


    @Slot()
    def cancel(self):
        return super(OrderWorkflowDialog,self).reject()

    @Slot()
    def save_and_accept(self):
        super(OrderWorkflowDialog,self).accept()

        s = self.scene.selectedItems()
        if s:
            # In cas there are more than one item selected,
            # we pick the first one (arbitrarily)
            self.selected_state = s[0].state
        else:
            self.selected_state = self.initial_state