Example #1
0
class WeekViewWidget(SubFrame):
    def __init__(self, parent):
        super(WeekViewWidget, self).__init__("Week", None, parent)

        self._table_model = QStandardItemModel(1, 2, None)
        self._table_model.setHorizontalHeaderLabels(
            [_("# Ord."), _("Customer")])

        self.table_view = LeftRightTableView(self)
        self.table_view.setModel(self._table_model)
        self.table_view.verticalHeader().hide()
        self.table_view.setAlternatingRowColors(True)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.table_view.horizontalHeader().setResizeMode(
            0, QHeaderView.ResizeToContents)
        self.table_view.horizontalHeader().setStretchLastSection(True)

        self.preorder_brush = QBrush(QColor(255, 255, 128))
        self.completed_order_brush = QBrush(QColor(128, 255, 128))

        self.layout().addWidget(self.table_view)

    def _set_last_row(self, data, role):
        for i in range(self._table_model.columnCount()):
            self._table_model.setData(
                self._table_model.index(self._table_model.rowCount() - 1, i),
                data, role)

    def set_data(self, data, base_date):
        self.set_title(date_to_dm(base_date))
        self._table_model.removeRows(0, self._table_model.rowCount())

        current_ndx = 0
        for d in data:
            order, customer_name = d

            number = order.preorder_label
            if order.accounting_label:
                number = order.accounting_label

            self._table_model.appendRow(
                [QStandardItem(str(number)),
                 QStandardItem(customer_name)])
            self._table_model.setData(self._table_model.index(current_ndx, 0),
                                      order.order_id, Qt.UserRole)

            if order.state == OrderStatusType.order_completed:
                self._set_last_row(self.completed_order_brush,
                                   Qt.BackgroundRole)
            elif order.state == OrderStatusType.preorder_definition:
                self._set_last_row(self.preorder_brush, Qt.BackgroundRole)

            current_ndx += 1
        # Not the slightest idea why this works
        # and not resizeColumnsToContents
        for i in range(self._table_model.columnCount()):
            self.table_view.resizeColumnToContents(i)
Example #2
0
class QuickOrderViewWidget(SubFrame):
    def __init__(self, parent):
        super(QuickOrderViewWidget, self).__init__("Quick view", None, parent)

        self._table_model = QStandardItemModel(1, 2, None)
        self.table_view = QTableView(self)
        self.table_view.setModel(self._table_model)
        self.layout().addWidget(self.table_view)

        self._table_model.setHorizontalHeaderLabels(
            ['Part Nr.', 'Description'])

        self.table_view.verticalHeader().hide()
        headers_view = self.table_view.horizontalHeader()
        headers_view.setResizeMode(0, QHeaderView.ResizeToContents)
        headers_view.setResizeMode(1, QHeaderView.Stretch)

    def selected_order(self, cur, prev):
        if cur.isValid():
            order_id = cur.model().index(cur.row(), 0).data(Qt.UserRole)

            self._table_model.removeRows(0, self._table_model.rowCount())
            row = 0
            for label, description in dao.order_dao.load_quick_view(order_id):
                self._table_model.appendRow(
                    [QStandardItem(label),
                     QStandardItem(description)])
Example #3
0
class BrowserWindow(QMainWindow):

    MO_ROLE = Qt.UserRole+1

    def __init__(self, conn):
        super(BrowserWindow, self).__init__()
        self._conn = conn
        self._resolver = AsyncResolver()
        self._resolver.object_resolved.connect(self._data_resolved)
        self._resolver.start()
        self._init_models()
        self._init_gui()
        self._init_data()
        self._init_connections()

    def __del__(self):
        self._resolver.stop_work()
        self._resolver.terminate()

    def _init_models(self):
        self._hierarchy_model = QStandardItemModel()
        self._hierarchy_model.setColumnCount(2)
        self._hierarchy_model.setHorizontalHeaderLabels(['class', 'dn'])
        self._details_model = QStandardItemModel()
        self._details_model.setColumnCount(2)
        self._details_model.setHorizontalHeaderLabels(['Property', 'Value'])

    def _init_gui(self):
        self._widget = QSplitter(self, Qt.Horizontal)
        self._hierarchy_view = QTreeView(self._widget)
        self._details_view = QTableView(self._widget)

        self._widget.addWidget(self._hierarchy_view)
        self._widget.addWidget(self._details_view)
        self._widget.setStretchFactor(0, 2)
        self._widget.setStretchFactor(1, 1)
        self.setCentralWidget(self._widget)

        self._hierarchy_view.setModel(self._hierarchy_model)
        self._details_view.setModel(self._details_model)

        self._hierarchy_view.expanded.connect(self._mo_item_expand)

    def _init_data(self):
        item = self._row_for_mo(self._conn.resolve_dn(''))
        self._hierarchy_model.insertRow(0, item)

    def _init_connections(self):
        self.connect(self._resolver,
                        SIGNAL('object_resolved(QVariant)'),
                     self,
                        SLOT('_data_resolved(QVariant)'))
        self._hierarchy_view.activated.connect(self._item_activated)
        #self.connect(self._hierarchy_view.selectionModel(),
        #                SIGNAL('currentChanged(QModelIndex,QModelIndex)'),
        #             self,
        #                SLOT('_current_changed(QModelIndex, QModelIndex)'))
        self.connect(self._hierarchy_view.selectionModel(),
                        SIGNAL('activated(QModelIndex)'),
                     self,
                        SLOT('_item_activated(QModelIndex)'))


    def _row_for_mo(self, mo):
        row = [QStandardItem(mo.ucs_class), QStandardItem(mo.dn)]
        for item in row:
            item.setEditable(False)
        row[0].appendColumn([QStandardItem('Loading...')])
        row[0].setData(mo, self.MO_ROLE)
        return row

    def _add_mo_in_tree(self, mo, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            item = self._get_item_for_dn(self._parent_dn(mo.dn))
        if item:
            item.appendColumn([self._row_for_mo(mo)[0]])
        self.auto_width()

    def _add_mos_in_tree(self, mos, index=QtCore.QModelIndex()):
        item = None
        if index.isValid():
            item = self._hierarchy_model.itemFromIndex(index)
        else:
            if not mos:
                return
            item = self._get_item_for_dn(self._parent_dn(mos[0].dn))
        while item.columnCount():
            item.removeColumn(0)
        items = map(self._row_for_mo, mos)
        if items:
            for x in xrange(len(items[0])):
                item.appendColumn([row[x] for row in items])
        self.auto_width()

    @staticmethod
    def _parent_dn(dn):
        parent_dn, _, rn = dn.rpartition('/')
        return parent_dn

    def _get_item_for_dn(self, dn):
        parent_dn = dn
        items = self._hierarchy_model.findItems(parent_dn, column=1)
        if items:
            return self._hierarchy_model.item(items[0].row())
        return None

    @QtCore.Slot('_data_resolved(QVariant)')
    def _data_resolved(self, datav):
        print 'Data resolved: ', datav
        index, data = datav
        if isinstance(data, UcsmObject):
            self._add_mo_in_tree(data, index=index)
        else:
            self._add_mos_in_tree(data, index=index)

    @QtCore.Slot('_current_changed(QModelIndex,QModelIndex)')
    def _current_changed(self, curr, prev):
        self._item_activated(curr)

    @QtCore.Slot('_item_activated(QModelIndex)')
    def _item_activated(self, index):
        print 'Activated: %s data %s' % (index, index.data(self.MO_ROLE))
        if index.sibling(0, 0).isValid():
            index = index.sibling(0, 0)
            data = index.data(self.MO_ROLE)
            self.set_detail_object(data)

    def _mo_item_expand(self, index):
        obj = index.data(self.MO_ROLE)
        print 'Expanded object: %s' % obj
        try:
            self._resolver.add_task(lambda: (index,
                                        self._conn.resolve_children(obj.dn)))
        except (KeyError, AttributeError):
            QtGui.QMessageBox.critical(0, 'Error', 'Object does not have dn')

    def auto_width(self):
        for view in [self._hierarchy_view, self._details_view]:
            for col in xrange(view.model().columnCount()):
                view.resizeColumnToContents(col)

    def set_detail_object(self, object):
        self._details_model.removeRows(0, self._details_model.rowCount())
        for k, v in object.attributes.iteritems():
            row = [QStandardItem(k), QStandardItem(v)]
            for item in row:
                item.setEditable(False)
            self._details_model.appendRow(row)
        self.auto_width()
Example #4
0
class ReprintDeliverySlipDialog(QDialog):
    def __init__(self, parent, dao):
        super(ReprintDeliverySlipDialog, self).__init__(parent)
        self.dao = dao

        title = _("Print a delivery slip")
        self.setWindowTitle(title)
        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title, None)

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

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Slip number")))
        self.slip_number = QLineEdit()
        hlayout.addWidget(self.slip_number)
        hlayout.addStretch()

        self.search_results_view = QTableView()
        self.search_results_model = QStandardItemModel()
        self.search_results_model.setHorizontalHeaderLabels(
            [_("Slip Nr"), _("Date"),
             _("Customer"), _("Order")])

        self.search_results_view.setModel(self.search_results_model)
        # self.search_results_view.setHorizontalHeader(self.headers_view)
        self.search_results_view.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.search_results_view.horizontalHeader().setResizeMode(
            1, QHeaderView.ResizeToContents)
        self.search_results_view.horizontalHeader().setResizeMode(
            2, QHeaderView.Stretch)
        self.search_results_view.verticalHeader().hide()

        self.slip_part_view = DeliverySlipViewWidget(self)

        hlayout_results = QHBoxLayout()
        hlayout_results.addWidget(self.search_results_view)
        hlayout_results.addWidget(self.slip_part_view)

        self.search_results_model.removeRows(
            0, self.search_results_model.rowCount())
        delivery_slips = self.dao.delivery_slip_part_dao.find_recent()
        for slip in delivery_slips:
            self.search_results_model.appendRow([
                QStandardItem(str(slip[0])),
                QStandardItem(date_to_dmy(slip[1])),
                QStandardItem(slip[2]),
                QStandardItem(slip[3])
            ])

        top_layout.addWidget(self.title_widget)
        top_layout.addLayout(hlayout)
        top_layout.addLayout(hlayout_results)
        top_layout.addWidget(self.buttons)
        top_layout.setStretch(2, 100)
        self.setLayout(top_layout)

        self.search_results_view.setSelectionBehavior(
            QAbstractItemView.SelectRows)
        self.search_results_view.setSelectionMode(
            QAbstractItemView.SingleSelection)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.search_results_view.activated.connect(self.row_activated)
        self.search_results_view.selectionModel().currentRowChanged.connect(
            self.row_selected)

    @Slot(QModelIndex, QModelIndex)
    def row_selected(self, cur_ndx, prev_ndx):
        slip_id = cur_ndx.model().index(cur_ndx.row(), 0).data()
        self.slip_number.setText(str(slip_id))
        self.slip_part_view.set_delivery_slip_parts(
            dao.delivery_slip_part_dao.load_slip_parts_frozen(slip_id))

    @Slot(QModelIndex)
    def row_activated(self, ndx):
        slip_id = ndx.model().index(ndx.row(), 0).data()
        self.slip_number.setText(str(slip_id))
        self.accept()

    @Slot()
    def accept(self):
        try:
            try:
                slip_id = int(self.slip_number.text())
            except ValueError as e:
                makeErrorBox(
                    _("The delivery slip number {} is not valid").format(
                        self.slip_number.text())).exec_()
                return

            if self.dao.delivery_slip_part_dao.id_exists(slip_id):
                print_delivery_slip(self.dao, slip_id)
            else:
                makeErrorBox(
                    _("The delivery slip {} doesn't exist").format(
                        slip_id)).exec_()
                return
        except Exception as e:
            mainlog.exception(e)
            msgBox = makeErrorBox(_("Something wrong happened while printing"))
            msgBox.exec_()

        return super(ReprintDeliverySlipDialog, self).accept()

    @Slot()
    def reject(self):
        return super(ReprintDeliverySlipDialog, self).reject()
Example #5
0
class FindOrderDialog(QDialog):
    def __init__(self,parent):
        global dao
        super(FindOrderDialog,self).__init__(parent)

        title = _("Find order")
        self.setWindowTitle(title)
        top_layout = QVBoxLayout()
        self.title_widget = TitleWidget(title,self)
        top_layout.addWidget(self.title_widget)

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Search")))
        self.search_criteria = QLineEdit()
        self.search_criteria.setObjectName("search_criteria")
        hlayout.addWidget(self.search_criteria)
        top_layout.addLayout(hlayout)



        self.search_results_view = QTableView()

        self.headers_view = QHeaderView(Qt.Orientation.Horizontal)
        self.header_model = make_header_model([_("Preorder Nr"),_("Order Nr"),_("Customer Nr"),_("Customer"),_("Order Part")])
        self.headers_view.setModel(self.header_model) # qt's doc : The view does *not* take ownership (bt there's something with the selecion mode

        self.search_results_model = QStandardItemModel()
        self.search_results_view.setModel(self.search_results_model)

        self.search_results_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.search_results_view.setHorizontalHeader(self.headers_view)
        self.search_results_view.verticalHeader().hide()
        # self.search_results_view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.search_results_view.horizontalHeader().setResizeMode(3, QHeaderView.Stretch)
        self.search_results_view.horizontalHeader().setResizeMode(4, QHeaderView.Stretch)

        self.search_results_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        self.buttons = QDialogButtonBox()
        self.buttons.addButton( QDialogButtonBox.StandardButton.Cancel)
        self.buttons.addButton( QDialogButtonBox.Ok)
        self.buttons.button(QDialogButtonBox.Ok).setObjectName("go_search")

        top_layout.addWidget(self.search_results_view)
        top_layout.setStretch(2,1000)
        top_layout.addWidget(self.buttons)
        self.setLayout(top_layout)

        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)
        self.search_results_view.activated.connect(self.row_activated)
        self.search_criteria.returnPressed.connect(self.search_criteria_submitted)

        self.setMinimumSize(800,640)

    def find_by_text(self,text):
        text = text.strip()

        try:
            too_many_results, res = dao.order_part_dao.find_ids_by_text(text.strip())

            if too_many_results:
                showWarningBox(_("Too many results"),_("The query you've given brought back too many results. Only a part of them is displayed. Consider refining your query"),object_name="too_many_results")

            return dao.order_part_dao.find_by_ids(res)

        except DataException as de:

            if de.code == DataException.CRITERIA_IS_EMPTY:
                showErrorBox(_("Error in the filter !"),
                             _("The filter can't be empty"),object_name="filter_is_empty")
            elif de.code == DataException.CRITERIA_IS_TOO_SHORT:
                showErrorBox(_("Error in the filter !"),
                             _("The filter is too short"),object_name="filter_is_too_short")
            elif de.code == DataException.CRITERIA_IS_TOO_LONG:
                showErrorBox(_("Error in the filter !"),
                             _("The filter is too long"),object_name="filter_is_too_long")

            return []
        


        # order_part_match = []
        # matches = []
        # super_matches = []

        # import re
        # re_order_part_identifier = re.compile("^([0-9]+)([A-Z]+)$")
        # re_label_identifier = re.compile("^[0-9]+$")

        # if re_order_part_identifier.match(text.upper()):
        #     # Look for an exact (and unique) match on the order part full identifier
        #     p = dao.order_part_dao.find_by_full_id(text.upper())
        #     if p:
        #         # Mimick SQLAlchemy's KeyTuples
        #         # FIXME It seems that I use something that's internal to SQLA
        #         # Search SQLA's doc for KeyedTuple to find about collections.namedtuple()

        #         from sqlalchemy.util._collections import KeyedTuple

        #         kt = KeyedTuple([p.order_id, p.order.preorder_label, p.order.accounting_label, p.order.customer_order_name, p.order.customer.fullname, p.order.creation_date, p.description, p.order_part_id, p.label],
        #                         labels=['order_id','preorder_label','accounting_label','customer_order_name','fullname','creation_date','description','order_part_id','label'])

        #         order_part_match = [ kt ]

        # if re_label_identifier.match(text):
        #     for r in dao.order_dao.find_by_labels(int(text)):
        #         super_matches.append(r)

        # for r in dao.order_dao.find_by_customer_name(text):
        #     # mainlog.debug('customer name match on {}'.format(text))
        #     matches.append(r)

        # for r in dao.order_dao.find_by_customer_order_name(text):
        #     # mainlog.debug('customer name match on {}'.format(text))
        #     matches.append(r)

        # for r in dao.order_part_dao.find_by_description(text):
        #     matches.append(r)

        # # Finally we order the matches to bring the most relevant
        # # first. The "most relevant" is really a business order.

        # return order_part_match + super_matches + \
        #     sorted(matches, lambda a,b: - cmp(a.order_id,b.order_id))


    def _search_results_to_array(self,search_results):
        array = []
        
        for res in search_results:
            # mainlog.debug("_search_results_to_array {}".format(res.creation_date))

            i = QStandardItem(res.preorder_part_label)
            row = [i,
                   QStandardItem(res.accounting_part_label),
                   QStandardItem(res.customer_order_name),
                   QStandardItem(res.fullname)]

            if 'order_part_id' in res.__dict__:
                # It's an order part

                i.setData( res.order_part_id, Qt.UserRole)
                i.setData( 'order_part', Qt.UserRole+1)
                row.append( QStandardItem(res.description))
            else:
                # It's an order

                i.setData( res.order_id, Qt.UserRole)
                i.setData( 'order', Qt.UserRole+1)
                row.append( QStandardItem())

            array.append(row)

        return array


    def load_search_results(self,text=None):
        global dao

        if text is None:
            text = self.search_criteria.text()

        db_results = self.find_by_text(text)
        array = self._search_results_to_array(db_results)

        self.search_results_model.removeRows(0,self.search_results_model.rowCount())
        for row in array:
            self.search_results_model.appendRow(row)
        mainlog.debug("Loaded model : {}".format(self.search_results_model.rowCount()))
        self.search_results_view.resizeColumnsToContents()

        if self.search_results_model.rowCount() > 0:
            self.search_results_view.setCurrentIndex(self.search_results_model.index(0,0))
            self.search_results_view.setFocus(Qt.OtherFocusReason)

        if self.search_results_model.rowCount() == 1:
            self.accept()


    def selected_item(self):
        mainlog.debug("FindOrder.selected_item")
        ndx = self.search_results_view.currentIndex()
        if ndx.isValid():
            ndx = self.search_results_view.model().index( ndx.row(), 0)

            item = ndx.data(Qt.UserRole)
            item_type = ndx.data(Qt.UserRole+1)

            if item_type == 'order':
                mainlog.debug("FindOrder.selected_item order_id={}".format(item))
                return dao.order_dao.find_by_id(item)
            elif item_type == 'order_part':
                mainlog.debug("FindOrder.selected_item order_part_id={}".format(item))
                return dao.order_part_dao.find_by_id(item)
            else:
                mainlog.error("Unsupported item type {}".format(item_type))
        else:
            mainlog.error("Invalid index")
            return None

    @Slot()
    def accept(self):
        # mainlog.debug("accept")
        # self.load_search_results()
        # mainlog.debug("accept - done")
        return super(FindOrderDialog,self).accept()

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

    @Slot()
    def search_criteria_submitted(self):
        mainlog.debug("search_criteria_submitted")
        self.load_search_results()

    @Slot(QModelIndex)
    def row_activated(self,ndx):
        mainlog.debug("row_activated")
        self.accept()

    def keyPressEvent(self,event):

        # The goal here is to make sure the accept signal is called only
        # if the user clicks on the "OK" button /with the mouse/ and,
        # not with the keyboard

        if event.key() in (Qt.Key_Enter, Qt.Key_Return):
            return
        else:
            super(FindOrderDialog,self).keyPressEvent(event)