Ejemplo n.º 1
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()
Ejemplo n.º 2
0
class PostViewWidget(HorsePanel):
    def __init__(self, parent, order_overview_widget, find_order_slot):
        global configuration

        super(PostViewWidget, self).__init__(parent)

        self.set_panel_title(_("Post overview"))
        self.bold_font = QFont(self.font())
        self.bold_font.setBold(True)
        self.nb_cols = 8  # Number of columns in the operation definition table

        self.order_overview_widget = order_overview_widget

        self.button = QPushButton(_("Refresh"), self)
        self.button.clicked.connect(self.refresh_action)
        self.sort_by_deadline_button = QRadioButton(_("By deadline"), self)
        self.sort_by_deadline_button.toggled.connect(self.sort_by_deadline)
        self.sort_by_size_button = QRadioButton(_("By hours left to do"), self)
        self.sort_by_size_button.toggled.connect(self.sort_by_size)

        # hlayout = QHBoxLayout()
        # hlayout.setObjectName("halyout")
        # hlayout.setContentsMargins(0,0,0,0)
        # hlayout.addWidget(self.sort_by_deadline_button)
        # hlayout.addWidget(self.sort_by_size_button)
        # hlayout.addWidget(self.button)
        # hlayout.addStretch()

        self.navbar = NavBar(self, [(self.sort_by_deadline_button, None),
                                    (self.sort_by_size_button, None),
                                    (self.button, None),
                                    (_("Find"), find_order_slot)])
        self.navbar.buttons[3].setObjectName("specialMenuButton")

        self.vlayout = QVBoxLayout(self)
        self.vlayout.setObjectName("Vlayout")
        self.vlayout.addWidget(
            TitleWidget(_("Posts Overview"), self, self.navbar))

        self._table_model = QStandardItemModel(1, self.nb_cols, self)
        self.table_view = QTableView(None)
        self.table_view.setModel(self._table_model)
        self.table_view.selectionModel().currentChanged.connect(
            self.operation_selected)

        self.table_view.verticalHeader().hide()
        self.table_view.horizontalHeader().hide()
        self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)

        # This forces Qt to expand layout once I fill data in
        # FIXME dirty but I really don't get why setting
        # the mini width to something smaller (that happens at
        # startup, on first refresh) doesn't work
        self.table_view.setMinimumWidth(1)
        self.table_view.setMaximumWidth(1)

        self.post_view_scene = PostViewScene(self, order_overview_widget)
        self.post_view_scene_view = QGraphicsView(self)
        self.post_view_scene_view.setScene(self.post_view_scene)
        self.post_view_scene_view.setSizePolicy(QSizePolicy.Expanding,
                                                QSizePolicy.Expanding)

        self.splitter = QSplitter(Qt.Horizontal)
        self.splitter.addWidget(
            SubFrame(_("Posts"), self.table_view, self.splitter))
        self.splitter.addWidget(
            SubFrame(_("Workload"), self.post_view_scene_view, self.splitter))
        # self.splitter.setStretchFactor(0,1)
        self.splitter.setStretchFactor(1, 1)
        self.vlayout.addWidget(self.splitter)

        # hlayout = QHBoxLayout()
        # hlayout.addWidget(SubFrame(_("Posts"),self.table_view,self))
        # hlayout.addWidget(SubFrame(_("Workload"),self.post_view_scene_view,self))
        # hlayout.setStretch(1,1)
        # self.vlayout.addLayout(hlayout)

        self.vlayout.setStretch(0, 0)
        self.vlayout.setStretch(1, 1)

        self.setLayout(self.vlayout)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.slidePostsScene)

        self.current_view_y = 0

    def _data_load(self):
        global dao

        all_operations = dao.operation_dao.load_all_operations_ready_for_production(
        )
        operation_definitions = dao.operation_definition_dao.all_direct_frozen(
        )

        return operation_definitions, all_operations

    def _reset_operation_definitions(self, operations):
        self._table_model.setColumnCount(1)
        self._table_model.setRowCount(len(operations))

        # BUG This should be refreshed on reload() too

        row = col = 0
        first_active = None

        for opdef in operations:

            if opdef.operation_definition_id in self.post_view_scene.drawn_operations_data:
                # currently total planned time
                t = self.post_view_scene.drawn_operations_data[
                    opdef.operation_definition_id]
                ndx = self._table_model.index(row, col)
                if not first_active:
                    first_active = ndx
                self._table_model.setData(
                    ndx, u"{} {}".format(opdef.description, t), Qt.DisplayRole)
                # self._table_model.setData(ndx,self.bold_font,Qt.FontRole)

                self._table_model.setData(self._table_model.index(row, col),
                                          opdef.operation_definition_id,
                                          Qt.UserRole)
                row += 1

            else:
                pass
                # self._table_model.setData(self._table_model.index(row,col),opdef.description,Qt.DisplayRole)

            # = col + 1
            # if col == self.nb_cols:
            #     col = 0
            #     row += 1

        self._table_model.setRowCount(row)

        # self.table_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.vlayout.setStretch(0,0)
        # self.vlayout.setStretch(1,10)
        # self.vlayout.setStretch(2,10000)

        # height = 0
        # for c in range(self.table_view.model().rowCount()):
        #     height += self.table_view.rowHeight(c) + 1 # +1 for cell border
        # self.table_view.setMinimumHeight(height)
        # self.table_view.setMaximumHeight(height)
        for i in range(self.nb_cols):
            self.table_view.resizeColumnToContents(i)
        self.table_view.setMaximumWidth(self.table_view.columnWidth(0))
        self.table_view.setMinimumWidth(self.table_view.columnWidth(0))
        self.table_view.setSizePolicy(QSizePolicy.Maximum,
                                      QSizePolicy.Preferred)

        self.table_view.update()
        self.splitter.update()

        return first_active

    def slide_to_operation(self, opdef_id):
        if opdef_id in self.post_view_scene.posts_offsets:
            self.slide_target_opdef_id = opdef_id
            # mainlog.debug("Target y = {}".format(self.post_view_scene.posts_offsets[self.slide_target_opdef]))
            self.timer.start(20)

    @Slot()
    def slidePostsScene(self):
        if self.slide_target_opdef_id is None:
            return

        # self.post_view_scene_view
        self.post_view_scene.set_cursor_on(
            self.slide_target_opdef_id
        )  # This done here also aviod some screen trashing

        v = self.post_view_scene_view.verticalScrollBar().value()
        # mainlog.debug( "slidePostsScene : {}".format(v))

        r = self.post_view_scene.posts_offsets[self.slide_target_opdef_id]
        target_y = r.y() + r.height() / 2
        delta = (target_y - self.current_view_y) * 0.4
        self.current_view_y = self.current_view_y + delta
        self.post_view_scene_view.centerOn(0, self.current_view_y)
        # mainlog.debug( "slidePostsScene : {} / {}".format(target_y, self.current_view_y))

        if self.post_view_scene_view.verticalScrollBar().value() == v:
            # Close enough => stop moving
            # FIXME not correct because we must stop when the view stops moving, not when the goal we set for centerOn is reached
            self.timer.stop()

    @Slot(QModelIndex, QModelIndex)
    def operation_selected(self, ndx_cur, ndx_old):
        if ndx_cur.isValid():
            opdef = self._table_model.data(ndx_cur, Qt.UserRole)
            if opdef:
                self.slide_to_operation(
                    self._table_model.data(ndx_cur, Qt.UserRole))

    @Slot()
    def refresh_action(self):
        # FIXME reload operations as well

        operation_definitions, all_operations = self._data_load()

        # mainlog.debug("reload")
        if self.sort_by_deadline_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 1)
        elif self.sort_by_size_button.isChecked():
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 2)
        else:
            self.post_view_scene.reload(self, operation_definitions,
                                        all_operations, 0)

        # mainlog.debug("reset")
        first_active = self._reset_operation_definitions(operation_definitions)
        # self.table_view.selectionModel().currentChanged.connect(self.operation_selected)
        if first_active:
            self.table_view.setCurrentIndex(first_active)

        # mainlog.debug("done reset")

    @Slot(bool)
    def sort_by_deadline(self, checked):
        if checked:
            self.refresh_action()

    @Slot(bool)
    def sort_by_size(self, checked):
        if checked:
            self.refresh_action()

    order_part_double_clicked = Signal(int)

    # Callback that will be called by HooverBar
    def set_on_order_part(self, order_part_id):
        self.order_part_double_clicked.emit(order_part_id)
Ejemplo n.º 3
0
class DialogLookup(QtGui.QDialog):
    def __init__(self, lookup):
        super().__init__()

        self._lookup = lookup
        self._model = QStandardItemModel()  # (4, 4)

        self.initUI()
        self.initDB()

    def initUI(self):
        global _compatible

        self.result = userCancelled

        # create our window
        # define window		xLoc,yLoc,xDim,yDim
        self.setGeometry(250, 250, 640, 480)
        self.setWindowTitle(translate('Rocket', "Component lookup..."))
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

        searchLabel = QtGui.QLabel(translate('Rocket', "Search"), self)

        self._searchInput = QtGui.QLineEdit(self)
        self._searchInput.setFixedWidth(80)
        self._searchInput.textEdited.connect(self.onSearch)

        lookupTypeLabel = QtGui.QLabel(translate('Rocket', "Component"), self)

        self._lookupTypeCombo = QtGui.QComboBox(self)
        self._lookupTypeCombo.addItems(_compatible[self._lookup])
        self._lookupTypeCombo.setCurrentText(self._lookup)
        self._lookupTypeCombo.currentTextChanged.connect(self.onLookupType)

        self._dbTable = QtGui.QTableView(self)
        self._dbTable.setModel(self._model)
        self._dbTable.setSelectionBehavior(QtGui.QTableView.SelectRows)
        self._dbTable.setSelectionMode(QtGui.QTableView.SingleSelection)
        self._dbTable.setSortingEnabled(True)
        self._dbTable.doubleClicked.connect(self.onTableDoubleClick)

        # cancel button
        cancelButton = QtGui.QPushButton('Cancel', self)
        cancelButton.clicked.connect(self.onCancel)
        cancelButton.setAutoDefault(True)

        # OK button
        okButton = QtGui.QPushButton('OK', self)
        okButton.setDefault(True)
        okButton.clicked.connect(self.onOk)

        layout = QVBoxLayout()
        line = QHBoxLayout()
        line.addWidget(searchLabel)
        line.addWidget(self._searchInput)
        line.addStretch()
        line.addWidget(lookupTypeLabel)
        line.addWidget(self._lookupTypeCombo)
        layout.addLayout(line)

        layout.addWidget(self._dbTable)

        line = QHBoxLayout()
        line.addStretch()
        line.addWidget(okButton)
        line.addWidget(cancelButton)
        layout.addLayout(line)

        self.setLayout(layout)

        # now make the window visible
        self.show()

    def initDB(self):
        self._connection = sqlite3.connect(
            "file:" + FreeCAD.getUserAppDataDir() +
            "Mod/Rocket/Resources/parts/Parts.db?mode=ro",
            uri=True)
        self._connection.row_factory = sqlite3.Row
        self._updateModel()

    def onLookupType(self, value):
        self._updateModel()

    def onSearch(self, value):
        rows = []
        value = str(value).strip()
        if len(value) > 0:
            for column in range(self._model.columnCount()):
                items = self._model.findItems(value, Qt.MatchContains, column)
                for item in items:
                    row = item.row()
                    if not row in rows:
                        rows.append(row)

            for row in range(self._model.rowCount()):
                if row in rows:
                    self._dbTable.showRow(row)
                else:
                    self._dbTable.hideRow(row)
        else:
            for row in range(self._model.rowCount()):
                self._dbTable.showRow(row)

    def onTableDoubleClick(self, selected):
        self.result = self._getSelected(selected.row())
        self.close()

    def onCancel(self):
        self.result = {}
        self.close()

    def onOk(self):
        selected = self._dbTable.selectedIndexes()
        if len(selected) > 0:
            row = selected[0].row()
            self.result = self._getSelected(row)
        else:
            self.result = {}
        self.close()

    def _getSelectedBodyTube(self, row):
        try:
            index = int(self._model.item(row, 0).text())
            cone = getBodyTube(self._connection, index)
            return cone
        except NotFoundError:
            _err(translate('Rocket', "Body tube not found"))
        except MultipleEntryError:
            _err(translate('Rocket', "Multiple identical entries found"))
        return {}

    def _getSelectedNose(self, row):
        try:
            index = int(self._model.item(row, 0).text())
            cone = getNoseCone(self._connection, index)
            return cone
        except NotFoundError:
            _err(translate('Rocket', "Nose cone not found"))
        except MultipleEntryError:
            _err(translate('Rocket', "Multiple identical entries found"))
        return {}

    def _getSelectedTransition(self, row):
        try:
            index = int(self._model.item(row, 0).text())
            tran = getTransition(self._connection, index)
            return tran
        except NotFoundError:
            _err(translate('Rocket', "Transition not found"))
        except MultipleEntryError:
            _err(translate('Rocket', "Multiple identical entries found"))
        return {}

    def _getSelected(self, row):
        queryType = str(self._lookupTypeCombo.currentText())
        if queryType == COMPONENT_TYPE_ANY:
            query = self._lookup
        else:
            query = queryType

        if query in [
                COMPONENT_TYPE_BODYTUBE, COMPONENT_TYPE_COUPLER,
                COMPONENT_TYPE_ENGINEBLOCK, COMPONENT_TYPE_LAUNCHLUG,
                COMPONENT_TYPE_CENTERINGRING, COMPONENT_TYPE_BULKHEAD
        ]:
            return self._getSelectedBodyTube(row)
        elif query == COMPONENT_TYPE_NOSECONE:
            return self._getSelectedNose(row)
        elif query == COMPONENT_TYPE_TRANSITION:
            return self._getSelectedTransition(row)
        # elif query == COMPONENT_TYPE_PARACHUTE:
        #     pass
        # elif query == COMPONENT_TYPE_STREAMER:
        #     pass
        return {}

    def _itemWithDimension(self, value, dim):
        return self._newItem(_valueWithUnits(value, dim))

    def _newItem(self, text):
        item = QStandardItem(text)
        item.setEditable(False)
        return item

    def _queryBodyTube(self, queryType):
        rows = listBodyTubes(self._connection, queryType)

        self._model.setRowCount(len(rows))
        if queryType == COMPONENT_TYPE_BULKHEAD:
            self._model.setColumnCount(7)
        else:
            self._model.setColumnCount(8)
        self._dbTable.hideColumn(0)  # This holds index for lookups
        self._dbTable.setVerticalHeader(None)

        # Add the column headers
        self._model.setHorizontalHeaderItem(
            1, self._newItem(translate('Rocket', "Type")))
        self._model.setHorizontalHeaderItem(
            2, self._newItem(translate('Rocket', "Manufacturer")))
        self._model.setHorizontalHeaderItem(
            3, self._newItem(translate('Rocket', "Part Number")))
        self._model.setHorizontalHeaderItem(
            4, self._newItem(translate('Rocket', "Description")))
        self._model.setHorizontalHeaderItem(
            5, self._newItem(translate('Rocket', "Outer Diameter")))
        if queryType == COMPONENT_TYPE_BULKHEAD:
            self._model.setHorizontalHeaderItem(
                6, self._newItem(translate('Rocket', "Length")))
        else:
            self._model.setHorizontalHeaderItem(
                6, self._newItem(translate('Rocket', "Inner Diameter")))
            self._model.setHorizontalHeaderItem(
                7, self._newItem(translate('Rocket', "Length")))

        rowCount = 0
        for row in rows:
            self._model.setItem(rowCount, 0,
                                self._newItem(str(row["body_tube_index"])))
            self._model.setItem(rowCount, 1, self._newItem(str(row["type"])))
            self._model.setItem(rowCount, 2,
                                self._newItem(str(row["manufacturer"])))
            self._model.setItem(rowCount, 3,
                                self._newItem(str(row["part_number"])))
            self._model.setItem(rowCount, 4,
                                self._newItem(str(row["description"])))
            self._model.setItem(
                rowCount, 5,
                self._newItem(
                    self._itemWithDimension(row["outer_diameter"],
                                            row["outer_diameter_units"])))
            if queryType == COMPONENT_TYPE_BULKHEAD:
                self._model.setItem(
                    rowCount, 6,
                    self._newItem(
                        self._itemWithDimension(row["length"],
                                                row["length_units"])))
            else:
                self._model.setItem(
                    rowCount, 6,
                    self._newItem(
                        self._itemWithDimension(row["inner_diameter"],
                                                row["inner_diameter_units"])))
                self._model.setItem(
                    rowCount, 7,
                    self._newItem(
                        self._itemWithDimension(row["length"],
                                                row["length_units"])))

            rowCount += 1

    def _queryNoseCone(self):
        rows = listNoseCones(self._connection)

        self._model.setRowCount(len(rows))
        self._model.setColumnCount(9)
        self._dbTable.hideColumn(0)  # This holds index for lookups
        self._dbTable.setVerticalHeader(None)

        # Add the column headers
        self._model.setHorizontalHeaderItem(
            1, self._newItem(translate('Rocket', "Manufacturer")))
        self._model.setHorizontalHeaderItem(
            2, self._newItem(translate('Rocket', "Part Number")))
        self._model.setHorizontalHeaderItem(
            3, self._newItem(translate('Rocket', "Description")))
        self._model.setHorizontalHeaderItem(
            4, self._newItem(translate('Rocket', "Diameter")))
        self._model.setHorizontalHeaderItem(
            5, self._newItem(translate('Rocket', "Length")))
        self._model.setHorizontalHeaderItem(
            6, self._newItem(translate('Rocket', "Shoulder Diameter")))
        self._model.setHorizontalHeaderItem(
            7, self._newItem(translate('Rocket', "Shoulder Length")))
        self._model.setHorizontalHeaderItem(
            8, self._newItem(translate('Rocket', "Shape")))

        rowCount = 0
        for row in rows:
            self._model.setItem(rowCount, 0,
                                self._newItem(str(row["nose_index"])))
            self._model.setItem(rowCount, 1,
                                self._newItem(str(row["manufacturer"])))
            self._model.setItem(rowCount, 2,
                                self._newItem(str(row["part_number"])))
            self._model.setItem(rowCount, 3,
                                self._newItem(str(row["description"])))
            self._model.setItem(
                rowCount, 4,
                self._newItem(
                    self._itemWithDimension(row["diameter"],
                                            row["diameter_units"])))
            self._model.setItem(
                rowCount, 5,
                self._newItem(
                    self._itemWithDimension(row["length"],
                                            row["length_units"])))
            self._model.setItem(
                rowCount, 6,
                self._newItem(
                    self._itemWithDimension(row["shoulder_diameter"],
                                            row["shoulder_diameter_units"])))
            self._model.setItem(
                rowCount, 7,
                self._newItem(
                    self._itemWithDimension(row["shoulder_length"],
                                            row["shoulder_length_units"])))
            self._model.setItem(rowCount, 8, self._newItem(str(row["shape"])))

            rowCount += 1

    def _queryTransition(self):
        rows = listTransitions(self._connection)

        self._model.setRowCount(len(rows))
        self._model.setColumnCount(12)
        self._dbTable.hideColumn(0)  # This holds index for lookups
        self._dbTable.setVerticalHeader(None)

        # Add the column headers
        self._model.setHorizontalHeaderItem(
            1, self._newItem(translate('Rocket', "Manufacturer")))
        self._model.setHorizontalHeaderItem(
            2, self._newItem(translate('Rocket', "Part Number")))
        self._model.setHorizontalHeaderItem(
            3, self._newItem(translate('Rocket', "Description")))
        self._model.setHorizontalHeaderItem(
            4, self._newItem(translate('Rocket', "Fore Diameter")))
        self._model.setHorizontalHeaderItem(
            5, self._newItem(translate('Rocket', "Aft Diameter")))
        self._model.setHorizontalHeaderItem(
            6, self._newItem(translate('Rocket', "Length")))
        self._model.setHorizontalHeaderItem(
            7, self._newItem(translate('Rocket', "Fore Shoulder Diameter")))
        self._model.setHorizontalHeaderItem(
            8, self._newItem(translate('Rocket', "Fore Shoulder Length")))
        self._model.setHorizontalHeaderItem(
            9, self._newItem(translate('Rocket', "Aft Shoulder Diameter")))
        self._model.setHorizontalHeaderItem(
            10, self._newItem(translate('Rocket', "Aft Shoulder Length")))
        self._model.setHorizontalHeaderItem(
            11, self._newItem(translate('Rocket', "Shape")))

        rowCount = 0
        for row in rows:
            self._model.setItem(rowCount, 0,
                                self._newItem(str(row["transition_index"])))
            self._model.setItem(rowCount, 1,
                                self._newItem(str(row["manufacturer"])))
            self._model.setItem(rowCount, 2,
                                self._newItem(str(row["part_number"])))
            self._model.setItem(rowCount, 3,
                                self._newItem(str(row["description"])))
            self._model.setItem(
                rowCount, 4,
                self._newItem(
                    self._itemWithDimension(
                        row["fore_outside_diameter"],
                        row["fore_outside_diameter_units"])))
            self._model.setItem(
                rowCount, 5,
                self._newItem(
                    self._itemWithDimension(
                        row["aft_outside_diameter"],
                        row["aft_outside_diameter_units"])))
            self._model.setItem(
                rowCount, 6,
                self._newItem(
                    self._itemWithDimension(row["length"],
                                            row["length_units"])))
            self._model.setItem(
                rowCount, 7,
                self._newItem(
                    self._itemWithDimension(
                        row["fore_shoulder_diameter"],
                        row["fore_shoulder_diameter_units"])))
            self._model.setItem(
                rowCount, 8,
                self._newItem(
                    self._itemWithDimension(
                        row["fore_shoulder_length"],
                        row["fore_shoulder_length_units"])))
            self._model.setItem(
                rowCount, 9,
                self._newItem(
                    self._itemWithDimension(
                        row["aft_shoulder_diameter"],
                        row["aft_shoulder_diameter_units"])))
            self._model.setItem(
                rowCount, 10,
                self._newItem(
                    self._itemWithDimension(row["aft_shoulder_length"],
                                            row["aft_shoulder_length_units"])))
            self._model.setItem(rowCount, 11, self._newItem(str(row["shape"])))

            rowCount += 1

    def _updateModel(self):
        queryType = str(self._lookupTypeCombo.currentText())
        if queryType == COMPONENT_TYPE_ANY:
            query = self._lookup
        else:
            query = queryType

        if query in [
                COMPONENT_TYPE_BODYTUBE, COMPONENT_TYPE_COUPLER,
                COMPONENT_TYPE_ENGINEBLOCK, COMPONENT_TYPE_LAUNCHLUG,
                COMPONENT_TYPE_CENTERINGRING, COMPONENT_TYPE_BULKHEAD
        ]:
            self._queryBodyTube(queryType)
        elif query == COMPONENT_TYPE_NOSECONE:
            self._queryNoseCone()
        elif query == COMPONENT_TYPE_TRANSITION:
            self._queryTransition()
        # elif query == COMPONENT_TYPE_PARACHUTE:
        #     pass
        # elif query == COMPONENT_TYPE_STREAMER:
        #     pass

    def update(self):
        # Update the SQL query
        pass
Ejemplo n.º 4
0
class ConsoleWidget(QMainWindow):
    def __init__(self):
        super(ConsoleWidget, self).__init__()
        self.setWindowTitle('1c query')

        self._connection = None

        self._home = os.path.expanduser('~/%s' % QApplication.applicationName())
        if not os.path.isdir(self._home):
            os.mkdir(self._home)

        self.queryToolBar = self.addToolBar('Query')
        self.queryAction = self.queryToolBar.addAction('Run', self.executeQuery)
        self.queryAction.setDisabled(True)

        uri_history = list()
        path = os.path.join(self._home, 'uri_history.txt')
        if os.path.isfile(path):
            uri_history = open(path, 'r').read().split('\n')

        self.connectionToolBar = self.addToolBar('Connection')
        self.connectionUriCombo = QComboBox(self)
        self.connectionUriCombo.setEditable(True)
        if not uri_history:
            self.connectionUriCombo.addItem('File="";usr="";pwd="";')
            self.connectionUriCombo.addItem('Srvr="{host}";Ref="{ref}";Usr="******";Pwd="{password}";')
        else:
            self.connectionUriCombo.addItems(uri_history)
            self.connectionUriCombo.setCurrentIndex(len(uri_history) - 1)
        self.connectionUriCombo.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum)
        self.connectionToolBar.addWidget(self.connectionUriCombo)

        self.onesVersionCombo = QComboBox(self)
        self.onesVersionCombo.addItems(['8.3', '8.2', '8.1', '8.0'])
        self.onesVersionCombo.setCurrentIndex(0)
        self.connectionToolBar.addWidget(self.onesVersionCombo)
        self.connectAction = self.connectionToolBar.addAction('Connect', self.connectOneS)
        self.disconnectAction = self.connectionToolBar.addAction('Disconnect', self.disconnectOneS)
        self.disconnectAction.setDisabled(True)

        self.logEdit = QPlainTextEdit(self)
        self.logDock = QDockWidget('Log', self)
        self.logDock.setWidget(self.logEdit)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.logDock, Qt.Horizontal)

        self.splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.splitter)

        self.sqlEdit = QTextEdit(self)
        self.sqlEdit.setLineWrapMode(QTextEdit.NoWrap)

        path = os.path.join(self._home, 'last-sql.txt')
        if os.path.isfile(path):
            sql = open(path, 'r').read()
            self.sqlEdit.setText(sql)

        self.model = QStandardItemModel(self)
        self.tableView = QTableView(self)
        self.tableView.setModel(self.model)

        self.splitter.addWidget(self.sqlEdit)
        self.splitter.addWidget(self.tableView)
        self.splitter.setStretchFactor(0, 3)
        self.splitter.setStretchFactor(1, 2)

    def query(self, sql):
        if not self._connection:
            self.logEdit.appendPlainText('No connection')
            return None

        try:
            query = self._connection.NewObject('Query', sql)
            result = query.Execute()
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return None

        return result

    def refresh(self, result):
        self.model.clear()

        columns = list()
        result_columns = result.Columns
        for index in range(result_columns.Count()):
            name = result_columns.Get(index).Name
            columns.append(name)

        self.model.setColumnCount(len(columns))
        for section, name in enumerate(columns):
            self.model.setHeaderData(section, Qt.Horizontal, name)

        select = result.Choose()
        self.logEdit.appendPlainText('Selected %d records' % select.Count())
        while select.Next():
            items = list()
            for index in range(len(columns)):
                value = select.Get(index)

                item = QStandardItem('')
                if isinstance(value, bool):
                    item.setText(value and 'Yes' or 'No')

                elif isinstance(value, (int, str)):
                    item.setText(str(value))

                elif isinstance(value, datetime.datetime):
                    item.setText(value.strftime('%Y.%m.%d %H:%M:%S'))

                else:
                    item.setText(str(value))
                items.append(item)

            self.model.appendRow(items)

    @Slot()
    def executeQuery(self):
        sql = self.sqlEdit.toPlainText()
        result = self.query(sql)
        if result:
            path = os.path.join(self._home, 'last-sql.txt')
            open(path, 'w').write(sql)
            self.refresh(result)

    @Slot()
    def connectOneS(self):
        uri = self.connectionUriCombo.currentText().strip()
        if not uri:
            self.logEdit.appendPlainText('Need a connection string')
            return

        version = self.onesVersionCombo.currentText()
        comName = "V%s.COMConnector" % str(version).replace('.', '')

        pythoncom.CoInitialize()
        try:
            obj = win32com.client.Dispatch(comName)
            self._connection = obj.Connect(uri)
        except Exception as e:
            self.logEdit.appendPlainText(str(e))
            return

        self.connectAction.setDisabled(True)
        self.disconnectAction.setEnabled(True)
        self.queryAction.setEnabled(True)

        uri_history = list()
        for i in range(self.connectionUriCombo.count()):
            uri_history.append(self.connectionUriCombo.itemText(i))

        if uri not in uri_history:
            self.connectionUriCombo.clearEditText()
            self.connectionUriCombo.addItem(uri)
            self.connectionUriCombo.setCurrentIndex(len(uri_history))
            uri_history.append(uri)
            path = os.path.join(self._home, 'uri_history.txt')
            open(path, 'w').write('\n'.join(uri_history))

    @Slot()
    def disconnectOneS(self):
        pythoncom.CoUninitialize()
        self._connection = None
        self.connectAction.setEnabled(True)
        self.disconnectAction.setDisabled(True)
        self.queryAction.setDisabled(True)