class MetricsTab(TabWidget): def __init__(self, font, parent=None): super().__init__(parent, name="Metrics") mainLayout = QGridLayout() styleMapFamilyLabel = QLabel("Style map family name:", self) self.styleMapFamilyEdit = QLineEdit(font.info.styleMapFamilyName, self) styleMapStyleLabel = QLabel("Style map style name:", self) self.styleMapStyleDrop = QComboBox(self) items = ["None", "Regular", "Italic", "Bold", "Bold Italic"] self.styleMapStyleDrop.insertItems(0, items) sn = font.info.styleMapStyleName if sn == "regular": self.styleMapStyleDrop.setCurrentIndex(1) elif sn == "italic": self.styleMapStyleDrop.setCurrentIndex(2) elif sn == "bold": self.styleMapStyleDrop.setCurrentIndex(3) elif sn == "bold italic": self.styleMapStyleDrop.setCurrentIndex(4) else: self.styleMapStyleDrop.setCurrentIndex(0) mainLayout.addWidget(styleMapFamilyLabel, 0, 0) mainLayout.addWidget(self.styleMapFamilyEdit, 0, 1, 1, 3) mainLayout.addWidget(styleMapStyleLabel, 0, 4) mainLayout.addWidget(self.styleMapStyleDrop, 0, 5) unitsPerEmLabel = QLabel("Units per em:", self) ascenderLabel = QLabel("Ascender:", self) capHeightLabel = QLabel("Cap height:", self) italicAngleLabel = QLabel("Italic angle:", self) descenderLabel = QLabel("Descender:", self) xHeightLabel = QLabel("x-height:", self) noteLabel = QLabel("Note:", self) # In the UFO specs these are integer or float, and unitsPerEm is # non-negative integer or float self.loadPositiveIntegerFloat(font, "unitsPerEm", "unitsPerEm") self.loadIntegerFloat(font, "ascender", "ascender") self.loadIntegerFloat(font, "capHeight", "capHeight") self.loadIntegerFloat(font, "italicAngle", "italicAngle") self.loadIntegerFloat(font, "descender", "descender") self.loadIntegerFloat(font, "xHeight", "xHeight") self.loadMultilineString(font, "note", "note") mainLayout.addWidget(unitsPerEmLabel, 1, 0) mainLayout.addWidget(self.unitsPerEmEdit, 1, 1) mainLayout.addWidget(ascenderLabel, 1, 2) mainLayout.addWidget(self.ascenderEdit, 1, 3) mainLayout.addWidget(capHeightLabel, 1, 4) mainLayout.addWidget(self.capHeightEdit, 1, 5) mainLayout.addWidget(italicAngleLabel, 2, 0) mainLayout.addWidget(self.italicAngleEdit, 2, 1) mainLayout.addWidget(descenderLabel, 2, 2) mainLayout.addWidget(self.descenderEdit, 2, 3) mainLayout.addWidget(xHeightLabel, 2, 4) mainLayout.addWidget(self.xHeightEdit, 2, 5) mainLayout.addWidget(noteLabel, 3, 0) mainLayout.addWidget(self.noteEdit, 3, 1, 1, 5) self.setLayout(mainLayout) def writeValues(self, font): styleMapFamilyName = self.styleMapFamilyEdit.text() if styleMapFamilyName != '': font.info.styleMapFamilyName = styleMapFamilyName else: font.info.styleMapFamilyName = None sn = self.styleMapStyleDrop.currentIndex() if sn == 1: font.info.styleMapStyleName = "regular" elif sn == 2: font.info.styleMapStyleName = "italic" elif sn == 3: font.info.styleMapStyleName = "bold" elif sn == 4: font.info.styleMapStyleName = "bold italic" else: font.info.styleMapStyleName = None self.writePositiveIntegerFloat(font, "unitsPerEm", "unitsPerEm") self.writeIntegerFloat(font, "italicAngle", "italicAngle") self.writeIntegerFloat(font, "ascender", "ascender") self.writeIntegerFloat(font, "descender", "descender") self.writeIntegerFloat(font, "capHeight", "capHeight") self.writeIntegerFloat(font, "xHeight", "xHeight") self.writeMultilineString(font, "note", "note")
def set_text(self, items): # where items should be list of lists of objects that can be either dict (loads as QComboBox) or string (used in setItem) # print('siphon itmes', items) self.table.setRowCount(len(items)) self.table.setColumnCount(len(items[0])) for i, row in enumerate(items): # print('siphon row', row) for j, value in enumerate(row): if isinstance(value, str): item = QTableWidgetItem(value) self.table.setItem(i, j, item) elif isinstance(value, dict): combo_box = QComboBox() dict_keys = list(value.keys()) selected = dict_keys[0] if isinstance(value[selected], dict): combo_box.insertItems(0, list(value[selected].values())) else: combo_box.insertItems(0, value[selected]) combo_box.setCurrentText(selected) self.table.setCellWidget(i, j, combo_box) else: message = 'Table cells are expected to be either Dict (added asQComboBox via setCellWidget) or String (added as QTableWidgetItem). You have type ' + str( type(value)) message += ' at position ' + str(i) + ', ' + str(j) raise CellObjectException(message)
def set_text(self, items): # where items should be list of lists of objects that can be either dict (loads as QComboBox) or string (used in setItem) # print('siphon itmes', items) self.table.setRowCount(len(items)) self.table.setColumnCount(len(items[0])) for i, row in enumerate(items): # print('siphon row', row) for j, value in enumerate(row): if isinstance(value, str): item = QTableWidgetItem(value) self.table.setItem(i, j, item) elif isinstance(value, dict): combo_box = QComboBox() dict_keys = list(value.keys()) selected = dict_keys[0] if isinstance(value[selected], dict): combo_box.insertItems(0, list(value[selected].values())) else: combo_box.insertItems(0, value[selected]) combo_box.setCurrentText(selected) self.table.setCellWidget(i, j, combo_box) else: message = 'Table cells are expected to be either Dict (added asQComboBox via setCellWidget) or String (added as QTableWidgetItem). You have type ' + str(type(value)) message += ' at position ' + str(i) + ', ' + str(j) raise CellObjectException(message)
class DiodeCalibration(QDialog): def __init__(self, d): # d - list with DiodeInterface instances super().__init__() self.d = d self.initUI() def init_widgets(self): self.id = QComboBox() self.id.insertItems(0, [str(i) for i in range(len(self.d))]) self.label = QLineEdit(self.d[0].label) self.unit = QLineEdit(self.d[0].unit) self.a = QLineEdit(str(self.d[0].a)) self.b = QLineEdit(str(self.d[0].b)) self.saveButton = QPushButton('Save') def init_layout(self): layout = QFormLayout() layout.addRow('Choose diode:', self.id) layout.addRow('Label:', self.label) layout.addRow('Unit:', self.unit) layout.addRow('a:', self.a) layout.addRow('b:', self.b) layout.addRow(self.saveButton) self.setLayout(layout) def initUI(self): self.init_widgets() self.init_layout() self.saveButton.clicked.connect(self.save) self.id.currentIndexChanged.connect(self.update) def save(self): i = int(self.id.currentText()) self.d[i].set_settings(float(self.a.text()), float(self.b.text()), self.label.text(), self.unit.text()) def update(self): i = int(self.id.currentText()) self.label.setText(self.d[i].label) self.unit.setText(self.d[i].unit) self.a.setText(str(self.d[i].a)) self.b.setText(str(self.d[i].b))
def __init__(self, model, parent=None): QDialog.__init__(self, parent=parent) self.setMinimumHeight(_VIEW_MINIMUM_HEIGHT) self.model = model self.font = None layout = QVBoxLayout(self) close_button = QPushButton('Go back to table view') scale_label = QLabel('Scale the image') photo_scale_button = QComboBox(self) photo_scale_button.insertItems(0, _PLANT_IMAGE_SCALE_FACTORS) font_size_button = QPushButton('Font') font_size_button.clicked.connect(self.font_dialog) buttons_layout = QHBoxLayout() buttons_layout.addWidget(close_button) buttons_layout.addStretch() buttons_layout.addWidget(scale_label) buttons_layout.addWidget(photo_scale_button) buttons_layout.addStretch() buttons_layout.addWidget(font_size_button) layout.addLayout(buttons_layout) close_button.clicked.connect(self._close) photo_scale_button.currentIndexChanged[str].connect(self._change_pixmap_factor) scale_factor = int(photo_scale_button.currentText()) self.model.scale = scale_factor self.view = QTableView() self.view.setModel(self.model) self.font = self.view.property('font') self._hide_info_columns(self.model.image_column) self.view.resizeRowsToContents() self.view.resizeColumnsToContents() #resize_window_to_columns(self, self.view, fudgeFactor=0) #self.view.horizontalHeader().setStretchLastSection(True) layout.addWidget(self.view)
class LaguerreGaussianBeamPage(AbstractSpecialBeamPage): def __init__(self): super().__init__() self.create_widgets() self.setWindowTitle('拉盖尔-高斯光束') def create_widgets(self): self.l_entry = QLineEdit('1') self.p_entry = QLineEdit('0') self.form_combobox = QComboBox() self.form_combobox.insertItems(0, ('简单模式', '复杂模式')) self.polar_checkbox = QCheckBox('是否使用极坐标?') l_label = QLabel('拓扑荷数(l):') p_label = QLabel('径向指数(p):') form_label = QLabel('选择模式') cal_button = self.create_button('计算复振幅', self.calculate) show_button = self.create_button('显示强度图像', self.check_and_show_intensity_image) # 布局 main_layout = QGridLayout(self) main_layout.addWidget(self.l_entry, 0, 1) main_layout.addWidget(self.p_entry, 1, 1) main_layout.addWidget(self.form_combobox, 2, 1) main_layout.addWidget(self.polar_checkbox, 3, 0) main_layout.addWidget(l_label, 0, 0) main_layout.addWidget(p_label, 1, 0) main_layout.addWidget(form_label, 2, 0) main_layout.addWidget(cal_button, 4, 0) main_layout.addWidget(show_button, 4, 1) def calculate(self): l = float(self.l_entry.text()) p = float(self.p_entry.text()) form = self.form_combobox.currentText() if form == '简单模式': simple = True else: # 复杂模式 simple = False polar = self.polar_checkbox.isChecked() self.beam = special_beam() self.ampOrInt = self.beam.Laguerre_GaussianBeam(l, p, simple, polar)
def __init__(self, db_name): super(DbView, self).__init__() self.setGeometry(50, 50, 800, 600) self.setWindowTitle("Database " + db_name) self.setWindowIcon(QIcon(':python-logo.png')) self.statusBar() # get first table self.conn = di.get_sqlite_connection(db_name) self.chunk_size = 10 db_tables = dv.get_table_names(self.conn) data = dv.get_table(self.conn, db_tables[0], chunk_size=self.chunk_size) self.data_iterator = iter(data) self.df = next(self.data_iterator) # add a combobox to a toolbar combo_box = QComboBox() combo_box.insertItems(1, db_tables) combo_box.activated[str].connect(self.table_changed) # add a more button more_button = QPushButton("More") more_button.clicked.connect(self.more_clicked) # add a toolbar self.toolBar = self.addToolBar("table") self.toolBar.addWidget(QLabel("Table: ")) self.toolBar.addWidget(combo_box) self.toolBar.addWidget(more_button) # add a TableView self.table_view = QTableView(self) model = md.PandasModel(self.df) self.table_view.setModel(model) self.setCentralWidget(self.table_view) self.show()
class LabelComboBox(QWidget): def __init__(self, label='', items={'UJ object reference value': 'Name to show'}): super(LabelComboBox, self).__init__() self.label = QLabel() self.label.setText(label) self.items = items self.combo_box = QComboBox() self.combo_box.insertItems(0, self.items.values()) self.layout = QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.addWidget(self.label) self.layout.addWidget(self.combo_box, stretch=1) def reset_items(self, items={'UJ object reference value': 'Name to show'}): while self.combo_box.count() != 0: self.combo_box.removeItem(0) self.items = items self.combo_box.addItems(self.items.values()) def show(self): self.combo_box.show() self.label.show() def hide(self): self.combo_box.hide() self.label.hide() def set_text(self, text): if text in self.items.values(): self.combo_box.setCurrentText(text) if text in self.items.keys(): self.combo_box.setCurrentText(self.items[text]) def text(self): return self.combo_box.currentText()
class LabelComboBox(QWidget): def __init__(self, label='', items = {'UJ object reference value': 'Name to show'}): super(LabelComboBox, self).__init__() self.label = QLabel() self.label.setText(label) self.items = items self.combo_box = QComboBox() self.combo_box.insertItems(0, self.items.values()) self.layout = QHBoxLayout() self.layout.setContentsMargins(0,0,0,0) self.layout.addWidget(self.label) self.layout.addWidget(self.combo_box, stretch = 1) def reset_items(self, items = {'UJ object reference value': 'Name to show'}): while self.combo_box.count() != 0: self.combo_box.removeItem(0) self.items = items self.combo_box.addItems(self.items.values()) def show(self): self.combo_box.show() self.label.show() def hide(self): self.combo_box.hide() self.label.hide() def set_text(self, text): if text in self.items.values(): self.combo_box.setCurrentText(text) if text in self.items.keys(): self.combo_box.setCurrentText(self.items[text]) def text(self): return self.combo_box.currentText()
class Solicitar(QWidget): def __init__(self, user, prestadores, text): super().__init__() self.user = user self.prestadores = prestadores self.resize(200, 250) self.move(200, 100) self.setWindowTitle('SOLICITAR') mainlay = QVBoxLayout() self.aquevino = QLabel(text.upper() + ' DISPONIBLES') self.aquevino.setAlignment(Qt.AlignCenter) mainlay.addWidget(self.aquevino) self.lista = QComboBox(self) mainlay.addWidget(self.lista) if not len(self.prestadores) == 0: opciones = [] for p in self.prestadores: opciones.append(p.nombre) self.lista.insertItems(0, opciones) self.lista.setCurrentIndex(0) self.lista.currentIndexChanged.connect(self.changeshit) self.dirlabel = QLabel('Direccion:') self.dirinfo = QLabel(self.prestadores[0].direccion) dirlay = QHBoxLayout() dirlay.addWidget(self.dirlabel) dirlay.addWidget(self.dirinfo) mainlay.addLayout(dirlay) self.emaillabel = QLabel('Correo:') self.emailinfo = QLabel(self.prestadores[0].email) emaillay = QHBoxLayout() emaillay.addWidget(self.emaillabel) emaillay.addWidget(self.emailinfo) mainlay.addLayout(emaillay) self.cellabel = QLabel('Celular:') self.celinfo = QLabel(self.prestadores[0].celular) cellay = QHBoxLayout() cellay.addWidget(self.cellabel) cellay.addWidget(self.celinfo) mainlay.addLayout(cellay) rating = '-/-' self.ratelabel = QLabel('Calificaion:') if len(self.prestadores[0].calificacion) > 0: rating = str( average([int(x) for x in self.prestadores[0].calificacion])) self.rateinfo = QLabel(rating) ratelay = QHBoxLayout() ratelay.addWidget(self.ratelabel) ratelay.addWidget(self.rateinfo) mainlay.addLayout(ratelay) self.comments = QListWidget(self) if len(self.prestadores[0].comentarios) > 0: self.comments.insertItems(0, self.prestadores[0].comentarios) else: self.comments.insertItems(0, ['-----NO HAY COMENTARIOS-----']) commentlay = QHBoxLayout() commentlay.addWidget(self.comments) commentlay.setAlignment(Qt.AlignCenter) mainlay.addLayout(commentlay) self.solicitarbutton = QPushButton('SOLICITAR') self.solicitarbutton.clicked.connect(self.solicitar) mainlay.addWidget(self.solicitarbutton) else: self.empty = QLabel('NO HAY PRESTADORES\nDISPONIBLES PARA USTED') self.empty.setAlignment(Qt.AlignCenter) mainlay.addWidget(self.empty) self.cancelarbutton = QPushButton('CANCELAR') self.cancelarbutton.clicked.connect(self.close) mainlay.addWidget(self.cancelarbutton) self.setLayout(mainlay) def solicitar(self): response = solicitar.ejecutar( self.prestadores[self.lista.currentIndex()], self.user) if response: QMessageBox.about(self, 'EXITO', 'Se registro la solicitud') else: QMessageBox.about(self, 'ERROR', 'Ya tiene una solicitud\ncon este prestador.') def changeshit(self): i = self.lista.currentIndex() self.dirinfo.setText(self.prestadores[i].direccion) self.emailinfo.setText(self.prestadores[i].email) self.celinfo.setText(self.prestadores[i].celular) rating = '-/-' if len(self.prestadores[i].calificacion) > 0: rating = str( average([int(x) for x in self.prestadores[i].calificacion])) self.rateinfo.setText(rating) self.comments.clear() if len(self.prestadores[i].comentarios) > 0: self.comments.insertItems(0, self.prestadores[i].comentarios) else: self.comments.insertItems(0, ['-----NO HAY COMENTARIOS-----'])
class TabPanel(QTabWidget): def __init__(self, tabs, name, table, graph, combobox_list=False, cutoff=False, export=True): super(TabPanel, self).__init__() # Generate generic tab items self.tab_layout = QVBoxLayout() self.setLayout(self.tab_layout) self.tabs = tabs self.name = name self.table = table self.graph = graph self.combobox_list = combobox_list self.cutoff = cutoff self.export = export self.mlca = object # Generate Cut-off menu self.cutoff_menu = QHBoxLayout() if cutoff: # Cut-off types self.cutoff_type = QVBoxLayout() self.cutoff_type_label = QLabel("Cut-off type") self.cutoff_type_absolute = QRadioButton("Absolute") self.cutoff_type_absolute.setChecked(True) self.cutoff_type_relative = QRadioButton("Relative") self.cutoff_type_topx = QRadioButton("Top x") # Cut-off slider self.cutoff_slider = QVBoxLayout() self.cutoff_slider_set = QVBoxLayout() self.cutoff_slider_label = QLabel("Cut-off level") self.cutoff_slider_slider = QSlider(Qt.Horizontal) self.cutoff_slider_slider.setMinimum(1) # temporary self.cutoff_slider_slider.setMaximum(99) # temporary self.cutoff_slider_slider.sizeHint() self.cutoff_slider_minmax = QHBoxLayout() self.cutoff_slider_min = QLabel( str(self.cutoff_slider_slider.minimum())) self.cutoff_slider_max = QLabel( str(self.cutoff_slider_slider.maximum())) self.cutoff_slider_ledit = QHBoxLayout() self.cutoff_slider_line = QLineEdit() self.cutoff_validator = QIntValidator(self.cutoff_slider_line) self.cutoff_slider_line.setValidator(self.cutoff_validator) self.cutoff_value = int( ) # set to max when known how to port data to this class self.cutoff_slider_unit = QLabel("unit") # Generate Combobox for method selection self.combobox_menu = QHBoxLayout() if combobox_list: self.combobox_menu_label = QLabel("Assesment method: ") self.combobox_menu_combobox = QComboBox() self.combobox_menu_combobox.scroll = False # add stuff for in the box # Generate Table and Graph area self.main_space = QScrollArea() self.main_space_widget = QWidget() self.main_space_widget_layout = QVBoxLayout() self.main_space_widget.setLayout(self.main_space_widget_layout) self.main_space.setWidget(self.main_space_widget) self.main_space.setWidgetResizable(True) # Option switch self.main_space_tb_grph = QHBoxLayout() self.main_space_tb_grph_table = QCheckBox("Table") self.main_space_tb_grph_table.setChecked(True) self.main_space_tb_grph_graph = QCheckBox("Graph") self.main_space_tb_grph_graph.setChecked(True) # Table self.main_space_table = self.table # Graph self.main_space_graph = self.graph # Generate Export buttons self.export_menu = QHBoxLayout() if export: # Export Table self.export_table = QVBoxLayout() self.export_table_label = QLabel("Export table") self.export_table_buttons = QHBoxLayout() self.export_table_buttons_copy = QPushButton("Copy") self.export_table_buttons_csv = QPushButton(".csv") self.export_table_buttons_excel = QPushButton("Excel") # Export Graph self.export_graph = QVBoxLayout() self.export_graph_label = QLabel("Export graph") self.export_graph_buttons = QHBoxLayout() self.export_graph_buttons_png = QPushButton(".png") self.export_graph_buttons_svg = QPushButton(".svg") # Assemble complete tab panel and add to tabs if cutoff: self.assemble_cutoff() if combobox_list: self.assemble_combobox() self.assemble_main_space() if export: self.assemble_export() self.assemble_panel(cutoff, combobox_list, export) self.tabs.addTab(self, name) # Connect signals self.connect_signals() def connect_signals(self): """ Connect all signals relevant to specific LCA Results tab. """ # Receive mlca signals.mlca_results.connect(self.get_mlca_results) # Update graph and table to selected method from combobox if self.combobox_list: self.combobox_menu_combobox.currentTextChanged.connect( lambda name: self.get_new_combobox_list(method=name)) # Generate tables, graphs and combobox signals.mlca_results.connect(self.generate_table_plot_combobox) # Cut-off if self.cutoff: # Cut-off types self.cutoff_type_absolute.clicked.connect( self.cutoff_type_absolute_check) self.cutoff_type_relative.clicked.connect( self.cutoff_type_relative_check) self.cutoff_type_topx.clicked.connect(self.cutoff_type_topx_check) # Cut-off slider self.cutoff_slider_slider.valueChanged.connect( lambda: self.cutoff_slider_check("S")) self.cutoff_slider_line.textChanged.connect( lambda: self.cutoff_slider_check("L")) # Main space checkboxes if self.table and self.graph: self.main_space_tb_grph_table.stateChanged.connect( lambda: self.main_space_check(self.main_space_tb_grph_table, self.main_space_tb_grph_graph)) self.main_space_tb_grph_graph.stateChanged.connect( lambda: self.main_space_check(self.main_space_tb_grph_table, self.main_space_tb_grph_graph)) # Export Table if self.table and self.export: self.export_table_buttons_copy.clicked.connect( self.table.to_clipboard) self.export_table_buttons_csv.clicked.connect(self.table.to_csv) self.export_table_buttons_excel.clicked.connect( self.table.to_excel) # Export Graph if self.graph and self.export: self.export_graph_buttons_png.clicked.connect(self.graph.to_png) self.export_graph_buttons_svg.clicked.connect(self.graph.to_svg) def get_mlca_results(self, mlca): """ Port mlca data from ImpactAssessmentTab to sub-tab. """ self.mlca = mlca self.method_dict = bc.get_LCIA_method_name_dict(self.mlca.methods) if self.combobox_list: self.combobox_menu_combobox.clear() self.combobox_list = list(self.method_dict.keys()) self.combobox_menu_combobox.insertItems(0, self.combobox_list) def generate_table_plot_combobox(self): """ Populate the relevant tables, graphs and comboboxes. """ if self.name == "LCIA Results": if self.table: self.table.sync(self.mlca) if self.graph: self.graph.plot(self.mlca) elif self.name == "Process Contributions": if self.table: self.table = False if self.graph: self.graph.plot(self.mlca, method=self.mlca.methods[0]) elif self.name == "Elementary Flow Contributions": if self.table: self.table = False if self.graph: self.graph.plot(self.mlca, method=self.mlca.methods[0]) elif self.name == "Correlations": if self.table: self.table = False if self.graph: labels = [str(x + 1) for x in range(len(self.mlca.func_units))] self.graph.plot(self.mlca, labels) elif self.name == "Inventory": if self.table: self.table.sync(self.mlca) if self.graph: self.graph = None #labels = [str(x + 1) for x in range(len(self.mlca.func_units))] #self.graph.plot(self.mlca, labels) if self.combobox_list: self.method_dict = bc.get_LCIA_method_name_dict(self.mlca.methods) self.combobox_menu_combobox.clear() self.combobox_list = list(self.method_dict.keys()) self.combobox_menu_combobox.insertItems(0, self.combobox_list) def get_new_combobox_list(self, method=None): """ Update the plot with method selected from combobox. """ if not method: method = next(iter(self.mlca.method_dict.keys())) else: method = self.method_dict[method] self.graph.plot(self.mlca, method=method) def cutoff_type_absolute_check(self): """ Work in progress. """ # set cutoff to some number self.cutoff_slider_unit.setText( "absolute selected, functionality to be added later") def cutoff_type_relative_check(self): """ Work in progress. """ # set cutoff to some % self.cutoff_slider_unit.setText( "relative selected, functionality to be added later") def cutoff_type_topx_check(self): """ Work in progress. """ # set cutoff to some number self.cutoff_slider_unit.setText( "topx selected, functionality to be added later") def set_cutoff(self): pass def cutoff_slider_check(self, editor): """ Update the slider and line-edit field when either one changes. """ cutoff = int if editor == "S": cutoff = abs(int(self.cutoff_slider_slider.value())) self.cutoff_slider_line.setText(str(cutoff)) elif editor == "L": if self.cutoff_slider_line.text() == '-': cutoff = self.cutoff_slider_slider.minimum() self.cutoff_slider_line.setText( str(self.cutoff_slider_slider.minimum())) elif self.cutoff_slider_line.text() == '': cutoff = self.cutoff_slider_slider.minimum() else: cutoff = abs(int(self.cutoff_slider_line.text())) if cutoff > self.cutoff_slider_slider.maximum(): cutoff = self.cutoff_slider_slider.maximum() self.cutoff_slider_line.setText(str(cutoff)) self.cutoff_slider_slider.setValue(int(cutoff)) self.cutoff_value = cutoff def main_space_check(self, table_ch, graph_ch): """ Show graph or table and related export functions, dependent on which is selected. """ table_state = table_ch.isChecked() graph_state = graph_ch.isChecked() if table_state and graph_state: self.main_space_table.setVisible(True) self.main_space_graph.setVisible(True) self.export_table_label.setVisible(True) self.export_table_buttons_copy.setVisible(True) self.export_table_buttons_csv.setVisible(True) self.export_table_buttons_excel.setVisible(True) self.export_menu_vert_line.setVisible(True) self.export_graph_label.setVisible(True) self.export_graph_buttons_png.setVisible(True) self.export_graph_buttons_svg.setVisible(True) elif not table_state and graph_state: self.main_space_table.setVisible(False) self.main_space_graph.setVisible(True) self.export_table_label.setVisible(False) self.export_table_buttons_copy.setVisible(False) self.export_table_buttons_csv.setVisible(False) self.export_table_buttons_excel.setVisible(False) self.export_menu_vert_line.setVisible(False) self.export_graph_label.setVisible(True) self.export_graph_buttons_png.setVisible(True) self.export_graph_buttons_svg.setVisible(True) else: self.main_space_tb_grph_table.setChecked(True) self.main_space_table.setVisible(True) self.main_space_graph.setVisible(False) self.export_table_label.setVisible(True) self.export_table_buttons_copy.setVisible(True) self.export_table_buttons_csv.setVisible(True) self.export_table_buttons_excel.setVisible(True) self.export_menu_vert_line.setVisible(False) self.export_graph_label.setVisible(False) self.export_graph_buttons_png.setVisible(False) self.export_graph_buttons_svg.setVisible(False) def assemble_cutoff(self): """ Assemble the cut-off section of the tab. """ # Assemble types self.cutoff_type.addWidget(self.cutoff_type_label) self.cutoff_type.addWidget(self.cutoff_type_absolute) self.cutoff_type.addWidget(self.cutoff_type_relative) self.cutoff_type.addWidget(self.cutoff_type_topx) # Assemble slider set self.cutoff_slider_set.addWidget(self.cutoff_slider_label) self.cutoff_slider_set.addWidget(self.cutoff_slider_slider) self.cutoff_slider_minmax.addWidget(self.cutoff_slider_min) self.cutoff_slider_minmax.addStretch() self.cutoff_slider_minmax.addWidget(self.cutoff_slider_max) self.cutoff_slider_set.addLayout(self.cutoff_slider_minmax) self.cutoff_slider_ledit.addWidget(self.cutoff_slider_line) self.cutoff_slider_ledit.addWidget(self.cutoff_slider_unit) self.cutoff_slider_ledit.addStretch(1) self.cutoff_slider.addLayout(self.cutoff_slider_set) self.cutoff_slider.addLayout(self.cutoff_slider_ledit) # Assemble cut-off menu self.cutoff_menu.addLayout(self.cutoff_type) self.cutoff_menu.addWidget(vertical_line()) self.cutoff_menu.addLayout(self.cutoff_slider) self.cutoff_menu.addStretch() def assemble_combobox(self): """ Assemble the combobox section of the tab. """ self.combobox_menu.addWidget(self.combobox_menu_label) self.combobox_menu.addWidget(self.combobox_menu_combobox, 1) self.combobox_menu.addStretch(1) def assemble_main_space(self): """ Assemble the main space section of the tab. """ # Assemble option switch self.main_space_tb_grph.addWidget(self.main_space_tb_grph_table) self.main_space_tb_grph.addWidget(self.main_space_tb_grph_graph) self.main_space_tb_grph.addStretch() # Assemble Table and Graph area if self.table and self.graph: self.main_space_widget_layout.addLayout(self.main_space_tb_grph) if self.table: self.main_space_widget_layout.addWidget(self.main_space_table) if self.graph: self.main_space_widget_layout.addWidget(self.main_space_graph, 1) self.main_space_widget_layout.addStretch() def assemble_export(self): """ Assemble the export section of the tab. """ # Assemble export table self.export_table.addWidget(self.export_table_label) self.export_table_buttons.addWidget(self.export_table_buttons_copy) self.export_table_buttons.addWidget(self.export_table_buttons_csv) self.export_table_buttons.addWidget(self.export_table_buttons_excel) self.export_table.addLayout(self.export_table_buttons) # Assemble export graph self.export_graph.addWidget(self.export_graph_label) self.export_graph_buttons.addWidget(self.export_graph_buttons_png) self.export_graph_buttons.addWidget(self.export_graph_buttons_svg) self.export_graph.addLayout(self.export_graph_buttons) # Assemble export menu if self.table: self.export_menu.addLayout(self.export_table) if self.table and self.graph: self.export_menu_vert_line = vertical_line() self.export_menu.addWidget(self.export_menu_vert_line) if self.graph: self.export_menu.addLayout(self.export_graph) """self.export_menu.addLayout(self.export_table) self.export_menu_vert_line = vertical_line() self.export_menu.addWidget(self.export_menu_vert_line) self.export_menu.addLayout(self.export_graph) if self.main_space_tb_grph_table.isChecked(): self.export_table.setVisible(True) self.export_menu_vert_line.setVisible(False) self.export_graph.setVisible(False) elif self.main_space_tb_grph_table.isChecked() and \ self.main_space_tb_grph_graph.isChecked(): self.export_table.setVisible(True) self.export_menu_vert_line.setVisible(True) self.export_graph.setVisible(True) elif self.main_space_tb_grph_table.isChecked(): self.export_table.setVisible(False) self.export_menu_vert_line.setVisible(False) self.export_graph.setVisible(True)""" self.export_menu.addStretch() def assemble_panel(self, cutoff, combobox, export): """ Assemble the tab. """ self.tab_layout.addWidget(header(self.name)) self.tab_layout.addWidget(horizontal_line()) if cutoff: self.tab_layout.addLayout(self.cutoff_menu) self.tab_layout.addWidget(horizontal_line()) if combobox: self.tab_layout.addLayout(self.combobox_menu) self.tab_layout.addWidget(horizontal_line()) self.tab_layout.addWidget(self.main_space) if export: self.tab_layout.addWidget(horizontal_line()) self.tab_layout.addLayout(self.export_menu)
class SerialController(QWidget): # 시리얼포트 상수 값 BAUDRATES = ( QSerialPort.Baud1200, QSerialPort.Baud2400, QSerialPort.Baud4800, QSerialPort.Baud9600, QSerialPort.Baud19200, QSerialPort.Baud38400, QSerialPort.Baud57600, QSerialPort.Baud115200, ) DATABITS = ( QSerialPort.Data5, QSerialPort.Data6, QSerialPort.Data7, QSerialPort.Data8, ) FLOWCONTROL = ( QSerialPort.NoFlowControl, QSerialPort.HardwareControl, QSerialPort.SoftwareControl, ) PARITY = ( QSerialPort.NoParity, QSerialPort.EvenParity, QSerialPort.OddParity, QSerialPort.SpaceParity, QSerialPort.MarkParity, ) STOPBITS = ( QSerialPort.OneStop, QSerialPort.OneAndHalfStop, QSerialPort.TwoStop, ) received_data = pyqtSignal(QByteArray, name="receivedData") sent_data = pyqtSignal(str, name="sentData") def __init__(self): QWidget.__init__(self, flags=Qt.Widget) # 위젯 선언 self.gb = QGroupBox(self.tr("Serial")) self.cb_port = QComboBox() self.cb_baud_rate = QComboBox() self.cb_data_bits = QComboBox() self.cb_flow_control = QComboBox() self.cb_parity = QComboBox() self.cb_stop_bits = QComboBox() # 시리얼 인스턴스 생성 # 시리얼 스레드 설정 및 시작 self.serial = QSerialPort() self.serial_info = QSerialPortInfo() self.serial_read_thread = SerialReadThread(self.serial) self.serial_read_thread.received_data.connect( lambda v: self.received_data.emit(v)) self.serial_read_thread.start() self.init_widget() def init_widget(self): self.setWindowTitle("Serial Controller") layout = QBoxLayout(QBoxLayout.TopToBottom, parent=self) grid_box = QGridLayout() grid_box.addWidget(QLabel(self.tr("Port")), 0, 0) grid_box.addWidget(self.cb_port, 0, 1) grid_box.addWidget(QLabel(self.tr("Baud Rate")), 1, 0) grid_box.addWidget(self.cb_baud_rate, 1, 1) grid_box.addWidget(QLabel(self.tr("Data Bits")), 2, 0) grid_box.addWidget(self.cb_data_bits, 2, 1) grid_box.addWidget(QLabel(self.tr("Flow Control")), 3, 0) grid_box.addWidget(self.cb_flow_control, 3, 1) grid_box.addWidget(QLabel(self.tr("Parity")), 4, 0) grid_box.addWidget(self.cb_parity, 4, 1) grid_box.addWidget(QLabel(self.tr("Stop Bits")), 5, 0) grid_box.addWidget(self.cb_stop_bits, 5, 1) self._fill_serial_info() self.gb.setLayout(grid_box) layout.addWidget(self.gb) self.setLayout(layout) def _fill_serial_info(self): # 시리얼 상수 값들을 위젯에 채운다 self.cb_port.insertItems(0, self._get_available_port()) self.cb_baud_rate.insertItems(0, [str(x) for x in self.BAUDRATES]) self.cb_data_bits.insertItems(0, [str(x) for x in self.DATABITS]) flow_name = {0: "None", 1: "Hardware", 2: "Software"} self.cb_flow_control.insertItems( 0, [flow_name[x] for x in self.FLOWCONTROL]) parity_name = {0: "None", 2: "Even", 3: "Odd", 4: "Space", 5: "Mark"} self.cb_parity.insertItems(0, [parity_name[x] for x in self.PARITY]) stop_bits_name = {1: "1", 3: "1.5", 2: "2"} self.cb_stop_bits.insertItems( 0, [stop_bits_name[x] for x in self.STOPBITS]) @staticmethod def get_port_path(): """ 현재플래폼에 맞게 경로 또는 지정어를 반환 :return: """ return {"linux": '/dev/ttyS', "win32": 'COM'}[__platform__] def _get_available_port(self): """ 255개의 포트를 열고 닫으면서 사용가능한 포트를 찾아서 반환 :return: """ available_port = list() port_path = self.get_port_path() for number in range(255): port_name = port_path + str(number) if not self._open(port_name): continue available_port.append(port_name) self.serial.close() return available_port def _open(self, port_name, baudrate=QSerialPort.Baud9600, data_bits=QSerialPort.Data8, flow_control=QSerialPort.NoFlowControl, parity=QSerialPort.NoParity, stop_bits=QSerialPort.OneStop): """ 인자값으로 받은 시리얼 접속 정보를 이용하여 해당 포트를 연결한다. :param port_name: :param baudrate: :param data_bits: :param flow_control: :param parity: :param stop_bits: :return: bool """ info = QSerialPortInfo(port_name) self.serial.setPort(info) self.serial.setBaudRate(baudrate) self.serial.setDataBits(data_bits) self.serial.setFlowControl(flow_control) self.serial.setParity(parity) self.serial.setStopBits(stop_bits) return self.serial.open(QIODevice.ReadWrite) def connect_serial(self): serial_info = { "port_name": self.cb_port.currentText(), "baudrate": self.BAUDRATES[self.cb_baud_rate.currentIndex()], "data_bits": self.DATABITS[self.cb_data_bits.currentIndex()], "flow_control": self.FLOWCONTROL[self.cb_flow_control.currentIndex()], "parity": self.PARITY[self.cb_parity.currentIndex()], "stop_bits": self.STOPBITS[self.cb_stop_bits.currentIndex()], } status = self._open(**serial_info) self.serial_read_thread.setStatus(status) return status def disconnect_serial(self): return self.serial.close() @pyqtSlot(bytes, name="writeData") def write_data(self, data): self.serial.writeData(data)
class OptionsWindow(QWidget): """ Window for changing settings. Useful attributes ----------------- parentWindow : MainWindow object Parent of the window. langCombo : QComboBox object Language selector. tdelta(Days|Hours|Mins|Secs)Edit : QLineEdit object Widgets for time delta change. mesoutSecsEdit : QLineEdit object Widget for message timeout change. backupMinsEdit : QLineEdit object Widget for backup timeout change. """ def __init__(self, parent=None): super().__init__() self.parentWindow = parent self.parentWindow.optActive = True self.initUI() def initUI(self): """ Init user interface. """ self.setWindowTitle(conf.lang.OPT_TITLE) iconOpt = Icon(byte=icons.options).convertToIcon().getIcon() self.setWindowIcon(iconOpt) self.resize(500, 175) self.move(QApplication.desktop().screen().rect().center() - self.rect().center()) # center window on screen self.grid = QGridLayout() self.setLayout(self.grid) self.fill() def fill(self): """ Fills window with widgets. """ clearLayout(self.grid) # language selector self.grid.addWidget(QLabel(conf.lang.CHANGE_LANGUAGE), 0, 0) self.langCombo = QComboBox() langList = [] for i in langs.values(): if i.NAME == conf.lang.NAME: langList.insert(0, i.FULL_NAME) # current language is first else: langList.append(i.FULL_NAME) self.langCombo.insertItems(0, langList) self.grid.addWidget(self.langCombo, 0, 1, 1, 4) # tdelta change tdeltaDict = parseSeconds(conf.tdelta, dic=True) self.grid.addWidget(QLabel(conf.lang.CHANGE_TDELTA), 1, 0) self.tdeltaDaysEdit = QLineEdit() self.tdeltaDaysEdit.setText(str(tdeltaDict['days'])) self.tdeltaDaysEdit.setValidator(QIntValidator(0, 999)) self.grid.addWidget(self.tdeltaDaysEdit, 1, 1) self.grid.addWidget(QLabel(conf.lang.DAYS), 1, 2) self.tdeltaHoursEdit = QLineEdit() self.tdeltaHoursEdit.setText(str(tdeltaDict['hours'])) self.tdeltaHoursEdit.setValidator(QIntValidator(0, 23)) self.grid.addWidget(self.tdeltaHoursEdit, 1, 3) self.grid.addWidget(QLabel(conf.lang.HOURS), 1, 4) self.tdeltaMinsEdit = QLineEdit() self.tdeltaMinsEdit.setText(str(tdeltaDict['minutes'])) self.tdeltaMinsEdit.setValidator(QIntValidator(0, 59)) self.grid.addWidget(self.tdeltaMinsEdit, 1, 5) self.grid.addWidget(QLabel(conf.lang.MINUTES), 1, 6) self.tdeltaSecsEdit = QLineEdit() self.tdeltaSecsEdit.setText(str(tdeltaDict['seconds'])) self.tdeltaSecsEdit.setValidator(QIntValidator(0, 59)) self.grid.addWidget(self.tdeltaSecsEdit, 1, 7) self.grid.addWidget(QLabel(conf.lang.SECONDS), 1, 8) # mesout change self.grid.addWidget(QLabel(conf.lang.MESSAGE_TIMER), 2, 0) self.mesoutSecsEdit = QLineEdit() self.mesoutSecsEdit.setText(str(conf.mesout)) self.mesoutSecsEdit.setValidator(QIntValidator(0, 299)) self.grid.addWidget(self.mesoutSecsEdit, 2, 1) self.grid.addWidget(QLabel(conf.lang.SECONDS), 2, 2) # backup timeout change self.grid.addWidget(QLabel(conf.lang.BACKUP_TIMER), 3, 0) self.backupMinsEdit = QLineEdit() self.backupMinsEdit.setText(str(int(conf.backup / 60))) self.backupMinsEdit.setValidator(QIntValidator(0, 999)) self.grid.addWidget(self.backupMinsEdit, 3, 1) self.grid.addWidget(QLabel(conf.lang.MINUTES), 3, 2) spacer = QSpacerItem(10, 0, vPolicy=QSizePolicy.MinimumExpanding) self.grid.addItem(spacer, 4, 0) saveBtn = QPushButton(conf.lang.SAVE) saveBtn.clicked.connect(self.save) self.grid.addWidget(saveBtn, 5, 5, 1, 2) closeBtn = QPushButton(conf.lang.CLOSE) closeBtn.clicked.connect(lambda: self.closeEvent(QCloseEvent())) self.grid.addWidget(closeBtn, 5, 7, 1, 2) def save(self): """ Save changes to config. """ tdelta = [self.tdeltaSecsEdit.text(), self.tdeltaMinsEdit.text(), self.tdeltaHoursEdit.text(), self.tdeltaDaysEdit.text()] tdelta = list(map(lambda x: int(x) if x != '' else 0, tdelta)) tdelta[1] *= 60 tdelta[2] *= 3600 tdelta[3] *= 86400 tdelta = sum(tdelta) conf.tdelta = tdelta if self.mesoutSecsEdit.text() == '': self.mesoutSecsEdit.setText('0') mesout = int(self.mesoutSecsEdit.text()) if mesout == 0: mesout = 60 conf.mesout = mesout if self.backupMinsEdit.text() == '': self.backupMinsEdit.setText('0') backup = int(self.backupMinsEdit.text()) if backup == 0: backup = 5 conf.backup = backup * 60 if self.langCombo.currentText() != conf.lang.FULL_NAME: for i in langs.values(): if i.FULL_NAME == self.langCombo.currentText(): conf.lang = i self.closeEvent(QCloseEvent(), changed=True) def closeEvent(self, event, changed=False): """ Closes window. """ self.parentWindow.optActive = False if self.parentWindow.addActive: self.parentWindow.addWindow.show() if self.parentWindow.addWindow.index == None: if self.parentWindow.editActive: self.parentWindow.editWindow.show() else: if self.parentWindow.editActive: self.parentWindow.editWindow.show() event.ignore() if changed: reload() self.hide()
class OS2Tab(TabWidget): def __init__(self, font, parent=None): super().__init__(parent, name="OS/2") # OS2Group = QGroupBox("OS/2 table", self) # OS2Group.setFlat(True) OS2Layout = QGridLayout(self) usWidthClassLabel = QLabel("usWidthClass:", self) self.usWidthClassDrop = QComboBox(self) items = [ "None", "Ultra-condensed", "Extra-condensed", "Condensed", "Semi-Condensed", "Medium (normal)", "Semi-expanded", "Expanded", "Extra-expanded", "Ultra-expanded"] self.usWidthClassDrop.insertItems(0, items) if font.info.openTypeOS2WidthClass is not None: self.usWidthClassDrop.setCurrentIndex( font.info.openTypeOS2WidthClass) fsSelectionLabel = QLabel("fsSelection:", self) fsSelection = font.info.openTypeOS2Selection self.fsSelectionList = QListView(self) items = [ "1 UNDERSCORE", "2 NEGATIVE", "3 OUTLINED", "4 STRIKEOUT", "7 USE_TYPO_METRICS", "8 WWS", "9 OBLIQUE"] # http://stackoverflow.com/a/26613163 model = QStandardItemModel(7, 1) for index, elem in enumerate(items): item = QStandardItem() item.setText(elem) item.setCheckable(True) bit = index + 1 if fsSelection is not None and bit in fsSelection: # maybe default setting? if so, unneeded item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) model.setItem(index, item) self.fsSelectionList.setModel(model) achVendorIDLabel = QLabel("achVendorID:", self) self.achVendorIDEdit = QLineEdit(font.info.openTypeOS2VendorID, self) self.achVendorIDEdit.setMaxLength(4) fsTypeLabel = QLabel("fsType:", self) fsType = font.info.openTypeOS2Type self.fsTypeDrop = QComboBox(self) items = [ "No embedding restrictions", "Restricted embedding", "Preview and print embedding allowed", "Editable embedding allowed"] self.allowSubsettingBox = QCheckBox("Allow subsetting", self) self.allowBitmapEmbeddingBox = QCheckBox( "Allow only bitmap embedding", self) self.fsTypeDrop.currentIndexChanged[int].connect( self._updateFsTypeVisibility) self.fsTypeDrop.insertItems(0, items) if fsType is not None: for i in range(1, 4): if i in fsType: self.fsTypeDrop.setCurrentIndex(i) break self.allowSubsettingBox.setChecked(8 not in fsType) self.allowBitmapEmbeddingBox.setChecked(9 in fsType) # XXX: ulUnicodeRange # XXX: ulCodePageRange sTypoAscenderLabel = QLabel("sTypoAscender:", self) sTypoDescenderLabel = QLabel("sTypoDescender:", self) sTypoLineGapLabel = QLabel("sTypoLineGap:", self) usWeightClassLabel = QLabel("usWeightClass:", self) usWinAscentLabel = QLabel("usWinAscent:", self) usWinDescentLabel = QLabel("usWinDescent:", self) ySubscriptXSizeLabel = QLabel("ySubscriptXSize:", self) ySubscriptYSizeLabel = QLabel("ySubscriptYSize:", self) ySubscriptXOffsetLabel = QLabel("ySubscriptXOffset:", self) ySubscriptYOffsetLabel = QLabel("ySubscriptYOffset:", self) ySuperscriptXSizeLabel = QLabel("ySuperscriptXSize:", self) ySuperscriptYSizeLabel = QLabel("ySuperscriptYSize:", self) ySuperscriptXOffsetLabel = QLabel("ySuperscriptXOffset:", self) ySuperscriptYOffsetLabel = QLabel("ySuperscriptYOffset:", self) yStrikeoutSizeLabel = QLabel("yStrikeoutSize:", self) yStrikeoutPositionLabel = QLabel("yStrikeoutPosition:", self) self.loadPositiveInteger( font, "openTypeOS2WeightClass", "usWeightClass") self.loadInteger(font, "openTypeOS2TypoAscender", "sTypoAscender") self.loadInteger(font, "openTypeOS2TypoDescender", "sTypoDescender") self.loadInteger(font, "openTypeOS2TypoLineGap", "sTypoLineGap") self.loadPositiveInteger(font, "openTypeOS2WinAscent", "usWinAscent") self.loadPositiveInteger(font, "openTypeOS2WinDescent", "usWinDescent") self.loadInteger(font, "openTypeOS2SubscriptXSize", "ySubscriptXSize") self.loadInteger(font, "openTypeOS2SubscriptYSize", "ySubscriptYSize") self.loadInteger( font, "openTypeOS2SubscriptXOffset", "ySubscriptXOffset") self.loadInteger( font, "openTypeOS2SubscriptYOffset", "ySubscriptYOffset") self.loadInteger( font, "openTypeOS2SuperscriptXSize", "ySuperscriptXSize") self.loadInteger( font, "openTypeOS2SuperscriptYSize", "ySuperscriptYSize") self.loadInteger( font, "openTypeOS2SuperscriptXOffset", "ySuperscriptXOffset") self.loadInteger( font, "openTypeOS2SuperscriptYOffset", "ySuperscriptYOffset") self.loadInteger(font, "openTypeOS2StrikeoutSize", "yStrikeoutSize") self.loadInteger( font, "openTypeOS2StrikeoutPosition", "yStrikeoutPosition") # XXX: panose l = 0 OS2Layout.addWidget(usWidthClassLabel, l, 0) OS2Layout.addWidget(self.usWidthClassDrop, l, 1, 1, 2) OS2Layout.addWidget(achVendorIDLabel, l, 3) OS2Layout.addWidget(self.achVendorIDEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(usWeightClassLabel, l, 0) OS2Layout.addWidget(self.usWeightClassEdit, l, 1, 1, 2) l += 1 OS2Layout.addWidget(fsSelectionLabel, l, 0, 3, 1) OS2Layout.addWidget(self.fsSelectionList, l, 1, 3, 2) OS2Layout.addWidget(fsTypeLabel, l, 3, 3, 1) OS2Layout.addWidget(self.fsTypeDrop, l, 4, 1, 2) l += 1 OS2Layout.addWidget(self.allowSubsettingBox, l, 4, 1, 2) l += 1 OS2Layout.addWidget(self.allowBitmapEmbeddingBox, l, 4, 1, 2) l += 1 OS2Layout.addWidget(sTypoAscenderLabel, l, 0) OS2Layout.addWidget(self.sTypoAscenderEdit, l, 1, 1, 2) OS2Layout.addWidget(usWinAscentLabel, l, 3) OS2Layout.addWidget(self.usWinAscentEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(sTypoDescenderLabel, l, 0) OS2Layout.addWidget(self.sTypoDescenderEdit, l, 1, 1, 2) OS2Layout.addWidget(usWinDescentLabel, l, 3) OS2Layout.addWidget(self.usWinDescentEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(sTypoLineGapLabel, l, 0) OS2Layout.addWidget(self.sTypoLineGapEdit, l, 1, 1, 2) l += 1 OS2Layout.addWidget(ySubscriptXSizeLabel, l, 0) OS2Layout.addWidget(self.ySubscriptXSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySubscriptXOffsetLabel, l, 3) OS2Layout.addWidget(self.ySubscriptXOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(ySubscriptYSizeLabel, l, 0) OS2Layout.addWidget(self.ySubscriptYSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySubscriptYOffsetLabel, l, 3) OS2Layout.addWidget(self.ySubscriptYOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(ySuperscriptXSizeLabel, l, 0) OS2Layout.addWidget(self.ySuperscriptXSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySuperscriptXOffsetLabel, l, 3) OS2Layout.addWidget(self.ySuperscriptXOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(ySuperscriptYSizeLabel, l, 0) OS2Layout.addWidget(self.ySuperscriptYSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySuperscriptYOffsetLabel, l, 3) OS2Layout.addWidget(self.ySuperscriptYOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(yStrikeoutSizeLabel, l, 0) OS2Layout.addWidget(self.yStrikeoutSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(yStrikeoutPositionLabel, l, 3) OS2Layout.addWidget(self.yStrikeoutPositionEdit, l, 4, 1, 2) # OS2Group.setLayout(OS2Layout) self.setLayout(OS2Layout) def _updateFsTypeVisibility(self, index): if index == 0: # TODO: maybe uncheck as well? self.allowSubsettingBox.setEnabled(False) self.allowBitmapEmbeddingBox.setEnabled(False) else: self.allowSubsettingBox.setEnabled(True) self.allowBitmapEmbeddingBox.setEnabled(True) def writeValues(self, font): self.writePositiveInteger( font, "usWeightClass", "openTypeOS2WeightClass") self.writeInteger(font, "sTypoAscender", "openTypeOS2TypoAscender") self.writeInteger(font, "sTypoDescender", "openTypeOS2TypoDescender") self.writeInteger(font, "sTypoLineGap", "openTypeOS2TypoLineGap") self.writePositiveInteger(font, "usWinAscent", "openTypeOS2WinAscent") self.writePositiveInteger( font, "usWinDescent", "openTypeOS2WinDescent") self.writeInteger(font, "ySubscriptXSize", "openTypeOS2SubscriptXSize") self.writeInteger(font, "ySubscriptYSize", "openTypeOS2SubscriptYSize") self.writeInteger( font, "ySubscriptXOffset", "openTypeOS2SubscriptXOffset") self.writeInteger( font, "ySubscriptYOffset", "openTypeOS2SubscriptYOffset") self.writeInteger( font, "ySuperscriptXSize", "openTypeOS2SuperscriptXSize") self.writeInteger( font, "ySuperscriptYSize", "openTypeOS2SuperscriptYSize") self.writeInteger( font, "ySuperscriptXOffset", "openTypeOS2SuperscriptXOffset") self.writeInteger( font, "ySuperscriptYOffset", "openTypeOS2SuperscriptYOffset") self.writeInteger(font, "yStrikeoutSize", "openTypeOS2StrikeoutSize") self.writeInteger( font, "yStrikeoutPosition", "openTypeOS2StrikeoutPosition") fsSelectionModel = self.fsSelectionList.model() fsSelection = [] for i in range(7): item = fsSelectionModel.item(i) if item.checkState() == Qt.Checked: fsSelection.append(i) if len(fsSelection): font.info.openTypeOS2Selection = fsSelection else: # XXX: None or empty array? should distinct those cases font.info.openTypeOS2Selection = None fsTypeIndex = self.fsTypeDrop.currentIndex() fsType = [] if fsTypeIndex > 0: fsType.append(fsTypeIndex) if not self.allowSubsettingBox.isChecked(): fsType.append(8) if self.allowBitmapEmbeddingBox.isChecked(): fsType.append(9) # TODO: provide a way to represent None w this? font.info.openTypeOS2Type = fsType # TODO: see if data needs to be padded to 4 chars. # I think that this is to be deferred to ufo2fdk(?) font.info.openTypeOS2VendorID = self.achVendorIDEdit.text()
class PostScriptTab(TabWidget): def __init__(self, font, parent=None): super().__init__(parent) self.name = self.tr("PostScript") namingGroup = QGroupBox(self.tr("Naming"), self) # namingGroup.setFlat(True) namingLayout = QGridLayout(self) fontNameLabel = RLabel(self.tr("FontName:"), self) fullNameLabel = RLabel(self.tr("FullName:"), self) weightNameLabel = RLabel(self.tr("WeightName:"), self) uniqueIDLabel = RLabel(self.tr("UniqueID:"), self) self.loadString(font, "postscriptFontName", "fontName") self.loadString(font, "postscriptFullName", "fullName") self.loadString(font, "postscriptWeightName", "weightName") self.loadInteger(font, "postscriptUniqueID", "uniqueID") l = 0 namingLayout.addWidget(fontNameLabel, l, 0) namingLayout.addWidget(self.fontNameEdit, l, 1, 1, 2) namingLayout.addWidget(weightNameLabel, l, 3) namingLayout.addWidget(self.weightNameEdit, l, 4, 1, 2) l += 1 namingLayout.addWidget(fullNameLabel, l, 0) namingLayout.addWidget(self.fullNameEdit, l, 1, 1, 2) namingLayout.addWidget(uniqueIDLabel, l, 3) namingLayout.addWidget(self.uniqueIDEdit, l, 4, 1, 2) namingGroup.setLayout(namingLayout) hintingGroup = QGroupBox(self.tr("Hints"), self) # hintingGroup.setFlat(True) hintingLayout = QGridLayout(self) self.loadIntegerFloatList(font, "postscriptBlueValues", "blueValues") self.loadIntegerFloatList(font, "postscriptOtherBlues", "otherBlues") self.loadIntegerFloatList(font, "postscriptFamilyBlues", "familyBlues") self.loadIntegerFloatList(font, "postscriptFamilyOtherBlues", "familyOtherBlues") blueValuesLabel = RLabel(self.tr("BlueValues:"), self) otherBluesLabel = RLabel(self.tr("OtherBlues:"), self) familyBluesLabel = RLabel(self.tr("FamilyBlues:"), self) familyOtherBluesLabel = RLabel(self.tr("FamilyOtherBlues:"), self) l = 0 hintingLayout.addWidget(blueValuesLabel, l, 0) hintingLayout.addWidget(self.blueValuesEdit, l, 1, 1, 2) hintingLayout.addWidget(familyBluesLabel, l, 3) hintingLayout.addWidget(self.familyBluesEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(otherBluesLabel, l, 0) hintingLayout.addWidget(self.otherBluesEdit, l, 1, 1, 2) hintingLayout.addWidget(familyOtherBluesLabel, l, 3) hintingLayout.addWidget(self.familyOtherBluesEdit, l, 4, 1, 2) l += 1 blueFuzzLabel = RLabel(self.tr("BlueFuzz:"), self) stemSnapHLabel = RLabel(self.tr("StemSnapH:"), self) blueScaleLabel = RLabel(self.tr("BlueScale:"), self) stemSnapVLabel = RLabel(self.tr("StemSnapV:"), self) blueShiftLabel = RLabel(self.tr("BlueShift:"), self) self.loadIntegerFloatList(font, "postscriptStemSnapH", "stemSnapH") self.loadIntegerFloatList(font, "postscriptStemSnapV", "stemSnapV") self.loadIntegerFloat(font, "postscriptBlueFuzz", "blueFuzz") self.loadIntegerFloat(font, "postscriptBlueScale", "blueScale") self.loadIntegerFloat(font, "postscriptBlueShift", "blueShift") forceBoldLabel = RLabel(self.tr("ForceBold:"), self) self.loadBoolean(font, "postscriptForceBold", "forceBold") hintingLayout.addWidget(blueFuzzLabel, l, 0) hintingLayout.addWidget(self.blueFuzzEdit, l, 1, 1, 2) hintingLayout.addWidget(stemSnapHLabel, l, 3) hintingLayout.addWidget(self.stemSnapHEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(blueScaleLabel, l, 0) hintingLayout.addWidget(self.blueScaleEdit, l, 1, 1, 2) hintingLayout.addWidget(stemSnapVLabel, l, 3) hintingLayout.addWidget(self.stemSnapVEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(blueShiftLabel, l, 0) hintingLayout.addWidget(self.blueShiftEdit, l, 1, 1, 2) hintingLayout.addWidget(forceBoldLabel, l, 3) hintingLayout.addWidget(self.forceBoldBox, l, 4, 1, 2) hintingGroup.setLayout(hintingLayout) metricsGroup = QGroupBox(self.tr("Metrics"), self) # metricsGroup.setFlat(True) metricsLayout = QGridLayout(self) defaultWidthXLabel = RLabel(self.tr("DefaultWidthX:"), self) underlineThicknessLabel = RLabel(self.tr("UnderlineThickness:"), self) nominalWidthXLabel = RLabel(self.tr("NominalWidthX:"), self) underlinePositionLabel = RLabel(self.tr("UnderlinePosition:"), self) slantAngleLabel = RLabel(self.tr("SlantAngle:"), self) self.loadIntegerFloat(font, "postscriptDefaultWidthX", "defaultWidthX") self.loadIntegerFloat(font, "postscriptNominalWidthX", "nominalWidthX") self.loadIntegerFloat(font, "postscriptUnderlineThickness", "underlineThickness") self.loadIntegerFloat(font, "postscriptUnderlinePosition", "underlinePosition") self.loadIntegerFloat(font, "postscriptSlantAngle", "slantAngle") isFixedPitchLabel = RLabel(self.tr("isFixedPitched:"), self) self.loadBoolean(font, "postscriptIsFixedPitch", "isFixedPitch") l = 0 metricsLayout.addWidget(defaultWidthXLabel, l, 0) metricsLayout.addWidget(self.defaultWidthXEdit, l, 1, 1, 2) metricsLayout.addWidget(underlineThicknessLabel, l, 3) metricsLayout.addWidget(self.underlineThicknessEdit, l, 4, 1, 2) l += 1 metricsLayout.addWidget(nominalWidthXLabel, l, 0) metricsLayout.addWidget(self.nominalWidthXEdit, l, 1, 1, 2) metricsLayout.addWidget(underlinePositionLabel, l, 3) metricsLayout.addWidget(self.underlinePositionEdit, l, 4, 1, 2) l += 1 metricsLayout.addWidget(slantAngleLabel, l, 0) metricsLayout.addWidget(self.slantAngleEdit, l, 1, 1, 2) metricsLayout.addWidget(isFixedPitchLabel, l, 3) metricsLayout.addWidget(self.isFixedPitchBox, l, 4, 1, 2) metricsGroup.setLayout(metricsLayout) charactersGroup = QGroupBox(self.tr("Characters"), self) # charactersGroup.setFlat(True) charactersLayout = QGridLayout(self) defaultCharacterLabel = RLabel(self.tr("Default character:"), self) self.loadString(font, "postscriptDefaultCharacter", "defaultCharacter") windowsCharacterSetLabel = RLabel(self.tr("Windows character set:"), self) self.windowsCharacterSetDrop = QComboBox(self) items = [ self.tr("None"), self.tr("ANSI"), self.tr("Default"), self.tr("Symbol"), self.tr("Macintosh"), self.tr("Shift JIS"), self.tr("Hangul"), self.tr("Hangul (Johab)"), self.tr("GB2312"), self.tr("Chinese BIG5"), self.tr("Greek"), self.tr("Turkish"), self.tr("Vietnamese"), self.tr("Hebrew"), self.tr("Arabic"), self.tr("Baltic"), self.tr("Bitstream"), self.tr("Cyrillic"), self.tr("Thai"), self.tr("Eastern European"), self.tr("OEM") ] self.windowsCharacterSetDrop.insertItems(0, items) if font.info.postscriptWindowsCharacterSet is not None: self.windowsCharacterSetDrop.setCurrentIndex( font.info.postscriptWindowsCharacterSet) l = 0 charactersLayout.addWidget(defaultCharacterLabel, l, 0) charactersLayout.addWidget(self.defaultCharacterEdit, l, 1, 1, 2) charactersLayout.addWidget(windowsCharacterSetLabel, l, 3) charactersLayout.addWidget(self.windowsCharacterSetDrop, l, 4, 1, 2) charactersGroup.setLayout(charactersLayout) mainLayout = QVBoxLayout() mainLayout.addWidget(namingGroup) mainLayout.addWidget(hintingGroup) mainLayout.addWidget(metricsGroup) mainLayout.addWidget(charactersGroup) self.setLayout(mainLayout) def writeValues(self, font): self.writeString(font, "fontName", "postscriptFontName") self.writeString(font, "fullName", "postscriptFullName") self.writeString(font, "weightName", "postscriptWeightName") self.writeInteger(font, "uniqueID", "postscriptUniqueID") self.writeIntegerFloatList(font, "blueValues", "postscriptBlueValues") self.writeIntegerFloatList(font, "otherBlues", "postscriptOtherBlues") self.writeIntegerFloatList(font, "familyBlues", "postscriptFamilyBlues") self.writeIntegerFloatList(font, "familyOtherBlues", "postscriptFamilyOtherBlues") self.writeIntegerFloatList(font, "stemSnapH", "postscriptStemSnapH") self.writeIntegerFloatList(font, "stemSnapV", "postscriptStemSnapV") self.writeIntegerFloat(font, "blueFuzz", "postscriptBlueFuzz") self.writeIntegerFloat(font, "blueScale", "postscriptBlueScale") self.writeIntegerFloat(font, "blueShift", "postscriptBlueShift") self.writeIntegerFloat(font, "defaultWidthX", "postscriptDefaultWidthX") self.writeIntegerFloat(font, "nominalWidthX", "postscriptNominalWidthX") self.writeIntegerFloat(font, "underlineThickness", "postscriptUnderlineThickness") self.writeIntegerFloat(font, "underlinePosition", "postscriptUnderlinePosition") self.writeIntegerFloat(font, "slantAngle", "postscriptSlantAngle") self.writeBoolean(font, "forceBold", "postscriptForceBold") self.writeBoolean(font, "isFixedPitch", "postscriptIsFixedPitch") self.writeString(font, "defaultCharacter", "postscriptDefaultCharacter") windowsCharacterSet = self.windowsCharacterSetDrop.currentIndex() if windowsCharacterSet == 0: font.info.postscriptWindowsCharacterSet = None else: font.info.postscriptWindowsCharacterSet = windowsCharacterSet
class ScrapperGui(QMainWindow): left = 100 top = 100 width = 1040 height = 720 argsWidget = None def __init__(self, reactor): super().__init__() self.setFont(QFont("Calibri", 10)) self.setWindowTitle("Movie Scrapper") import configparser self.config = configparser.ConfigParser() self.config.read('scrapper.ini') self.initConfig() self.setCentralWidget(CentralWidget(self.config)) self.createToolbar() self.createMenu() self.setGeometry(self.left, self.top, self.width, self.height) self.reactor = reactor def initConfig(self): if not self.config.has_section('Scrapper'): self.config.add_section('Scrapper') if not self.config.has_section('FolderView'): self.config.add_section('FolderView') self.scrapperConf = self.config['Scrapper'] def closeEvent(self, event): QApplication.instance().quit() with open('scrapper.ini', 'w') as configfile: self.config.write(configfile) def selectFolder(self): dialog = QFileDialog() dialog.setFileMode(QFileDialog.DirectoryOnly) #dialog.setSidebarUrls([QUrl.fromLocalFile(place)]) if dialog.exec_() == QDialog.Accepted: directory = dialog.selectedFiles()[0] #print(directory) self.centralWidget().changeDir(directory) def setSite(self, site): #print(site) self.scrapperConf['site'] = site sitesNeededArgs = self.scrapperConf.get('sites_needed_args', []) self.showArgsWidget(site in sitesNeededArgs) def showArgsWidget(self, bShow): aw = self.argsWidget if not aw: aw = ArgsWidget() aw.action = self.scrapToolbar.addWidget(aw) self.argsWidget = aw aw.action.setVisible(bShow) if bShow: aw.reset() def scrap(self): aw = self.argsWidget args = {} if aw.action.isVisible(): args['num_page'] = aw.getNumPages() args['stop_id'] = aw.getStopId() self.centralWidget().scrap(**args) def createToolbar(self): self.toolbar = self.addToolBar('Files') action = QAction(QIcon('res/[email protected]'), 'Up', self) action.triggered.connect(self.centralWidget().upDir) self.toolbar.addAction(action) action = QAction(QIcon('res/[email protected]'), 'Browse', self) action.triggered.connect(self.selectFolder) self.toolbar.addAction(action) action = QAction(QIcon('res/[email protected]'), 'Scrap', self) action.triggered.connect(self.scrap) self.toolbar.addAction(action) action = QAction(QIcon('res/[email protected]'), 'Save', self) action.triggered.connect(self.centralWidget().saveAll) self.toolbar.addAction(action) action = QAction(QIcon('res/[email protected]'), 'Play', self) action.triggered.connect(self.centralWidget().fileView.playFile) self.toolbar.addAction(action) action = QAction(QIcon('res/[email protected]'), 'Switch View', self) action.triggered.connect(self.centralWidget().listView.switchModel) self.toolbar.addAction(action) self.scrapToolbar = self.addToolBar('Scrapper') self.sites = QComboBox(self) site = self.scrapperConf.get('site', 'javlibrary') sites = self.scrapperConf['sites'].split(',') self.sites.insertItems(1, sites) self.sites.setCurrentText(site) self.sites.currentTextChanged.connect(self.setSite) self.scrapToolbar.addWidget(self.sites) self.setSite(site) def createMenu(self): menubar = self.menuBar() filemenu = menubar.addMenu('&File') #filemenu.addToolBar() action = QAction('Rename files', self) action.triggered.connect(self.centralWidget().fileRenameTool) filemenu.addAction(action)
class SessionResearcherManager(SessionManager, Ui_SessionDateManager): def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(SessionResearcherManager, self).__init__(parent) self.setupUi(self) self.setWindowTitle("Session Researcher") self.setToolTip( 'Choose a researcher to fill in by default for the remainder of the session.' ) self.label.setText('Set a default a researcher\nfor the work session.') self.rschrCode = QComboBox() self.rschrCode.setMinimumSize(QSize(164, 32)) self.rschrCode.setMaximumSize(QSize(164, 32)) codeList = sorted(dataIndex.rschrDict.keys()) self.rschrCode.insertItems(0, codeList) self.verticalLayout.insertWidget(0, self.rschrCode) if dataIndex.lastRschr != None: i = self.rschrCode.findText(dataIndex.lastRschr, Qt.MatchExactly) self.rschrCode.setCurrentIndex(i) def getSessionResearcher(self): researcher = self.rschrCode.currentText().split(None, 1)[0] return researcher
class MisSolicitudes(QWidget): def __init__(self, user, servicios): super().__init__() self.user = user self.servicios = servicios self.resize(250, 250) self.move(200, 100) self.setWindowTitle('MIS SOLICITUDES') mainlay = QVBoxLayout() self.solicitudes = QComboBox(self) if len(self.servicios) > 0: opciones = [] for x in self.servicios: opciones.append(x.prestador) self.solicitudes.insertItems(0, opciones) self.solicitudes.setCurrentIndex(0) mainlay.addWidget(self.solicitudes) self.ratelabel = QLabel('Calificacion:') self.rateinput = QComboBox(self) self.rateinput.insertItems(0, [str(x) for x in range(1, 6)]) self.rateinput.setCurrentIndex(0) ratelay = QHBoxLayout() ratelay.addWidget(self.ratelabel) ratelay.addWidget(self.rateinput) mainlay.addLayout(ratelay) self.commentlabel = QLabel('Comentario') self.commentinpupt = QLineEdit(self) commentlay = QHBoxLayout() commentlay.addWidget(self.commentlabel) commentlay.addWidget(self.commentinpupt) mainlay.addLayout(commentlay) self.completarbutton = QPushButton('COMPLETAR') self.cancelbutton = QPushButton('CANCELAR') self.completarbutton.clicked.connect(self.completar) self.cancelbutton.clicked.connect(self.close) mainlay.addWidget(self.completarbutton) mainlay.addWidget(self.cancelbutton) self.setLayout(mainlay) def completar(self): response = buscar.calificar( self.servicios[self.solicitudes.currentIndex()], int(self.rateinput.currentText()), self.commentinpupt.text()) if response: QMessageBox.about(self, 'EXITO', 'Gracias por su\ncalificacion.') self.close() else: QMessageBox.about(self, 'ERROR', 'ERROR')
def __init__(self): super().__init__() layout = QHBoxLayout() layout.addStretch() layout.addWidget(QLabel("Form: ")) cb = QComboBox() cb.insertItems(0, tuple(str(vf) for vf in self.model.valid_forms)) cb.currentTextChanged.connect(self.set_form) layout.addWidget(cb) layout.addStretch() self.layout().insertLayout(0, layout) # put at top of the editor
def insertItems(self, idx, lst): self.minWidth = 0 if isinstance(lst, str): lst = [ lst, ] if not isinstance(lst, list): lst = list(lst) QComboBox.insertItems(self, idx, lst)
def add_row(self): new_row_number = self.table.rowCount() self.table.setRowCount(self.table.rowCount() + 1) for column, key in enumerate(self.ordered_column_keys): value = self.default_row[key] # print(value, type(value)) if isinstance(value, str): item = QTableWidgetItem(value) self.table.setItem(new_row_number, column, item) elif isinstance(value, list): combo_box = QComboBox() combo_box.insertItems(0, value) # combo_box.setCurrentText(value[0]) self.table.setCellWidget(new_row_number, column, combo_box) else: message = 'Table cells are expected to be either Dict (added asQComboBox via setCellWidget) or String (added as QTableWidgetItem). You have type ' + str( type(value)) message += ' at position ' + str(new_row_number) + ', ' + str( column) raise CellObjectException(message)
class SessionSpeakerManager(SessionManager, Ui_SessionDateManager): def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget @type QWidget """ super(SessionSpeakerManager, self).__init__(parent) self.setupUi(self) self.setWindowTitle("Session Speaker") self.setToolTip( 'Choose a speaker to fill in by default for the remainder of the session.' ) self.label.setText('Set a default a speaker\nfor the work session.') self.speakerCode = QComboBox() self.speakerCode.setMinimumSize(QSize(164, 32)) self.speakerCode.setMaximumSize(QSize(164, 32)) codeList = sorted(dataIndex.speakerDict.keys()) for index, item in enumerate(codeList): try: fullName = dataIndex.speakerDict.get(item).findtext('Name') if fullName == 'Unattributed': fullName = 'unattr.' item += ' (' + fullName + ')' except TypeError: item += ' (unattr.)' codeList[index] = item self.speakerCode.insertItems(0, codeList) self.verticalLayout.insertWidget(0, self.speakerCode) if dataIndex.lastSpeaker != None: i = self.speakerCode.findText(dataIndex.lastSpeaker, Qt.MatchStartsWith) self.speakerCode.setCurrentIndex(i) def getSessionSpeaker(self): speaker = self.speakerCode.currentText().split(None, 1)[0] return speaker
class SubCubeControl(QWidget): __LOG: Logger = LogHelper.logger("SubCubeControl") cancel = pyqtSignal() save = pyqtSignal(SaveSubCubeEvent) def __init__(self, files: Dict[str, FileSubCubeParams], parent=None): super().__init__(parent) self.__files = files num_files = len(self.__files) layout = QVBoxLayout() form_layout = QFormLayout() self.__file_list = QComboBox(self) if num_files > 1: self.__file_list.insertItem(0, "Select origin file...") self.__file_list.insertItems(1, self.__files.keys()) else: self.__file_list.insertItems(0, self.__files.keys()) self.__file_list.currentIndexChanged.connect(self.__handle_file_select) form_layout.addRow("Original File:", self.__file_list) self.__file_type = QComboBox(self) self.__format_map = { OpenSpectraHeader.BIL_INTERLEAVE: "BIL - Band Interleaved by Line", OpenSpectraHeader.BSQ_INTERLEAVE: "BSQ - Band Sequential", OpenSpectraHeader.BIP_INTERLEAVE: "BIP - Band Interleaved by Pixel" } self.__file_type.insertItem(0, "") self.__file_type.insertItems(1, self.__format_map.values()) form_layout.addRow("Output File Interleave:", self.__file_type) self.__sample_range = RangeSelector(self) form_layout.addRow("Sample Range:", self.__sample_range) self.__line_range = RangeSelector(self) form_layout.addRow("Line Range:", self.__line_range) self.__band_select = QLineEdit(self) self.__band_select.setMinimumWidth(250) self.__band_validator = QRegExpValidator( QRegExp("[1-9][0-9]*((-|,)([1-9][0-9]*))*")) self.__band_select.setValidator(self.__band_validator) self.__band_select.setToolTip\ ("Use '-' for a range, ',' to separate ranges and single bands.\nExample: 1-10,12,14,19-21") self.__max_band = 0 form_layout.addRow("Bands:", self.__band_select) layout.addLayout(form_layout) button_layout = QHBoxLayout() cancel_button = QPushButton("Cancel", self) cancel_button.clicked.connect(self.cancel) button_layout.addWidget(cancel_button) self.__save_button = QPushButton("Save", self) self.__save_button.setDisabled(True) self.__save_button.clicked.connect(self.__handle_save) button_layout.addWidget(self.__save_button) layout.addLayout(button_layout) self.setLayout(layout) self.__handle_file_select(0) @pyqtSlot(int) def __handle_file_select(self, index: int): if index == 0 and len(self.__files) > 1: self.__save_button.setDisabled(True) self.__line_range.clear() self.__sample_range.clear() self.__max_band = 0 self.__band_select.clear() self.__file_type.setCurrentIndex(0) else: selected_file_name = self.__file_list.currentText() params: FileSubCubeParams = self.__files[selected_file_name] self.__line_range.set_range(1, params.lines()) self.__sample_range.set_range(1, params.samples()) self.__max_band = params.bands() self.__band_select.setText("1-" + str(self.__max_band)) self.__file_type.setCurrentText( self.__format_map[params.file_format()]) self.__save_button.setDisabled(False) @pyqtSlot() def __handle_save(self): source_file_name = self.__file_list.currentText() file_type = self.__file_type.currentText()[0:3].lower() # Convert to zero based indexing using slice range rules lines = self.__line_range.from_value() - 1, self.__line_range.to_value( ) samples = self.__sample_range.from_value( ) - 1, self.__sample_range.to_value() bands_str = self.__band_select.text() SubCubeControl.__LOG.debug( "save button clicked, source file: {0}, type: {1}, lines: {2}, samples: {3}, bands: {4}" .format(source_file_name, file_type, lines, samples, bands_str)) # validate bands args and build the parameter bands = self.__get_band_list(bands_str) SubCubeControl.__LOG.debug("get_band_list returned: {0}".format(bands)) if bands is not None: cube_params = CubeParams(file_type, lines, samples, bands) self.save.emit(SaveSubCubeEvent(source_file_name, cube_params)) def __get_band_list(self, bands: str) -> Union[Tuple[int, int], List[int]]: bands_str = bands validate_result = self.__band_validator.validate(bands_str, 0) if validate_result[0] == QValidator.Invalid: self.__show_error( "Cannot validate band list argument of {0}".format( self.__band_select.text())) return None elif validate_result[0] == QValidator.Intermediate: if str.endswith(bands_str, (",", "-")): bands_str = bands_str[:len(bands_str) - 1] SubCubeControl.__LOG.debug( "attempted to fix band str and got: {0}".format(bands_str)) validate_result = self.__band_validator.validate(bands_str, 0) if validate_result[0] != QValidator.Acceptable: self.__show_error( "Cannot validate band list argument of {0}".format( self.__band_select.text())) return None # collect up the ranges and single bands ranges: List[Tuple[int, int]] = list() single_bands: List[int] = list() # this should produce a list of ranges, 1-5, and individual values # we also convert indexes from 1 based to 0 here # thanks to the validator we should not be getting 0 or negative values so no need to check # validate against self.__max_bands band_range_strs = str.split(bands_str, ",") for band_range in band_range_strs: range_parts = str.split(band_range, "-") if len(range_parts) == 2: # make sure tuple ranges have the lesser value first # it will make things a bit more simple below r1 = int(range_parts[0]) - 1 r2 = int(range_parts[1]) if r1 > self.__max_band: self.__show_error( "Band range value cannot exceed {0}, received range with one end {1}" .format(self.__max_band, range_parts[0])) if r2 > self.__max_band: self.__show_error( "Band range value cannot exceed {0}, received range with one end {1}" .format(self.__max_band, range_parts[1])) if r1 < r2: ranges.append((r1, r2)) elif r2 < r1: ranges.append((r2, r1)) else: # they were equal single_bands.append(r1) elif len(range_parts) == 1: b = int(range_parts[0]) if b >= self.__max_band: self.__show_error( "Band value cannot exceed {0}, received single band index of {1}" .format(self.__max_band, range_parts[0])) single_bands.append(b) else: self.__show_error( "Cannot validate band list argument of {0}".format( self.__band_select.text())) return None # check to see if we just have a single range or band range_cnt = len(ranges) singles_cnt = len(single_bands) if range_cnt == 1 and singles_cnt == 0: return ranges[0] if range_cnt == 0 and singles_cnt == 1: return single_bands # otherwise consolidate the lists to a minimum set of ranges and single bands # reducing it to a tuple if possible # first generate a list of containing all the ranges range_list_list = [list(range(r[0], r[1])) for r in ranges] # SubCubeControl.__LOG.debug("range_list_list: {0}".format(range_list_list)) band_list = list(chain.from_iterable(range_list_list)) # SubCubeControl.__LOG.debug("band_list: {0}".format(band_list)) band_list.extend(single_bands) # SubCubeControl.__LOG.debug("full band_list: {0}".format(band_list)) # now we have all the bands specified by both ranges and single bands # so now create a set from the list to eliminate duplicates band_set = set(band_list) sorted_band_list = sorted(band_set) # SubCubeControl.__LOG.debug("sorted band_set: {0}".format(sorted_band_list)) # now see if it's contiguous and can be returned as a tuple is_contiguous = True last_index = -1 for band_index in sorted_band_list: if last_index == -1: last_index = band_index elif band_index != last_index + 1: is_contiguous = False break else: last_index = band_index if is_contiguous: # then return the bounds as a tuple return sorted_band_list[0], sorted_band_list[len(sorted_band_list) - 1] else: return sorted_band_list def __show_error(self, message: str): dialog = QMessageBox(self) dialog.setIcon(QMessageBox.Critical) dialog.setText(message) dialog.addButton(QMessageBox.Ok) dialog.exec()
class BruteWidget(QWidget): def __initold__(self, ip, port, service, hydraServices, hydraNoUsernameServices, hydraNoPasswordServices, bruteSettings, generalSettings, parent=None): QWidget.__init__(self, parent) self.ip = ip self.port = port self.service = service self.hydraServices = hydraServices self.hydraNoUsernameServices = hydraNoUsernameServices self.hydraNoPasswordServices = hydraNoPasswordServices self.bruteSettings = bruteSettings self.generalSettings = generalSettings self.pid = -1 # will store hydra's pid so we can kill it self.setupLayout() self.browseUsersButton.clicked.connect(lambda: self.wordlistDialog()) self.browsePasswordsButton.clicked.connect( lambda: self.wordlistDialog('Choose password list')) self.usersTextinput.textEdited.connect(self.singleUserRadio.toggle) self.passwordsTextinput.textEdited.connect(self.singlePassRadio.toggle) self.userlistTextinput.textEdited.connect(self.userListRadio.toggle) self.passlistTextinput.textEdited.connect(self.passListRadio.toggle) self.checkAddMoreOptions.stateChanged.connect(self.showMoreOptions) def __init__(self, ip, port, service, settings, parent=None): QWidget.__init__(self, parent) self.ip = ip self.port = port self.service = service # self.hydraServices = hydraServices # self.hydraNoUsernameServices = hydraNoUsernameServices # self.hydraNoPasswordServices = hydraNoPasswordServices # self.bruteSettings = bruteSettings # self.generalSettings = generalSettings self.settings = settings self.pid = -1 # will store hydra's pid so we can kill it self.setupLayout() self.browseUsersButton.clicked.connect(lambda: self.wordlistDialog()) self.browsePasswordsButton.clicked.connect( lambda: self.wordlistDialog('Choose password list')) self.usersTextinput.textEdited.connect(self.singleUserRadio.toggle) self.passwordsTextinput.textEdited.connect(self.singlePassRadio.toggle) self.userlistTextinput.textEdited.connect(self.userListRadio.toggle) self.passlistTextinput.textEdited.connect(self.passListRadio.toggle) self.checkAddMoreOptions.stateChanged.connect(self.showMoreOptions) def setupLayout(self): # sometimes nmap service name is different from hydra service name if self.service is None: self.service = '' elif self.service == "login": self.service = "rlogin" elif self.service == "ms-sql-s": self.service = "mssql" elif self.service == "ms-wbt-server": self.service = "rdp" elif self.service == "netbios-ssn" or self.service == "netbios-ns" or self.service == "microsoft-ds": self.service = "smb" elif self.service == "postgresql": self.service = "postgres" elif self.service == "vmware-auth": self.service = "vmauthd" self.label1 = QLabel() self.label1.setText('IP') #self.label1.setFixedWidth(10) # experimental #self.label1.setAlignment(Qt.AlignLeft) self.ipTextinput = QLineEdit() self.ipTextinput.setText(str(self.ip)) self.ipTextinput.setFixedWidth(125) self.label2 = QLabel() self.label2.setText('Port') #self.label2.setFixedWidth(10) # experimental #self.label2.setAlignment(Qt.AlignLeft) self.portTextinput = QLineEdit() self.portTextinput.setText(str(self.port)) self.portTextinput.setFixedWidth(60) self.label3 = QLabel() self.label3.setText('Service') #self.label3.setFixedWidth(10) # experimental #self.label3.setAlignment(Qt.AlignLeft) self.serviceComboBox = QComboBox() self.serviceComboBox.insertItems( 0, self.settings.brute_services.split(",")) self.serviceComboBox.setStyleSheet("QComboBox { combobox-popup: 0; }") # autoselect service from combo box for i in range(len(self.settings.brute_services.split(","))): if str(self.service) in self.settings.brute_services.split(",")[i]: self.serviceComboBox.setCurrentIndex(i) break # self.labelPath = QLineEdit() # this is the extra input field to insert the path to brute force # self.labelPath.setFixedWidth(800) # self.labelPath.setText('/') self.runButton = QPushButton('Run') self.runButton.setMaximumSize(110, 30) self.runButton.setDefault(True) # new ### self.validationLabel = QLabel(self) self.validationLabel.setText('Invalid input. Please try again!') self.validationLabel.setStyleSheet('QLabel { color: red }') ### self.hlayout = QHBoxLayout() self.hlayout.addWidget(self.label1) self.hlayout.addWidget(self.ipTextinput) self.hlayout.addWidget(self.label2) self.hlayout.addWidget(self.portTextinput) self.hlayout.addWidget(self.label3) self.hlayout.addWidget(self.serviceComboBox) self.hlayout.addWidget(self.runButton) ### self.hlayout.addWidget(self.validationLabel) self.validationLabel.hide() ### self.hlayout.addStretch() self.singleUserRadio = QRadioButton() self.label4 = QLabel() self.label4.setText('Username') self.label4.setFixedWidth(70) self.usersTextinput = QLineEdit() self.usersTextinput.setFixedWidth(125) self.usersTextinput.setText(self.settings.brute_default_username) self.userListRadio = QRadioButton() self.label5 = QLabel() self.label5.setText('Username list') self.label5.setFixedWidth(90) self.userlistTextinput = QLineEdit() self.userlistTextinput.setFixedWidth(125) self.browseUsersButton = QPushButton('Browse') self.browseUsersButton.setMaximumSize(80, 30) self.foundUsersRadio = QRadioButton() self.label9 = QLabel() self.label9.setText('Found usernames') self.label9.setFixedWidth(117) self.userGroup = QButtonGroup() self.userGroup.addButton(self.singleUserRadio) self.userGroup.addButton(self.userListRadio) self.userGroup.addButton(self.foundUsersRadio) self.foundUsersRadio.toggle() self.hlayout2 = QHBoxLayout() self.hlayout2.addWidget(self.singleUserRadio) self.hlayout2.addWidget(self.label4) self.hlayout2.addWidget(self.usersTextinput) self.hlayout2.addWidget(self.userListRadio) self.hlayout2.addWidget(self.label5) self.hlayout2.addWidget(self.userlistTextinput) self.hlayout2.addWidget(self.browseUsersButton) self.hlayout2.addWidget(self.foundUsersRadio) self.hlayout2.addWidget(self.label9) self.hlayout2.addStretch() #add usernames wordlist self.singlePassRadio = QRadioButton() self.label6 = QLabel() self.label6.setText('Password') self.label6.setFixedWidth(70) self.passwordsTextinput = QLineEdit() self.passwordsTextinput.setFixedWidth(125) self.passwordsTextinput.setText(self.settings.brute_default_password) self.passListRadio = QRadioButton() self.label7 = QLabel() self.label7.setText('Password list') self.label7.setFixedWidth(90) self.passlistTextinput = QLineEdit() self.passlistTextinput.setFixedWidth(125) self.browsePasswordsButton = QPushButton('Browse') self.browsePasswordsButton.setMaximumSize(80, 30) self.foundPasswordsRadio = QRadioButton() self.label10 = QLabel() self.label10.setText('Found passwords') self.label10.setFixedWidth(115) self.passGroup = QButtonGroup() self.passGroup.addButton(self.singlePassRadio) self.passGroup.addButton(self.passListRadio) self.passGroup.addButton(self.foundPasswordsRadio) self.foundPasswordsRadio.toggle() self.label8 = QLabel() self.label8.setText('Threads') self.label8.setFixedWidth(60) self.threadOptions = [] for i in range(1, 129): self.threadOptions.append(str(i)) self.threadsComboBox = QComboBox() self.threadsComboBox.insertItems(0, self.threadOptions) self.threadsComboBox.setMinimumContentsLength(3) self.threadsComboBox.setMaxVisibleItems(3) self.threadsComboBox.setStyleSheet("QComboBox { combobox-popup: 0; }") self.threadsComboBox.setCurrentIndex(15) self.hlayout3 = QHBoxLayout() self.hlayout3.addWidget(self.singlePassRadio) self.hlayout3.addWidget(self.label6) self.hlayout3.addWidget(self.passwordsTextinput) self.hlayout3.addWidget(self.passListRadio) self.hlayout3.addWidget(self.label7) self.hlayout3.addWidget(self.passlistTextinput) self.hlayout3.addWidget(self.browsePasswordsButton) self.hlayout3.addWidget(self.foundPasswordsRadio) self.hlayout3.addWidget(self.label10) self.hlayout3.addStretch() self.hlayout3.addWidget(self.label8) self.hlayout3.addWidget(self.threadsComboBox) #self.hlayout3.addStretch() #label6.setText('Try blank password') self.checkBlankPass = QCheckBox() self.checkBlankPass.setText('Try blank password') self.checkBlankPass.toggle() #add 'try blank password' #label7.setText('Try login as password') self.checkLoginAsPass = QCheckBox() self.checkLoginAsPass.setText('Try login as password') self.checkLoginAsPass.toggle() #add 'try login as password' #label8.setText('Loop around users') self.checkLoopUsers = QCheckBox() self.checkLoopUsers.setText('Loop around users') self.checkLoopUsers.toggle() #add 'loop around users' #label9.setText('Exit on first valid') self.checkExitOnValid = QCheckBox() self.checkExitOnValid.setText('Exit on first valid') self.checkExitOnValid.toggle() #add 'exit after first valid combination is found' self.checkVerbose = QCheckBox() self.checkVerbose.setText('Verbose') self.checkAddMoreOptions = QCheckBox() self.checkAddMoreOptions.setText('Additional Options') ### self.labelPath = QLineEdit( ) # this is the extra input field to insert the path to brute force self.labelPath.setFixedWidth(800) self.labelPath.setText('/') ### self.hlayout4 = QHBoxLayout() self.hlayout4.addWidget(self.checkBlankPass) self.hlayout4.addWidget(self.checkLoginAsPass) self.hlayout4.addWidget(self.checkLoopUsers) self.hlayout4.addWidget(self.checkExitOnValid) self.hlayout4.addWidget(self.checkVerbose) self.hlayout4.addWidget(self.checkAddMoreOptions) self.hlayout4.addStretch() self.layoutAddOptions = QHBoxLayout() self.layoutAddOptions.addWidget(self.labelPath) self.labelPath.hide() self.layoutAddOptions.addStretch() self.display = QPlainTextEdit() self.display.setReadOnly(True) if self.settings.general_tool_output_black_background == 'True': #self.display.setStyleSheet("background: rgb(0,0,0)") # black background #self.display.setTextColor(QtGui.QColor('white')) # white font p = self.display.palette() p.setColor(QPalette.Base, Qt.black) # black background p.setColor(QPalette.Text, Qt.white) # white font self.display.setPalette(p) self.display.setStyleSheet( "QMenu { color:black;}" ) #font-size:18px; width: 150px; color:red; left: 20px;}"); # set the menu font color: black self.vlayout = QVBoxLayout() self.vlayout.addLayout(self.hlayout) self.vlayout.addLayout(self.hlayout4) self.vlayout.addLayout(self.layoutAddOptions) self.vlayout.addLayout(self.hlayout2) self.vlayout.addLayout(self.hlayout3) self.vlayout.addWidget(self.display) self.setLayout(self.vlayout) # TODO: need to check all the methods that need an additional input field and add them here # def showMoreOptions(self, text): # if str(text) == "http-head": # self.labelPath.show() # else: # self.labelPath.hide() def showMoreOptions(self): if self.checkAddMoreOptions.isChecked(): self.labelPath.show() else: self.labelPath.hide() def wordlistDialog(self, title='Choose username list'): if title == 'Choose username list': filename = QFileDialog.getOpenFileName( self, title, self.settings.brute_username_wordlist_path) self.userlistTextinput.setText(str(filename[0])) self.userListRadio.toggle() else: filename = QFileDialog.getOpenFileName( self, title, self.settings.brute_password_wordlist_path) self.passlistTextinput.setText(str(filename[0])) self.passListRadio.toggle() def buildHydraCommand(self, runningfolder, userlistPath, passlistPath): self.ip = self.ipTextinput.text() self.port = self.portTextinput.text() self.service = str(self.serviceComboBox.currentText()) self.command = "hydra " + self.ip + " -s " + self.port + " -o " self.outputfile = runningfolder + "/hydra/" + getTimestamp( ) + "-" + self.ip + "-" + self.port + "-" + self.service + ".txt" self.command += "\"" + self.outputfile + "\"" # deal with paths with spaces #self.service = str(self.serviceComboBox.currentText()) #if not self.service == "snmp": # no username required for snmp if not self.service in self.settings.brute_no_username_services.split( ","): if self.singleUserRadio.isChecked(): self.command += " -l " + self.usersTextinput.text() elif self.foundUsersRadio.isChecked(): self.command += " -L \"" + userlistPath + "\"" else: self.command += " -L \"" + self.userlistTextinput.text() + "\"" #if not self.service == "smtp-enum": # no password required for smtp-enum if not self.service in self.settings.brute_no_password_services.split( ","): if self.singlePassRadio.isChecked(): escaped_password = self.passwordsTextinput.text().replace( '"', '\"\"\"') #.replace("'", "\'") self.command += " -p \"" + escaped_password + "\"" elif self.foundPasswordsRadio.isChecked(): self.command += " -P \"" + passlistPath + "\"" else: self.command += " -P \"" + self.passlistTextinput.text() + "\"" if self.checkBlankPass.isChecked(): self.command += " -e n" if self.checkLoginAsPass.isChecked(): self.command += "s" elif self.checkLoginAsPass.isChecked(): self.command += " -e s" if self.checkLoopUsers.isChecked(): self.command += " -u" if self.checkExitOnValid.isChecked(): self.command += " -f" if self.checkVerbose.isChecked(): self.command += " -V" self.command += " -t " + str(self.threadsComboBox.currentText()) self.command += " " + self.service # if self.labelPath.isVisible(): # append the additional field's content, if it was visible if self.checkAddMoreOptions.isChecked(): self.command += " " + str( self.labelPath.text()) # TODO: sanitise this? #command = "echo "+escaped_password+" > /tmp/hydra-sub.txt" #os.system(str(command)) return self.command def getPort(self): return self.port def toggleRunButton(self): if self.runButton.text() == 'Run': self.runButton.setText('Stop') else: self.runButton.setText('Run') def resetDisplay( self ): # used to be able to display the tool output in both the Brute tab and the tool display panel self.display.setParent(None) self.display = QPlainTextEdit() self.display.setReadOnly(True) if self.settings.general_tool_output_black_background == 'True': #self.display.setStyleSheet("background: rgb(0,0,0)") # black background #self.display.setTextColor(QtGui.QColor('white')) # white font p = self.display.palette() p.setColor(QPalette.Base, Qt.black) # black background p.setColor(QPalette.Text, Qt.white) # white font self.display.setPalette(p) self.display.setStyleSheet( "QMenu { color:black;}" ) #font-size:18px; width: 150px; color:red; left: 20px;}"); # set the menu font color: black self.vlayout.addWidget(self.display)
class MetricsTab(QWidget): name = "Metrics" def __init__(self, font, parent=None): super(MetricsTab, self).__init__(parent) mainLayout = QGridLayout() styleMapFamilyLabel = QLabel("Style map family name:", self) self.styleMapFamilyEdit = QLineEdit(font.info.styleMapFamilyName, self) styleMapStyleLabel = QLabel("Style map style name:", self) self.styleMapStyleDrop = QComboBox(self) items = ["None", "Regular", "Italic", "Bold", "Bold Italic"] self.styleMapStyleDrop.insertItems(0, items) sn = font.info.styleMapStyleName if sn == "regular": self.styleMapStyleDrop.setCurrentIndex(1) elif sn == "regular italic": self.styleMapStyleDrop.setCurrentIndex(2) elif sn == "bold": self.styleMapStyleDrop.setCurrentIndex(3) elif sn == "bold italic": self.styleMapStyleDrop.setCurrentIndex(4) else: self.styleMapStyleDrop.setCurrentIndex(0) mainLayout.addWidget(styleMapFamilyLabel, 0, 0) mainLayout.addWidget(self.styleMapFamilyEdit, 0, 1, 1, 3) mainLayout.addWidget(styleMapStyleLabel, 0, 4) mainLayout.addWidget(self.styleMapStyleDrop, 0, 5) unitsPerEmLabel = QLabel("Units per em:", self) unitsPerEm = str( font.info.unitsPerEm) if font.info.unitsPerEm is not None else '' self.unitsPerEmEdit = QLineEdit(unitsPerEm, self) validator = QIntValidator(self) validator.setBottom(0) self.unitsPerEmEdit.setValidator(validator) ascenderLabel = QLabel("Ascender:", self) ascender = str( font.info.ascender) if font.info.ascender is not None else '' self.ascenderEdit = QLineEdit(ascender, self) self.ascenderEdit.setValidator(QIntValidator(self)) capHeightLabel = QLabel("Cap height:", self) capHeight = str( font.info.capHeight) if font.info.capHeight is not None else '' self.capHeightEdit = QLineEdit(capHeight, self) self.capHeightEdit.setValidator(QIntValidator(self)) mainLayout.addWidget(unitsPerEmLabel, 1, 0) mainLayout.addWidget(self.unitsPerEmEdit, 1, 1) mainLayout.addWidget(ascenderLabel, 1, 2) mainLayout.addWidget(self.ascenderEdit, 1, 3) mainLayout.addWidget(capHeightLabel, 1, 4) mainLayout.addWidget(self.capHeightEdit, 1, 5) italicAngleLabel = QLabel("Italic angle:", self) italicAngle = str( font.info.italicAngle) if font.info.italicAngle is not None else '' self.italicAngleEdit = QLineEdit(italicAngle, self) self.italicAngleEdit.setValidator(QDoubleValidator(self)) descenderLabel = QLabel("Descender:", self) descender = str( font.info.descender) if font.info.descender is not None else '' self.descenderEdit = QLineEdit(descender, self) self.descenderEdit.setValidator(QIntValidator(self)) xHeightLabel = QLabel("x-height:", self) xHeight = str( font.info.xHeight) if font.info.xHeight is not None else '' self.xHeightEdit = QLineEdit(xHeight, self) self.xHeightEdit.setValidator(QIntValidator(self)) mainLayout.addWidget(italicAngleLabel, 2, 0) mainLayout.addWidget(self.italicAngleEdit, 2, 1) mainLayout.addWidget(descenderLabel, 2, 2) mainLayout.addWidget(self.descenderEdit, 2, 3) mainLayout.addWidget(xHeightLabel, 2, 4) mainLayout.addWidget(self.xHeightEdit, 2, 5) noteLabel = QLabel("Note:", self) self.noteEdit = QPlainTextEdit(font.info.note, self) mainLayout.addWidget(noteLabel, 3, 0) mainLayout.addWidget(self.noteEdit, 3, 1, 1, 5) self.setLayout(mainLayout) def writeValues(self, font): styleMapFamilyName = self.styleMapFamilyEdit.text() if styleMapFamilyName != '': font.info.styleMapFamilyName = styleMapFamilyName else: font.info.styleMapFamilyName = None sn = self.styleMapStyleDrop.currentIndex() if sn == 1: font.info.styleMapStyleName = "regular" elif sn == 2: font.info.styleMapStyleName = "italic" elif sn == 3: font.info.styleMapStyleName = "bold" elif sn == 4: font.info.styleMapStyleName = "bold italic" else: font.info.styleMapStyleName = None unitsPerEm = self.unitsPerEmEdit.text() if "." in unitsPerEm: font.info.unitsPerEm = float(unitsPerEm) elif unitsPerEm: font.info.unitsPerEm = int(unitsPerEm) else: font.info.unitsPerEm = None italicAngle = self.italicAngleEdit.text() if "." in italicAngle: font.info.italicAngle = float(italicAngle) elif italicAngle: font.info.italicAngle = int(italicAngle) else: font.info.italicAngle = None ascender = self.ascenderEdit.text() if "." in ascender: font.info.ascender = float(ascender) elif ascender: font.info.ascender = int(ascender) else: font.info.ascender = None descender = self.descenderEdit.text() if "." in descender: font.info.descender = float(descender) elif descender: font.info.descender = int(descender) else: font.info.descender = None capHeight = self.capHeightEdit.text() if "." in capHeight: font.info.capHeight = float(capHeight) elif capHeight: font.info.capHeight = int(capHeight) else: font.info.capHeight = None xHeight = self.xHeightEdit.text() if "." in xHeight: font.info.xHeight = float(xHeight) elif xHeight: font.info.xHeight = int(xHeight) else: font.info.xHeight = None note = self.noteEdit.toPlainText() if note != '': font.info.note = note else: font.info.note = None
class OS2Tab(TabWidget): def __init__(self, font, parent=None): super().__init__(parent) self.name = self.tr("OS/2") # OS2Group = QGroupBox("OS/2 table", self) # OS2Group.setFlat(True) OS2Layout = QGridLayout(self) usWidthClassLabel = RLabel(self.tr("usWidthClass:"), self) self.usWidthClassDrop = QComboBox(self) items = [ self.tr("None"), self.tr("Ultra-condensed"), self.tr("Extra-condensed"), self.tr("Condensed"), self.tr("Semi-Condensed"), self.tr("Medium (normal)"), self.tr("Semi-expanded"), self.tr("Expanded"), self.tr("Extra-expanded"), self.tr("Ultra-expanded") ] self.usWidthClassDrop.insertItems(0, items) if font.info.openTypeOS2WidthClass is not None: self.usWidthClassDrop.setCurrentIndex( font.info.openTypeOS2WidthClass) fsSelectionLabel = RLabel(self.tr("fsSelection:"), self) fsSelection = font.info.openTypeOS2Selection self.fsSelectionList = QListView(self) items = [ "1 UNDERSCORE", "2 NEGATIVE", "3 OUTLINED", "4 STRIKEOUT", "7 USE_TYPO_METRICS", "8 WWS", "9 OBLIQUE" ] # http://stackoverflow.com/a/26613163 model = QStandardItemModel(7, 1) for index, elem in enumerate(items): item = QStandardItem() item.setText(elem) item.setCheckable(True) bit = index + 1 if fsSelection is not None and bit in fsSelection: # maybe default setting? if so, unneeded item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) model.setItem(index, item) self.fsSelectionList.setModel(model) achVendorIDLabel = RLabel(self.tr("achVendorID:"), self) self.achVendorIDEdit = QLineEdit(font.info.openTypeOS2VendorID, self) self.achVendorIDEdit.setMaxLength(4) fsTypeLabel = RLabel(self.tr("fsType:"), self) fsType = font.info.openTypeOS2Type self.fsTypeDrop = QComboBox(self) items = [ self.tr("No embedding restrictions"), self.tr("Restricted embedding"), self.tr("Preview and print embedding allowed"), self.tr("Editable embedding allowed") ] self.allowSubsettingBox = QCheckBox(self.tr("Allow subsetting"), self) self.allowBitmapEmbeddingBox = QCheckBox( self.tr("Allow only bitmap embedding"), self) self.fsTypeDrop.currentIndexChanged[int].connect( self._updateFsTypeVisibility) self.fsTypeDrop.insertItems(0, items) if fsType is not None: for i in range(1, 4): if i in fsType: self.fsTypeDrop.setCurrentIndex(i) break self.allowSubsettingBox.setChecked(8 not in fsType) self.allowBitmapEmbeddingBox.setChecked(9 in fsType) # XXX: ulUnicodeRange # XXX: ulCodePageRange sTypoAscenderLabel = RLabel(self.tr("sTypoAscender:"), self) sTypoDescenderLabel = RLabel(self.tr("sTypoDescender:"), self) sTypoLineGapLabel = RLabel(self.tr("sTypoLineGap:"), self) usWeightClassLabel = RLabel(self.tr("usWeightClass:"), self) usWinAscentLabel = RLabel(self.tr("usWinAscent:"), self) usWinDescentLabel = RLabel(self.tr("usWinDescent:"), self) ySubscriptXSizeLabel = RLabel(self.tr("ySubscriptXSize:"), self) ySubscriptYSizeLabel = RLabel(self.tr("ySubscriptYSize:"), self) ySubscriptXOffsetLabel = RLabel(self.tr("ySubscriptXOffset:"), self) ySubscriptYOffsetLabel = RLabel(self.tr("ySubscriptYOffset:"), self) ySuperscriptXSizeLabel = RLabel(self.tr("ySuperscriptXSize:"), self) ySuperscriptYSizeLabel = RLabel(self.tr("ySuperscriptYSize:"), self) ySuperscriptXOffsetLabel = RLabel(self.tr("ySuperscriptXOffset:"), self) ySuperscriptYOffsetLabel = RLabel(self.tr("ySuperscriptYOffset:"), self) yStrikeoutSizeLabel = RLabel(self.tr("yStrikeoutSize:"), self) yStrikeoutPositionLabel = RLabel(self.tr("yStrikeoutPosition:"), self) self.loadPositiveInteger(font, "openTypeOS2WeightClass", "usWeightClass") self.loadInteger(font, "openTypeOS2TypoAscender", "sTypoAscender") self.loadInteger(font, "openTypeOS2TypoDescender", "sTypoDescender") self.loadInteger(font, "openTypeOS2TypoLineGap", "sTypoLineGap") self.loadPositiveInteger(font, "openTypeOS2WinAscent", "usWinAscent") self.loadPositiveInteger(font, "openTypeOS2WinDescent", "usWinDescent") self.loadInteger(font, "openTypeOS2SubscriptXSize", "ySubscriptXSize") self.loadInteger(font, "openTypeOS2SubscriptYSize", "ySubscriptYSize") self.loadInteger(font, "openTypeOS2SubscriptXOffset", "ySubscriptXOffset") self.loadInteger(font, "openTypeOS2SubscriptYOffset", "ySubscriptYOffset") self.loadInteger(font, "openTypeOS2SuperscriptXSize", "ySuperscriptXSize") self.loadInteger(font, "openTypeOS2SuperscriptYSize", "ySuperscriptYSize") self.loadInteger(font, "openTypeOS2SuperscriptXOffset", "ySuperscriptXOffset") self.loadInteger(font, "openTypeOS2SuperscriptYOffset", "ySuperscriptYOffset") self.loadInteger(font, "openTypeOS2StrikeoutSize", "yStrikeoutSize") self.loadInteger(font, "openTypeOS2StrikeoutPosition", "yStrikeoutPosition") # XXX: panose l = 0 OS2Layout.addWidget(usWidthClassLabel, l, 0) OS2Layout.addWidget(self.usWidthClassDrop, l, 1, 1, 2) OS2Layout.addWidget(achVendorIDLabel, l, 3) OS2Layout.addWidget(self.achVendorIDEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(usWeightClassLabel, l, 0) OS2Layout.addWidget(self.usWeightClassEdit, l, 1, 1, 2) l += 1 OS2Layout.addWidget(fsSelectionLabel, l, 0, 3, 1) OS2Layout.addWidget(self.fsSelectionList, l, 1, 3, 2) OS2Layout.addWidget(fsTypeLabel, l, 3, 3, 1) OS2Layout.addWidget(self.fsTypeDrop, l, 4, 1, 2) l += 1 OS2Layout.addWidget(self.allowSubsettingBox, l, 4, 1, 2) l += 1 OS2Layout.addWidget(self.allowBitmapEmbeddingBox, l, 4, 1, 2) l += 1 OS2Layout.addWidget(sTypoAscenderLabel, l, 0) OS2Layout.addWidget(self.sTypoAscenderEdit, l, 1, 1, 2) OS2Layout.addWidget(usWinAscentLabel, l, 3) OS2Layout.addWidget(self.usWinAscentEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(sTypoDescenderLabel, l, 0) OS2Layout.addWidget(self.sTypoDescenderEdit, l, 1, 1, 2) OS2Layout.addWidget(usWinDescentLabel, l, 3) OS2Layout.addWidget(self.usWinDescentEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(sTypoLineGapLabel, l, 0) OS2Layout.addWidget(self.sTypoLineGapEdit, l, 1, 1, 2) l += 1 OS2Layout.addWidget(ySubscriptXSizeLabel, l, 0) OS2Layout.addWidget(self.ySubscriptXSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySubscriptXOffsetLabel, l, 3) OS2Layout.addWidget(self.ySubscriptXOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(ySubscriptYSizeLabel, l, 0) OS2Layout.addWidget(self.ySubscriptYSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySubscriptYOffsetLabel, l, 3) OS2Layout.addWidget(self.ySubscriptYOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(ySuperscriptXSizeLabel, l, 0) OS2Layout.addWidget(self.ySuperscriptXSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySuperscriptXOffsetLabel, l, 3) OS2Layout.addWidget(self.ySuperscriptXOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(ySuperscriptYSizeLabel, l, 0) OS2Layout.addWidget(self.ySuperscriptYSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(ySuperscriptYOffsetLabel, l, 3) OS2Layout.addWidget(self.ySuperscriptYOffsetEdit, l, 4, 1, 2) l += 1 OS2Layout.addWidget(yStrikeoutSizeLabel, l, 0) OS2Layout.addWidget(self.yStrikeoutSizeEdit, l, 1, 1, 2) OS2Layout.addWidget(yStrikeoutPositionLabel, l, 3) OS2Layout.addWidget(self.yStrikeoutPositionEdit, l, 4, 1, 2) # OS2Group.setLayout(OS2Layout) self.setLayout(OS2Layout) def _updateFsTypeVisibility(self, index): if index == 0: # TODO: maybe uncheck as well? self.allowSubsettingBox.setEnabled(False) self.allowBitmapEmbeddingBox.setEnabled(False) else: self.allowSubsettingBox.setEnabled(True) self.allowBitmapEmbeddingBox.setEnabled(True) def writeValues(self, font): self.writePositiveInteger(font, "usWeightClass", "openTypeOS2WeightClass") self.writeInteger(font, "sTypoAscender", "openTypeOS2TypoAscender") self.writeInteger(font, "sTypoDescender", "openTypeOS2TypoDescender") self.writeInteger(font, "sTypoLineGap", "openTypeOS2TypoLineGap") self.writePositiveInteger(font, "usWinAscent", "openTypeOS2WinAscent") self.writePositiveInteger(font, "usWinDescent", "openTypeOS2WinDescent") self.writeInteger(font, "ySubscriptXSize", "openTypeOS2SubscriptXSize") self.writeInteger(font, "ySubscriptYSize", "openTypeOS2SubscriptYSize") self.writeInteger(font, "ySubscriptXOffset", "openTypeOS2SubscriptXOffset") self.writeInteger(font, "ySubscriptYOffset", "openTypeOS2SubscriptYOffset") self.writeInteger(font, "ySuperscriptXSize", "openTypeOS2SuperscriptXSize") self.writeInteger(font, "ySuperscriptYSize", "openTypeOS2SuperscriptYSize") self.writeInteger(font, "ySuperscriptXOffset", "openTypeOS2SuperscriptXOffset") self.writeInteger(font, "ySuperscriptYOffset", "openTypeOS2SuperscriptYOffset") self.writeInteger(font, "yStrikeoutSize", "openTypeOS2StrikeoutSize") self.writeInteger(font, "yStrikeoutPosition", "openTypeOS2StrikeoutPosition") fsSelectionModel = self.fsSelectionList.model() fsSelection = [] for i in range(7): item = fsSelectionModel.item(i) if item.checkState() == Qt.Checked: fsSelection.append(i) if len(fsSelection): font.info.openTypeOS2Selection = fsSelection else: # XXX: None or empty array? should distinct those cases font.info.openTypeOS2Selection = None fsTypeIndex = self.fsTypeDrop.currentIndex() fsType = [] if fsTypeIndex > 0: fsType.append(fsTypeIndex) if not self.allowSubsettingBox.isChecked(): fsType.append(8) if self.allowBitmapEmbeddingBox.isChecked(): fsType.append(9) # TODO: provide a way to represent None w this? font.info.openTypeOS2Type = fsType # TODO: see if data needs to be padded to 4 chars. # I think that this is to be deferred to ufo2fdk(?) font.info.openTypeOS2VendorID = self.achVendorIDEdit.text()
class MetricsTab(TabWidget): def __init__(self, font, parent=None): super().__init__(parent) self.name = self.tr("Metrics") mainLayout = QGridLayout() styleMapFamilyLabel = RLabel(self.tr("Style map family name:"), self) self.styleMapFamilyEdit = QLineEdit(font.info.styleMapFamilyName, self) styleMapStyleLabel = RLabel(self.tr("Style map style name:"), self) self.styleMapStyleDrop = QComboBox(self) items = [ self.tr("None"), self.tr("Regular"), self.tr("Italic"), self.tr("Bold"), self.tr("Bold Italic") ] self.styleMapStyleDrop.insertItems(0, items) sn = font.info.styleMapStyleName if sn == "regular": self.styleMapStyleDrop.setCurrentIndex(1) elif sn == "italic": self.styleMapStyleDrop.setCurrentIndex(2) elif sn == "bold": self.styleMapStyleDrop.setCurrentIndex(3) elif sn == "bold italic": self.styleMapStyleDrop.setCurrentIndex(4) else: self.styleMapStyleDrop.setCurrentIndex(0) mainLayout.addWidget(styleMapFamilyLabel, 0, 0) mainLayout.addWidget(self.styleMapFamilyEdit, 0, 1, 1, 3) mainLayout.addWidget(styleMapStyleLabel, 0, 4) mainLayout.addWidget(self.styleMapStyleDrop, 0, 5) unitsPerEmLabel = RLabel(self.tr("Units per em:"), self) ascenderLabel = RLabel(self.tr("Ascender:"), self) capHeightLabel = RLabel(self.tr("Cap height:"), self) italicAngleLabel = RLabel(self.tr("Italic angle:"), self) descenderLabel = RLabel(self.tr("Descender:"), self) xHeightLabel = RLabel(self.tr("x-height:"), self) noteLabel = RLabel(self.tr("Note:"), self) # In the UFO specs these are integer or float, and unitsPerEm is # non-negative integer or float self.loadPositiveIntegerFloat(font, "unitsPerEm", "unitsPerEm") self.loadIntegerFloat(font, "ascender", "ascender") self.loadIntegerFloat(font, "capHeight", "capHeight") self.loadIntegerFloat(font, "italicAngle", "italicAngle") self.loadIntegerFloat(font, "descender", "descender") self.loadIntegerFloat(font, "xHeight", "xHeight") self.loadMultilineString(font, "note", "note") mainLayout.addWidget(unitsPerEmLabel, 1, 0) mainLayout.addWidget(self.unitsPerEmEdit, 1, 1) mainLayout.addWidget(ascenderLabel, 1, 2) mainLayout.addWidget(self.ascenderEdit, 1, 3) mainLayout.addWidget(capHeightLabel, 1, 4) mainLayout.addWidget(self.capHeightEdit, 1, 5) mainLayout.addWidget(italicAngleLabel, 2, 0) mainLayout.addWidget(self.italicAngleEdit, 2, 1) mainLayout.addWidget(descenderLabel, 2, 2) mainLayout.addWidget(self.descenderEdit, 2, 3) mainLayout.addWidget(xHeightLabel, 2, 4) mainLayout.addWidget(self.xHeightEdit, 2, 5) mainLayout.addWidget(noteLabel, 3, 0) mainLayout.addWidget(self.noteEdit, 3, 1, 1, 5) self.setLayout(mainLayout) def writeValues(self, font): styleMapFamilyName = self.styleMapFamilyEdit.text() if styleMapFamilyName != '': font.info.styleMapFamilyName = styleMapFamilyName else: font.info.styleMapFamilyName = None sn = self.styleMapStyleDrop.currentIndex() if sn == 1: font.info.styleMapStyleName = "regular" elif sn == 2: font.info.styleMapStyleName = "italic" elif sn == 3: font.info.styleMapStyleName = "bold" elif sn == 4: font.info.styleMapStyleName = "bold italic" else: font.info.styleMapStyleName = None self.writePositiveIntegerFloat(font, "unitsPerEm", "unitsPerEm") self.writeIntegerFloat(font, "italicAngle", "italicAngle") self.writeIntegerFloat(font, "ascender", "ascender") self.writeIntegerFloat(font, "descender", "descender") self.writeIntegerFloat(font, "capHeight", "capHeight") self.writeIntegerFloat(font, "xHeight", "xHeight") self.writeMultilineString(font, "note", "note")
class PostScriptTab(QWidget): name = "Postscript" def __init__(self, font, parent=None): super(PostScriptTab, self).__init__(parent) namingGroup = QGroupBox("Naming", self) # namingGroup.setFlat(True) namingLayout = QGridLayout(self) fontNameLabel = QLabel("FontName:", self) self.fontNameEdit = QLineEdit(font.info.postscriptFontName, self) fullNameLabel = QLabel("FullName:", self) self.fullNameEdit = QLineEdit(font.info.postscriptFullName, self) weightNameLabel = QLabel("WeightName:", self) self.weightNameEdit = QLineEdit(font.info.postscriptWeightName, self) uniqueIDLabel = QLabel("Unique ID:", self) if font.info.postscriptUniqueID is not None: uniqueID = str(font.info.postscriptUniqueID) else: uniqueID = '' self.uniqueIDEdit = QLineEdit(uniqueID, self) self.uniqueIDEdit.setValidator(QIntValidator(self)) l = 0 namingLayout.addWidget(fontNameLabel, l, 0) namingLayout.addWidget(self.fontNameEdit, l, 1, 1, 2) namingLayout.addWidget(weightNameLabel, l, 3) namingLayout.addWidget(self.weightNameEdit, l, 4, 1, 2) l += 1 namingLayout.addWidget(fullNameLabel, l, 0) namingLayout.addWidget(self.fullNameEdit, l, 1, 1, 2) namingLayout.addWidget(uniqueIDLabel, l, 3) namingLayout.addWidget(self.uniqueIDEdit, l, 4, 1, 2) namingGroup.setLayout(namingLayout) hintingGroup = QGroupBox("Hinting", self) # hintingGroup.setFlat(True) hintingLayout = QGridLayout(self) blueValuesLabel = QLabel("Blue values:", self) blueValues = " ".join(str(val) for val in font.info.postscriptBlueValues) self.blueValuesEdit = QLineEdit(blueValues, self) otherBluesLabel = QLabel("Other blues:", self) otherBlues = " ".join(str(val) for val in font.info.postscriptOtherBlues) self.otherBluesEdit = QLineEdit(otherBlues, self) familyBluesLabel = QLabel("Family blues:", self) familyBlues = " ".join(str(val) for val in font.info.postscriptFamilyBlues) self.familyBluesEdit = QLineEdit(familyBlues, self) familyOtherBluesLabel = QLabel("Family other blues:", self) familyOtherBlues = " ".join( str(val) for val in font.info.postscriptFamilyOtherBlues) self.familyOtherBluesEdit = QLineEdit(familyOtherBlues, self) l = 0 hintingLayout.addWidget(blueValuesLabel, l, 0) hintingLayout.addWidget(self.blueValuesEdit, l, 1, 1, 2) hintingLayout.addWidget(familyBluesLabel, l, 3) hintingLayout.addWidget(self.familyBluesEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(otherBluesLabel, l, 0) hintingLayout.addWidget(self.otherBluesEdit, l, 1, 1, 2) hintingLayout.addWidget(familyOtherBluesLabel, l, 3) hintingLayout.addWidget(self.familyOtherBluesEdit, l, 4, 1, 2) l += 1 blueFuzzLabel = QLabel("Blue fuzz:", self) if font.info.postscriptBlueFuzz is not None: blueFuzz = str(font.info.postscriptBlueFuzz) else: blueFuzz = '' self.blueFuzzEdit = QLineEdit(blueFuzz, self) self.blueFuzzEdit.setValidator(QDoubleValidator(self)) stemSnapHLabel = QLabel("StemSnapH:", self) stemSnapH = " ".join(str(val) for val in font.info.postscriptStemSnapH) self.stemSnapHEdit = QLineEdit(stemSnapH, self) blueScaleLabel = QLabel("Blue scale:", self) if font.info.postscriptBlueScale is not None: blueScale = str(font.info.postscriptBlueScale) else: blueScale = '' self.blueScaleEdit = QLineEdit(blueScale, self) self.blueScaleEdit.setValidator(QDoubleValidator(self)) stemSnapVLabel = QLabel("StemSnapV:", self) stemSnapV = " ".join(str(val) for val in font.info.postscriptStemSnapV) self.stemSnapVEdit = QLineEdit(stemSnapV, self) blueShiftLabel = QLabel("Blue shift:", self) if font.info.postscriptBlueShift is not None: blueShift = str(font.info.postscriptBlueShift) else: blueShift = '' self.blueShiftEdit = QLineEdit(blueShift, self) self.blueShiftEdit.setValidator(QDoubleValidator(self)) forceBoldLabel = QLabel("Force bold:", self) forceBold = font.info.postscriptForceBold self.forceBoldBox = QCheckBox(self) self.forceBoldBox.setTristate() if forceBold is None: self.forceBoldBox.setCheckState(Qt.PartiallyChecked) else: self.forceBoldBox.setChecked(forceBold) hintingLayout.addWidget(blueFuzzLabel, l, 0) hintingLayout.addWidget(self.blueFuzzEdit, l, 1, 1, 2) hintingLayout.addWidget(stemSnapHLabel, l, 3) hintingLayout.addWidget(self.stemSnapHEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(blueScaleLabel, l, 0) hintingLayout.addWidget(self.blueScaleEdit, l, 1, 1, 2) hintingLayout.addWidget(stemSnapVLabel, l, 3) hintingLayout.addWidget(self.stemSnapVEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(blueShiftLabel, l, 0) hintingLayout.addWidget(self.blueShiftEdit, l, 1, 1, 2) hintingLayout.addWidget(forceBoldLabel, l, 3) hintingLayout.addWidget(self.forceBoldBox, l, 4, 1, 2) hintingGroup.setLayout(hintingLayout) metricsGroup = QGroupBox("Metrics", self) # metricsGroup.setFlat(True) metricsLayout = QGridLayout(self) defaultWidthXLabel = QLabel("DefaultWidthX:", self) if font.info.postscriptDefaultWidthX is not None: defaultWidthX = str(font.info.postscriptDefaultWidthX) else: defaultWidthX = '' self.defaultWidthXEdit = QLineEdit(defaultWidthX, self) self.defaultWidthXEdit.setValidator(QDoubleValidator(self)) underlineThicknessLabel = QLabel("UnderlineThickness:", self) if font.info.postscriptUnderlineThickness is not None: underlineThickness = str(font.info.postscriptUnderlineThickness) else: underlineThickness = '' self.underlineThicknessEdit = QLineEdit(underlineThickness, self) self.underlineThicknessEdit.setValidator(QDoubleValidator(self)) nominalWidthXLabel = QLabel("NominalWidthX:", self) if font.info.postscriptNominalWidthX is not None: nominalWidthX = str(font.info.postscriptNominalWidthX) else: nominalWidthX = '' self.nominalWidthXEdit = QLineEdit(nominalWidthX, self) self.nominalWidthXEdit.setValidator(QDoubleValidator(self)) underlinePositionLabel = QLabel("UnderlinePosition:", self) if font.info.postscriptUnderlinePosition is not None: underlinePosition = str(font.info.postscriptUnderlinePosition) else: underlinePosition = '' self.underlinePositionEdit = QLineEdit(underlinePosition, self) self.underlinePositionEdit.setValidator(QDoubleValidator(self)) slantAngleLabel = QLabel("SlantAngle:", self) if font.info.postscriptSlantAngle is not None: slantAngle = str(font.info.postscriptSlantAngle) else: slantAngle = '' self.slantAngleEdit = QLineEdit(slantAngle, self) self.slantAngleEdit.setValidator(QDoubleValidator(self)) isFixedPitchLabel = QLabel("isFixedPitched:", self) isFixedPitch = font.info.postscriptIsFixedPitch self.isFixedPitchBox = QCheckBox(self) self.isFixedPitchBox.setTristate() if isFixedPitch is None: self.isFixedPitchBox.setCheckState(Qt.PartiallyChecked) else: self.isFixedPitchBox.setChecked(isFixedPitch) l = 0 metricsLayout.addWidget(defaultWidthXLabel, l, 0) metricsLayout.addWidget(self.defaultWidthXEdit, l, 1, 1, 2) metricsLayout.addWidget(underlineThicknessLabel, l, 3) metricsLayout.addWidget(self.underlineThicknessEdit, l, 4, 1, 2) l += 1 metricsLayout.addWidget(nominalWidthXLabel, l, 0) metricsLayout.addWidget(self.nominalWidthXEdit, l, 1, 1, 2) metricsLayout.addWidget(underlinePositionLabel, l, 3) metricsLayout.addWidget(self.underlinePositionEdit, l, 4, 1, 2) l += 1 metricsLayout.addWidget(slantAngleLabel, l, 0) metricsLayout.addWidget(self.slantAngleEdit, l, 1, 1, 2) metricsLayout.addWidget(isFixedPitchLabel, l, 3) metricsLayout.addWidget(self.isFixedPitchBox, l, 4, 1, 2) metricsGroup.setLayout(metricsLayout) charactersGroup = QGroupBox("Characters", self) # charactersGroup.setFlat(True) charactersLayout = QGridLayout(self) defaultCharacterLabel = QLabel("Default character:", self) self.defaultCharacterEdit = QLineEdit( font.info.postscriptDefaultCharacter, self) windowsCharacterSetLabel = QLabel("Windows character set:", self) self.windowsCharacterSetDrop = QComboBox(self) items = [ "None", "ANSI", "Default", "Symbol", "Macintosh", "Shift JIS", "Hangul", "Hangul (Johab)", "GB2312", "Chinese BIG5", "Greek", "Turkish", "Vietnamese", "Hebrew", "Arabic", "Baltic", "Bitstream", "Cyrillic", "Thai", "Eastern European", "OEM"] self.windowsCharacterSetDrop.insertItems(0, items) if font.info.postscriptWindowsCharacterSet is not None: self.windowsCharacterSetDrop.setCurrentIndex( font.info.postscriptWindowsCharacterSet) l = 0 charactersLayout.addWidget(defaultCharacterLabel, l, 0) charactersLayout.addWidget(self.defaultCharacterEdit, l, 1, 1, 2) charactersLayout.addWidget(windowsCharacterSetLabel, l, 3) charactersLayout.addWidget(self.windowsCharacterSetDrop, l, 4, 1, 2) charactersGroup.setLayout(charactersLayout) mainLayout = QVBoxLayout() mainLayout.addWidget(namingGroup) mainLayout.addWidget(hintingGroup) mainLayout.addWidget(metricsGroup) mainLayout.addWidget(charactersGroup) self.setLayout(mainLayout) def writeValues(self, font): fontName = self.fontNameEdit.text() if fontName != '': font.info.postscriptFontName = fontName else: font.info.postscriptFontName = None fullName = self.fullNameEdit.text() if fullName != '': font.info.postscriptFullName = fullName else: font.info.postscriptFullName = None weightName = self.weightNameEdit.text() if weightName != '': font.info.postscriptWeightName = weightName else: font.info.postscriptWeightName = None uniqueID = self.uniqueIDEdit.text() if uniqueID != '': font.info.postscriptUniqueID = int(uniqueID) else: font.info.postscriptUniqueID = None blueValues = self.blueValuesEdit.text().split(" ") if blueValues is None: font.info.postscriptBlueValues = None else: blues = [] for blue in blueValues: if blue != '': blues.append(int(blue)) font.info.postscriptBlueValues = blues otherBlues = self.otherBluesEdit.text().split(" ") if otherBlues is None: font.info.postscriptOtherBlues = None else: blues = [] for blue in otherBlues: if blue != '': blues.append(int(blue)) font.info.postscriptOtherBlues = blues familyBlues = self.familyBluesEdit.text().split(" ") if familyBlues is None: font.info.postscriptFamilyBlues = None else: blues = [] for blue in familyBlues: if blue != '': blues.append(int(blue)) font.info.postscriptFamilyBlues = blues familyOtherBlues = self.familyOtherBluesEdit.text().split(" ") if familyOtherBlues is None: font.info.postscriptFamilyOtherBlues = None else: blues = [] for blue in familyOtherBlues: if blue != '': blues.append(int(blue)) font.info.postscriptFamilyOtherBlues = blues blueFuzz = self.blueFuzzEdit.text() if "." in blueFuzz: font.info.postscriptBlueFuzz = float(blueFuzz) elif blueFuzz != '': font.info.postscriptBlueFuzz = int(blueFuzz) else: font.info.postscriptBlueFuzz = None blueScale = self.blueScaleEdit.text() if blueScale != '': font.info.postscriptBlueScale = float(blueScale) else: font.info.postscriptBlueScale = None blueShift = self.blueShiftEdit.text() if "." in blueShift: font.info.postscriptBlueShift = float(blueShift) elif blueShift != '': font.info.postscriptBlueShift = int(blueShift) else: font.info.postscriptBlueShift = None stemSnapH = self.stemSnapHEdit.text().split(" ") if stemSnapH is None: font.info.postscriptStemSnapH = None else: stems = [] for stem in stemSnapH: if stem != '': stems.append(int(stem)) font.info.postscriptStemSnapH = stems stemSnapV = self.stemSnapVEdit.text().split(" ") if stemSnapV is None: font.info.postscriptStemSnapV = None else: stems = [] for stem in stemSnapV: if stem != '': stems.append(int(stem)) font.info.postscriptStemSnapV = stems forceBold = self.forceBoldBox.checkState() if forceBold == Qt.PartiallyChecked: font.info.postscriptForceBold = None else: font.info.postscriptForceBold = bool(forceBold) defaultWidthX = self.defaultWidthXEdit.text() if "." in defaultWidthX: font.info.postscriptDefaultWidthX = float(defaultWidthX) elif defaultWidthX != '': font.info.postscriptDefaultWidthX = int(defaultWidthX) else: font.info.postscriptDefaultWidthX = None nominalWidthX = self.nominalWidthXEdit.text() if "." in nominalWidthX: font.info.postscriptNominalWidthX = float(nominalWidthX) elif nominalWidthX != '': font.info.postscriptNominalWidthX = int(nominalWidthX) else: font.info.postscriptNominalWidthX = None underlineThickness = self.underlineThicknessEdit.text() if "." in underlineThickness: font.info.postscriptUnderlineThickness = float(underlineThickness) elif underlineThickness != '': font.info.postscriptUnderlineThickness = \ int(underlineThickness) else: font.info.postscriptUnderlineThickness = None underlinePosition = self.underlinePositionEdit.text() if "." in underlinePosition: font.info.postscriptUnderlinePosition = float(underlinePosition) elif underlinePosition != '': font.info.postscriptUnderlinePosition = int(underlinePosition) else: font.info.postscriptUnderlinePosition = None slantAngle = self.slantAngleEdit.text() if "." in slantAngle: font.info.postscriptSlantAngle = float(slantAngle) elif slantAngle != '': font.info.postscriptSlantAngle = int(slantAngle) else: font.info.postscriptSlantAngle = None isFixedPitch = self.isFixedPitchBox.checkState() if isFixedPitch == Qt.PartiallyChecked: font.info.postscriptIsFixedPitch = None else: font.info.postscriptIsFixedPitch = bool(isFixedPitch) defaultCharacter = self.defaultCharacterEdit.text() if defaultCharacter != '': font.info.postscriptDefaultCharacter = defaultCharacter else: font.info.postscriptDefaultCharacter = None windowsCharacterSet = self.windowsCharacterSetDrop.currentIndex() if windowsCharacterSet == 0: font.info.postscriptWindowsCharacterSet = None else: font.info.postscriptWindowsCharacterSet = windowsCharacterSet
class PostScriptTab(TabWidget): def __init__(self, font, parent=None): super().__init__(parent, name="PostScript") namingGroup = QGroupBox("Naming", self) # namingGroup.setFlat(True) namingLayout = QGridLayout(self) fontNameLabel = QLabel("FontName:", self) fullNameLabel = QLabel("FullName:", self) weightNameLabel = QLabel("WeightName:", self) uniqueIDLabel = QLabel("Unique ID:", self) self.loadString(font, "postscriptFontName", "fontName") self.loadString(font, "postscriptFullName", "fullName") self.loadString(font, "postscriptWeightName", "weightName") self.loadInteger(font, "postscriptUniqueID", "uniqueID") l = 0 namingLayout.addWidget(fontNameLabel, l, 0) namingLayout.addWidget(self.fontNameEdit, l, 1, 1, 2) namingLayout.addWidget(weightNameLabel, l, 3) namingLayout.addWidget(self.weightNameEdit, l, 4, 1, 2) l += 1 namingLayout.addWidget(fullNameLabel, l, 0) namingLayout.addWidget(self.fullNameEdit, l, 1, 1, 2) namingLayout.addWidget(uniqueIDLabel, l, 3) namingLayout.addWidget(self.uniqueIDEdit, l, 4, 1, 2) namingGroup.setLayout(namingLayout) hintingGroup = QGroupBox("Hinting", self) # hintingGroup.setFlat(True) hintingLayout = QGridLayout(self) self.loadIntegerFloatList(font, "postscriptBlueValues", "blueValues") self.loadIntegerFloatList(font, "postscriptOtherBlues", "otherBlues") self.loadIntegerFloatList(font, "postscriptFamilyBlues", "familyBlues") self.loadIntegerFloatList( font, "postscriptFamilyOtherBlues", "familyOtherBlues") blueValuesLabel = QLabel("Blue values:", self) otherBluesLabel = QLabel("Other blues:", self) familyBluesLabel = QLabel("Family blues:", self) familyOtherBluesLabel = QLabel("Family other blues:", self) l = 0 hintingLayout.addWidget(blueValuesLabel, l, 0) hintingLayout.addWidget(self.blueValuesEdit, l, 1, 1, 2) hintingLayout.addWidget(familyBluesLabel, l, 3) hintingLayout.addWidget(self.familyBluesEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(otherBluesLabel, l, 0) hintingLayout.addWidget(self.otherBluesEdit, l, 1, 1, 2) hintingLayout.addWidget(familyOtherBluesLabel, l, 3) hintingLayout.addWidget(self.familyOtherBluesEdit, l, 4, 1, 2) l += 1 blueFuzzLabel = QLabel("Blue fuzz:", self) stemSnapHLabel = QLabel("StemSnapH:", self) blueScaleLabel = QLabel("Blue scale:", self) stemSnapVLabel = QLabel("StemSnapV:", self) blueShiftLabel = QLabel("Blue shift:", self) self.loadIntegerFloatList(font, "postscriptStemSnapH", "stemSnapH") self.loadIntegerFloatList(font, "postscriptStemSnapV", "stemSnapV") self.loadIntegerFloat(font, "postscriptBlueFuzz", "blueFuzz") self.loadIntegerFloat(font, "postscriptBlueScale", "blueScale") self.loadIntegerFloat(font, "postscriptBlueShift", "blueShift") forceBoldLabel = QLabel("Force bold:", self) self.loadBoolean(font, "postscriptForceBold", "forceBold") hintingLayout.addWidget(blueFuzzLabel, l, 0) hintingLayout.addWidget(self.blueFuzzEdit, l, 1, 1, 2) hintingLayout.addWidget(stemSnapHLabel, l, 3) hintingLayout.addWidget(self.stemSnapHEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(blueScaleLabel, l, 0) hintingLayout.addWidget(self.blueScaleEdit, l, 1, 1, 2) hintingLayout.addWidget(stemSnapVLabel, l, 3) hintingLayout.addWidget(self.stemSnapVEdit, l, 4, 1, 2) l += 1 hintingLayout.addWidget(blueShiftLabel, l, 0) hintingLayout.addWidget(self.blueShiftEdit, l, 1, 1, 2) hintingLayout.addWidget(forceBoldLabel, l, 3) hintingLayout.addWidget(self.forceBoldBox, l, 4, 1, 2) hintingGroup.setLayout(hintingLayout) metricsGroup = QGroupBox("Metrics", self) # metricsGroup.setFlat(True) metricsLayout = QGridLayout(self) defaultWidthXLabel = QLabel("DefaultWidthX:", self) underlineThicknessLabel = QLabel("UnderlineThickness:", self) nominalWidthXLabel = QLabel("NominalWidthX:", self) underlinePositionLabel = QLabel("UnderlinePosition:", self) slantAngleLabel = QLabel("SlantAngle:", self) self.loadIntegerFloat(font, "postscriptDefaultWidthX", "defaultWidthX") self.loadIntegerFloat(font, "postscriptNominalWidthX", "nominalWidthX") self.loadIntegerFloat( font, "postscriptUnderlineThickness", "underlineThickness") self.loadIntegerFloat( font, "postscriptUnderlinePosition", "underlinePosition") self.loadIntegerFloat(font, "postscriptSlantAngle", "slantAngle") isFixedPitchLabel = QLabel("isFixedPitched:", self) self.loadBoolean(font, "postscriptIsFixedPitch", "isFixedPitch") l = 0 metricsLayout.addWidget(defaultWidthXLabel, l, 0) metricsLayout.addWidget(self.defaultWidthXEdit, l, 1, 1, 2) metricsLayout.addWidget(underlineThicknessLabel, l, 3) metricsLayout.addWidget(self.underlineThicknessEdit, l, 4, 1, 2) l += 1 metricsLayout.addWidget(nominalWidthXLabel, l, 0) metricsLayout.addWidget(self.nominalWidthXEdit, l, 1, 1, 2) metricsLayout.addWidget(underlinePositionLabel, l, 3) metricsLayout.addWidget(self.underlinePositionEdit, l, 4, 1, 2) l += 1 metricsLayout.addWidget(slantAngleLabel, l, 0) metricsLayout.addWidget(self.slantAngleEdit, l, 1, 1, 2) metricsLayout.addWidget(isFixedPitchLabel, l, 3) metricsLayout.addWidget(self.isFixedPitchBox, l, 4, 1, 2) metricsGroup.setLayout(metricsLayout) charactersGroup = QGroupBox("Characters", self) # charactersGroup.setFlat(True) charactersLayout = QGridLayout(self) defaultCharacterLabel = QLabel("Default character:", self) self.loadString(font, "postscriptDefaultCharacter", "defaultCharacter") windowsCharacterSetLabel = QLabel("Windows character set:", self) self.windowsCharacterSetDrop = QComboBox(self) items = [ "None", "ANSI", "Default", "Symbol", "Macintosh", "Shift JIS", "Hangul", "Hangul (Johab)", "GB2312", "Chinese BIG5", "Greek", "Turkish", "Vietnamese", "Hebrew", "Arabic", "Baltic", "Bitstream", "Cyrillic", "Thai", "Eastern European", "OEM"] self.windowsCharacterSetDrop.insertItems(0, items) if font.info.postscriptWindowsCharacterSet is not None: self.windowsCharacterSetDrop.setCurrentIndex( font.info.postscriptWindowsCharacterSet) l = 0 charactersLayout.addWidget(defaultCharacterLabel, l, 0) charactersLayout.addWidget(self.defaultCharacterEdit, l, 1, 1, 2) charactersLayout.addWidget(windowsCharacterSetLabel, l, 3) charactersLayout.addWidget(self.windowsCharacterSetDrop, l, 4, 1, 2) charactersGroup.setLayout(charactersLayout) mainLayout = QVBoxLayout() mainLayout.addWidget(namingGroup) mainLayout.addWidget(hintingGroup) mainLayout.addWidget(metricsGroup) mainLayout.addWidget(charactersGroup) self.setLayout(mainLayout) def writeValues(self, font): self.writeString(font, "fontName", "postscriptFontName") self.writeString(font, "fullName", "postscriptFullName") self.writeString(font, "weightName", "postscriptWeightName") self.writeInteger(font, "uniqueID", "postscriptUniqueID") self.writeIntegerFloatList(font, "blueValues", "postscriptBlueValues") self.writeIntegerFloatList(font, "otherBlues", "postscriptOtherBlues") self.writeIntegerFloatList( font, "familyBlues", "postscriptFamilyBlues") self.writeIntegerFloatList( font, "familyOtherBlues", "postscriptFamilyOtherBlues") self.writeIntegerFloatList(font, "stemSnapH", "postscriptStemSnapH") self.writeIntegerFloatList(font, "stemSnapV", "postscriptStemSnapV") self.writeIntegerFloat(font, "blueFuzz", "postscriptBlueFuzz") self.writeIntegerFloat(font, "blueScale", "postscriptBlueScale") self.writeIntegerFloat(font, "blueShift", "postscriptBlueShift") self.writeIntegerFloat( font, "defaultWidthX", "postscriptDefaultWidthX") self.writeIntegerFloat( font, "nominalWidthX", "postscriptNominalWidthX") self.writeIntegerFloat( font, "underlineThickness", "postscriptUnderlineThickness") self.writeIntegerFloat( font, "underlinePosition", "postscriptUnderlinePosition") self.writeIntegerFloat(font, "slantAngle", "postscriptSlantAngle") self.writeBoolean(font, "forceBold", "postscriptForceBold") self.writeBoolean(font, "isFixedPitch", "postscriptIsFixedPitch") self.writeString( font, "defaultCharacter", "postscriptDefaultCharacter") windowsCharacterSet = self.windowsCharacterSetDrop.currentIndex() if windowsCharacterSet == 0: font.info.postscriptWindowsCharacterSet = None else: font.info.postscriptWindowsCharacterSet = windowsCharacterSet
class iniWin(QWidget, parent.posClass, parent.win): retSig = pyqtSignal() def __init__(self, folder): super().__init__() self.dim = [600, 450] self.layout = QGridLayout() self.iniList = QComboBox() self.other = QPushButton("Load from other directory?") self.ldButton = QPushButton("Load Fic") self.fandomLab = QLabel("Fandom:") self.fandom = QTextEdit() self.font = QFont() self.font.setPointSize(16) self.fandom.setFont(self.font) self.fandom.setReadOnly(True) self.layout.addWidget(self.iniList, 0, 2, 1, 2) self.layout.addWidget(self.other, 0, 0, 1, 1) self.layout.addWidget(self.ldButton, 6, 3, 1, 1) # self.layout.addWidget(self.fandomLab, 2, 0, 1, 1) self.layout.addWidget(self.fandom, 3, 0, 3, -1) self.folder = folder self.dirs = [] self.titles = [] self.fandoms = [] self.setLayout(self.layout) self.loadFiles() self.ldButton.clicked.connect(self.ret) self.iniList.activated.connect(self.loadFandom) def ret(self): self.retSig.emit() self.close() def clear(self): self.dirs.clear() self.titles.clear() self.fandoms.clear() def loadFandom(self): ind = self.iniList.currentIndex() load = configparser.ConfigParser() try: load.read(self.dirs[ind]) self.fandom.setText("<h3>" + self.titles[ind] + "</h3>" + str(self.fandoms[ind])) except: if __name__ != '__main__': with open(GLOBALlogPath, 'a') as f: now = datetime.now() # dd/mm/YY H:M:S dt_string = now.strftime("%d/%m/%Y %H:%M:%S") f.write(dt_string + " : Error in loadFandoms reading: " + self.dirs[ind] + "\n") else: print("Error in loadFandoms reading: ", self.dirs[ind]) def loadTitles(self): for x in self.dirs: load = configparser.ConfigParser() try: load.read(x) soup = BeautifulSoup( codecs.open(load['FicDetails']['filepath'], 'r', 'utf-8'), 'html.parser') self.titles.append( soup.find("h1").get_text() + " by " + soup.find("a", rel="author").get_text()) self.fandoms.append(soup.find('dl', class_='tags')) except: if __name__ != '__main__': with open(GLOBALlogPath, 'a') as f: now = datetime.now() # dd/mm/YY H:M:S dt_string = now.strftime("%d/%m/%Y %H:%M:%S") f.write(dt_string + " : Error in loadFandoms reading: " + x + "\n") else: print("Error in loadTitles: ", x) def loadFiles(self): self.iniList.clear() self.dirs.clear() self.titles.clear() for file in os.listdir(self.folder): if file.endswith(".ini"): self.dirs.append(self.folder + file) self.dirs.sort(key=os.path.getmtime) self.dirs.reverse() if (len(self.dirs)): self.loadTitles() self.iniList.insertItems(0, self.titles) self.loadFandom()
def run_setup_window(icon): win = QDialog() win.setWindowTitle('Application Setup') win.setWindowIcon(icon) win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint) win.setAttribute( Qt.WA_DeleteOnClose) # This is required to stop background timers! combo = QComboBox(win) combo.setEditable(True) combo.setInsertPolicy(QComboBox.NoInsert) combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) combo.setFont(get_monospace_font()) combo_completer = QCompleter() combo_completer.setCaseSensitivity(Qt.CaseSensitive) combo_completer.setModel(combo.model()) combo.setCompleter(combo_completer) bitrate = QSpinBox(win) bitrate.setMaximum(1000000) bitrate.setMinimum(10000) bitrate.setValue(1000000) baudrate = QComboBox(win) baudrate.setEditable(True) baudrate.setInsertPolicy(QComboBox.NoInsert) baudrate.setSizeAdjustPolicy(QComboBox.AdjustToContents) baudrate.setFont(get_monospace_font()) baudrate_completer = QCompleter(win) baudrate_completer.setModel(baudrate.model()) baudrate.setCompleter(baudrate_completer) baudrate.setValidator( QIntValidator(min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES))) baudrate.insertItems(0, map(str, STANDARD_BAUD_RATES)) baudrate.setCurrentText(str(DEFAULT_BAUD_RATE)) dir_selection = DirectorySelectionWidget(win) ok = QPushButton('OK', win) def update_slcan_options_visibility(): if RUNNING_ON_LINUX: slcan_active = '/' in combo.currentText() else: slcan_active = True slcan_group.setEnabled(slcan_active) combo.currentTextChanged.connect(update_slcan_options_visibility) ifaces = None def update_iface_list(): nonlocal ifaces ifaces = iface_lister.get_list() known_keys = set() remove_indices = [] was_empty = combo.count() == 0 # Marking known and scheduling for removal for idx in count(): tx = combo.itemText(idx) if not tx: break known_keys.add(tx) if tx not in ifaces: logger.debug('Removing iface %r', tx) remove_indices.append(idx) # Removing - starting from the last item in order to retain indexes for idx in remove_indices[::-1]: combo.removeItem(idx) # Adding new items - starting from the last item in order to retain the final order for key in list(ifaces.keys())[::-1]: if key not in known_keys: logger.debug('Adding iface %r', key) combo.insertItem(0, key) # Updating selection if was_empty: combo.setCurrentIndex(0) result = None kwargs = {} def on_ok(): nonlocal result, kwargs try: baud_rate_value = int(baudrate.currentText()) except ValueError: show_error('Invalid parameters', 'Could not parse baud rate', 'Please specify correct baud rate', parent=win) return if not (min(STANDARD_BAUD_RATES) <= baud_rate_value <= max(STANDARD_BAUD_RATES)): show_error('Invalid parameters', 'Baud rate is out of range', 'Baud rate value should be within [%s, %s]' % (min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)), parent=win) return kwargs['baudrate'] = baud_rate_value kwargs['bitrate'] = int(bitrate.value()) result_key = str(combo.currentText()).strip() if not result_key: show_error('Invalid parameters', 'Interface name cannot be empty', 'Please select a valid interface', parent=win) return try: result = ifaces[result_key] except KeyError: result = result_key win.close() ok.clicked.connect(on_ok) can_group = QGroupBox('CAN interface setup', win) can_layout = QVBoxLayout() can_layout.addWidget(QLabel('Select CAN interface')) can_layout.addWidget(combo) slcan_group = QGroupBox('SLCAN adapter settings', win) slcan_layout = QGridLayout() slcan_layout.addWidget(QLabel('CAN bus bit rate:'), 0, 0) slcan_layout.addWidget(bitrate, 0, 1) slcan_layout.addWidget( QLabel('Adapter baud rate (not applicable to USB-CAN adapters):'), 1, 0) slcan_layout.addWidget(baudrate, 1, 1) slcan_group.setLayout(slcan_layout) can_layout.addWidget(slcan_group) can_group.setLayout(can_layout) layout = QVBoxLayout() layout.addWidget(can_group) layout.addWidget(dir_selection) layout.addWidget(ok) layout.setSizeConstraint(layout.SetFixedSize) win.setLayout(layout) with BackgroundIfaceListUpdater() as iface_lister: update_slcan_options_visibility() update_iface_list() timer = QTimer(win) timer.setSingleShot(False) timer.timeout.connect(update_iface_list) timer.start(int(BackgroundIfaceListUpdater.UPDATE_INTERVAL / 2 * 1000)) win.exec() return result, kwargs, dir_selection.get_selection()
def run_iface_config_window(icon): win = QDialog() win.setWindowTitle('CAN Interface Configuration') win.setWindowIcon(icon) win.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint) win.setAttribute(Qt.WA_DeleteOnClose) # This is required to stop background timers! combo = QComboBox(win) combo.setEditable(True) combo.setInsertPolicy(QComboBox.NoInsert) combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) combo.setFont(get_monospace_font()) combo_completer = QCompleter() combo_completer.setCaseSensitivity(Qt.CaseSensitive) combo_completer.setModel(combo.model()) combo.setCompleter(combo_completer) bitrate = QSpinBox(win) bitrate.setMaximum(1000000) bitrate.setMinimum(10000) bitrate.setValue(1000000) baudrate = QComboBox(win) baudrate.setEditable(True) baudrate.setInsertPolicy(QComboBox.NoInsert) baudrate.setSizeAdjustPolicy(QComboBox.AdjustToContents) baudrate.setFont(get_monospace_font()) baudrate_completer = QCompleter(win) baudrate_completer.setModel(baudrate.model()) baudrate.setCompleter(baudrate_completer) baudrate.setValidator(QIntValidator(min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES))) baudrate.insertItems(0, map(str, STANDARD_BAUD_RATES)) baudrate.setCurrentText(str(DEFAULT_BAUD_RATE)) ok = QPushButton('OK', win) def update_slcan_options_visibility(): if RUNNING_ON_LINUX: slcan_active = '/' in combo.currentText() else: slcan_active = True slcan_group.setEnabled(slcan_active) combo.currentTextChanged.connect(update_slcan_options_visibility) ifaces = None def update_iface_list(): nonlocal ifaces ifaces = iface_lister.get_list() known_keys = set() remove_indices = [] was_empty = combo.count() == 0 # Marking known and scheduling for removal for idx in count(): tx = combo.itemText(idx) if not tx: break known_keys.add(tx) if tx not in ifaces: logger.debug('Removing iface %r', tx) remove_indices.append(idx) # Removing - starting from the last item in order to retain indexes for idx in remove_indices[::-1]: combo.removeItem(idx) # Adding new items - starting from the last item in order to retain the final order for key in list(ifaces.keys())[::-1]: if key not in known_keys: logger.debug('Adding iface %r', key) combo.insertItem(0, key) # Updating selection if was_empty: combo.setCurrentIndex(0) result = None kwargs = {} def on_ok(): nonlocal result, kwargs try: baud_rate_value = int(baudrate.currentText()) except ValueError: show_error('Invalid parameters', 'Could not parse baud rate', 'Please specify correct baud rate', parent=win) return if not (min(STANDARD_BAUD_RATES) <= baud_rate_value <= max(STANDARD_BAUD_RATES)): show_error('Invalid parameters', 'Baud rate is out of range', 'Baud rate value should be within [%s, %s]' % (min(STANDARD_BAUD_RATES), max(STANDARD_BAUD_RATES)), parent=win) return kwargs['baudrate'] = baud_rate_value kwargs['bitrate'] = int(bitrate.value()) result_key = str(combo.currentText()).strip() if not result_key: show_error('Invalid parameters', 'Interface name cannot be empty', 'Please select a valid interface', parent=win) return try: result = ifaces[result_key] except KeyError: result = result_key win.close() ok.clicked.connect(on_ok) layout = QVBoxLayout(win) layout.addWidget(QLabel('Select CAN interface')) layout.addWidget(combo) slcan_group = QGroupBox('SLCAN adapter settings', win) slcan_layout = QVBoxLayout(slcan_group) slcan_layout.addWidget(QLabel('CAN bus bit rate:')) slcan_layout.addWidget(bitrate) slcan_layout.addWidget(QLabel('Adapter baud rate (not applicable to USB-CAN adapters):')) slcan_layout.addWidget(baudrate) slcan_group.setLayout(slcan_layout) layout.addWidget(slcan_group) layout.addWidget(ok) layout.setSizeConstraint(layout.SetFixedSize) win.setLayout(layout) with BackgroundIfaceListUpdater() as iface_lister: update_slcan_options_visibility() update_iface_list() timer = QTimer(win) timer.setSingleShot(False) timer.timeout.connect(update_iface_list) timer.start(int(BackgroundIfaceListUpdater.UPDATE_INTERVAL / 2 * 1000)) win.exec() return result, kwargs
class BruteWidget(QWidget): def __init__(self, ip, port, service, settings, parent=None): QWidget.__init__(self, parent) self.ip = ip self.port = port self.service = service ## # self.hydraServices = hydraServices # self.hydraNoUsernameServices = hydraNoUsernameServices # self.hydraNoPasswordServices = hydraNoPasswordServices # self.bruteSettings = bruteSettings # self.generalSettings = generalSettings ## self.settings = settings self.pid = -1 # will store hydra's pid so we can kill it self.setupLayout() self.browseUsersButton.clicked.connect(lambda: self.wordlistDialog()) self.browsePasswordsButton.clicked.connect( lambda: self.wordlistDialog('Choose password list')) self.usersTextinput.textEdited.connect(self.singleUserRadio.toggle) self.passwordsTextinput.textEdited.connect(self.singlePassRadio.toggle) self.userlistTextinput.textEdited.connect(self.userListRadio.toggle) self.passlistTextinput.textEdited.connect(self.passListRadio.toggle) self.checkAddMoreOptions.stateChanged.connect(self.showMoreOptions) def setupLayoutHlayout(self): hydraServiceConversion = { 'login': '******', 'ms-sql-s': 'mssql', 'ms-wbt-server': 'rdp', 'netbios-ssn': 'smb', 'netbios-ns': 'smb', 'microsoft-ds': 'smb', 'postgresql': 'postgres', 'vmware-auth': 'vmauthd"' } # sometimes nmap service name is different from hydra service name if self.service is None: self.service = '' elif str(self.service) in hydraServiceConversion: self.service = hydraServiceConversion.get(str(self.service)) self.label1 = QLabel() self.label1.setText('IP') self.label1.setAlignment(Qt.AlignLeft) self.label1.setAlignment(Qt.AlignVCenter) self.ipTextinput = QLineEdit() self.ipTextinput.setText(str(self.ip)) self.ipTextinput.setFixedWidth(125) self.label2 = QLabel() self.label2.setText('Port') self.label2.setAlignment(Qt.AlignLeft) self.label2.setAlignment(Qt.AlignVCenter) self.portTextinput = QLineEdit() self.portTextinput.setText(str(self.port)) self.portTextinput.setFixedWidth(60) self.label3 = QLabel() self.label3.setText('Service') self.label3.setAlignment(Qt.AlignLeft) self.label3.setAlignment(Qt.AlignVCenter) self.serviceComboBox = QComboBox() self.serviceComboBox.insertItems( 0, self.settings.brute_services.split(",")) self.serviceComboBox.setStyleSheet("QComboBox { combobox-popup: 0; }") self.serviceComboBox.currentIndexChanged.connect( self.checkSelectedService) # autoselect service from combo box for i in range(len(self.settings.brute_services.split(","))): if str(self.service) in self.settings.brute_services.split(",")[i]: self.serviceComboBox.setCurrentIndex(i) break # self.labelPath = QLineEdit() # this is the extra input field to insert the path to brute force # self.labelPath.setFixedWidth(800) # self.labelPath.setText('/') self.runButton = QPushButton('Run') self.runButton.setMaximumSize(110, 30) self.runButton.setDefault(True) # new ### self.validationLabel = QLabel(self) self.validationLabel.setText('Invalid input. Please try again!') self.validationLabel.setStyleSheet('QLabel { color: red }') ### self.hlayout = QHBoxLayout() self.hlayout.addWidget(self.label1) self.hlayout.addWidget(self.ipTextinput) self.hlayout.addWidget(self.label2) self.hlayout.addWidget(self.portTextinput) self.hlayout.addWidget(self.label3) self.hlayout.addWidget(self.serviceComboBox) self.hlayout.addWidget(self.runButton) ### self.hlayout.addWidget(self.validationLabel) self.validationLabel.hide() ### self.hlayout.addStretch() return self.hlayout def setupLayoutHlayout2(self): self.singleUserRadio = QRadioButton() self.label4 = QLabel() self.label4.setText('Username') self.label4.setFixedWidth(70) self.usersTextinput = QLineEdit() self.usersTextinput.setFixedWidth(125) self.usersTextinput.setText(self.settings.brute_default_username) self.userListRadio = QRadioButton() self.label5 = QLabel() self.label5.setText('Username list') self.label5.setFixedWidth(90) self.userlistTextinput = QLineEdit() self.userlistTextinput.setFixedWidth(125) self.browseUsersButton = QPushButton('Browse') self.browseUsersButton.setMaximumSize(80, 30) self.foundUsersRadio = QRadioButton() self.label9 = QLabel() self.label9.setText('Found usernames') self.label9.setFixedWidth(117) self.userGroup = QButtonGroup() self.userGroup.addButton(self.singleUserRadio) self.userGroup.addButton(self.userListRadio) self.userGroup.addButton(self.foundUsersRadio) self.foundUsersRadio.toggle() self.warningLabel = QLabel() self.warningLabel.setText( '*Note: when using form-based services from the Service menu, ' + 'select the "Additional Options" checkbox and add the proper arguments' + ' for the webpage form. See Hydra documentation for extra help when' + ' targeting HTTP/HTTPS forms.') self.warningLabel.setWordWrap(True) self.warningLabel.setAlignment(Qt.AlignRight) self.warningLabel.setStyleSheet('QLabel { color: red }') self.hlayout2 = QHBoxLayout() self.hlayout2.addWidget(self.singleUserRadio) self.hlayout2.addWidget(self.label4) self.hlayout2.addWidget(self.usersTextinput) self.hlayout2.addWidget(self.userListRadio) self.hlayout2.addWidget(self.label5) self.hlayout2.addWidget(self.userlistTextinput) self.hlayout2.addWidget(self.browseUsersButton) self.hlayout2.addWidget(self.foundUsersRadio) self.hlayout2.addWidget(self.label9) self.hlayout2.addWidget(self.warningLabel) self.warningLabel.hide() self.hlayout2.addStretch() return self.hlayout2 def checkSelectedService(self): self.service = str(self.serviceComboBox.currentText()) if 'form' in str(self.service): self.warningLabel.show() # else: This clause would produce an interesting logic error and crash # self.warningLabel.hide() def setupLayoutHlayout3(self): # add usernames wordlist self.singlePassRadio = QRadioButton() self.label6 = QLabel() self.label6.setText('Password') self.label6.setFixedWidth(70) self.passwordsTextinput = QLineEdit() self.passwordsTextinput.setFixedWidth(125) self.passwordsTextinput.setText(self.settings.brute_default_password) self.passListRadio = QRadioButton() self.label7 = QLabel() self.label7.setText('Password list') self.label7.setFixedWidth(90) self.passlistTextinput = QLineEdit() self.passlistTextinput.setFixedWidth(125) self.browsePasswordsButton = QPushButton('Browse') self.browsePasswordsButton.setMaximumSize(80, 30) self.foundPasswordsRadio = QRadioButton() self.label10 = QLabel() self.label10.setText('Found passwords') self.label10.setFixedWidth(115) self.passGroup = QButtonGroup() self.passGroup.addButton(self.singlePassRadio) self.passGroup.addButton(self.passListRadio) self.passGroup.addButton(self.foundPasswordsRadio) self.foundPasswordsRadio.toggle() self.label8 = QLabel() self.label8.setText('Threads') self.label8.setFixedWidth(60) self.threadOptions = [] for i in range(1, 129): self.threadOptions.append(str(i)) self.threadsComboBox = QComboBox() self.threadsComboBox.insertItems(0, self.threadOptions) self.threadsComboBox.setMinimumContentsLength(3) self.threadsComboBox.setMaxVisibleItems(3) self.threadsComboBox.setStyleSheet("QComboBox { combobox-popup: 0; }") self.threadsComboBox.setCurrentIndex(15) self.hlayout3 = QHBoxLayout() self.hlayout3.addWidget(self.singlePassRadio) self.hlayout3.addWidget(self.label6) self.hlayout3.addWidget(self.passwordsTextinput) self.hlayout3.addWidget(self.passListRadio) self.hlayout3.addWidget(self.label7) self.hlayout3.addWidget(self.passlistTextinput) self.hlayout3.addWidget(self.browsePasswordsButton) self.hlayout3.addWidget(self.foundPasswordsRadio) self.hlayout3.addWidget(self.label10) self.hlayout3.addStretch() self.hlayout3.addWidget(self.label8) self.hlayout3.addWidget(self.threadsComboBox) # self.hlayout3.addStretch() return self.hlayout3 def setupLayoutHlayout4(self): # label6.setText('Try blank password') self.checkBlankPass = QCheckBox() self.checkBlankPass.setText('Try blank password') self.checkBlankPass.toggle() # add 'try blank password' # label7.setText('Try login as password') self.checkLoginAsPass = QCheckBox() self.checkLoginAsPass.setText('Try login as password') self.checkLoginAsPass.toggle() # add 'try login as password' # label8.setText('Loop around users') self.checkLoopUsers = QCheckBox() self.checkLoopUsers.setText('Loop around users') self.checkLoopUsers.toggle() # add 'loop around users' # label9.setText('Exit on first valid') self.checkExitOnValid = QCheckBox() self.checkExitOnValid.setText('Exit on first valid') self.checkExitOnValid.toggle() # add 'exit after first valid combination is found' self.checkVerbose = QCheckBox() self.checkVerbose.setText('Verbose') self.checkAddMoreOptions = QCheckBox() self.checkAddMoreOptions.setText('Additional Options') self.hlayout4 = QHBoxLayout() self.hlayout4.addWidget(self.checkBlankPass) self.hlayout4.addWidget(self.checkLoginAsPass) self.hlayout4.addWidget(self.checkLoopUsers) self.hlayout4.addWidget(self.checkExitOnValid) self.hlayout4.addWidget(self.checkVerbose) self.hlayout4.addWidget(self.checkAddMoreOptions) self.hlayout4.addStretch() return self.hlayout4 def setupLayout(self): ### self.labelPath = QLineEdit( ) # this is the extra input field to insert the path to brute force self.labelPath.setFixedWidth(800) self.labelPath.setText( '-m "/login/login.html:username=^USER^&password=^PASS^&Login=Login:failed"' ) ### self.layoutAddOptions = QHBoxLayout() self.layoutAddOptions.addWidget(self.labelPath) self.labelPath.hide() self.layoutAddOptions.addStretch() self.display = QPlainTextEdit() self.display.setReadOnly(True) if self.settings.general_tool_output_black_background == 'True': self.__drawPalette() self.vlayout = QVBoxLayout() self.vlayout.addLayout(self.setupLayoutHlayout()) self.vlayout.addLayout(self.setupLayoutHlayout4()) self.vlayout.addLayout(self.layoutAddOptions) self.vlayout.addLayout(self.setupLayoutHlayout2()) self.vlayout.addLayout(self.setupLayoutHlayout3()) self.vlayout.addWidget(self.display) self.setLayout(self.vlayout) def __drawPalette(self): p = self.display.palette() p.setColor(QPalette.Base, Qt.black) # black background p.setColor(QPalette.Text, Qt.white) # white font self.display.setPalette(p) self.display.setStyleSheet("QMenu { color:black;}") # TODO: need to check all the methods that need an additional input field and add them here # def showMoreOptions(self, text): # if str(text) == "http-head": # self.labelPath.show() # else: # self.labelPath.hide() def showMoreOptions(self): if self.checkAddMoreOptions.isChecked(): self.labelPath.show() else: self.labelPath.hide() def wordlistDialog(self, title='Choose username list'): if title == 'Choose username list': filename = QFileDialog.getOpenFileName( self, title, self.settings.brute_username_wordlist_path) self.userlistTextinput.setText(str(filename[0])) self.userListRadio.toggle() else: filename = QFileDialog.getOpenFileName( self, title, self.settings.brute_password_wordlist_path) self.passlistTextinput.setText(str(filename[0])) self.passListRadio.toggle() def buildHydraCommand(self, runningfolder, userlistPath, passlistPath): self.ip = self.ipTextinput.text() self.port = self.portTextinput.text() self.service = str(self.serviceComboBox.currentText()) outputFile = getHydraOutputFileName(runningfolder, self.ip, self.port, self.service) threadsToUse = str(self.threadsComboBox.currentText()) labelText = str(self.labelPath.text() ) if self.checkAddMoreOptions.isChecked() else None if 'form' not in str(self.service): self.warningLabel.hide() tryLoginName = None tryLoginNameFile = None if not self.service in self.settings.brute_no_username_services.split( ","): if self.singleUserRadio.isChecked(): tryLoginName = self.usersTextinput.text() elif self.foundUsersRadio.isChecked(): tryLoginNameFile = userlistPath else: tryLoginNameFile = self.userlistTextinput.text() tryPassword = None tryPasswordFile = None if not self.service in self.settings.brute_no_password_services.split( ","): if self.singlePassRadio.isChecked(): tryPassword = self.passwordsTextinput.text().replace( '"', '\"\"\"') elif self.foundPasswordsRadio.isChecked(): tryPasswordFile = passlistPath else: tryPasswordFile = self.passlistTextinput.text() hydraArgs = HydraCommandArguments( ipAddress=str(self.ip), port=self.port, outputFile=outputFile, threadsToUse=threadsToUse, service=self.service, verbose=self.checkVerbose.isChecked(), label=labelText, exitAfterFirstUserPassPairFound=self.checkExitOnValid.isChecked(), loopUsers=self.checkLoopUsers.isChecked(), tryLoginAsPass=self.checkLoginAsPass.isChecked(), tryNullPassword=self.checkBlankPass.isChecked(), tryPassword=tryPassword, tryPasswordFile=tryPasswordFile, tryLoginName=tryLoginName, tryLoginNameFile=tryLoginNameFile) return buildHydraCommand(hydraArgs) def getPort(self): return self.port def toggleRunButton(self): if self.runButton.text() == 'Run': self.runButton.setText('Stop') else: self.runButton.setText('Run') # used to be able to display the tool output in both the Brute tab and the tool display panel def resetDisplay(self): self.display.setParent(None) self.display = QPlainTextEdit() self.display.setReadOnly(True) if self.settings.general_tool_output_black_background == 'True': self.__drawPalette() self.vlayout.addWidget(self.display)
class SerialController(QWidget): # 시리얼포트 상수 값 BAUDRATES = ( QSerialPort.Baud1200, QSerialPort.Baud2400, QSerialPort.Baud4800, QSerialPort.Baud9600, QSerialPort.Baud19200, QSerialPort.Baud38400, QSerialPort.Baud57600, QSerialPort.Baud115200, ) received_data = pyqtSignal(QByteArray, name="receivedData") sent_data = pyqtSignal(str, name="sentData") def __init__(self): QWidget.__init__(self, flags=Qt.Widget) # 위젯 선언 self.gb = QGroupBox(self.tr("Serial")) self.cb_port = QComboBox() self.cb_baud_rate = QComboBox() # 시리얼 인스턴스 생성 # 시리얼 스레드 설정 및 시작 self.serial = QSerialPort() self.serial_info = QSerialPortInfo() self.serial_read_thread = SerialReadThread(self.serial) self.serial_read_thread.received_data.connect( lambda v: self.received_data.emit(v)) self.serial_read_thread.start() self.init_widget() def init_widget(self): self.setWindowTitle("Serial Controller") layout = QBoxLayout(QBoxLayout.TopToBottom, parent=self) grid_box = QGridLayout() grid_box.addWidget(QLabel(self.tr("Port")), 0, 0) grid_box.addWidget(self.cb_port, 0, 1) grid_box.addWidget(QLabel(self.tr("Baud Rate")), 1, 0) grid_box.addWidget(self.cb_baud_rate, 1, 1) self._fill_serial_info() self.gb.setLayout(grid_box) layout.addWidget(self.gb) self.setLayout(layout) def _fill_serial_info(self): # 시리얼 상수 값들을 위젯에 채운다 self.cb_port.insertItems(0, self._get_available_port()) self.cb_baud_rate.insertItems(0, [str(x) for x in self.BAUDRATES]) @staticmethod def get_port_path(): """ 현재플래폼에 맞게 경로 또는 지정어를 반환 :return: """ return {"linux": '/dev/ttyS', "win32": 'COM'}[__platform__] def _get_available_port(self): """ 255개의 포트를 열고 닫으면서 사용가능한 포트를 찾아서 반환 :return: """ available_port = list() port_path = self.get_port_path() for number in range(255): port_name = port_path + str(number) if not self._open(port_name): continue available_port.append(port_name) self.serial.close() return available_port def _open(self, port_name, baudrate=QSerialPort.Baud115200): """ 인자값으로 받은 시리얼 접속 정보를 이용하여 해당 포트를 연결한다. :param port_name: :param baudrate: :param data_bits: :param flow_control: :param parity: :param stop_bits: :return: bool """ info = QSerialPortInfo(port_name) self.serial.setPort(info) self.serial.setBaudRate(baudrate) self.serial.setDataBits(QSerialPort.Data8) self.serial.setFlowControl(QSerialPort.NoFlowControl) self.serial.setParity(QSerialPort.NoParity) self.serial.setStopBits(QSerialPort.OneStop) return self.serial.open(QIODevice.ReadWrite) def connect_serial(self): serial_info = { "port_name": self.cb_port.currentText(), "baudrate": self.BAUDRATES[self.cb_baud_rate.currentIndex()] } status = self._open(**serial_info) self.serial_read_thread.setStatus(status) return status def disconnect_serial(self): return self.serial.close() @pyqtSlot(bytes, name="writeData") def write_data(self, data): self.serial.writeData(data)
class HistoryList(MyTreeWidget, AcceptFileDragDrop): filter_columns = [2, 3, 4] # Date, Description, Amount def __init__(self, parent=None): MyTreeWidget.__init__(self, parent, self.create_menu, [], 3) AcceptFileDragDrop.__init__(self, ".txn") self.refresh_headers() self.setColumnHidden(1, True) self.setSortingEnabled(True) self.sortByColumn(0, Qt.AscendingOrder) self.start_timestamp = None self.end_timestamp = None self.years = [] self.create_toolbar_buttons() self.wallet = None def format_date(self, d): return str(datetime.date(d.year, d.month, d.day)) if d else _('None') def refresh_headers(self): headers = [ '', '', _('Date'), _('Description'), _('Amount'), _('Balance') ] fx = self.parent.fx if fx and fx.show_history(): headers.extend(['%s ' % fx.ccy + _('Value')]) self.editable_columns |= {6} if fx.get_history_capital_gains_config(): headers.extend(['%s ' % fx.ccy + _('Acquisition price')]) headers.extend(['%s ' % fx.ccy + _('Capital Gains')]) else: self.editable_columns -= {6} self.update_headers(headers) # Set fixed width for the first column self.header().setSectionResizeMode(0, QHeaderView.Fixed) self.header().resizeSection(0, 20) # Set default column width just in case there is no data self.header().setSectionResizeMode(1, QHeaderView.Fixed) self.header().resizeSection(1, 100) self.header().setSectionResizeMode(2, QHeaderView.Fixed) self.header().resizeSection(2, 100) self.header().setSectionResizeMode(4, QHeaderView.Fixed) self.header().resizeSection(4, 100) self.header().setSectionResizeMode(5, QHeaderView.Fixed) self.header().resizeSection(5, 100) def get_domain(self): '''Replaced in address_dialog.py''' return self.wallet.get_addresses() def on_combo(self, x): s = self.period_combo.itemText(x) x = s == _('Custom') self.start_button.setEnabled(x) self.end_button.setEnabled(x) if s == _('All'): self.start_timestamp = None self.end_timestamp = None self.start_button.setText("-") self.end_button.setText("-") else: try: year = int(s) except: return start_date = datetime.datetime(year, 1, 1) end_date = datetime.datetime(year + 1, 1, 1) self.start_timestamp = time.mktime(start_date.timetuple()) self.end_timestamp = time.mktime(end_date.timetuple()) self.start_button.setText( _('From') + ' ' + self.format_date(start_date)) self.end_button.setText(_('To') + ' ' + self.format_date(end_date)) self.update() def create_toolbar_buttons(self): self.period_combo = QComboBox() self.start_button = QPushButton('-') self.start_button.pressed.connect(self.select_start_date) self.start_button.setEnabled(False) self.end_button = QPushButton('-') self.end_button.pressed.connect(self.select_end_date) self.end_button.setEnabled(False) self.period_combo.addItems([_('All'), _('Custom')]) self.period_combo.activated.connect(self.on_combo) def get_toolbar_buttons(self): return self.period_combo, self.start_button, self.end_button def on_hide_toolbar(self): self.start_timestamp = None self.end_timestamp = None self.update() def save_toolbar_state(self, state, config): config.set_key('show_toolbar_history', state) def select_start_date(self): self.start_timestamp = self.select_date(self.start_button) self.update() def select_end_date(self): self.end_timestamp = self.select_date(self.end_button) self.update() def select_date(self, button): d = WindowModalDialog(self, _("Select date")) d.setMinimumSize(600, 150) d.date = None vbox = QVBoxLayout() def on_date(date): d.date = date cal = QCalendarWidget() cal.setGridVisible(True) cal.clicked[QDate].connect(on_date) vbox.addWidget(cal) vbox.addLayout(Buttons(OkButton(d), CancelButton(d))) d.setLayout(vbox) if d.exec_(): if d.date is None: return None date = d.date.toPyDate() button.setText(self.format_date(date)) return time.mktime(date.timetuple()) def show_summary(self): h = self.summary if not h: self.parent.show_message(_("Nothing to summarize.")) return start_date = h.get('start_date') end_date = h.get('end_date') format_amount = lambda x: self.parent.format_amount( x.value) + ' ' + self.parent.base_unit() d = WindowModalDialog(self, _("Summary")) d.setMinimumSize(600, 150) vbox = QVBoxLayout() grid = QGridLayout() grid.addWidget(QLabel(_("Start")), 0, 0) grid.addWidget(QLabel(self.format_date(start_date)), 0, 1) grid.addWidget(QLabel(str(h.get('start_fiat_value')) + '/$PAC'), 0, 2) grid.addWidget(QLabel(_("Initial balance")), 1, 0) grid.addWidget(QLabel(format_amount(h['start_balance'])), 1, 1) grid.addWidget(QLabel(str(h.get('start_fiat_balance'))), 1, 2) grid.addWidget(QLabel(_("End")), 2, 0) grid.addWidget(QLabel(self.format_date(end_date)), 2, 1) grid.addWidget(QLabel(str(h.get('end_fiat_value')) + '/$PAC'), 2, 2) grid.addWidget(QLabel(_("Final balance")), 4, 0) grid.addWidget(QLabel(format_amount(h['end_balance'])), 4, 1) grid.addWidget(QLabel(str(h.get('end_fiat_balance'))), 4, 2) grid.addWidget(QLabel(_("Income")), 5, 0) grid.addWidget(QLabel(format_amount(h.get('income'))), 5, 1) grid.addWidget(QLabel(str(h.get('fiat_income'))), 5, 2) grid.addWidget(QLabel(_("Expenditures")), 6, 0) grid.addWidget(QLabel(format_amount(h.get('expenditures'))), 6, 1) grid.addWidget(QLabel(str(h.get('fiat_expenditures'))), 6, 2) grid.addWidget(QLabel(_("Capital gains")), 7, 0) grid.addWidget(QLabel(str(h.get('capital_gains'))), 7, 2) grid.addWidget(QLabel(_("Unrealized gains")), 8, 0) grid.addWidget(QLabel(str(h.get('unrealized_gains', ''))), 8, 2) vbox.addLayout(grid) vbox.addLayout(Buttons(CloseButton(d))) d.setLayout(vbox) d.exec_() def plot_history_dialog(self): if plot_history is None: self.parent.show_message( _("Can't plot history.") + '\n' + _("Perhaps some dependencies are missing...") + " (matplotlib?)") return try: plt = plot_history(self.transactions) plt.show() except NothingToPlotException as e: self.parent.show_message(str(e)) @profiler def on_update(self): self.wallet = self.parent.wallet fx = self.parent.fx r = self.wallet.get_full_history(domain=self.get_domain(), from_timestamp=self.start_timestamp, to_timestamp=self.end_timestamp, fx=fx) self.transactions = r['transactions'] self.summary = r['summary'] if not self.years and self.transactions: from datetime import date start_date = self.transactions[0].get('date') or date.today() end_date = self.transactions[-1].get('date') or date.today() self.years = [ str(i) for i in range(start_date.year, end_date.year + 1) ] self.period_combo.insertItems(1, self.years) item = self.currentItem() current_tx = item.data(0, Qt.UserRole) if item else None self.clear() if fx: fx.history_used_spot = False blue_brush = QBrush(QColor("#1E1EFF")) red_brush = QBrush(QColor("#BC1E1E")) # Resize to content when there are data if len(self.transactions) > 0: self.header().setSectionResizeMode(1, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(2, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(4, QHeaderView.ResizeToContents) self.header().setSectionResizeMode(5, QHeaderView.ResizeToContents) for tx_item in self.transactions: tx_hash = tx_item['txid'] conf = tx_item['confirmations'] value = tx_item['value'].value balance = tx_item['balance'].value label = tx_item['label'] tx_mined_status = TxMinedInfo(height=tx_item['height'], conf=tx_item['confirmations'], timestamp=tx_item['timestamp']) status, status_str = self.wallet.get_tx_status( tx_hash, tx_mined_status) has_invoice = self.wallet.invoices.paid.get(tx_hash) icon = read_QIcon(TX_ICONS[status]) v_str = self.parent.format_amount(value, is_diff=True, whitespaces=True) balance_str = self.parent.format_amount(balance, whitespaces=True) entry = ['', tx_hash, status_str, label, v_str, balance_str] fiat_value = None if value is not None and fx and fx.show_history(): fiat_value = tx_item['fiat_value'].value value_str = fx.format_fiat(fiat_value) entry.append(value_str) # fixme: should use is_mine if value < 0: entry.append( fx.format_fiat(tx_item['acquisition_price'].value)) entry.append(fx.format_fiat(tx_item['capital_gain'].value)) item = SortableTreeWidgetItem(entry) item.setIcon(0, icon) item.setToolTip( 0, str(conf) + " confirmation" + ("s" if conf != 1 else "")) item.setData(0, SortableTreeWidgetItem.DataRole, (status, conf)) if has_invoice: item.setIcon(3, self.icon_cache.get(":icons/seal")) for i in range(len(entry)): if i > 3: item.setTextAlignment(i, Qt.AlignRight | Qt.AlignVCenter) if value and value < 0: item.setForeground(3, red_brush) item.setForeground(4, red_brush) if fiat_value and not tx_item['fiat_default']: item.setForeground(6, blue_brush) if tx_hash: item.setData(0, Qt.UserRole, tx_hash) self.insertTopLevelItem(0, item) if current_tx == tx_hash: self.setCurrentItem(item) def on_edited(self, item, column, prior): '''Called only when the text actually changes''' key = item.data(0, Qt.UserRole) text = item.text(column) # fixme if column == 3: self.parent.wallet.set_label(key, text) self.update_labels() self.parent.update_completions() elif column == 6: self.parent.wallet.set_fiat_value(key, self.parent.fx.ccy, text) self.on_update() def on_doubleclick(self, item, column): if self.permit_edit(item, column): super(HistoryList, self).on_doubleclick(item, column) else: tx_hash = item.data(0, Qt.UserRole) tx = self.wallet.transactions.get(tx_hash) self.parent.show_transaction(tx) def update_labels(self): root = self.invisibleRootItem() child_count = root.childCount() for i in range(child_count): item = root.child(i) txid = item.data(0, Qt.UserRole) label = self.wallet.get_label(txid) item.setText(3, label) def update_item(self, wallet, tx_hash, tx_mined_status): if self.wallet is None: return conf = tx_mined_status.conf status, status_str = self.wallet.get_tx_status(tx_hash, tx_mined_status) icon = read_QIcon(TX_ICONS[status]) items = self.findItems(tx_hash, Qt.UserRole | Qt.MatchContains | Qt.MatchRecursive, column=1) if items: item = items[0] item.setIcon(0, icon) item.setData(0, SortableTreeWidgetItem.DataRole, (status, conf)) item.setText(2, status_str) def create_menu(self, position): self.selectedIndexes() item = self.currentItem() if not item: return column = self.currentColumn() tx_hash = item.data(0, Qt.UserRole) if not tx_hash: return if column is 0: column_title = "ID" column_data = tx_hash else: column_title = self.headerItem().text(column) column_data = item.text(column) tx_URL = block_explorer_URL(self.config, 'tx', tx_hash) height = self.wallet.get_tx_height(tx_hash).height tx = self.wallet.db.get_transaction(tx_hash) is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx) is_unconfirmed = height <= 0 pr_key = self.wallet.invoices.paid.get(tx_hash) menu = QMenu() if height == TX_HEIGHT_LOCAL: menu.addAction(_("Remove"), lambda: self.remove_local_tx(tx_hash)) menu.addAction( _("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data)) for c in self.editable_columns: menu.addAction(_("Edit {}").format(self.headerItem().text(c)), lambda bound_c=c: self.editItem(item, bound_c)) menu.addAction(_("Details"), lambda: self.parent.show_transaction(tx)) if pr_key: menu.addAction(read_QIcon("seal"), _("View invoice"), lambda: self.parent.show_invoice(pr_key)) if tx_URL: menu.addAction(_("View on block explorer"), lambda: webbrowser.open(tx_URL)) menu.exec_(self.viewport().mapToGlobal(position)) def remove_local_tx(self, delete_tx): to_delete = {delete_tx} to_delete |= self.wallet.get_depending_transactions(delete_tx) question = _("Are you sure you want to remove this transaction?") if len(to_delete) > 1: question = _( "Are you sure you want to remove this transaction and {} child transactions?" .format(len(to_delete) - 1)) answer = QMessageBox.question(self.parent, _("Please confirm"), question, QMessageBox.Yes, QMessageBox.No) if answer == QMessageBox.No: return for tx in to_delete: self.wallet.remove_transaction(tx) self.wallet.save_transactions(write=True) # need to update at least: history_list, utxo_list, address_list self.parent.need_update.set() def onFileAdded(self, fn): try: with open(fn) as f: tx = self.parent.tx_from_text(f.read()) self.parent.save_transaction_into_wallet(tx) except IOError as e: self.parent.show_error(e) def export_history_dialog(self): d = WindowModalDialog(self, _('Export History')) d.setMinimumSize(400, 200) vbox = QVBoxLayout(d) defaultname = os.path.expanduser('~/electrum-pac-history.csv') select_msg = _('Select file to export your wallet transactions to') hbox, filename_e, csv_button = filename_field(self, self.config, defaultname, select_msg) vbox.addLayout(hbox) vbox.addStretch(1) hbox = Buttons(CancelButton(d), OkButton(d, _('Export'))) vbox.addLayout(hbox) #run_hook('export_history_dialog', self, hbox) self.update() if not d.exec_(): return filename = filename_e.text() if not filename: return try: self.do_export_history(self.wallet, filename, csv_button.isChecked()) except (IOError, os.error) as reason: export_error_label = _( "Pac-Electrum was unable to produce a transaction export.") self.parent.show_critical(export_error_label + "\n" + str(reason), title=_("Unable to export history")) return self.parent.show_message( _("Your wallet history has been successfully exported.")) def do_export_history(self, wallet, fileName, is_csv): history = self.transactions lines = [] for item in history: if is_csv: lines.append([ item['txid'], item.get('label', ''), item['confirmations'], item['value'], item['date'] ]) else: lines.append(item) with open(fileName, "w+", encoding='utf-8') as f: if is_csv: import csv transaction = csv.writer(f, lineterminator='\n') transaction.writerow([ "transaction_hash", "label", "confirmations", "value", "timestamp" ]) for line in lines: transaction.writerow(line) else: from electrum_pac.util import json_encode f.write(json_encode(history))
class Admin(QWidget): def __init__(self): super().__init__() self.resize(250, 300) self.setWindowTitle('PRESTADORES - QUICKHOME') self.move(100, 100) mainlay = QVBoxLayout() self.nombrelabel = QLabel('Nombre:') self.nombreentry = QLineEdit(self) namelay = QHBoxLayout() namelay.addWidget(self.nombrelabel) namelay.addWidget(self.nombreentry) mainlay.addLayout(namelay) tipos = [ 'estilista', 'estecisista', 'nutricionista', 'masajista', 'entrenador', 'manicurista' ] self.tipolabel = QLabel('Tipo:') self.tipoentry = QComboBox(self) self.tipoentry.insertItems(0, tipos) self.tipoentry.setCurrentIndex(0) tipolay = QHBoxLayout() tipolay.addWidget(self.tipolabel) tipolay.addWidget(self.tipoentry) mainlay.addLayout(tipolay) self.direccionlabel = QLabel('Direccion:') self.direccionentry = QLineEdit(self) dirlay = QHBoxLayout() dirlay.addWidget(self.direccionlabel) dirlay.addWidget(self.direccionentry) mainlay.addLayout(dirlay) self.emaillabel = QLabel('Email:') self.emailentry = QLineEdit(self) emaillay = QHBoxLayout() emaillay.addWidget(self.emaillabel) emaillay.addWidget(self.emailentry) mainlay.addLayout(emaillay) self.cellabel = QLabel('Celular:') self.celentry = QLineEdit(self) cellay = QHBoxLayout() cellay.addWidget(self.cellabel) cellay.addWidget(self.celentry) mainlay.addLayout(cellay) self.passwordlabel = QLabel('Contrasena:') self.passwordentry = QLineEdit(self) self.passwordentry.setEchoMode(QLineEdit.Password) passlayout = QHBoxLayout() passlayout.addWidget(self.passwordlabel) passlayout.addWidget(self.passwordentry) mainlay.addLayout(passlayout) self.registrarbutton = QPushButton('REGISTRAR') self.cancelbutton = QPushButton('CANCELAR') self.registrarbutton.clicked.connect(self.register) self.cancelbutton.clicked.connect(self.kill) buttonlay = QHBoxLayout() buttonlay.addWidget(self.registrarbutton) buttonlay.addWidget(self.cancelbutton) mainlay.addLayout(buttonlay) self.setLayout(mainlay) def kill(self): self.close() def register(self): prestador = qh.Prestador(self.nombreentry.text(), self.tipoentry.currentText(), self.direccionentry.text(), self.emailentry.text(), self.celentry.text(), self.passwordentry.text()) response = rp.ejecutar(prestador) if response: QMessageBox.about(self, 'EXITO', 'Se ha registrado el prestador') else: QMessageBox.about(self, 'ERROR', 'Ya existe con ese nombre')
def createEditor( self, parent:QWidget, option: QStyleOptionViewItem, idx: QModelIndex): combobox = QComboBox(parent) combobox.insertItems(0, self.data) combobox.currentIndexChanged.connect(self.currentIndexChanged) return combobox
def add_row(self): new_row_number = self.table.rowCount() self.table.setRowCount(self.table.rowCount()+1) for column, key in enumerate(self.ordered_column_keys): value = self.default_row[key] # print(value, type(value)) if isinstance(value, str): item = QTableWidgetItem(value) self.table.setItem(new_row_number, column, item) elif isinstance(value, list): combo_box = QComboBox() combo_box.insertItems(0, value) # combo_box.setCurrentText(value[0]) self.table.setCellWidget(new_row_number, column, combo_box) else: message = 'Table cells are expected to be either Dict (added asQComboBox via setCellWidget) or String (added as QTableWidgetItem). You have type ' + str(type(value)) message += ' at position ' + str(new_row_number) + ', ' + str(column) raise CellObjectException(message)
def __init__ (self, parent): super().__init__(parent) self.setEnabled(False) layout = QFormLayout(self) l_persistence = QLabel("&Persistence", self) persistence = QComboBox(self) persvals = ("", "Mark", "OnceEver", "OncePerConv") persistence.insertItems(len(persvals), persvals) persistence.currentTextChanged.connect(self.persistencechanged) l_persistence.setBuddy(persistence) self.persistence = persistence l_bankmode = QLabel("&Bank play mode", self) bankmode = QComboBox(self) bankmodes = ("First", "All", "Append") bankmode.insertItems(len(bankmodes), bankmodes) bankmode.currentTextChanged.connect(self.bankmodechanged) l_bankmode.setBuddy(bankmode) self.bankmode = bankmode l_questionhub = QLabel("&Question hub", self) questionhub = QComboBox(self) qhubtypes = ("", "ShowOnce", "ShowNever") questionhub.insertItems(len(qhubtypes), qhubtypes) questionhub.currentTextChanged.connect(self.questionhubchanged) l_questionhub.setBuddy(questionhub) self.questionhub = questionhub l_trigger = QLabel("&Trigger conversation", self) trigger = QComboBox(self) trigger.currentTextChanged.connect(self.triggerchanged) l_trigger.setBuddy(trigger) self.trigger = trigger l_randweight = QLabel("&Random weight", self) randweight = QLineEdit(self) rwvalidator = QDoubleValidator(self) rwvalidator.setBottom(0) rwvalidator.setDecimals(3) randweight.setValidator(rwvalidator) randweight.editingFinished.connect(self.randweightchanged) l_randweight.setBuddy(randweight) self.randweight = randweight l_comment = QLabel("&Comment", self) comment = ParagraphEdit(self) comment.textChanged.connect(self.commentchanged) self.comment = comment l_comment.setBuddy(comment) layout.addRow(l_persistence, persistence) layout.addRow(l_bankmode, bankmode) layout.addRow(l_questionhub, questionhub) layout.addRow(l_trigger, trigger) layout.addRow(l_randweight, randweight) layout.addRow(l_comment, comment) textdoc = QTextDocument(self) textdoc.setDocumentLayout(QPlainTextDocumentLayout(textdoc)) self.blankdoc = textdoc
def addTLSusageCombox(self): usage = ("encipherment", "verify", "issue") comboxUsage = QComboBox() comboxUsage.setView(QListView()) comboxUsage.insertItems(0, usage) return comboxUsage
class QDisplayWidget(QWidget): widget_id = None newLanguageAreaRequested = pyqtSignal() closeLanguageArea = pyqtSignal(int) sword = Sword() def __init__(self): super().__init__() self.layout = QGridLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) self.combo_language = QComboBox() self.combo_translation = QComboBox() self.layout.addWidget(self.combo_language, 0, 0) self.layout.addWidget(self.combo_translation, 0, 1) self.combo_language.currentTextChanged.connect(self.languageChanged) self.combo_translation.currentTextChanged.connect( self.translationChanged) #self.dropdown = QComboBox() #self.dropdown.currentIndexChanged.connect(self.comboBoxChanged) #self.layout.addWidget(self.dropdown, 0, 0) new_language_button = QPushButton(self) new_language_button.setIcon(QIcon.fromTheme('window-new')) new_language_button.setMaximumSize(25, 20) new_language_button.clicked.connect(self.newLanguageButtonClick) self.layout.addWidget(new_language_button, 0, 2) close_language_button = QPushButton(self) close_language_button.setIcon(QIcon.fromTheme('window-close')) close_language_button.setMaximumSize(25, 20) close_language_button.clicked.connect(self.closeButtonClicked) self.layout.addWidget(close_language_button, 0, 3) self.display_widget = QTextEdit() self.display_widget.setReadOnly(True) self.layout.addWidget(self.display_widget, 1, 0, 3, 0) self.getLanguagesForDropdown() """ def setDropdownItems(self, items): self.dropdown.insertItems(0, items) """ def setText(self, text): self.display_widget.setText(text) def getModuleName(self): return self.combo_translation.currentText() def comboBoxChanged(self, index): print(index) print(self.combo_translation.currentText()) def newLanguageButtonClick(self): self.newLanguageAreaRequested.emit() def closeButtonClicked(self): self.closeLanguageArea.emit(self.widget_id) def getLanguagesForDropdown(self): #result = self.interpreter.interpreter('sword.languages', self.queue).payload result = self.sword.listLanguages(None, []).payload self.combo_language.clear() self.combo_language.insertItems(0, result) def getTranslationsForDropdown(self, language): #result = self.interpreter.interpreter('sword.modules '+language, self.queue).payload result = self.sword.listModules(None, [language]).payload translations = [] for translation in result: translations.append(translation[0]) self.combo_translation.clear() self.combo_translation.insertItems(0, translations) def languageChanged(self, language): self.getTranslationsForDropdown(language) def translationChanged(self, translation): #self.showText() pass