Пример #1
0
class OperationsOverviewWidget(QWidget):
    def __init__(self,parent=None):
        super(OperationsOverviewWidget,self).__init__(parent)

        self.operation_prototype = []
        self.operation_prototype.append( OperationDefinitionPrototype('operation_definition_id',_('Op.'),operation_definition_cache.all_on_order_part(), editable=False))
        self.operation_prototype.append( TextAreaPrototype('description',_('Description'),nullable=True,editable=False))
        self.operation_prototype.append( FloatNumberPrototype('value',_('Value'),nullable=True,editable=False))
        self.operation_prototype.append( DurationPrototype('planned_hours',_('Planned time'),nullable=True,editable=False))
        # operation_prototype.append( DurationPrototype('t_reel',_('Used time'),nullable=False,editable=False))
        self.operation_prototype.append( DurationPrototype('done_hours',_('Imputations'),editable=False))
        # operation_prototype.append( TextLinePrototype('note',_('Note'),editable=True,nullable=True,hidden=True))


        self.model = PrototypedModelView(self.operation_prototype,self)
        self.view = PrototypedQuickView(self.operation_prototype,self)
        self.view.setModel(self.model)
        self.view.verticalHeader().hide()
        self.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) # Description column wide enough
        self.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch)
        self.view.setWordWrap(True)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.view.setSelectionMode(QAbstractItemView.ExtendedSelection)

        # self.controller_operation = PrototypeController(self,
        #                                                 self.operation_prototype,
        #                                                 ProxyTableView(None,self.operation_prototype))
        # self.controller_operation.view.verticalHeader().hide()
        # # self.controller_operation.setModel(TrackingProxyModel(None,operation_prototype))
        # self.controller_operation.setModel(TrackingProxyModel(self,self.operation_prototype))

        # self.controller_operation.view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents) # Description column wide enough
        # self.controller_operation.view.horizontalHeader().setResizeMode(1,QHeaderView.Stretch)

        # self.controller_operation.view.setSelectionBehavior(QAbstractItemView.SelectRows)

        layout = QHBoxLayout()
        layout.setContentsMargins(0,0,0,0)
        layout.addWidget(self.view)
        self.setLayout(layout)

        self.copy_operations_action = QAction(_("Copy operations"),self.view)
        self.copy_operations_action.triggered.connect( self.copy_operations_slot)
        self.copy_operations_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C))
        self.copy_operations_action.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        self.view.addAction(self.copy_operations_action)


    def fill_order_part(self, order_part_id):
        """ Fill with order part's data.
        Doesn't keep any reference to the order part.
        """

        if order_part_id:
            mainlog.debug("fill_order_part : triggered !")
            operations = dao.operation_dao.find_by_order_part_id_frozen(order_part_id)
            mainlog.debug("fill_order_part : build model !")
            self.model.buildModelFromObjects(operations)
            mainlog.debug("fill_order_part : build model complete !")
            self.view.verticalHeader().setResizeMode(QHeaderView.ResizeToContents)
        else:
            self.model.clear()

        ndx = self.model.index(0,0)
        mainlog.debug("fill_order_part : setCurrentIndex !")
        self.view.setCurrentIndex(ndx)
        mainlog.debug("fill_order_part : setCurrentIndex done!")

    @Slot()
    def copy_operations_slot(self):
        mainlog.debug("copy_operations_slot")

        view = self.view
        model = self.model

        # Collect the rows indices

        rows = set()
        for ndx in view.selectedIndexes():
            if ndx.row() >= 0:
                rows.add(ndx.row())

        # There are no guarantee on the selectedIndexes order
        rows = sorted(list(rows))


        # Copy for elsewhere in Horse

        if len(rows):
            operations = []
            for row_ndx in rows:
                operation = model.object_at(row_ndx)
                mainlog.debug(operation)
                operations.append(operation)
            copy_paste_manager.copy_operations(operations)
        else:
            # If nothing to copy then we leave the copy/paste clipboard
            # as it is. So one could paste again what he copied before.
            pass
Пример #2
0
class DeliverySlipPanel(HorsePanel):

    delivery_slip_changed = Signal()

    def close_panel(self):
        self.filter_widget.remember_current_selection( configuration)

    def _selected_slip(self):
        cur_ndx = self.search_results_view.currentIndex()
        if cur_ndx.row() >= 0:
            return cur_ndx.model().object_at(cur_ndx.row())
        return None

    def reprint(self):
        cur_ndx = self.search_results_view.currentIndex()
        slip_id = cur_ndx.model().index(cur_ndx.row(),0).data()

        if dao.delivery_slip_part_dao.id_exists(slip_id):
            print_delivery_slip(dao,slip_id)
        else:
            makeErrorBox(_("The delivery slip {} doesn't exist").format(slip_id)).exec_()

    def desactivate(self):
        slip_id = self._selected_slip().delivery_slip_id
        mainlog.debug("Desactivate slip {}".format(slip_id))
        dao.delivery_slip_part_dao.deactivate(slip_id)
        self.refresh(slip_id)
        self.delivery_slip_changed.emit()

    def activate(self):
        slip_id = self._selected_slip().delivery_slip_id
        dao.delivery_slip_part_dao.activate(slip_id)
        self.refresh(slip_id)
        self.delivery_slip_changed.emit()

    def delete(self):
        slip_id = self._selected_slip().delivery_slip_id
        dao.delivery_slip_part_dao.delete_last(slip_id)
        self.refresh(slip_id)
        self.delivery_slip_changed.emit()

    @Slot()
    def show_actions(self):
        button = self.action_menu.parent()
        p = button.mapToGlobal(QPoint(0,button.height()))
        self.action_menu.exec_(p)

    @Slot()
    def _toggle_edit_filters(self):
        self.filter_widget.setVisible( not self.filter_widget.isVisible())

    def __init__(self,parent):
        super(DeliverySlipPanel,self).__init__(parent)

        title = _("Delivery slips")

        self.slip_data = None

        self.set_panel_title(_("Delivery slip overview"))
        self.reprint_delivery_slip = QAction(_("Reprint delivery slip"),self) # , parent
        self.reprint_delivery_slip.triggered.connect( self.reprint)
        # self.reprint_delivery_slip.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_V))
        self.reprint_delivery_slip.setShortcutContext(Qt.WidgetWithChildrenShortcut)
        # self.controller_operation.view.addAction(self.reprint_delivery_slip)


        self.desactivate_delivery_slip = QAction(_("Desactivate delivery slip"),self) # , parent
        self.desactivate_delivery_slip.triggered.connect( self.desactivate)
        self.desactivate_delivery_slip.setShortcutContext(Qt.WidgetWithChildrenShortcut)

        self.activate_delivery_slip = QAction(_("Activate delivery slip"),self) # , parent
        self.activate_delivery_slip.triggered.connect( self.activate)
        self.activate_delivery_slip.setShortcutContext(Qt.WidgetWithChildrenShortcut)

        self.delete_delivery_slip = QAction(_("Delete delivery slip"),self) # , parent
        self.delete_delivery_slip.triggered.connect( self.delete)
        self.delete_delivery_slip.setShortcutContext(Qt.WidgetWithChildrenShortcut)


        filter_family = FilterQuery.DELIVERY_SLIPS_FAMILY
        self.filter_widget = PersistentFilter( filter_family, suggestion_finder)
        self.filter_widget.apply_filter.connect(self.apply_filter_slot)
        self.filter_widget.hide()

        navigation = NavBar( self,
                             [ (self.filter_widget.get_filters_combo(), None),
                               (_("Edit filter"),self._toggle_edit_filters),
                               (_("Action"),self.show_actions) ] )

        self.title_widget = TitleWidget(title, self, navigation) # navigation)


        self.action_menu = QMenu(navigation.buttons[0])
        list_actions = [ (self.reprint_delivery_slip,None),
                         (self.activate_delivery_slip,None),
                         (self.desactivate_delivery_slip,None),
                         # (self.delete_delivery_slip,None)
        ]
        populate_menu(self.action_menu, self, list_actions, context=Qt.WidgetWithChildrenShortcut)

        # self.setWindowTitle(title)


        top_layout = QVBoxLayout(self)

        # self.filter_line_edit = QLineEdit()

        # self.filter_line_edit = QueryLineEdit(suggestion_finder)
        initialize_customer_cache() # FIXME Not the place to do that

        # filter_family = 'delivery_slips'
        # self.filter_name = FiltersCombo(self, filter_family)
        # filter_widget = PersistentFilter(filter_family, self.filter_name)
        # filter_widget.apply_filter.connect(self.apply_filter_slot)

        self.proto = []
        self.proto.append( IntegerNumberPrototype('delivery_slip_id',_("Slip Nr"), editable=False))
        self.proto.append( DatePrototype('creation',_('Date'), editable=False))
        self.proto.append( TextLinePrototype('fullname',_('Customer'), editable=False))
        self.proto.append( TextLinePrototype('user_label',_('Order'), editable=False))

        self.search_results_model = DeliverySlipPanelModel(self.proto, self)
        self.search_results_view = PrototypedQuickView(self.proto, self)
        self.search_results_view.setModel(self.search_results_model)


        self.search_results_view.verticalHeader().hide()
        self.search_results_view.horizontalHeader().setResizeMode(1, QHeaderView.ResizeToContents)
        self.search_results_view.horizontalHeader().setResizeMode(2, QHeaderView.Stretch)
        self.search_results_view.horizontalHeader().setSortIndicatorShown(True)
        self.search_results_view.horizontalHeader().setSortIndicator(0,Qt.AscendingOrder)
        self.search_results_view.horizontalHeader().sectionClicked.connect(self._section_clicked)
        self.search_results_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.search_results_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.search_results_view.selectionModel().currentRowChanged.connect(self.row_selected)

        self.slip_part_view = DeliverySlipViewWidget(self)

        hlayout_results = QHBoxLayout()
        # w = SubFrame(_("Delivery slips"),self.search_results_view,None)
        hlayout_results.addWidget(self.search_results_view)
        w = SubFrame(_("Detail"),self.slip_part_view,None)
        hlayout_results.addWidget(w)

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

        self.filter_widget.load_last_filter( configuration)



    def refresh(self,slip_id):
        filter_string = self.filter_line_edit.text()
        self.apply_filter_slot(filter_string)

        if slip_id:
            ndx = self.search_results_model.find_index( lambda s:s.delivery_slip_id == slip_id)

            r = 0
            m = self.search_results_model
            if ndx:
                r = ndx.row()

            s = QItemSelection(m.index(r,0), m.index(r, m.columnCount()-1))
            self.search_results_view.selectionModel().select(s, QItemSelectionModel.Select)

    @Slot(int)
    def _section_clicked(self,logical_ndx):
        self.refresh_action()

    @Slot(str)
    def apply_filter_slot(self, filter_string):
        if filter_string:
            try:
                self.slip_data = dao.delivery_slip_part_dao.load_slip_parts_on_filter(filter_string)
            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
        else:
            self.slip_data = dao.delivery_slip_part_dao.find_recent2(1000)
        self.refresh_action()


    def refresh_action(self):

        if self.slip_data == None:
            self.slip_data = dao.delivery_slip_part_dao.find_recent2(1000)

        data = self.slip_data
        headers = self.search_results_view.horizontalHeader()
        section_sorted = headers.sortIndicatorSection()
        sort_criteria = self._get_sort_criteria( section_sorted)
        sort_order = None

        if sort_criteria:
            sort_order = headers.sortIndicatorOrder()
            data = sorted(data, key=cmp_to_key(sort_criteria), reverse = sort_order == Qt.DescendingOrder)

        self.search_results_model.buildModelFromObjects(data)

        if sort_criteria:
            # Changing the model removes the sort order (which makes sense because
            # changing the model may alter the order of rows)
            headers.setSortIndicator(section_sorted,sort_order)

        self.search_results_view.setFocus(Qt.OtherFocusReason)


    @Slot(QModelIndex,QModelIndex)
    def row_selected(self,cur_ndx,prev_ndx):
        if cur_ndx.model():
            slip = cur_ndx.model().object_at( cur_ndx.row())
            if slip:
                slip_id = slip.delivery_slip_id
                self.slip_part_view.set_delivery_slip_parts(dao.delivery_slip_part_dao.load_slip_parts_frozen(slip_id))

                self.activate_delivery_slip.setEnabled( not slip.active)
                self.desactivate_delivery_slip.setEnabled( slip.active)
                self.delete_delivery_slip.setEnabled( cur_ndx.row() == 0)
                return

        self.slip_part_view.set_delivery_slip_parts(None)

    SECTION_SLIP_ID = 0
    SECTION_CREATION_DATE = 1
    SECTION_CUSTOMER = 2
    SECTION_ORDER_LABEL = 3


    def _get_sort_criteria(self,section_sorted):
        sort_criteria = None

        # True if the parts of the order stay grouped
        # together in the table
        order_stay_together = True

        if section_sorted == self.SECTION_CUSTOMER: # Customer
            sort_criteria = lambda a,b: cmp(a.fullname, b.fullname) or \
                            cmp(a.delivery_slip_id,b.delivery_slip_id)
        elif section_sorted == self.SECTION_CREATION_DATE:
            sort_criteria = lambda a,b: cmp(a.creation or date(2100,1,1), b.creation or date(2100,1,1))
        elif section_sorted == self.SECTION_SLIP_ID:
            sort_criteria = lambda a,b: cmp(a.delivery_slip_id, b.delivery_slip_id)
        elif section_sorted == self.SECTION_ORDER_LABEL:
            sort_criteria = lambda a,b: cmp(a.user_label, b.user_label)
        else:
            sort_criteria = None

        if sort_criteria is not None:
            self.current_sort_criteria = sort_criteria
        else:
            sort_criteria = self.current_sort_criteria

        return sort_criteria
Пример #3
0
class SupplyOrderOverview(HorsePanel):
    def close_panel(self):
        self.filter_widget.remember_current_selection(configuration)

    def _selected_supply_order_part(self):
        cur_ndx = self.search_results_view.currentIndex()
        if cur_ndx.row() >= 0:
            return cur_ndx.model().object_at(cur_ndx.row())
        return None

    @Slot()
    def show_actions(self):
        button = self.action_menu.parent()
        p = button.mapToGlobal(QPoint(0, button.height()))
        self.action_menu.exec_(p)

    SECTION_REFERENCE = 0
    SECTION_SUPPLIER = 1
    SECTION_DEADLINE = 2
    SECTION_DESCRIPTION = 3
    SECTION_CREATION_DATE = 6

    def _make_sort_criteria(self, section_sorted, sort_order):

        sort_criteria = None

        if section_sorted == self.SECTION_REFERENCE:
            if sort_order == Qt.AscendingOrder:

                def ordering_key(p):
                    return p.accounting_label * 1000 + p.position

                sort_criteria = lambda a, b: cmp(ordering_key(a),
                                                 ordering_key(b))
            else:

                def ordering_key(p):
                    return p.accounting_label * 1000 + 999 - p.position

                sort_criteria = lambda a, b: cmp(ordering_key(a),
                                                 ordering_key(b))
        elif section_sorted == self.SECTION_SUPPLIER:
            order_correction = +1
            if sort_order == Qt.DescendingOrder:
                order_correction = -1

            sort_criteria = lambda a,b: cmp(a.supplier_fullname, b.supplier_fullname) or \
                            cmp(a.accounting_label,b.accounting_label) or order_correction * cmp(a.position,b.position)
        elif section_sorted == self.SECTION_DEADLINE:  # Deadline
            sort_criteria = lambda a, b: cmp(
                a.expected_delivery_date or date(2100, 1, 1), b.
                expected_delivery_date or date(2100, 1, 1))

        return sort_criteria

    def _fill_model(self, parts_data=None):
        """ Refills the list of parts data with given parts
        data. If no parts data are given, then the last
        data set is reused.

        This thake into account the currently selected sort
        indicator and, if any, the currently selected filter.
        """

        if parts_data is not None:
            self.parts_data = parts_data
        else:
            parts_data = self.parts_data

        view = self.search_results_view
        model = self.search_results_model
        headers = view.horizontalHeader()
        sort_order = headers.sortIndicatorOrder()
        section_sorted = headers.sortIndicatorSection()

        sort_criteria = self._make_sort_criteria(section_sorted, sort_order)
        if sort_criteria:
            sort_order = headers.sortIndicatorOrder()

            if sys.version[0] == '3':
                parts_data = sorted(parts_data,
                                    key=cmp_to_key(sort_criteria),
                                    reverse=sort_order == Qt.DescendingOrder)
            else:
                parts_data = sorted(parts_data,
                                    sort_criteria,
                                    reverse=sort_order == Qt.DescendingOrder)

        model.buildModelFromObjects(parts_data)

        if sort_criteria:
            # Changing the model removes the sort order (which makes sense because
            # changing the model may alter the order of rows)
            # => I have to reset it
            headers.setSortIndicator(section_sorted, sort_order)

        if len(parts_data) == 0:
            # Must do this because when the model is empty
            # the slection is not updated, so no signal
            # is sent
            self._fill_order_part_detail(None)
        else:
            view.selectionModel().reset()
            view.selectionModel().select(
                view.model().index(0, 0),
                QItemSelectionModel.Select | QItemSelectionModel.Rows)

        view.horizontalHeader().setResizeMode(self.SECTION_DESCRIPTION,
                                              QHeaderView.Stretch)

    @Slot()
    def refresh_action(self):
        mainlog.debug("refresh_action")
        self._apply_filter(self.filter_widget.current_filter())

    @Slot(int)
    def section_clicked(self, logical_ndx):
        self._fill_model()

    @Slot(str)
    def _apply_filter(self, filter_text):
        mainlog.debug(u"_apply_filter : {}".format(filter_text))

        parts = []
        len_check = False

        if " " in filter_text.strip():
            # More than one word in the filter => I assume it's the full
            # fledged filtering

            check = check_parse(filter_text)
            if check == True:
                parts = supply_order_service.find_parts_expression_filter(
                    filter_text)
                len_check = True
            else:
                showErrorBox(_("Error in the filter !"),
                             check,
                             object_name="filter_is_wrong")

        elif filter_text:
            parts = supply_order_service.find_parts_filtered(filter_text)
            len_check = True
        else:
            parts = supply_order_service.find_recent_parts()
            len_check = False

        if len_check and len(parts) >= supply_order_service.MAX_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"
                  ))
        self._fill_model(parts)
        self.search_results_view.setFocus(Qt.OtherFocusReason)

    def _make_supply_order_detail_view(self):

        # There's a self.proto somewhere, don't mess with it :-)

        # proto = []
        # proto.append( TextLinePrototype('description',_('Description'), editable=True,nullable=False))
        # proto.append( FloatNumberPrototype('quantity',_('Quantity'), editable=True,nullable=False))
        # proto.append( FloatNumberPrototype('unit_price',_('Unit price'), editable=True,nullable=False))

        # self.detail_model = PrototypedModelView(proto, self)
        # self.detail_view = PrototypedQuickView(proto, self)
        # self.detail_view.setModel(self.detail_model)
        # self.detail_view.verticalHeader().hide()

        self.detail_description = QTextEdit()
        self.detail_description.setTextInteractionFlags(
            Qt.TextBrowserInteraction)

        self.delivery_date_widget = QLabel()
        self.creation_date_widget = QLabel()
        self.supplier_reference_widget = QLabel()

        hlayout = QHBoxLayout()
        hlayout.addWidget(QLabel(_("Delivery date")))
        hlayout.addWidget(self.delivery_date_widget)
        hlayout.addStretch()

        hlayout3 = QHBoxLayout()
        hlayout3.addWidget(QLabel(_("Creation date")))
        hlayout3.addWidget(self.creation_date_widget)
        hlayout3.addStretch()

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(QLabel(_("Supplier's reference")))
        hlayout2.addWidget(self.supplier_reference_widget)
        hlayout2.addStretch()

        layout = QVBoxLayout()
        layout.addLayout(hlayout)
        layout.addLayout(hlayout3)
        layout.addLayout(hlayout2)
        layout.addWidget(self.detail_description)
        layout.addStretch()

        # layout.addWidget(self.detail_view)
        # layout.setStretch(0,1)
        # layout.setStretch(1,3)

        return layout

    @Slot()
    def _toggle_edit_filters(self):
        self.filter_widget.setVisible(not self.filter_widget.isVisible())

    def __init__(self, parent):
        super(SupplyOrderOverview, self).__init__(parent)

        initialize_supplier_cache()

        self.set_panel_title(_("Supply Orders"))

        # navigation = NavBar( self,
        #                      [ (_("Action"),self.show_actions) ] )
        # self.action_menu = QMenu(navigation.buttons[0])

        title = _("Supply orders")
        # self.setWindowTitle(title)

        filter_family = FilterQuery.SUPPLIER_ORDER_SLIPS_FAMILY
        self.filter_widget = PersistentFilter(filter_family)
        self.filter_widget.apply_filter.connect(self._apply_filter)
        self.filter_widget.hide()

        self.proto = []
        self.proto.append(
            TextLinePrototype('human_identifier', _("Part Nr"),
                              editable=False))
        self.proto.append(
            TextLinePrototype('supplier_fullname',
                              _('Supplier'),
                              editable=False))
        self.proto.append(
            DatePrototype('expected_delivery_date',
                          _('Deadline'),
                          editable=True,
                          nullable=False))
        self.proto.append(
            TextLinePrototype('description',
                              _('Description'),
                              editable=True,
                              nullable=False))
        self.proto.append(
            FloatNumberPrototype('quantity',
                                 _('Quantity'),
                                 editable=True,
                                 nullable=False))
        self.proto.append(
            FloatNumberPrototype('unit_price',
                                 _('Unit price'),
                                 editable=True,
                                 nullable=False))
        self.proto.append(
            DatePrototype('creation_date',
                          _('Creation date'),
                          editable=False,
                          nullable=False))

        # self.proto.append( DatePrototype('creation_date',_('Creation'), editable=False))
        # self.proto.append( DatePrototype('expected_delivery_date',_('Expected\ndelivery'), editable=False))
        # self.proto.append( TextLinePrototype('supplier_fullname',_('Supplier'), editable=False))

        self.search_results_model = PrototypedModelView(self.proto, self)
        self.search_results_view = PrototypedQuickView(self.proto, self)
        self.search_results_view.setModel(self.search_results_model)
        self.search_results_view.horizontalHeader().setSortIndicatorShown(True)

        self.search_results_view.verticalHeader().hide()
        self.search_results_view.verticalHeader().setResizeMode(
            QHeaderView.ResizeToContents)
        self.search_results_view.doubleClicked.connect(
            self._supply_order_double_clicked)
        self.search_results_view.activated.connect(
            self._supply_order_double_clicked)
        self.search_results_view.horizontalHeader().sectionClicked.connect(
            self.section_clicked)

        top_layout = QVBoxLayout(self)

        navigation = NavBar(self,
                            [(self.filter_widget.get_filters_combo(), None),
                             (_("Edit filter"), self._toggle_edit_filters)])

        self.title_widget = TitleWidget(title, self, navigation)  # navigation)

        hlayout_results = QHBoxLayout()
        # w = SubFrame(_("Supply order parts"),self.search_results_view,None)
        hlayout_results.addWidget(self.search_results_view)

        w = SubFrame(_("Supply order detail"),
                     self._make_supply_order_detail_view(), None)
        hlayout_results.addWidget(w)

        hlayout_results.setStretch(0, 2)
        hlayout_results.setStretch(0, 1)

        top_layout.addWidget(self.title_widget)
        top_layout.addWidget(self.filter_widget)
        top_layout.addLayout(hlayout_results)
        top_layout.setStretch(3, 100)
        self.setLayout(top_layout)

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

        # self.search_results_view.activated.connect(self.row_activated)
        self.search_results_view.selectionModel().currentRowChanged.connect(
            self.row_selected)
        # self.detail_view.doubleClicked.connect(self._supply_order_double_clicked)

        # pub.subscribe(self.refresh_panel, 'supply_order.changed')
        # pub.subscribe(self.refresh_panel, 'supply_order.deleted')
        # self.filter_widget.select_default_filter()
        self.filter_widget.load_last_filter(configuration)

    supply_order_selected = Signal(object)

    @Slot(QModelIndex)
    def _supply_order_double_clicked(self, cur_ndx):
        mainlog.debug("_supply_order_double_clicked")
        supply_order = cur_ndx.model().object_at(cur_ndx.row())
        if supply_order:
            self.supply_order_selected.emit(supply_order)

    def _fill_order_part_detail(self, supply_order_part):
        if supply_order_part:
            supply_order_part_id = supply_order_part.supply_order_id
            supply_order, parts = supply_order_service.find_by_id(
                supply_order_part.supply_order_id)
            self.detail_description.setText(supply_order.description)
            self.delivery_date_widget.setText(
                date_to_s(supply_order.expected_delivery_date) or "-")
            self.supplier_reference_widget.setText(
                supply_order.supplier_reference or "-")
            self.creation_date_widget.setText(
                date_to_s(supply_order.creation_date) or "-")
        else:
            self.detail_description.setText("-")
            self.delivery_date_widget.setText("-")
            self.supplier_reference_widget.setText("-")
            self.creation_date_widget.setText("-")

    @Slot(QModelIndex, QModelIndex)
    def row_selected(self, cur_ndx, prev_ndx):
        if cur_ndx.model():
            supply_order_part = cur_ndx.model().object_at(cur_ndx.row())
            self._fill_order_part_detail(supply_order_part)