def _context_menu(self, point): if not self.is_table_enabled: return item = self.bondpadTable.itemAt(point) if item is None: return column = item.column() if column == PAD_INFO.PAD_NAME_COLUMN(): self.create_menu(self.pad_type, self.pad_direction) return if column == PAD_INFO.PAD_TYPE_COLUMN(): # type self.create_menu(self.pad_type) item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) return if column == PAD_INFO.PAD_DIRECTION_COLUMN(): # direction self.create_menu(self.pad_direction) item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) return if column in (PAD_INFO.PAD_SIZE_X_COLUMN(), PAD_INFO.PAD_SIZE_Y_COLUMN()): self.create_menu(self.pad_standard_size) item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) return
def _set_pad_size_cells(self, value): for item in self.bondpadTable.selectedItems(): row = item.row() for c in range(self.columns): if c in (PAD_INFO.PAD_SIZE_X_COLUMN(), PAD_INFO.PAD_SIZE_Y_COLUMN()): self.bondpadTable.item(row, c).setText(value)
def _edit_cell_done(self, checkable_widget, row, column): if self.dieSizeX.text() == '' or self.dieSizeY.text() == '': self.feedback.setText("die size is not set yet") checkable_widget.clear() self._update_row(row) return if column == PAD_INFO.PAD_NAME_COLUMN(): # name must be unique self._validate_name(checkable_widget, row, column=0) if not self._is_defined_only_once(column=0): item = self.bondpadTable.item(row, 0) self.feedback.setText( f'name: {item.text()} has already been used') item.setText('') self.OKButton.setEnabled(False) self._update_row(row) return success = True if column in (PAD_INFO.PAD_POS_X_COLUMN(), PAD_INFO.PAD_POS_Y_COLUMN()): success = self._handle_pos_cols(checkable_widget, row, column) elif column in (PAD_INFO.PAD_SIZE_X_COLUMN(), PAD_INFO.PAD_SIZE_Y_COLUMN()): success = self._validate_pads_size_references( checkable_widget, row, column) self._update_row(row) if success: self.feedback.setText('') self._validate_table(row)
def _are_coordinates_valid(self, item_x, item_y, current_row, current_col): for row in range(self.rows): if current_row == row: continue if self.bondpadTable.item(row, PAD_INFO.PAD_POS_X_COLUMN()).text() == item_x and \ self.bondpadTable.item(row, PAD_INFO.PAD_POS_Y_COLUMN()).text() == item_y: self.bondpadTable.item(current_row, current_col).setText('') self.feedback.setText("coordinates are already occupied") return False return True
def _double_click_handler(self, item): if not self.is_table_enabled: return column = item.column() if column == PAD_INFO.PAD_TYPE_COLUMN(): item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) elif column == PAD_INFO.PAD_DIRECTION_COLUMN(): item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) else: self._create_checkable_cell(item) self.selected_cell = item
def _handle_pos_cols(self, checkable_widget, row, column): success = True if column == PAD_INFO.PAD_POS_X_COLUMN(): success = self._validate_pads_position_references( checkable_widget, row, column, self.dieSizeX.text()) if column == PAD_INFO.PAD_POS_Y_COLUMN(): success = self._validate_pads_position_references( checkable_widget, row, column, self.dieSizeY.text()) if success: success = self._are_coordinates_valid(row, column) if not success: checkable_widget.clear() return success
def _make_bondpad_bounding_box(self, row): try: x = int( self.bondpadTable.item(row, PAD_INFO.PAD_POS_X_COLUMN()).text()) y = int( self.bondpadTable.item(row, PAD_INFO.PAD_POS_Y_COLUMN()).text()) w = int( self.bondpadTable.item(row, PAD_INFO.PAD_SIZE_X_COLUMN()).text()) h = int( self.bondpadTable.item(row, PAD_INFO.PAD_SIZE_Y_COLUMN()).text()) return (x, y, x + w, y + h) except Exception: return None
def set_pad_selection(self, pad_type, column): for item in [ item for item in self.bondpadTable.selectedItems() if item.column() == column ]: item.setText(pad_type[0]) # special case: user friendly option to change Type and Direction directly from name column for item in [ item for item in self.bondpadTable.selectedItems() if item.column() == PAD_INFO.PAD_NAME_COLUMN() ]: self.bondpadTable.item(item.row(), column).setText(pad_type[0])
def _init_table(dialog, table_size, enable_edit): dialog.bondpadTable.setRowCount(table_size) row = dialog.bondpadTable.rowCount() column = dialog.bondpadTable.columnCount() for r in range(row): for c in range(column): item = QtWidgets.QTableWidgetItem('') dialog.bondpadTable.setItem(r, c, item) item.setFlags(QtCore.Qt.NoItemFlags) if c == 0: item.setTextAlignment( int(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)) else: item.setTextAlignment( int(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter)) # resize cell columns for c in range(dialog.bondpadTable.columnCount()): if c == PAD_INFO.PAD_NAME_COLUMN(): dialog.bondpadTable.setColumnWidth(c, PAD_INFO.NAME_COL_SIZE()) elif c in (PAD_INFO.PAD_POS_X_COLUMN(), PAD_INFO.PAD_POS_Y_COLUMN(), PAD_INFO.PAD_SIZE_X_COLUMN(), PAD_INFO.PAD_SIZE_Y_COLUMN(), PAD_INFO.PAD_TYPE_COLUMN()): dialog.bondpadTable.setColumnWidth(c, PAD_INFO.REF_COL_SIZE()) elif c == PAD_INFO.PAD_DIRECTION_COLUMN(): dialog.bondpadTable.setColumnWidth(c, PAD_INFO.DIR_COL_SIZE()) dialog.bondpadTable.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Fixed) dialog.bondpadTable.verticalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Fixed) dialog.bondpadTable.setEnabled(enable_edit)
def _create_checkable_cell(self, item): column = item.column() row = item.row() # set cell widget to qlineEdit widget checkable_widget = QtWidgets.QLineEdit() checkable_widget.setText(item.text()) if column == PAD_INFO.PAD_NAME_COLUMN(): checkable_widget.setValidator(self.maskset_name_validator) else: checkable_widget.setValidator(self.positive_integer_validator) self.bondpadTable.setCellWidget(row, column, checkable_widget) checkable_widget.editingFinished.connect( lambda row=row, column=column, checkable_widget=checkable_widget: self._edit_cell_done(checkable_widget, row, column))
def _setup_item(self, maskset_name): self.setWindowTitle("Maskset Setting") self.masksetName.setText(maskset_name) self.masksetName.setEnabled(False) self.bondpads.setEnabled(False) self.waferDiameter.setEnabled(False) self.dieSizeX.setEnabled(False) self.dieSizeY.setEnabled(False) self.scribeX.setEnabled(False) self.scribeY.setEnabled(False) self.dieRefY.setEnabled(False) self.dieRefX.setEnabled(False) self.xOffset.setEnabled(False) self.yOffset.setEnabled(False) self.flat.setEnabled(False) self.Type.setEnabled(False) self.editWaferMapButton.setEnabled(False) self.importFor.setEnabled(False) self.XYFlipButton.setEnabled(False) self.viewDieButton.setEnabled(False) self.bondpadTable.setRowCount(len(self.maskset_configuration["BondpadTable"])) row = self.bondpadTable.rowCount() column = self.bondpadTable.columnCount() for r in range(row): for c in range(column): item = QtWidgets.QTableWidgetItem('') self.bondpadTable.setItem(r, c, item) item.setFlags(QtCore.Qt.NoItemFlags) # resize cell columns for c in range(self.bondpadTable.columnCount()): if c == PAD_INFO.PAD_NAME_COLUMN(): self.bondpadTable.setColumnWidth(c, PAD_INFO.NAME_COL_SIZE()) elif c in (PAD_INFO.PAD_POS_X_COLUMN(), PAD_INFO.PAD_POS_Y_COLUMN(), PAD_INFO.PAD_SIZE_X_COLUMN(), PAD_INFO.PAD_SIZE_Y_COLUMN(), PAD_INFO.PAD_TYPE_COLUMN()): self.bondpadTable.setColumnWidth(c, PAD_INFO.REF_COL_SIZE()) elif c == PAD_INFO.PAD_DIRECTION_COLUMN(): self.bondpadTable.setColumnWidth(c, PAD_INFO.DIR_COL_SIZE()) self.bondpadTable.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed) self.bondpadTable.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed) self.bondpadTable.setEnabled(False)
def select_power_pad_type(self): self.set_pad_selection(PadType.Power(), PAD_INFO.PAD_TYPE_COLUMN())
def select_digital_pad_type(self): self.set_pad_selection(PadType.Digital(), PAD_INFO.PAD_TYPE_COLUMN())
def select_mixed_pad_type(self): self.set_pad_selection(PadType.Mixed(), PAD_INFO.PAD_TYPE_COLUMN())
def select_analog_pad_type(self): self.set_pad_selection(PadType.Analog(), PAD_INFO.PAD_TYPE_COLUMN())
def select_bidirectional_direction(self): self.set_pad_selection(PadDirection.Bidirectional(), PAD_INFO.PAD_DIRECTION_COLUMN())
def select_output_direction(self): self.set_pad_selection(PadDirection.Output(), PAD_INFO.PAD_DIRECTION_COLUMN())
def _item_entered(self, item): if item.column() in (PAD_INFO.PAD_DIRECTION_COLUMN(), PAD_INFO.PAD_TYPE_COLUMN()): self._update_row(item.row())
def _setup(self): self.setWindowTitle(' '.join( re.findall('.[^A-Z]*', os.path.basename(__file__).replace('.py', '')))) from ATE.spyder.widgets.validation import valid_positive_integer_regex rxi = QtCore.QRegExp(valid_positive_integer_regex) self.positive_integer_validator = QtGui.QRegExpValidator(rxi, self) from ATE.spyder.widgets.validation import valid_positive_float_1_regex rxf = QtCore.QRegExp(valid_positive_float_1_regex) positive_float_validator = QtGui.QRegExpValidator(rxf, self) from ATE.spyder.widgets.validation import valid_maskset_name_regex rxMaskSetName = QtCore.QRegExp(valid_maskset_name_regex) self.maskset_name_validator = QtGui.QRegExpValidator( rxMaskSetName, self) # maskset self.existing_masksets = self.project_info.get_maskset_names() self.masksetName.setText("") self.masksetName.setValidator(self.maskset_name_validator) # Type & Customer self.Type.setCurrentText('ASSP') self.customerLabel.setVisible(False) self.customer.setText('') self.customer.setVisible(False) # wafer diameter self.waferDiameter.setCurrentIndex(self.waferDiameter.findText('200')) # bondpads self.bondpads.setMinimum(2) self.bondpads.setMaximum(99) self.bondpads.setValue(2) self._set_row_elements(DEFAULT_ROW) # XY Flip Button self.XYFlipButton.setText("") self.XYFlipButton.setIcon(qta.icon('mdi.arrow-up-down', color='white')) # die size X NewMasksetWizard._setup_input_element(self.dieSizeX, "", self.positive_integer_validator) # die size Y NewMasksetWizard._setup_input_element(self.dieSizeY, "", self.positive_integer_validator) # die Ref X NewMasksetWizard._setup_input_element(self.dieRefX, "", positive_float_validator) # die Ref Y NewMasksetWizard._setup_input_element(self.dieRefY, "", positive_float_validator) # X Offset NewMasksetWizard._setup_input_element(self.xOffset, "0", positive_float_validator) # Y Offset NewMasksetWizard._setup_input_element(self.yOffset, "0", positive_float_validator) # scribe X NewMasksetWizard._setup_input_element(self.scribeX, str(standard_scribe), positive_float_validator) # scribe Y NewMasksetWizard._setup_input_element(self.scribeY, str(standard_scribe), positive_float_validator) # Flat WaferDiameter = int(self.waferDiameter.currentText()) Flat = (WaferDiameter / 2) - standard_flat_height if Flat - int(Flat) == 0: self.flat.setText(str(int(Flat))) else: self.flat.setText(str(Flat)) # bondpad table self.bondpadTable.setRowCount(self.bondpads.value()) self.bondpadTable.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.bondpadTable.customContextMenuRequested.connect( self._context_menu) self.bondpadTable.itemDoubleClicked.connect(self._double_click_handler) self.bondpadTable.itemClicked.connect(self._select_item) self.bondpadTable.itemSelectionChanged.connect(self._table_clicked) self.bondpadTable.itemEntered.connect(self._item_entered) self.pad_type = { PadType.Analog(): self.select_analog_pad_type, PadType.Digital(): self.select_digital_pad_type, PadType.Mixed(): self.select_mixed_pad_type, PadType.Power(): self.select_power_pad_type } self.pad_direction = { PadDirection.Input(): self.select_input_direction, PadDirection.Output(): self.select_output_direction, PadDirection.Bidirectional(): self.select_bidirectional_direction } self.pad_standard_size = { PadStandardSize.Standard_1(): self._standard_1_selected, PadStandardSize.Standard_2(): self._standard_2_selected, PadStandardSize.Standard_3(): self._standard_3_selected } # resize cell columns for c in range(self.columns): if c == PAD_INFO.PAD_NAME_COLUMN(): self.bondpadTable.setColumnWidth(c, PAD_INFO.NAME_COL_SIZE()) elif c in (PAD_INFO.PAD_POS_X_COLUMN(), PAD_INFO.PAD_POS_Y_COLUMN(), PAD_INFO.PAD_SIZE_X_COLUMN(), PAD_INFO.PAD_SIZE_Y_COLUMN(), PAD_INFO.PAD_TYPE_COLUMN()): self.bondpadTable.setColumnWidth(c, PAD_INFO.REF_COL_SIZE()) elif c == PAD_INFO.PAD_DIRECTION_COLUMN(): self.bondpadTable.setColumnWidth(c, PAD_INFO.DIR_COL_SIZE()) self.bondpadTable.horizontalHeader().setSectionResizeMode( 0, QtWidgets.QHeaderView.Stretch) self.bondpadTable.verticalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Fixed) # view die button self.viewDieButton.setText("") self.viewDieButton.setIcon(qta.icon('mdi.eye-outline', color='white')) self.viewDieButton.clicked.connect(self.viewDie) # import For importer_name_lists = self.plugin_manager.hook.get_importer_names() self.importFor.clear() self.importFor.addItem('') for importer_name_list in importer_name_lists: for importer_name in importer_name_list: self.importFor.addItem(importer_name["display_name"]) self.plugin_names.append(importer_name) self.importFor.setCurrentIndex(0) # empty string # feedback self.feedback.setText("") self.feedback.setStyleSheet('color: orange') self.validate()